Annotation of embedaddon/quagga/ospfd/ospf_api.c, revision 1.1.1.3

1.1       misho       1: /*
                      2:  * API message handling module for OSPF daemon and client.
                      3:  * Copyright (C) 2001, 2002 Ralph Keller
                      4:  *
                      5:  * This file is part of GNU Zebra.
                      6:  * 
                      7:  * GNU Zebra is free software; you can redistribute it and/or modify
                      8:  * it under the terms of the GNU General Public License as published
                      9:  * by the Free Software Foundation; either version 2, or (at your
                     10:  * option) any later version.
                     11:  *
                     12:  * GNU Zebra is distributed in the hope that it will be useful, but
                     13:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     15:  * General Public License for more details.
                     16:  *
                     17:  * You should have received a copy of the GNU General Public License
                     18:  * along with GNU Zebra; see the file COPYING.  If not, write to the
                     19:  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
                     20:  * Boston, MA 02111-1307, USA.
                     21:  */
                     22: 
                     23: #include <zebra.h>
                     24: 
                     25: #ifdef SUPPORT_OSPF_API
                     26: 
                     27: #include "linklist.h"
                     28: #include "prefix.h"
                     29: #include "if.h"
                     30: #include "table.h"
                     31: #include "memory.h"
                     32: #include "command.h"
                     33: #include "vty.h"
                     34: #include "stream.h"
                     35: #include "log.h"
                     36: #include "thread.h"
                     37: #include "hash.h"
                     38: #include "sockunion.h"         /* for inet_aton() */
                     39: #include "buffer.h"
                     40: #include "network.h"
                     41: 
                     42: #include "ospfd/ospfd.h"
                     43: #include "ospfd/ospf_interface.h"
                     44: #include "ospfd/ospf_ism.h"
                     45: #include "ospfd/ospf_asbr.h"
                     46: #include "ospfd/ospf_lsa.h"
                     47: #include "ospfd/ospf_lsdb.h"
                     48: #include "ospfd/ospf_neighbor.h"
                     49: #include "ospfd/ospf_nsm.h"
                     50: #include "ospfd/ospf_flood.h"
                     51: #include "ospfd/ospf_packet.h"
                     52: #include "ospfd/ospf_spf.h"
                     53: #include "ospfd/ospf_dump.h"
                     54: #include "ospfd/ospf_route.h"
                     55: #include "ospfd/ospf_ase.h"
                     56: #include "ospfd/ospf_zebra.h"
                     57: 
                     58: #include "ospfd/ospf_api.h"
                     59: 
                     60: 
                     61: /* For debugging only, will be removed */
                     62: void
                     63: api_opaque_lsa_print (struct lsa_header *data)
                     64: {
                     65:   struct opaque_lsa
                     66:   {
                     67:     struct lsa_header header;
                     68:     u_char mydata[];
                     69:   };
                     70: 
                     71:   struct opaque_lsa *olsa;
                     72:   int opaquelen;
                     73:   int i;
                     74: 
                     75:   ospf_lsa_header_dump (data);
                     76: 
                     77:   olsa = (struct opaque_lsa *) data;
                     78: 
                     79:   opaquelen = ntohs (data->length) - OSPF_LSA_HEADER_SIZE;
                     80:   zlog_debug ("apiserver_lsa_print: opaquelen=%d\n", opaquelen);
                     81: 
                     82:   for (i = 0; i < opaquelen; i++)
                     83:     {
                     84:       zlog_debug ("0x%x ", olsa->mydata[i]);
                     85:     }
                     86:   zlog_debug ("\n");
                     87: }
                     88: 
                     89: /* -----------------------------------------------------------
                     90:  * Generic messages
                     91:  * -----------------------------------------------------------
                     92:  */
                     93: 
                     94: struct msg *
                     95: msg_new (u_char msgtype, void *msgbody, u_int32_t seqnum, u_int16_t msglen)
                     96: {
                     97:   struct msg *new;
                     98: 
                     99:   new = XCALLOC (MTYPE_OSPF_API_MSG, sizeof (struct msg));
                    100: 
                    101:   new->hdr.version = OSPF_API_VERSION;
                    102:   new->hdr.msgtype = msgtype;
                    103:   new->hdr.msglen = htons (msglen);
                    104:   new->hdr.msgseq = htonl (seqnum);
                    105: 
                    106:   new->s = stream_new (msglen);
                    107:   assert (new->s);
                    108:   stream_put (new->s, msgbody, msglen);
                    109: 
                    110:   return new;
                    111: }
                    112: 
                    113: 
                    114: /* Duplicate a message by copying content. */
                    115: struct msg *
                    116: msg_dup (struct msg *msg)
                    117: {
                    118:   struct msg *new;
                    119: 
                    120:   assert (msg);
                    121: 
                    122:   new = msg_new (msg->hdr.msgtype, STREAM_DATA (msg->s),
                    123:                 ntohl (msg->hdr.msgseq), ntohs (msg->hdr.msglen));
                    124:   return new;
                    125: }
                    126: 
                    127: 
                    128: /* XXX only for testing, will be removed */
                    129: 
                    130: struct nametab {
                    131:   int value;
                    132:   const char *name;
                    133: };
                    134: 
                    135: const char *
                    136: ospf_api_typename (int msgtype)
                    137: {
                    138:   struct nametab NameTab[] = {
                    139:     { MSG_REGISTER_OPAQUETYPE,   "Register opaque-type",   },
                    140:     { MSG_UNREGISTER_OPAQUETYPE, "Unregister opaque-type", },
                    141:     { MSG_REGISTER_EVENT,        "Register event",         },
                    142:     { MSG_SYNC_LSDB,             "Sync LSDB",              },
                    143:     { MSG_ORIGINATE_REQUEST,     "Originate request",      },
                    144:     { MSG_DELETE_REQUEST,        "Delete request",         },
                    145:     { MSG_REPLY,                 "Reply",                  },
                    146:     { MSG_READY_NOTIFY,          "Ready notify",           },
                    147:     { MSG_LSA_UPDATE_NOTIFY,     "LSA update notify",      },
                    148:     { MSG_LSA_DELETE_NOTIFY,     "LSA delete notify",      },
                    149:     { MSG_NEW_IF,                "New interface",          },
                    150:     { MSG_DEL_IF,                "Del interface",          },
                    151:     { MSG_ISM_CHANGE,            "ISM change",             },
                    152:     { MSG_NSM_CHANGE,            "NSM change",             },
                    153:   };
                    154: 
1.1.1.2   misho     155:   int i, n = array_size(NameTab);
1.1       misho     156:   const char *name = NULL;
                    157: 
                    158:   for (i = 0; i < n; i++)
                    159:     {
                    160:       if (NameTab[i].value == msgtype)
                    161:         {
                    162:           name = NameTab[i].name;
                    163:           break;
                    164:         }
                    165:     }
                    166: 
                    167:   return name ? name : "?";
                    168: }
                    169: 
                    170: const char *
                    171: ospf_api_errname (int errcode)
                    172: {
                    173:   struct nametab NameTab[] = {
                    174:     { OSPF_API_OK,                      "OK",                         },
                    175:     { OSPF_API_NOSUCHINTERFACE,         "No such interface",          },
                    176:     { OSPF_API_NOSUCHAREA,              "No such area",               },
                    177:     { OSPF_API_NOSUCHLSA,               "No such LSA",                },
                    178:     { OSPF_API_ILLEGALLSATYPE,          "Illegal LSA type",           },
                    179:     { OSPF_API_OPAQUETYPEINUSE,         "Opaque type in use",         },
                    180:     { OSPF_API_OPAQUETYPENOTREGISTERED, "Opaque type not registered", },
                    181:     { OSPF_API_NOTREADY,                "Not ready",                  },
                    182:     { OSPF_API_NOMEMORY,                "No memory",                  },
                    183:     { OSPF_API_ERROR,                   "Other error",                },
                    184:     { OSPF_API_UNDEF,                   "Undefined",                  },
                    185:   };
                    186: 
1.1.1.2   misho     187:   int i, n = array_size(NameTab);
1.1       misho     188:   const char *name = NULL;
                    189: 
                    190:   for (i = 0; i < n; i++)
                    191:     {
                    192:       if (NameTab[i].value == errcode)
                    193:         {
                    194:           name = NameTab[i].name;
                    195:           break;
                    196:         }
                    197:     }
                    198: 
                    199:   return name ? name : "?";
                    200: }
                    201: 
                    202: void
                    203: msg_print (struct msg *msg)
                    204: {
                    205:   if (!msg)
                    206:     {
                    207:       zlog_debug ("msg_print msg=NULL!\n");
                    208:       return;
                    209:     }
                    210: 
                    211: #ifdef ORIGINAL_CODING
                    212:   zlog_debug
                    213:     ("msg=%p msgtype=%d msglen=%d msgseq=%d streamdata=%p streamsize=%lu\n",
                    214:      msg, msg->hdr.msgtype, ntohs (msg->hdr.msglen), ntohl (msg->hdr.msgseq),
                    215:      STREAM_DATA (msg->s), STREAM_SIZE (msg->s));
                    216: #else /* ORIGINAL_CODING */
                    217:   /* API message common header part. */
                    218:   zlog_debug
                    219:     ("API-msg [%s]: type(%d),len(%d),seq(%lu),data(%p),size(%zd)",
                    220:      ospf_api_typename (msg->hdr.msgtype), msg->hdr.msgtype, 
                    221:      ntohs (msg->hdr.msglen), (unsigned long) ntohl (msg->hdr.msgseq),
                    222:      STREAM_DATA (msg->s), STREAM_SIZE (msg->s));
                    223: 
                    224:   /* API message body part. */
                    225: #ifdef ndef
                    226:   /* Generic Hex/Ascii dump */
                    227:   DumpBuf (STREAM_DATA (msg->s), STREAM_SIZE (msg->s)); /* Sorry, deleted! */
                    228: #else /* ndef */
                    229:   /* Message-type dependent dump function. */
                    230: #endif /* ndef */
                    231: 
                    232:   return;
                    233: #endif /* ORIGINAL_CODING */
                    234: }
                    235: 
                    236: void
                    237: msg_free (struct msg *msg)
                    238: {
                    239:   if (msg->s)
                    240:     stream_free (msg->s);
                    241: 
                    242:   XFREE (MTYPE_OSPF_API_MSG, msg);
                    243: }
                    244: 
                    245: 
                    246: /* Set sequence number of message */
                    247: void
                    248: msg_set_seq (struct msg *msg, u_int32_t seqnr)
                    249: {
                    250:   assert (msg);
                    251:   msg->hdr.msgseq = htonl (seqnr);
                    252: }
                    253: 
                    254: /* Get sequence number of message */
                    255: u_int32_t
                    256: msg_get_seq (struct msg *msg)
                    257: {
                    258:   assert (msg);
                    259:   return ntohl (msg->hdr.msgseq);
                    260: }
                    261: 
                    262: /* -----------------------------------------------------------
                    263:  * Message fifo queues
                    264:  * -----------------------------------------------------------
                    265:  */
                    266: 
                    267: struct msg_fifo *
                    268: msg_fifo_new ()
                    269: {
                    270:   return XCALLOC (MTYPE_OSPF_API_FIFO, sizeof (struct msg_fifo));
                    271: }
                    272: 
                    273: /* Add new message to fifo. */
                    274: void
                    275: msg_fifo_push (struct msg_fifo *fifo, struct msg *msg)
                    276: {
                    277:   if (fifo->tail)
                    278:     fifo->tail->next = msg;
                    279:   else
                    280:     fifo->head = msg;
                    281: 
                    282:   fifo->tail = msg;
                    283:   fifo->count++;
                    284: }
                    285: 
                    286: 
                    287: /* Remove first message from fifo. */
                    288: struct msg *
                    289: msg_fifo_pop (struct msg_fifo *fifo)
                    290: {
                    291:   struct msg *msg;
                    292: 
                    293:   msg = fifo->head;
                    294:   if (msg)
                    295:     {
                    296:       fifo->head = msg->next;
                    297: 
                    298:       if (fifo->head == NULL)
                    299:        fifo->tail = NULL;
                    300: 
                    301:       fifo->count--;
                    302:     }
                    303:   return msg;
                    304: }
                    305: 
                    306: /* Return first fifo entry but do not remove it. */
                    307: struct msg *
                    308: msg_fifo_head (struct msg_fifo *fifo)
                    309: {
                    310:   return fifo->head;
                    311: }
                    312: 
                    313: /* Flush message fifo. */
                    314: void
                    315: msg_fifo_flush (struct msg_fifo *fifo)
                    316: {
                    317:   struct msg *op;
                    318:   struct msg *next;
                    319: 
                    320:   for (op = fifo->head; op; op = next)
                    321:     {
                    322:       next = op->next;
                    323:       msg_free (op);
                    324:     }
                    325: 
                    326:   fifo->head = fifo->tail = NULL;
                    327:   fifo->count = 0;
                    328: }
                    329: 
                    330: /* Free API message fifo. */
                    331: void
                    332: msg_fifo_free (struct msg_fifo *fifo)
                    333: {
                    334:   msg_fifo_flush (fifo);
                    335: 
                    336:   XFREE (MTYPE_OSPF_API_FIFO, fifo);
                    337: }
                    338: 
                    339: struct msg *
                    340: msg_read (int fd)
                    341: {
                    342:   struct msg *msg;
                    343:   struct apimsghdr hdr;
                    344:   u_char buf[OSPF_API_MAX_MSG_SIZE];
                    345:   int bodylen;
                    346:   int rlen;
                    347: 
                    348:   /* Read message header */
                    349:   rlen = readn (fd, (u_char *) &hdr, sizeof (struct apimsghdr));
                    350: 
                    351:   if (rlen < 0)
                    352:     {
                    353:       zlog_warn ("msg_read: readn %s", safe_strerror (errno));
                    354:       return NULL;
                    355:     }
                    356:   else if (rlen == 0)
                    357:     {
                    358:       zlog_warn ("msg_read: Connection closed by peer");
                    359:       return NULL;
                    360:     }
                    361:   else if (rlen != sizeof (struct apimsghdr))
                    362:     {
                    363:       zlog_warn ("msg_read: Cannot read message header!");
                    364:       return NULL;
                    365:     }
                    366: 
                    367:   /* Check version of API protocol */
                    368:   if (hdr.version != OSPF_API_VERSION)
                    369:     {
                    370:       zlog_warn ("msg_read: OSPF API protocol version mismatch");
                    371:       return NULL;
                    372:     }
                    373: 
                    374:   /* Determine body length. */
                    375:   bodylen = ntohs (hdr.msglen);
                    376:   if (bodylen > 0)
                    377:     {
                    378: 
                    379:       /* Read message body */
                    380:       rlen = readn (fd, buf, bodylen);
                    381:       if (rlen < 0)
                    382:        {
                    383:          zlog_warn ("msg_read: readn %s", safe_strerror (errno));
                    384:          return NULL;
                    385:        }
                    386:       else if (rlen == 0)
                    387:        {
                    388:          zlog_warn ("msg_read: Connection closed by peer");
                    389:          return NULL;
                    390:        }
                    391:       else if (rlen != bodylen)
                    392:        {
                    393:          zlog_warn ("msg_read: Cannot read message body!");
                    394:          return NULL;
                    395:        }
                    396:     }
                    397: 
                    398:   /* Allocate new message */
                    399:   msg = msg_new (hdr.msgtype, buf, ntohl (hdr.msgseq), ntohs (hdr.msglen));
                    400: 
                    401:   return msg;
                    402: }
                    403: 
                    404: int
                    405: msg_write (int fd, struct msg *msg)
                    406: {
                    407:   u_char buf[OSPF_API_MAX_MSG_SIZE];
                    408:   int l;
                    409:   int wlen;
                    410: 
                    411:   assert (msg);
                    412:   assert (msg->s);
                    413: 
                    414:   /* Length of message including header */
                    415:   l = sizeof (struct apimsghdr) + ntohs (msg->hdr.msglen);
                    416: 
                    417:   /* Make contiguous memory buffer for message */
                    418:   memcpy (buf, &msg->hdr, sizeof (struct apimsghdr));
                    419:   memcpy (buf + sizeof (struct apimsghdr), STREAM_DATA (msg->s),
                    420:          ntohs (msg->hdr.msglen));
                    421: 
                    422:   wlen = writen (fd, buf, l);
                    423:   if (wlen < 0)
                    424:     {
                    425:       zlog_warn ("msg_write: writen %s", safe_strerror (errno));
                    426:       return -1;
                    427:     }
                    428:   else if (wlen == 0)
                    429:     {
                    430:       zlog_warn ("msg_write: Connection closed by peer");
                    431:       return -1;
                    432:     }
                    433:   else if (wlen != l)
                    434:     {
                    435:       zlog_warn ("msg_write: Cannot write API message");
                    436:       return -1;
                    437:     }
                    438:   return 0;
                    439: }
                    440: 
                    441: /* -----------------------------------------------------------
                    442:  * Specific messages
                    443:  * -----------------------------------------------------------
                    444:  */
                    445: 
                    446: struct msg *
                    447: new_msg_register_opaque_type (u_int32_t seqnum, u_char ltype, u_char otype)
                    448: {
                    449:   struct msg_register_opaque_type rmsg;
                    450: 
                    451:   rmsg.lsatype = ltype;
                    452:   rmsg.opaquetype = otype;
                    453:   memset (&rmsg.pad, 0, sizeof (rmsg.pad));
                    454: 
                    455:   return msg_new (MSG_REGISTER_OPAQUETYPE, &rmsg, seqnum,
                    456:                  sizeof (struct msg_register_opaque_type));
                    457: }
                    458: 
                    459: struct msg *
                    460: new_msg_register_event (u_int32_t seqnum, struct lsa_filter_type *filter)
                    461: {
                    462:   u_char buf[OSPF_API_MAX_MSG_SIZE];
                    463:   struct msg_register_event *emsg;
1.1.1.3 ! misho     464:   size_t len;
1.1       misho     465: 
                    466:   emsg = (struct msg_register_event *) buf;
                    467:   len = sizeof (struct msg_register_event) +
                    468:     filter->num_areas * sizeof (struct in_addr);
                    469:   emsg->filter.typemask = htons (filter->typemask);
                    470:   emsg->filter.origin = filter->origin;
                    471:   emsg->filter.num_areas = filter->num_areas;
1.1.1.3 ! misho     472:   if (len > sizeof (buf))
        !           473:     len = sizeof(buf);
        !           474:   /* API broken - missing memcpy to fill data */
1.1       misho     475:   return msg_new (MSG_REGISTER_EVENT, emsg, seqnum, len);
                    476: }
                    477: 
                    478: struct msg *
                    479: new_msg_sync_lsdb (u_int32_t seqnum, struct lsa_filter_type *filter)
                    480: {
                    481:   u_char buf[OSPF_API_MAX_MSG_SIZE];
                    482:   struct msg_sync_lsdb *smsg;
1.1.1.3 ! misho     483:   size_t len;
1.1       misho     484: 
                    485:   smsg = (struct msg_sync_lsdb *) buf;
                    486:   len = sizeof (struct msg_sync_lsdb) +
                    487:     filter->num_areas * sizeof (struct in_addr);
                    488:   smsg->filter.typemask = htons (filter->typemask);
                    489:   smsg->filter.origin = filter->origin;
                    490:   smsg->filter.num_areas = filter->num_areas;
1.1.1.3 ! misho     491:   if (len > sizeof (buf))
        !           492:     len = sizeof(buf);
        !           493:   /* API broken - missing memcpy to fill data */
1.1       misho     494:   return msg_new (MSG_SYNC_LSDB, smsg, seqnum, len);
                    495: }
                    496: 
                    497: 
                    498: struct msg *
                    499: new_msg_originate_request (u_int32_t seqnum,
                    500:                           struct in_addr ifaddr,
                    501:                           struct in_addr area_id, struct lsa_header *data)
                    502: {
                    503:   struct msg_originate_request *omsg;
1.1.1.3 ! misho     504:   size_t omsglen;
1.1       misho     505:   char buf[OSPF_API_MAX_MSG_SIZE];
                    506: 
                    507:   omsg = (struct msg_originate_request *) buf;
                    508:   omsg->ifaddr = ifaddr;
                    509:   omsg->area_id = area_id;
1.1.1.3 ! misho     510: 
        !           511:   omsglen = ntohs (data->length);
        !           512:   if (omsglen > sizeof (buf) - offsetof (struct msg_originate_request, data))
        !           513:     omsglen = sizeof (buf) - offsetof (struct msg_originate_request, data);
        !           514:   memcpy (&omsg->data, data, omsglen);
        !           515:   omsglen += sizeof (struct msg_originate_request) - sizeof (struct lsa_header);
1.1       misho     516: 
                    517:   return msg_new (MSG_ORIGINATE_REQUEST, omsg, seqnum, omsglen);
                    518: }
                    519: 
                    520: struct msg *
                    521: new_msg_delete_request (u_int32_t seqnum,
                    522:                        struct in_addr area_id, u_char lsa_type,
                    523:                        u_char opaque_type, u_int32_t opaque_id)
                    524: {
                    525:   struct msg_delete_request dmsg;
                    526:   dmsg.area_id = area_id;
                    527:   dmsg.lsa_type = lsa_type;
                    528:   dmsg.opaque_type = opaque_type;
                    529:   dmsg.opaque_id = htonl (opaque_id);
                    530:   memset (&dmsg.pad, 0, sizeof (dmsg.pad));
                    531: 
                    532:   return msg_new (MSG_DELETE_REQUEST, &dmsg, seqnum,
                    533:                  sizeof (struct msg_delete_request));
                    534: }
                    535: 
                    536: 
                    537: struct msg *
                    538: new_msg_reply (u_int32_t seqnr, u_char rc)
                    539: {
                    540:   struct msg *msg;
                    541:   struct msg_reply rmsg;
                    542: 
                    543:   /* Set return code */
                    544:   rmsg.errcode = rc;
                    545:   memset (&rmsg.pad, 0, sizeof (rmsg.pad));
                    546: 
                    547:   msg = msg_new (MSG_REPLY, &rmsg, seqnr, sizeof (struct msg_reply));
                    548: 
                    549:   return msg;
                    550: }
                    551: 
                    552: struct msg *
                    553: new_msg_ready_notify (u_int32_t seqnr, u_char lsa_type,
                    554:                      u_char opaque_type, struct in_addr addr)
                    555: {
                    556:   struct msg_ready_notify rmsg;
                    557: 
                    558:   rmsg.lsa_type = lsa_type;
                    559:   rmsg.opaque_type = opaque_type;
                    560:   memset (&rmsg.pad, 0, sizeof (rmsg.pad));
                    561:   rmsg.addr = addr;
                    562: 
                    563:   return msg_new (MSG_READY_NOTIFY, &rmsg, seqnr,
                    564:                  sizeof (struct msg_ready_notify));
                    565: }
                    566: 
                    567: struct msg *
                    568: new_msg_new_if (u_int32_t seqnr,
                    569:                struct in_addr ifaddr, struct in_addr area_id)
                    570: {
                    571:   struct msg_new_if nmsg;
                    572: 
                    573:   nmsg.ifaddr = ifaddr;
                    574:   nmsg.area_id = area_id;
                    575: 
                    576:   return msg_new (MSG_NEW_IF, &nmsg, seqnr, sizeof (struct msg_new_if));
                    577: }
                    578: 
                    579: struct msg *
                    580: new_msg_del_if (u_int32_t seqnr, struct in_addr ifaddr)
                    581: {
                    582:   struct msg_del_if dmsg;
                    583: 
                    584:   dmsg.ifaddr = ifaddr;
                    585: 
                    586:   return msg_new (MSG_DEL_IF, &dmsg, seqnr, sizeof (struct msg_del_if));
                    587: }
                    588: 
                    589: struct msg *
                    590: new_msg_ism_change (u_int32_t seqnr, struct in_addr ifaddr,
                    591:                    struct in_addr area_id, u_char status)
                    592: {
                    593:   struct msg_ism_change imsg;
                    594: 
                    595:   imsg.ifaddr = ifaddr;
                    596:   imsg.area_id = area_id;
                    597:   imsg.status = status;
                    598:   memset (&imsg.pad, 0, sizeof (imsg.pad));
                    599: 
                    600:   return msg_new (MSG_ISM_CHANGE, &imsg, seqnr,
                    601:                  sizeof (struct msg_ism_change));
                    602: }
                    603: 
                    604: struct msg *
                    605: new_msg_nsm_change (u_int32_t seqnr, struct in_addr ifaddr,
                    606:                    struct in_addr nbraddr,
                    607:                    struct in_addr router_id, u_char status)
                    608: {
                    609:   struct msg_nsm_change nmsg;
                    610: 
                    611:   nmsg.ifaddr = ifaddr;
                    612:   nmsg.nbraddr = nbraddr;
                    613:   nmsg.router_id = router_id;
                    614:   nmsg.status = status;
                    615:   memset (&nmsg.pad, 0, sizeof (nmsg.pad));
                    616: 
                    617:   return msg_new (MSG_NSM_CHANGE, &nmsg, seqnr,
                    618:                  sizeof (struct msg_nsm_change));
                    619: }
                    620: 
                    621: struct msg *
                    622: new_msg_lsa_change_notify (u_char msgtype,
                    623:                           u_int32_t seqnum,
                    624:                           struct in_addr ifaddr,
                    625:                           struct in_addr area_id,
                    626:                           u_char is_self_originated, struct lsa_header *data)
                    627: {
                    628:   u_char buf[OSPF_API_MAX_MSG_SIZE];
                    629:   struct msg_lsa_change_notify *nmsg;
1.1.1.3 ! misho     630:   size_t len;
1.1       misho     631: 
                    632:   assert (data);
                    633: 
                    634:   nmsg = (struct msg_lsa_change_notify *) buf;
                    635:   nmsg->ifaddr = ifaddr;
                    636:   nmsg->area_id = area_id;
                    637:   nmsg->is_self_originated = is_self_originated;
                    638:   memset (&nmsg->pad, 0, sizeof (nmsg->pad));
1.1.1.3 ! misho     639: 
        !           640:   len = ntohs (data->length);
        !           641:   if (len > sizeof (buf) - offsetof (struct msg_lsa_change_notify, data))
        !           642:     len = sizeof (buf) - offsetof (struct msg_lsa_change_notify, data);
        !           643:   memcpy (&nmsg->data, data, len);
        !           644:   len += sizeof (struct msg_lsa_change_notify) - sizeof (struct lsa_header);
1.1       misho     645: 
                    646:   return msg_new (msgtype, nmsg, seqnum, len);
                    647: }
                    648: 
                    649: #endif /* SUPPORT_OSPF_API */

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