Annotation of embedaddon/quagga/ospfclient/ospfclient.c, revision 1.1.1.2

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>