Annotation of embedaddon/quagga/ospfclient/ospfclient.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Simple program to demonstrate how OSPF API can be used. This
! 3: * application retrieves the LSDB from the OSPF daemon and then
! 4: * originates, updates and finally deletes an application-specific
! 5: * opaque LSA. You can use this application as a template when writing
! 6: * your own application.
! 7: */
! 8:
! 9: /* The following includes are needed in all OSPF API client
! 10: applications. */
! 11:
! 12: #include <zebra.h>
! 13: #include "prefix.h" /* needed by ospf_asbr.h */
! 14: #include "privs.h"
! 15: #include "log.h"
! 16:
! 17: #include "ospfd/ospfd.h"
! 18: #include "ospfd/ospf_asbr.h"
! 19: #include "ospfd/ospf_lsa.h"
! 20: #include "ospfd/ospf_opaque.h"
! 21: #include "ospfd/ospf_api.h"
! 22: #include "ospf_apiclient.h"
! 23:
! 24: /* privileges struct.
! 25: * set cap_num_* and uid/gid to nothing to use NULL privs
! 26: * as ospfapiclient links in libospf.a which uses privs.
! 27: */
! 28: struct zebra_privs_t ospfd_privs =
! 29: {
! 30: .user = NULL,
! 31: .group = NULL,
! 32: .cap_num_p = 0,
! 33: .cap_num_i = 0
! 34: };
! 35:
! 36: /* The following includes are specific to this application. For
! 37: example it uses threads from libzebra, however your application is
! 38: free to use any thread library (like pthreads). */
! 39:
! 40: #include "ospfd/ospf_dump.h" /* for ospf_lsa_header_dump */
! 41: #include "thread.h"
! 42: #include "log.h"
! 43:
! 44: /* Local portnumber for async channel. Note that OSPF API library will also
! 45: allocate a sync channel at ASYNCPORT+1. */
! 46: #define ASYNCPORT 4000
! 47:
! 48: /* Master thread */
! 49: struct thread_master *master;
! 50:
! 51: /* Global variables */
! 52: struct ospf_apiclient *oclient;
! 53: char **args;
! 54:
! 55: /* Our opaque LSAs have the following format. */
! 56: struct my_opaque_lsa
! 57: {
! 58: struct lsa_header hdr; /* include common LSA header */
! 59: u_char data[4]; /* our own data format then follows here */
! 60: };
! 61:
! 62:
! 63: /* ---------------------------------------------------------
! 64: * Threads for asynchronous messages and LSA update/delete
! 65: * ---------------------------------------------------------
! 66: */
! 67:
! 68: static int
! 69: lsa_delete (struct thread *t)
! 70: {
! 71: struct ospf_apiclient *oclient;
! 72: struct in_addr area_id;
! 73: int rc;
! 74:
! 75: oclient = THREAD_ARG (t);
! 76:
! 77: inet_aton (args[6], &area_id);
! 78:
! 79: printf ("Deleting LSA... ");
! 80: rc = ospf_apiclient_lsa_delete (oclient,
! 81: area_id,
! 82: atoi (args[2]), /* lsa type */
! 83: atoi (args[3]), /* opaque type */
! 84: atoi (args[4])); /* opaque ID */
! 85: printf ("done, return code is = %d\n", rc);
! 86: return rc;
! 87: }
! 88:
! 89: static int
! 90: lsa_inject (struct thread *t)
! 91: {
! 92: struct ospf_apiclient *cl;
! 93: struct in_addr ifaddr;
! 94: struct in_addr area_id;
! 95: u_char lsa_type;
! 96: u_char opaque_type;
! 97: u_int32_t opaque_id;
! 98: void *opaquedata;
! 99: int opaquelen;
! 100:
! 101: static u_int32_t counter = 1; /* Incremented each time invoked */
! 102: int rc;
! 103:
! 104: cl = THREAD_ARG (t);
! 105:
! 106: inet_aton (args[5], &ifaddr);
! 107: inet_aton (args[6], &area_id);
! 108: lsa_type = atoi (args[2]);
! 109: opaque_type = atoi (args[3]);
! 110: opaque_id = atoi (args[4]);
! 111: opaquedata = &counter;
! 112: opaquelen = sizeof (u_int32_t);
! 113:
! 114: printf ("Originating/updating LSA with counter=%d... ", counter);
! 115: rc = ospf_apiclient_lsa_originate(cl, ifaddr, area_id,
! 116: lsa_type,
! 117: opaque_type, opaque_id,
! 118: opaquedata, opaquelen);
! 119:
! 120: printf ("done, return code is %d\n", rc);
! 121:
! 122: counter++;
! 123:
! 124: return 0;
! 125: }
! 126:
! 127:
! 128: /* This thread handles asynchronous messages coming in from the OSPF
! 129: API server */
! 130: static int
! 131: lsa_read (struct thread *thread)
! 132: {
! 133: struct ospf_apiclient *oclient;
! 134: int fd;
! 135: int ret;
! 136:
! 137: printf ("lsa_read called\n");
! 138:
! 139: oclient = THREAD_ARG (thread);
! 140: fd = THREAD_FD (thread);
! 141:
! 142: /* Handle asynchronous message */
! 143: ret = ospf_apiclient_handle_async (oclient);
! 144: if (ret < 0) {
! 145: printf ("Connection closed, exiting...");
! 146: exit(0);
! 147: }
! 148:
! 149: /* Reschedule read thread */
! 150: thread_add_read (master, lsa_read, oclient, fd);
! 151:
! 152: return 0;
! 153: }
! 154:
! 155: /* ---------------------------------------------------------
! 156: * Callback functions for asynchronous events
! 157: * ---------------------------------------------------------
! 158: */
! 159:
! 160: static void
! 161: lsa_update_callback (struct in_addr ifaddr, struct in_addr area_id,
! 162: u_char is_self_originated,
! 163: struct lsa_header *lsa)
! 164: {
! 165: printf ("lsa_update_callback: ");
! 166: printf ("ifaddr: %s ", inet_ntoa (ifaddr));
! 167: printf ("area: %s\n", inet_ntoa (area_id));
! 168: printf ("is_self_origin: %u\n", is_self_originated);
! 169:
! 170: /* It is important to note that lsa_header does indeed include the
! 171: header and the LSA payload. To access the payload, first check
! 172: the LSA type and then typecast lsa into the corresponding type,
! 173: e.g.:
! 174:
! 175: if (lsa->type == OSPF_ROUTER_LSA) {
! 176: struct router_lsa *rl = (struct router_lsa) lsa;
! 177: ...
! 178: u_int16_t links = rl->links;
! 179: ...
! 180: }
! 181: */
! 182:
! 183: ospf_lsa_header_dump (lsa);
! 184: }
! 185:
! 186: static void
! 187: lsa_delete_callback (struct in_addr ifaddr, struct in_addr area_id,
! 188: u_char is_self_originated,
! 189: struct lsa_header *lsa)
! 190: {
! 191: printf ("lsa_delete_callback: ");
! 192: printf ("ifaddr: %s ", inet_ntoa (ifaddr));
! 193: printf ("area: %s\n", inet_ntoa (area_id));
! 194: printf ("is_self_origin: %u\n", is_self_originated);
! 195:
! 196: ospf_lsa_header_dump (lsa);
! 197: }
! 198:
! 199: static void
! 200: ready_callback (u_char lsa_type, u_char opaque_type, struct in_addr addr)
! 201: {
! 202: printf ("ready_callback: lsa_type: %d opaque_type: %d addr=%s\n",
! 203: lsa_type, opaque_type, inet_ntoa (addr));
! 204:
! 205: /* Schedule opaque LSA originate in 5 secs */
! 206: thread_add_timer (master, lsa_inject, oclient, 5);
! 207:
! 208: /* Schedule opaque LSA update with new value */
! 209: thread_add_timer (master, lsa_inject, oclient, 10);
! 210:
! 211: /* Schedule delete */
! 212: thread_add_timer (master, lsa_delete, oclient, 30);
! 213: }
! 214:
! 215: static void
! 216: new_if_callback (struct in_addr ifaddr, struct in_addr area_id)
! 217: {
! 218: printf ("new_if_callback: ifaddr: %s ", inet_ntoa (ifaddr));
! 219: printf ("area_id: %s\n", inet_ntoa (area_id));
! 220: }
! 221:
! 222: static void
! 223: del_if_callback (struct in_addr ifaddr)
! 224: {
! 225: printf ("new_if_callback: ifaddr: %s\n ", inet_ntoa (ifaddr));
! 226: }
! 227:
! 228: static void
! 229: ism_change_callback (struct in_addr ifaddr, struct in_addr area_id,
! 230: u_char state)
! 231: {
! 232: printf ("ism_change: ifaddr: %s ", inet_ntoa (ifaddr));
! 233: printf ("area_id: %s\n", inet_ntoa (area_id));
! 234: printf ("state: %d [%s]\n", state, LOOKUP (ospf_ism_state_msg, state));
! 235: }
! 236:
! 237: static void
! 238: nsm_change_callback (struct in_addr ifaddr, struct in_addr nbraddr,
! 239: struct in_addr router_id, u_char state)
! 240: {
! 241: printf ("nsm_change: ifaddr: %s ", inet_ntoa (ifaddr));
! 242: printf ("nbraddr: %s\n", inet_ntoa (nbraddr));
! 243: printf ("router_id: %s\n", inet_ntoa (router_id));
! 244: printf ("state: %d [%s]\n", state, LOOKUP (ospf_nsm_state_msg, state));
! 245: }
! 246:
! 247:
! 248: /* ---------------------------------------------------------
! 249: * Main program
! 250: * ---------------------------------------------------------
! 251: */
! 252:
! 253: static int usage()
! 254: {
! 255: printf("Usage: ospfclient <ospfd> <lsatype> <opaquetype> <opaqueid> <ifaddr> <areaid>\n");
! 256: printf("where ospfd : router where API-enabled OSPF daemon is running\n");
! 257: printf(" lsatype : either 9, 10, or 11 depending on flooding scope\n");
! 258: printf(" opaquetype: 0-255 (e.g., experimental applications use > 128)\n");
! 259: printf(" opaqueid : arbitrary application instance (24 bits)\n");
! 260: printf(" ifaddr : interface IP address (for type 9) otherwise ignored\n");
! 261: printf(" areaid : area in IP address format (for type 10) otherwise ignored\n");
! 262:
! 263: exit(1);
! 264: }
! 265:
! 266: int
! 267: main (int argc, char *argv[])
! 268: {
! 269: struct thread thread;
! 270:
! 271: args = argv;
! 272:
! 273: /* ospfclient should be started with the following arguments:
! 274: *
! 275: * (1) host (2) lsa_type (3) opaque_type (4) opaque_id (5) if_addr
! 276: * (6) area_id
! 277: *
! 278: * host: name or IP of host where ospfd is running
! 279: * lsa_type: 9, 10, or 11
! 280: * opaque_type: 0-255 (e.g., experimental applications use > 128)
! 281: * opaque_id: arbitrary application instance (24 bits)
! 282: * if_addr: interface IP address (for type 9) otherwise ignored
! 283: * area_id: area in IP address format (for type 10) otherwise ignored
! 284: */
! 285:
! 286: if (argc != 7)
! 287: {
! 288: usage();
! 289: }
! 290:
! 291: /* Initialization */
! 292: zprivs_init (&ospfd_privs);
! 293: master = thread_master_create ();
! 294:
! 295: /* Open connection to OSPF daemon */
! 296: oclient = ospf_apiclient_connect (args[1], ASYNCPORT);
! 297: if (!oclient)
! 298: {
! 299: printf ("Connecting to OSPF daemon on %s failed!\n",
! 300: args[1]);
! 301: exit (1);
! 302: }
! 303:
! 304: /* Register callback functions. */
! 305: ospf_apiclient_register_callback (oclient,
! 306: ready_callback,
! 307: new_if_callback,
! 308: del_if_callback,
! 309: ism_change_callback,
! 310: nsm_change_callback,
! 311: lsa_update_callback,
! 312: lsa_delete_callback);
! 313:
! 314: /* Register LSA type and opaque type. */
! 315: ospf_apiclient_register_opaque_type (oclient, atoi (args[2]),
! 316: atoi (args[3]));
! 317:
! 318: /* Synchronize database with OSPF daemon. */
! 319: ospf_apiclient_sync_lsdb (oclient);
! 320:
! 321: /* Schedule thread that handles asynchronous messages */
! 322: thread_add_read (master, lsa_read, oclient, oclient->fd_async);
! 323:
! 324: /* Now connection is established, run loop */
! 325: while (1)
! 326: {
! 327: thread_fetch (master, &thread);
! 328: thread_call (&thread);
! 329: }
! 330:
! 331: /* Never reached */
! 332: return 0;
! 333: }
! 334:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>