Annotation of embedaddon/quagga/ospfclient/ospfclient.c, revision 1.1.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>