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>