ospfclient.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. * Simple main program to demonstrate how OSPF API can be used.
  3. */
  4. /* The following includes are needed in all OSPF API client
  5. applications */
  6. #include <zebra.h>
  7. #include "prefix.h" /* for ospf_asbr.h */
  8. #include "ospfd/ospfd.h"
  9. #include "ospfd/ospf_asbr.h"
  10. #include "ospfd/ospf_lsa.h"
  11. #include "ospfd/ospf_opaque.h"
  12. #include "ospfd/ospf_lsdb.h"
  13. #include "ospfd/ospf_dump.h"
  14. #include "ospfd/ospf_api.h"
  15. #include "ospf_apiclient.h"
  16. /* The following includes are specific to this main application. Here
  17. main uses the thread functionality from libzebra (however an
  18. application can use any thread library like pthreads) */
  19. #include "thread.h"
  20. #include "log.h"
  21. /* local portnumber for async channel */
  22. #define ASYNCPORT 4000
  23. /* Master thread */
  24. struct thread_master *master;
  25. /* Global variables */
  26. struct ospf_apiclient *oclient;
  27. char **args;
  28. /* Our opaque LSAs have the following format */
  29. struct my_opaque_lsa
  30. {
  31. struct lsa_header hdr;
  32. u_char data[4];
  33. };
  34. /* ---------------------------------------------------------
  35. * Threads for asynchronous messages and LSA update/delete
  36. * ---------------------------------------------------------
  37. */
  38. int
  39. lsa_delete (struct thread *t)
  40. {
  41. struct ospf_apiclient *oclient;
  42. struct in_addr area_id;
  43. int rc;
  44. oclient = THREAD_ARG (t);
  45. inet_aton (args[6], &area_id);
  46. printf ("Deleting LSA... ");
  47. rc = ospf_apiclient_lsa_delete (oclient,
  48. area_id,
  49. atoi (args[2]), /* lsa type */
  50. atoi (args[3]), /* opaque type */
  51. atoi (args[4])); /* opaque ID */
  52. printf ("done, return code is = %d\n", rc);
  53. return rc;
  54. }
  55. int
  56. lsa_inject (struct thread *t)
  57. {
  58. struct ospf_apiclient *cl;
  59. struct in_addr ifaddr;
  60. struct in_addr area_id;
  61. u_char lsa_type;
  62. u_char opaque_type;
  63. u_int32_t opaque_id;
  64. void *opaquedata;
  65. int opaquelen;
  66. static u_int32_t counter = 1; /* Incremented each time */
  67. int rc;
  68. cl = THREAD_ARG (t);
  69. inet_aton (args[5], &ifaddr);
  70. inet_aton (args[6], &area_id);
  71. lsa_type = atoi (args[2]);
  72. opaque_type = atoi (args[3]);
  73. opaque_id = atoi (args[4]);
  74. opaquedata = &counter;
  75. opaquelen = sizeof (u_int32_t);
  76. printf ("Originating/updating LSA with counter=%d... ", counter);
  77. rc = ospf_apiclient_lsa_originate(cl, ifaddr, area_id,
  78. lsa_type,
  79. opaque_type, opaque_id,
  80. opaquedata, opaquelen);
  81. printf ("done, return code is %d\n", rc);
  82. counter++;
  83. return 0;
  84. };
  85. /* This thread handles asynchronous messages coming in from the OSPF
  86. API server */
  87. int
  88. lsa_read (struct thread *thread)
  89. {
  90. struct ospf_apiclient *oclient;
  91. int fd;
  92. int ret;
  93. printf ("lsa_read called\n");
  94. oclient = THREAD_ARG (thread);
  95. fd = THREAD_FD (thread);
  96. /* Handle asynchronous message */
  97. ret = ospf_apiclient_handle_async (oclient);
  98. if (ret < 0) {
  99. printf ("Connection closed, exiting...");
  100. exit(0);
  101. }
  102. /* Reschedule read thread */
  103. thread_add_read (master, lsa_read, oclient, fd);
  104. return 0;
  105. }
  106. /* ---------------------------------------------------------
  107. * Callback functions for asynchronous events
  108. * ---------------------------------------------------------
  109. */
  110. void
  111. lsa_update_callback (struct in_addr ifaddr, struct in_addr area_id,
  112. u_char is_self_originated,
  113. struct lsa_header *lsa)
  114. {
  115. printf ("lsa_update_callback: ");
  116. printf ("ifaddr: %s ", inet_ntoa (ifaddr));
  117. printf ("area: %s\n", inet_ntoa (area_id));
  118. printf ("is_self_origin: %u\n", is_self_originated);
  119. ospf_lsa_header_dump (lsa);
  120. }
  121. void
  122. lsa_delete_callback (struct in_addr ifaddr, struct in_addr area_id,
  123. u_char is_self_originated,
  124. struct lsa_header *lsa)
  125. {
  126. printf ("lsa_delete_callback: ");
  127. printf ("ifaddr: %s ", inet_ntoa (ifaddr));
  128. printf ("area: %s\n", inet_ntoa (area_id));
  129. printf ("is_self_origin: %u\n", is_self_originated);
  130. ospf_lsa_header_dump (lsa);
  131. }
  132. void
  133. ready_callback (u_char lsa_type, u_char opaque_type, struct in_addr addr)
  134. {
  135. printf ("ready_callback: lsa_type: %d opaque_type: %d addr=%s\n",
  136. lsa_type, opaque_type, inet_ntoa (addr));
  137. /* Schedule opaque LSA originate in 5 secs */
  138. thread_add_timer (master, lsa_inject, oclient, 5);
  139. /* Schedule opaque LSA update with new value */
  140. thread_add_timer (master, lsa_inject, oclient, 10);
  141. /* Schedule delete */
  142. thread_add_timer (master, lsa_delete, oclient, 30);
  143. }
  144. void
  145. new_if_callback (struct in_addr ifaddr, struct in_addr area_id)
  146. {
  147. printf ("new_if_callback: ifaddr: %s ", inet_ntoa (ifaddr));
  148. printf ("area_id: %s\n", inet_ntoa (area_id));
  149. }
  150. void
  151. del_if_callback (struct in_addr ifaddr)
  152. {
  153. printf ("new_if_callback: ifaddr: %s\n ", inet_ntoa (ifaddr));
  154. }
  155. void
  156. ism_change_callback (struct in_addr ifaddr, struct in_addr area_id,
  157. u_char state)
  158. {
  159. printf ("ism_change: ifaddr: %s ", inet_ntoa (ifaddr));
  160. printf ("area_id: %s\n", inet_ntoa (area_id));
  161. printf ("state: %d [%s]\n", state, LOOKUP (ospf_ism_state_msg, state));
  162. }
  163. void
  164. nsm_change_callback (struct in_addr ifaddr, struct in_addr nbraddr,
  165. struct in_addr router_id, u_char state)
  166. {
  167. printf ("nsm_change: ifaddr: %s ", inet_ntoa (ifaddr));
  168. printf ("nbraddr: %s\n", inet_ntoa (nbraddr));
  169. printf ("router_id: %s\n", inet_ntoa (router_id));
  170. printf ("state: %d [%s]\n", state, LOOKUP (ospf_nsm_state_msg, state));
  171. }
  172. /* ---------------------------------------------------------
  173. * Main program
  174. * ---------------------------------------------------------
  175. */
  176. int
  177. main (int argc, char *argv[])
  178. {
  179. struct thread thread;
  180. args = argv;
  181. /* Main should be started with the following arguments:
  182. *
  183. * (1) host (2) lsa_type (3) opaque_type (4) opaque_id (5) if_addr
  184. * (6) area_id
  185. *
  186. * host: name or IP of host where ospfd is running
  187. * lsa_type: 9, 10, or 11
  188. * opaque_type: 0-255 (e.g., 140 for experimental Active Networking)
  189. * opaque_id: arbitrary application instance (24 bits)
  190. * if_addr: interface IP address (for type 9) otherwise ignored
  191. * area_id: area in IP address format (for type 10) otherwise ignored
  192. */
  193. if (argc != 7)
  194. {
  195. printf ("main: wrong number of arguments!\n");
  196. exit (1);
  197. }
  198. /* Initialization */
  199. master = thread_master_create ();
  200. /* Open connection to OSPF daemon */
  201. oclient = ospf_apiclient_connect (args[1], ASYNCPORT);
  202. if (!oclient)
  203. {
  204. printf ("main: connect failed!\n");
  205. exit (1);
  206. }
  207. /* Register callback functions. */
  208. ospf_apiclient_register_callback (oclient,
  209. ready_callback,
  210. new_if_callback,
  211. del_if_callback,
  212. ism_change_callback,
  213. nsm_change_callback,
  214. lsa_update_callback,
  215. lsa_delete_callback);
  216. /* Register LSA type and opaque type. */
  217. ospf_apiclient_register_opaque_type (oclient, atoi (args[2]),
  218. atoi (args[3]));
  219. /* Synchronize database with OSPF daemon. */
  220. ospf_apiclient_sync_lsdb (oclient);
  221. /* Schedule thread that handles asynchronous messages */
  222. thread_add_read (master, lsa_read, oclient, oclient->fd_async);
  223. /* Now connection is established, run loop */
  224. while (1)
  225. {
  226. thread_fetch (master, &thread);
  227. thread_call (&thread);
  228. }
  229. /* Never reached */
  230. return 0;
  231. }