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

1.1       misho       1: /*
                      2:  * OSPF Sending and Receiving OSPF Packets.
                      3:  * Copyright (C) 1999, 2000 Toshiaki Takada
                      4:  *
                      5:  * This file is part of GNU Zebra.
                      6:  *
                      7:  * GNU Zebra is free software; you can redistribute it and/or modify it
                      8:  * under the terms of the GNU General Public License as published by the
                      9:  * Free Software Foundation; either version 2, or (at your option) any
                     10:  * 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 Free
                     19:  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
                     20:  * 02111-1307, USA.
                     21:  */
                     22: 
                     23: #include <zebra.h>
                     24: 
                     25: #include "thread.h"
                     26: #include "memory.h"
                     27: #include "linklist.h"
                     28: #include "prefix.h"
                     29: #include "if.h"
                     30: #include "table.h"
                     31: #include "sockunion.h"
                     32: #include "stream.h"
                     33: #include "log.h"
                     34: #include "sockopt.h"
                     35: #include "checksum.h"
                     36: #include "md5.h"
                     37: 
                     38: #include "ospfd/ospfd.h"
                     39: #include "ospfd/ospf_network.h"
                     40: #include "ospfd/ospf_interface.h"
                     41: #include "ospfd/ospf_ism.h"
                     42: #include "ospfd/ospf_asbr.h"
                     43: #include "ospfd/ospf_lsa.h"
                     44: #include "ospfd/ospf_lsdb.h"
                     45: #include "ospfd/ospf_neighbor.h"
                     46: #include "ospfd/ospf_nsm.h"
                     47: #include "ospfd/ospf_packet.h"
                     48: #include "ospfd/ospf_spf.h"
                     49: #include "ospfd/ospf_flood.h"
                     50: #include "ospfd/ospf_dump.h"
                     51: 
                     52: /* Packet Type String. */
1.1.1.2   misho      53: const struct message ospf_packet_type_str[] =
1.1       misho      54: {
1.1.1.2   misho      55:   { OSPF_MSG_HELLO,   "Hello"                     },
                     56:   { OSPF_MSG_DB_DESC, "Database Description"      },
                     57:   { OSPF_MSG_LS_REQ,  "Link State Request"        },
                     58:   { OSPF_MSG_LS_UPD,  "Link State Update"         },
                     59:   { OSPF_MSG_LS_ACK,  "Link State Acknowledgment" },
1.1       misho      60: };
1.1.1.2   misho      61: const size_t ospf_packet_type_str_max = sizeof (ospf_packet_type_str) /
                     62:   sizeof (ospf_packet_type_str[0]);
                     63: 
                     64: /* Minimum (besides OSPF_HEADER_SIZE) lengths for OSPF packets of
                     65:    particular types, offset is the "type" field of a packet. */
                     66: static const u_int16_t ospf_packet_minlen[] =
                     67: {
                     68:   0,
                     69:   OSPF_HELLO_MIN_SIZE,
                     70:   OSPF_DB_DESC_MIN_SIZE,
                     71:   OSPF_LS_REQ_MIN_SIZE,
                     72:   OSPF_LS_UPD_MIN_SIZE,
                     73:   OSPF_LS_ACK_MIN_SIZE,
                     74: };
                     75: 
                     76: /* Minimum (besides OSPF_LSA_HEADER_SIZE) lengths for LSAs of particular
                     77:    types, offset is the "LSA type" field. */
                     78: static const u_int16_t ospf_lsa_minlen[] =
                     79: {
                     80:   0,
                     81:   OSPF_ROUTER_LSA_MIN_SIZE,
                     82:   OSPF_NETWORK_LSA_MIN_SIZE,
                     83:   OSPF_SUMMARY_LSA_MIN_SIZE,
                     84:   OSPF_SUMMARY_LSA_MIN_SIZE,
                     85:   OSPF_AS_EXTERNAL_LSA_MIN_SIZE,
                     86:   0,
                     87:   OSPF_AS_EXTERNAL_LSA_MIN_SIZE,
                     88:   0,
                     89:   0,
                     90:   0,
                     91:   0,
                     92: };
                     93: 
                     94: /* for ospf_check_auth() */
                     95: static int ospf_check_sum (struct ospf_header *);
1.1       misho      96: 
                     97: /* OSPF authentication checking function */
                     98: static int
                     99: ospf_auth_type (struct ospf_interface *oi)
                    100: {
                    101:   int auth_type;
                    102: 
                    103:   if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
                    104:     auth_type = oi->area->auth_type;
                    105:   else
                    106:     auth_type = OSPF_IF_PARAM (oi, auth_type);
                    107: 
                    108:   /* Handle case where MD5 key list is not configured aka Cisco */
                    109:   if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
                    110:       list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
                    111:     return OSPF_AUTH_NULL;
                    112:   
                    113:   return auth_type;
                    114: 
                    115: }
                    116: 
                    117: struct ospf_packet *
                    118: ospf_packet_new (size_t size)
                    119: {
                    120:   struct ospf_packet *new;
                    121: 
                    122:   new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
                    123:   new->s = stream_new (size);
                    124: 
                    125:   return new;
                    126: }
                    127: 
                    128: void
                    129: ospf_packet_free (struct ospf_packet *op)
                    130: {
                    131:   if (op->s)
                    132:     stream_free (op->s);
                    133: 
                    134:   XFREE (MTYPE_OSPF_PACKET, op);
                    135: 
                    136:   op = NULL;
                    137: }
                    138: 
                    139: struct ospf_fifo *
                    140: ospf_fifo_new ()
                    141: {
                    142:   struct ospf_fifo *new;
                    143: 
                    144:   new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
                    145:   return new;
                    146: }
                    147: 
                    148: /* Add new packet to fifo. */
                    149: void
                    150: ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
                    151: {
                    152:   if (fifo->tail)
                    153:     fifo->tail->next = op;
                    154:   else
                    155:     fifo->head = op;
                    156: 
                    157:   fifo->tail = op;
                    158: 
                    159:   fifo->count++;
                    160: }
                    161: 
                    162: /* Add new packet to head of fifo. */
                    163: static void
                    164: ospf_fifo_push_head (struct ospf_fifo *fifo, struct ospf_packet *op)
                    165: {
                    166:   op->next = fifo->head;
                    167:   
                    168:   if (fifo->tail == NULL)
                    169:     fifo->tail = op;
                    170:   
                    171:   fifo->head = op;
                    172:   
                    173:   fifo->count++;
                    174: }
                    175: 
                    176: /* Delete first packet from fifo. */
                    177: struct ospf_packet *
                    178: ospf_fifo_pop (struct ospf_fifo *fifo)
                    179: {
                    180:   struct ospf_packet *op;
                    181: 
                    182:   op = fifo->head;
                    183: 
                    184:   if (op)
                    185:     {
                    186:       fifo->head = op->next;
                    187: 
                    188:       if (fifo->head == NULL)
                    189:        fifo->tail = NULL;
                    190: 
                    191:       fifo->count--;
                    192:     }
                    193: 
                    194:   return op;
                    195: }
                    196: 
                    197: /* Return first fifo entry. */
                    198: struct ospf_packet *
                    199: ospf_fifo_head (struct ospf_fifo *fifo)
                    200: {
                    201:   return fifo->head;
                    202: }
                    203: 
                    204: /* Flush ospf packet fifo. */
                    205: void
                    206: ospf_fifo_flush (struct ospf_fifo *fifo)
                    207: {
                    208:   struct ospf_packet *op;
                    209:   struct ospf_packet *next;
                    210: 
                    211:   for (op = fifo->head; op; op = next)
                    212:     {
                    213:       next = op->next;
                    214:       ospf_packet_free (op);
                    215:     }
                    216:   fifo->head = fifo->tail = NULL;
                    217:   fifo->count = 0;
                    218: }
                    219: 
                    220: /* Free ospf packet fifo. */
                    221: void
                    222: ospf_fifo_free (struct ospf_fifo *fifo)
                    223: {
                    224:   ospf_fifo_flush (fifo);
                    225: 
                    226:   XFREE (MTYPE_OSPF_FIFO, fifo);
                    227: }
                    228: 
                    229: void
                    230: ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
                    231: {
                    232:   if (!oi->obuf)
                    233:     {
                    234:       zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
                    235:               "destination %s) called with NULL obuf, ignoring "
                    236:               "(please report this bug)!\n",
                    237:               IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
1.1.1.2   misho     238:               LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
1.1       misho     239:               inet_ntoa (op->dst));
                    240:       return;
                    241:     }
                    242: 
                    243:   /* Add packet to end of queue. */
                    244:   ospf_fifo_push (oi->obuf, op);
                    245: 
                    246:   /* Debug of packet fifo*/
                    247:   /* ospf_fifo_debug (oi->obuf); */
                    248: }
                    249: 
                    250: static void
                    251: ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op)
                    252: {
                    253:   if (!oi->obuf)
                    254:     {
                    255:       zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
                    256:               "destination %s) called with NULL obuf, ignoring "
                    257:               "(please report this bug)!\n",
                    258:               IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
1.1.1.2   misho     259:               LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
1.1       misho     260:               inet_ntoa (op->dst));
                    261:       return;
                    262:     }
                    263: 
                    264:   /* Add packet to head of queue. */
                    265:   ospf_fifo_push_head (oi->obuf, op);
                    266: 
                    267:   /* Debug of packet fifo*/
                    268:   /* ospf_fifo_debug (oi->obuf); */
                    269: }
                    270: 
                    271: void
                    272: ospf_packet_delete (struct ospf_interface *oi)
                    273: {
                    274:   struct ospf_packet *op;
                    275:   
                    276:   op = ospf_fifo_pop (oi->obuf);
                    277: 
                    278:   if (op)
                    279:     ospf_packet_free (op);
                    280: }
                    281: 
                    282: struct ospf_packet *
                    283: ospf_packet_dup (struct ospf_packet *op)
                    284: {
                    285:   struct ospf_packet *new;
                    286: 
                    287:   if (stream_get_endp(op->s) != op->length)
                    288:     /* XXX size_t */
                    289:     zlog_warn ("ospf_packet_dup stream %lu ospf_packet %u size mismatch",
                    290:               (u_long)STREAM_SIZE(op->s), op->length);
                    291: 
                    292:   /* Reserve space for MD5 authentication that may be added later. */
                    293:   new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
                    294:   stream_copy (new->s, op->s);
                    295: 
                    296:   new->dst = op->dst;
                    297:   new->length = op->length;
                    298: 
                    299:   return new;
                    300: }
                    301: 
                    302: /* XXX inline */
1.1.1.3 ! misho     303: static unsigned int
1.1       misho     304: ospf_packet_authspace (struct ospf_interface *oi)
                    305: {
                    306:   int auth = 0;
                    307: 
                    308:   if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
                    309:     auth = OSPF_AUTH_MD5_SIZE;
                    310: 
                    311:   return auth;
                    312: }
                    313: 
                    314: static unsigned int
                    315: ospf_packet_max (struct ospf_interface *oi)
                    316: {
                    317:   int max;
                    318: 
                    319:   max = oi->ifp->mtu - ospf_packet_authspace(oi);
                    320: 
                    321:   max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
                    322: 
                    323:   return max;
                    324: }
                    325: 
                    326: 
                    327: static int
1.1.1.2   misho     328: ospf_check_md5_digest (struct ospf_interface *oi, struct ospf_header *ospfh)
1.1       misho     329: {
                    330:   MD5_CTX ctx;
                    331:   unsigned char digest[OSPF_AUTH_MD5_SIZE];
                    332:   struct crypt_key *ck;
                    333:   struct ospf_neighbor *nbr;
1.1.1.2   misho     334:   u_int16_t length = ntohs (ospfh->length);
1.1       misho     335:   
                    336:   /* Get secret key. */
                    337:   ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
                    338:                              ospfh->u.crypt.key_id);
                    339:   if (ck == NULL)
                    340:     {
                    341:       zlog_warn ("interface %s: ospf_check_md5 no key %d",
                    342:                 IF_NAME (oi), ospfh->u.crypt.key_id);
                    343:       return 0;
                    344:     }
                    345: 
                    346:   /* check crypto seqnum. */
                    347:   nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
                    348: 
                    349:   if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
                    350:     {
                    351:       zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
                    352:                 IF_NAME (oi),
                    353:                 ntohl(ospfh->u.crypt.crypt_seqnum),
                    354:                 ntohl(nbr->crypt_seqnum));
                    355:       return 0;
                    356:     }
                    357:       
                    358:   /* Generate a digest for the ospf packet - their digest + our digest. */
                    359:   memset(&ctx, 0, sizeof(ctx));
                    360:   MD5Init(&ctx);
1.1.1.2   misho     361:   MD5Update(&ctx, ospfh, length);
1.1       misho     362:   MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);
                    363:   MD5Final(digest, &ctx);
                    364: 
                    365:   /* compare the two */
1.1.1.2   misho     366:   if (memcmp ((caddr_t)ospfh + length, digest, OSPF_AUTH_MD5_SIZE))
1.1       misho     367:     {
                    368:       zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
                    369:                 IF_NAME (oi));
                    370:       return 0;
                    371:     }
                    372: 
                    373:   /* save neighbor's crypt_seqnum */
                    374:   if (nbr)
                    375:     nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
                    376:   return 1;
                    377: }
                    378: 
                    379: /* This function is called from ospf_write(), it will detect the
                    380:    authentication scheme and if it is MD5, it will change the sequence
                    381:    and update the MD5 digest. */
                    382: static int
                    383: ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
                    384: {
                    385:   struct ospf_header *ospfh;
                    386:   unsigned char digest[OSPF_AUTH_MD5_SIZE];
                    387:   MD5_CTX ctx;
                    388:   void *ibuf;
                    389:   u_int32_t t;
                    390:   struct crypt_key *ck;
                    391:   const u_int8_t *auth_key;
                    392: 
                    393:   ibuf = STREAM_DATA (op->s);
                    394:   ospfh = (struct ospf_header *) ibuf;
                    395: 
                    396:   if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
                    397:     return 0;
                    398: 
                    399:   /* We do this here so when we dup a packet, we don't have to
                    400:      waste CPU rewriting other headers.
                    401:      
                    402:      Note that quagga_time /deliberately/ is not used here */
                    403:   t = (time(NULL) & 0xFFFFFFFF);
                    404:   if (t > oi->crypt_seqnum)
                    405:     oi->crypt_seqnum = t;
                    406:   else
                    407:     oi->crypt_seqnum++;
                    408:   
                    409:   ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum); 
                    410: 
                    411:   /* Get MD5 Authentication key from auth_key list. */
                    412:   if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
                    413:     auth_key = (const u_int8_t *) "";
                    414:   else
                    415:     {
                    416:       ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
                    417:       auth_key = ck->auth_key;
                    418:     }
                    419: 
                    420:   /* Generate a digest for the entire packet + our secret key. */
                    421:   memset(&ctx, 0, sizeof(ctx));
                    422:   MD5Init(&ctx);
                    423:   MD5Update(&ctx, ibuf, ntohs (ospfh->length));
                    424:   MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
                    425:   MD5Final(digest, &ctx);
                    426: 
                    427:   /* Append md5 digest to the end of the stream. */
                    428:   stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
                    429: 
                    430:   /* We do *NOT* increment the OSPF header length. */
                    431:   op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
                    432: 
                    433:   if (stream_get_endp(op->s) != op->length)
                    434:     /* XXX size_t */
                    435:     zlog_warn("ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u",
                    436:              (u_long)stream_get_endp(op->s), op->length);
                    437: 
                    438:   return OSPF_AUTH_MD5_SIZE;
                    439: }
                    440: 
                    441: 
                    442: static int
                    443: ospf_ls_req_timer (struct thread *thread)
                    444: {
                    445:   struct ospf_neighbor *nbr;
                    446: 
                    447:   nbr = THREAD_ARG (thread);
                    448:   nbr->t_ls_req = NULL;
                    449: 
                    450:   /* Send Link State Request. */
                    451:   if (ospf_ls_request_count (nbr))
                    452:     ospf_ls_req_send (nbr);
                    453: 
                    454:   /* Set Link State Request retransmission timer. */
                    455:   OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
                    456: 
                    457:   return 0;
                    458: }
                    459: 
                    460: void
                    461: ospf_ls_req_event (struct ospf_neighbor *nbr)
                    462: {
                    463:   if (nbr->t_ls_req)
                    464:     {
                    465:       thread_cancel (nbr->t_ls_req);
                    466:       nbr->t_ls_req = NULL;
                    467:     }
                    468:   nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
                    469: }
                    470: 
                    471: /* Cyclic timer function.  Fist registered in ospf_nbr_new () in
                    472:    ospf_neighbor.c  */
                    473: int
                    474: ospf_ls_upd_timer (struct thread *thread)
                    475: {
                    476:   struct ospf_neighbor *nbr;
                    477: 
                    478:   nbr = THREAD_ARG (thread);
                    479:   nbr->t_ls_upd = NULL;
                    480: 
                    481:   /* Send Link State Update. */
                    482:   if (ospf_ls_retransmit_count (nbr) > 0)
                    483:     {
                    484:       struct list *update;
                    485:       struct ospf_lsdb *lsdb;
                    486:       int i;
                    487:       int retransmit_interval;
                    488: 
                    489:       retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
                    490: 
                    491:       lsdb = &nbr->ls_rxmt;
                    492:       update = list_new ();
                    493: 
                    494:       for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
                    495:        {
                    496:          struct route_table *table = lsdb->type[i].db;
                    497:          struct route_node *rn;
                    498:          
                    499:          for (rn = route_top (table); rn; rn = route_next (rn))
                    500:            {
                    501:              struct ospf_lsa *lsa;
                    502:              
                    503:              if ((lsa = rn->info) != NULL)
                    504:                /* Don't retransmit an LSA if we received it within
                    505:                  the last RxmtInterval seconds - this is to allow the
                    506:                  neighbour a chance to acknowledge the LSA as it may
                    507:                  have ben just received before the retransmit timer
                    508:                  fired.  This is a small tweak to what is in the RFC,
                    509:                  but it will cut out out a lot of retransmit traffic
                    510:                  - MAG */
                    511:                if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv), 
                    512:                            int2tv (retransmit_interval)) >= 0)
                    513:                  listnode_add (update, rn->info);
                    514:            }
                    515:        }
                    516: 
                    517:       if (listcount (update) > 0)
                    518:        ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
                    519:       list_delete (update);
                    520:     }
                    521: 
                    522:   /* Set LS Update retransmission timer. */
                    523:   OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
                    524: 
                    525:   return 0;
                    526: }
                    527: 
                    528: int
                    529: ospf_ls_ack_timer (struct thread *thread)
                    530: {
                    531:   struct ospf_interface *oi;
                    532: 
                    533:   oi = THREAD_ARG (thread);
                    534:   oi->t_ls_ack = NULL;
                    535: 
                    536:   /* Send Link State Acknowledgment. */
                    537:   if (listcount (oi->ls_ack) > 0)
                    538:     ospf_ls_ack_send_delayed (oi);
                    539: 
                    540:   /* Set LS Ack timer. */
                    541:   OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
                    542: 
                    543:   return 0;
                    544: }
                    545: 
                    546: #ifdef WANT_OSPF_WRITE_FRAGMENT
                    547: static void
                    548: ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph, 
                    549:                   struct msghdr *msg, unsigned int maxdatasize, 
                    550:                   unsigned int mtu, int flags, u_char type)
                    551: {
                    552: #define OSPF_WRITE_FRAG_SHIFT 3
                    553:   u_int16_t offset;
                    554:   struct iovec *iovp;
                    555:   int ret;
                    556: 
                    557:   assert ( op->length == stream_get_endp(op->s) );
                    558:   assert (msg->msg_iovlen == 2);
                    559: 
                    560:   /* we can but try.
                    561:    *
                    562:    * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
                    563:    * well as the IP_MF flag, making this all quite pointless.
                    564:    *
                    565:    * However, for a system on which IP_MF is left alone, and ip_id left
                    566:    * alone or else which sets same ip_id for each fragment this might
                    567:    * work, eg linux.
                    568:    *
                    569:    * XXX-TODO: It would be much nicer to have the kernel's use their
                    570:    * existing fragmentation support to do this for us. Bugs/RFEs need to
                    571:    * be raised against the various kernels.
                    572:    */
                    573:   
                    574:   /* set More Frag */
                    575:   iph->ip_off |= IP_MF;
                    576:   
                    577:   /* ip frag offset is expressed in units of 8byte words */
                    578:   offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
                    579:   
                    580:   iovp = &msg->msg_iov[1];
                    581:   
                    582:   while ( (stream_get_endp(op->s) - stream_get_getp (op->s)) 
                    583:          > maxdatasize )
                    584:     {
                    585:       /* data length of this frag is to next offset value */
                    586:       iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
                    587:       iph->ip_len = iovp->iov_len + sizeof (struct ip);
                    588:       assert (iph->ip_len <= mtu);
                    589: 
                    590:       sockopt_iphdrincl_swab_htosys (iph);
                    591: 
                    592:       ret = sendmsg (fd, msg, flags);
                    593:       
                    594:       sockopt_iphdrincl_swab_systoh (iph);
                    595:       
                    596:       if (ret < 0)
                    597:         zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
                    598:                   " id %d, off %d, len %d, mtu %u failed with %s",
                    599:                   inet_ntoa (iph->ip_dst),
                    600:                   iph->ip_id,
                    601:                   iph->ip_off,
                    602:                   iph->ip_len,
                    603:                   mtu,
                    604:                   safe_strerror (errno));
                    605:       
                    606:       if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
                    607:         {
                    608:           zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
                    609:                      iph->ip_id, iph->ip_off, iph->ip_len,
                    610:                      inet_ntoa (iph->ip_dst));
                    611:           if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
                    612:             {
                    613:               zlog_debug ("-----------------IP Header Dump----------------------");
                    614:               ospf_ip_header_dump (iph);
                    615:               zlog_debug ("-----------------------------------------------------");
                    616:             }
                    617:         }
                    618:       
                    619:       iph->ip_off += offset;
                    620:       stream_forward_getp (op->s, iovp->iov_len);
                    621:       iovp->iov_base = STREAM_PNT (op->s); 
                    622:     }
                    623:     
                    624:   /* setup for final fragment */
                    625:   iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
                    626:   iph->ip_len = iovp->iov_len + sizeof (struct ip);
                    627:   iph->ip_off &= (~IP_MF);
                    628: }
                    629: #endif /* WANT_OSPF_WRITE_FRAGMENT */
                    630: 
                    631: static int
                    632: ospf_write (struct thread *thread)
                    633: {
                    634:   struct ospf *ospf = THREAD_ARG (thread);
                    635:   struct ospf_interface *oi;
                    636:   struct ospf_packet *op;
                    637:   struct sockaddr_in sa_dst;
                    638:   struct ip iph;
                    639:   struct msghdr msg;
                    640:   struct iovec iov[2];
                    641:   u_char type;
                    642:   int ret;
                    643:   int flags = 0;
                    644:   struct listnode *node;
                    645: #ifdef WANT_OSPF_WRITE_FRAGMENT
                    646:   static u_int16_t ipid = 0;
                    647: #endif /* WANT_OSPF_WRITE_FRAGMENT */
                    648:   u_int16_t maxdatasize;
                    649: #define OSPF_WRITE_IPHL_SHIFT 2
                    650:   
                    651:   ospf->t_write = NULL;
                    652: 
                    653:   node = listhead (ospf->oi_write_q);
                    654:   assert (node);
                    655:   oi = listgetdata (node);
                    656:   assert (oi);
                    657: 
                    658: #ifdef WANT_OSPF_WRITE_FRAGMENT
                    659:   /* seed ipid static with low order bits of time */
                    660:   if (ipid == 0)
                    661:     ipid = (time(NULL) & 0xffff);
                    662: #endif /* WANT_OSPF_WRITE_FRAGMENT */
                    663: 
                    664:   /* convenience - max OSPF data per packet,
                    665:    * and reliability - not more data, than our
                    666:    * socket can accept
                    667:    */
                    668:   maxdatasize = MIN (oi->ifp->mtu, ospf->maxsndbuflen) -
                    669:     sizeof (struct ip);
                    670:   
                    671:   /* Get one packet from queue. */
                    672:   op = ospf_fifo_head (oi->obuf);
                    673:   assert (op);
                    674:   assert (op->length >= OSPF_HEADER_SIZE);
                    675: 
                    676:   if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
                    677:       || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
                    678:       ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
                    679:     
                    680:   /* Rewrite the md5 signature & update the seq */
                    681:   ospf_make_md5_digest (oi, op);
                    682: 
                    683:   /* Retrieve OSPF packet type. */
                    684:   stream_set_getp (op->s, 1);
                    685:   type = stream_getc (op->s);
                    686:   
                    687:   /* reset get pointer */
                    688:   stream_set_getp (op->s, 0);
                    689: 
                    690:   memset (&iph, 0, sizeof (struct ip));
                    691:   memset (&sa_dst, 0, sizeof (sa_dst));
                    692:   
                    693:   sa_dst.sin_family = AF_INET;
                    694: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
                    695:   sa_dst.sin_len = sizeof(sa_dst);
                    696: #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
                    697:   sa_dst.sin_addr = op->dst;
                    698:   sa_dst.sin_port = htons (0);
                    699: 
                    700:   /* Set DONTROUTE flag if dst is unicast. */
                    701:   if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
                    702:     if (!IN_MULTICAST (htonl (op->dst.s_addr)))
                    703:       flags = MSG_DONTROUTE;
                    704: 
                    705:   iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
                    706:   /* it'd be very strange for header to not be 4byte-word aligned but.. */
                    707:   if ( sizeof (struct ip) 
                    708:         > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
                    709:     iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
                    710:   
                    711:   iph.ip_v = IPVERSION;
                    712:   iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
                    713:   iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
                    714: 
                    715: #if defined(__DragonFly__)
                    716:   /*
                    717:    * DragonFly's raw socket expects ip_len/ip_off in network byte order.
                    718:    */
                    719:   iph.ip_len = htons(iph.ip_len);
                    720: #endif
                    721: 
                    722: #ifdef WANT_OSPF_WRITE_FRAGMENT
                    723:   /* XXX-MT: not thread-safe at all..
                    724:    * XXX: this presumes this is only programme sending OSPF packets 
                    725:    * otherwise, no guarantee ipid will be unique
                    726:    */
                    727:   iph.ip_id = ++ipid;
                    728: #endif /* WANT_OSPF_WRITE_FRAGMENT */
                    729: 
                    730:   iph.ip_off = 0;
                    731:   if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
                    732:     iph.ip_ttl = OSPF_VL_IP_TTL;
                    733:   else
                    734:     iph.ip_ttl = OSPF_IP_TTL;
                    735:   iph.ip_p = IPPROTO_OSPFIGP;
                    736:   iph.ip_sum = 0;
                    737:   iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
                    738:   iph.ip_dst.s_addr = op->dst.s_addr;
                    739: 
                    740:   memset (&msg, 0, sizeof (msg));
                    741:   msg.msg_name = (caddr_t) &sa_dst;
                    742:   msg.msg_namelen = sizeof (sa_dst); 
                    743:   msg.msg_iov = iov;
                    744:   msg.msg_iovlen = 2;
                    745:   iov[0].iov_base = (char*)&iph;
                    746:   iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
                    747:   iov[1].iov_base = STREAM_PNT (op->s);
                    748:   iov[1].iov_len = op->length;
                    749:   
                    750:   /* Sadly we can not rely on kernels to fragment packets because of either
                    751:    * IP_HDRINCL and/or multicast destination being set.
                    752:    */
                    753: #ifdef WANT_OSPF_WRITE_FRAGMENT
                    754:   if ( op->length > maxdatasize )
                    755:     ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize, 
                    756:                       oi->ifp->mtu, flags, type);
                    757: #endif /* WANT_OSPF_WRITE_FRAGMENT */
                    758: 
                    759:   /* send final fragment (could be first) */
                    760:   sockopt_iphdrincl_swab_htosys (&iph);
                    761:   ret = sendmsg (ospf->fd, &msg, flags);
                    762:   sockopt_iphdrincl_swab_systoh (&iph);
                    763:   
                    764:   if (ret < 0)
                    765:     zlog_warn ("*** sendmsg in ospf_write failed to %s, "
                    766:               "id %d, off %d, len %d, interface %s, mtu %u: %s",
                    767:               inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
                    768:               oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
                    769: 
                    770:   /* Show debug sending packet. */
                    771:   if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
                    772:     {
                    773:       if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
                    774:        {
                    775:          zlog_debug ("-----------------------------------------------------");
                    776:          ospf_ip_header_dump (&iph);
                    777:          stream_set_getp (op->s, 0);
                    778:          ospf_packet_dump (op->s);
                    779:        }
                    780: 
                    781:       zlog_debug ("%s sent to [%s] via [%s].",
1.1.1.2   misho     782:                 LOOKUP (ospf_packet_type_str, type), inet_ntoa (op->dst),
1.1       misho     783:                 IF_NAME (oi));
                    784: 
                    785:       if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
                    786:        zlog_debug ("-----------------------------------------------------");
                    787:     }
                    788: 
                    789:   /* Now delete packet from queue. */
                    790:   ospf_packet_delete (oi);
                    791: 
                    792:   if (ospf_fifo_head (oi->obuf) == NULL)
                    793:     {
                    794:       oi->on_write_q = 0;
                    795:       list_delete_node (ospf->oi_write_q, node);
                    796:     }
                    797:   
                    798:   /* If packets still remain in queue, call write thread. */
                    799:   if (!list_isempty (ospf->oi_write_q))
                    800:     ospf->t_write =                                              
                    801:       thread_add_write (master, ospf_write, ospf, ospf->fd);
                    802: 
                    803:   return 0;
                    804: }
                    805: 
                    806: /* OSPF Hello message read -- RFC2328 Section 10.5. */
                    807: static void
                    808: ospf_hello (struct ip *iph, struct ospf_header *ospfh,
                    809:            struct stream * s, struct ospf_interface *oi, int size)
                    810: {
                    811:   struct ospf_hello *hello;
                    812:   struct ospf_neighbor *nbr;
                    813:   int old_state;
                    814:   struct prefix p;
                    815: 
                    816:   /* increment statistics. */
                    817:   oi->hello_in++;
                    818: 
                    819:   hello = (struct ospf_hello *) STREAM_PNT (s);
                    820: 
                    821:   /* If Hello is myself, silently discard. */
                    822:   if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
                    823:     {
                    824:       if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
                    825:         {
                    826:           zlog_debug ("ospf_header[%s/%s]: selforiginated, "
                    827:                      "dropping.",
1.1.1.2   misho     828:                      LOOKUP (ospf_packet_type_str, ospfh->type),
1.1       misho     829:                      inet_ntoa (iph->ip_src));
                    830:         }
                    831:       return;
                    832:     }
                    833: 
                    834:   /* get neighbor prefix. */
                    835:   p.family = AF_INET;
                    836:   p.prefixlen = ip_masklen (hello->network_mask);
                    837:   p.u.prefix4 = iph->ip_src;
                    838: 
                    839:   /* Compare network mask. */
                    840:   /* Checking is ignored for Point-to-Point and Virtual link. */
                    841:   if (oi->type != OSPF_IFTYPE_POINTOPOINT 
                    842:       && oi->type != OSPF_IFTYPE_VIRTUALLINK)
                    843:     if (oi->address->prefixlen != p.prefixlen)
                    844:       {
                    845:        zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
                    846:                   inet_ntoa(ospfh->router_id), IF_NAME(oi),
                    847:                   (int)oi->address->prefixlen, (int)p.prefixlen);
                    848:        return;
                    849:       }
                    850: 
                    851:   /* Compare Router Dead Interval. */
                    852:   if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
                    853:     {
                    854:       zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
                    855:                 "(expected %u, but received %u).",
                    856:                 inet_ntoa(ospfh->router_id),
                    857:                 OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
                    858:       return;
                    859:     }
                    860: 
                    861:   /* Compare Hello Interval - ignored if fast-hellos are set. */
                    862:   if (OSPF_IF_PARAM (oi, fast_hello) == 0)
                    863:     {
                    864:       if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
                    865:         {
                    866:           zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch "
                    867:                     "(expected %u, but received %u).",
                    868:                     inet_ntoa(ospfh->router_id),
                    869:                     OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval));
                    870:           return;
                    871:         }
                    872:     }
                    873:   
                    874:   if (IS_DEBUG_OSPF_EVENT)
                    875:     zlog_debug ("Packet %s [Hello:RECV]: Options %s",
                    876:               inet_ntoa (ospfh->router_id),
                    877:               ospf_options_dump (hello->options));
                    878: 
                    879:   /* Compare options. */
                    880: #define REJECT_IF_TBIT_ON      1 /* XXX */
                    881: #ifdef REJECT_IF_TBIT_ON
                    882:   if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
                    883:     {
                    884:       /*
                    885:        * This router does not support non-zero TOS.
                    886:        * Drop this Hello packet not to establish neighbor relationship.
                    887:        */
                    888:       zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
                    889:                 inet_ntoa (ospfh->router_id));
                    890:       return;
                    891:     }
                    892: #endif /* REJECT_IF_TBIT_ON */
                    893: 
                    894: #ifdef HAVE_OPAQUE_LSA
                    895:   if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
                    896:       && CHECK_FLAG (hello->options, OSPF_OPTION_O))
                    897:     {
                    898:       /*
                    899:        * This router does know the correct usage of O-bit
                    900:        * the bit should be set in DD packet only.
                    901:        */
                    902:       zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
                    903:                 inet_ntoa (ospfh->router_id));
                    904: #ifdef STRICT_OBIT_USAGE_CHECK
                    905:       return;                                     /* Reject this packet. */
                    906: #else /* STRICT_OBIT_USAGE_CHECK */
                    907:       UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
                    908: #endif /* STRICT_OBIT_USAGE_CHECK */
                    909:     }
                    910: #endif /* HAVE_OPAQUE_LSA */
                    911: 
                    912:   /* new for NSSA is to ensure that NP is on and E is off */
                    913: 
                    914:   if (oi->area->external_routing == OSPF_AREA_NSSA) 
                    915:     {
                    916:       if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
                    917:             && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
                    918:             && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
                    919:             && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
                    920:        {
                    921:          zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
                    922:          return;
                    923:        }
                    924:       if (IS_DEBUG_OSPF_NSSA)
                    925:         zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
                    926:     }
                    927:   else    
                    928:     /* The setting of the E-bit found in the Hello Packet's Options
                    929:        field must match this area's ExternalRoutingCapability A
                    930:        mismatch causes processing to stop and the packet to be
                    931:        dropped. The setting of the rest of the bits in the Hello
                    932:        Packet's Options field should be ignored. */
                    933:     if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
                    934:        CHECK_FLAG (hello->options, OSPF_OPTION_E))
                    935:       {
                    936:        zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
                    937:                   inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
                    938:        return;
                    939:       }
                    940:   
                    941:   /* get neighbour struct */
                    942:   nbr = ospf_nbr_get (oi, ospfh, iph, &p);
                    943: 
                    944:   /* neighbour must be valid, ospf_nbr_get creates if none existed */
                    945:   assert (nbr);
                    946: 
                    947:   old_state = nbr->state;
                    948: 
                    949:   /* Add event to thread. */
                    950:   OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
                    951: 
                    952:   /*  RFC2328  Section 9.5.1
                    953:       If the router is not eligible to become Designated Router,
                    954:       (snip)   It      must also send an Hello Packet in reply to an
                    955:       Hello Packet received from any eligible neighbor (other than
                    956:       the      current Designated Router and Backup Designated Router).  */
                    957:   if (oi->type == OSPF_IFTYPE_NBMA)
                    958:     if (PRIORITY(oi) == 0 && hello->priority > 0
                    959:        && IPV4_ADDR_CMP(&DR(oi),  &iph->ip_src)
                    960:        && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
                    961:       OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
                    962:                         OSPF_HELLO_REPLY_DELAY);
                    963: 
                    964:   /* on NBMA network type, it happens to receive bidirectional Hello packet
                    965:      without advance 1-Way Received event.
                    966:      To avoid incorrect DR-seletion, raise 1-Way Received event.*/
                    967:   if (oi->type == OSPF_IFTYPE_NBMA &&
                    968:       (old_state == NSM_Down || old_state == NSM_Attempt))
                    969:     {
                    970:       OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
                    971:       nbr->priority = hello->priority;
                    972:       nbr->d_router = hello->d_router;
                    973:       nbr->bd_router = hello->bd_router;
                    974:       return;
                    975:     }
                    976: 
                    977:   if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
                    978:                              size - OSPF_HELLO_MIN_SIZE))
                    979:     {
                    980:       OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);
                    981:       nbr->options |= hello->options;
                    982:     }
                    983:   else
                    984:     {
                    985:       OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
                    986:       /* Set neighbor information. */
                    987:       nbr->priority = hello->priority;
                    988:       nbr->d_router = hello->d_router;
                    989:       nbr->bd_router = hello->bd_router;
                    990:       return;
                    991:     }
                    992: 
                    993:   /* If neighbor itself declares DR and no BDR exists,
                    994:      cause event BackupSeen */
                    995:   if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
                    996:     if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
                    997:       OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
                    998: 
                    999:   /* neighbor itself declares BDR. */
                   1000:   if (oi->state == ISM_Waiting &&
                   1001:       IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
                   1002:     OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
                   1003: 
                   1004:   /* had not previously. */
                   1005:   if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
                   1006:        IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
                   1007:       (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
                   1008:        IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
                   1009:     OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
                   1010: 
                   1011:   /* had not previously. */
                   1012:   if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
                   1013:        IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
                   1014:       (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
                   1015:        IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
                   1016:     OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
                   1017: 
                   1018:   /* Neighbor priority check. */
                   1019:   if (nbr->priority >= 0 && nbr->priority != hello->priority)
                   1020:     OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
                   1021: 
                   1022:   /* Set neighbor information. */
                   1023:   nbr->priority = hello->priority;
                   1024:   nbr->d_router = hello->d_router;
                   1025:   nbr->bd_router = hello->bd_router;
                   1026: }
                   1027: 
                   1028: /* Save DD flags/options/Seqnum received. */
                   1029: static void
                   1030: ospf_db_desc_save_current (struct ospf_neighbor *nbr,
                   1031:                           struct ospf_db_desc *dd)
                   1032: {
                   1033:   nbr->last_recv.flags = dd->flags;
                   1034:   nbr->last_recv.options = dd->options;
                   1035:   nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
                   1036: }
                   1037: 
                   1038: /* Process rest of DD packet. */
                   1039: static void
                   1040: ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
                   1041:                   struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
                   1042:                   u_int16_t size)
                   1043: {
                   1044:   struct ospf_lsa *new, *find;
                   1045:   struct lsa_header *lsah;
                   1046: 
                   1047:   stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
                   1048:   for (size -= OSPF_DB_DESC_MIN_SIZE;
                   1049:        size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE) 
                   1050:     {
                   1051:       lsah = (struct lsa_header *) STREAM_PNT (s);
                   1052:       stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
                   1053: 
                   1054:       /* Unknown LS type. */
                   1055:       if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
                   1056:        {
                   1057:          zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
                   1058:          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
                   1059:          return;
                   1060:        }
                   1061: 
                   1062: #ifdef HAVE_OPAQUE_LSA
                   1063:       if (IS_OPAQUE_LSA (lsah->type)
                   1064:       &&  ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
                   1065:         {
                   1066:           zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
                   1067:           OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
                   1068:           return;
                   1069:         }
                   1070: #endif /* HAVE_OPAQUE_LSA */
                   1071: 
                   1072:       switch (lsah->type)
                   1073:         {
                   1074:         case OSPF_AS_EXTERNAL_LSA:
                   1075: #ifdef HAVE_OPAQUE_LSA
                   1076:        case OSPF_OPAQUE_AS_LSA:
                   1077: #endif /* HAVE_OPAQUE_LSA */
                   1078:           /* Check for stub area.  Reject if AS-External from stub but
                   1079:              allow if from NSSA. */
                   1080:           if (oi->area->external_routing == OSPF_AREA_STUB)
                   1081:             {
                   1082:               zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
                   1083:                          lsah->type, inet_ntoa (lsah->id),
                   1084:                          (oi->area->external_routing == OSPF_AREA_STUB) ?\
                   1085:                          "STUB" : "NSSA");
                   1086:               OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
                   1087:               return;
                   1088:             }
                   1089:           break;
                   1090:        default:
                   1091:          break;
                   1092:         }
                   1093: 
                   1094:       /* Create LS-request object. */
                   1095:       new = ospf_ls_request_new (lsah);
                   1096: 
                   1097:       /* Lookup received LSA, then add LS request list. */
                   1098:       find = ospf_lsa_lookup_by_header (oi->area, lsah);
                   1099:       
                   1100:       /* ospf_lsa_more_recent is fine with NULL pointers */
                   1101:       switch (ospf_lsa_more_recent (find, new))
                   1102:         {
                   1103:           case -1:
                   1104:             /* Neighbour has a more recent LSA, we must request it */
                   1105:             ospf_ls_request_add (nbr, new);
                   1106:           case 0:
                   1107:             /* If we have a copy of this LSA, it's either less recent
                   1108:              * and we're requesting it from neighbour (the case above), or
                   1109:              * it's as recent and we both have same copy (this case).
                   1110:              *
                   1111:              * In neither of these two cases is there any point in
                   1112:              * describing our copy of the LSA to the neighbour in a
                   1113:              * DB-Summary packet, if we're still intending to do so.
                   1114:              *
                   1115:              * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
                   1116:              * backward compatible optimisation to OSPF DB Exchange /
                   1117:              * DB Description process implemented here.
                   1118:              */
                   1119:             if (find)
                   1120:               ospf_lsdb_delete (&nbr->db_sum, find);
                   1121:             ospf_lsa_discard (new);
                   1122:             break;
                   1123:           default:
                   1124:             /* We have the more recent copy, nothing specific to do:
                   1125:              * - no need to request neighbours stale copy
                   1126:              * - must leave DB summary list copy alone
                   1127:              */
                   1128:             if (IS_DEBUG_OSPF_EVENT)
                   1129:               zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
                   1130:                          "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
                   1131:             ospf_lsa_discard (new);
                   1132:         }
                   1133:     }
                   1134: 
                   1135:   /* Master */
                   1136:   if (IS_SET_DD_MS (nbr->dd_flags))
                   1137:     {
                   1138:       nbr->dd_seqnum++;
                   1139: 
                   1140:       /* Both sides have no More, then we're done with Exchange */
                   1141:       if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
                   1142:        OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
                   1143:       else
                   1144:        ospf_db_desc_send (nbr);
                   1145:     }
                   1146:   /* Slave */
                   1147:   else
                   1148:     {
                   1149:       nbr->dd_seqnum = ntohl (dd->dd_seqnum);
                   1150: 
                   1151:       /* Send DD packet in reply. 
                   1152:        * 
                   1153:        * Must be done to acknowledge the Master's DD, regardless of
                   1154:        * whether we have more LSAs ourselves to describe.
                   1155:        *
                   1156:        * This function will clear the 'More' bit, if after this DD
                   1157:        * we have no more LSAs to describe to the master..
                   1158:        */
                   1159:       ospf_db_desc_send (nbr);
                   1160:       
                   1161:       /* Slave can raise ExchangeDone now, if master is also done */
                   1162:       if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
                   1163:        OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
                   1164:     }
                   1165:   
                   1166:   /* Save received neighbor values from DD. */
                   1167:   ospf_db_desc_save_current (nbr, dd);
                   1168: }
                   1169: 
                   1170: static int
                   1171: ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
                   1172: {
                   1173:   /* Is DD duplicated? */
                   1174:   if (dd->options == nbr->last_recv.options &&
                   1175:       dd->flags == nbr->last_recv.flags &&
                   1176:       dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
                   1177:     return 1;
                   1178: 
                   1179:   return 0;
                   1180: }
                   1181: 
                   1182: /* OSPF Database Description message read -- RFC2328 Section 10.6. */
                   1183: static void
                   1184: ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
                   1185:              struct stream *s, struct ospf_interface *oi, u_int16_t size)
                   1186: {
                   1187:   struct ospf_db_desc *dd;
                   1188:   struct ospf_neighbor *nbr;
                   1189: 
                   1190:   /* Increment statistics. */
                   1191:   oi->db_desc_in++;
                   1192: 
                   1193:   dd = (struct ospf_db_desc *) STREAM_PNT (s);
                   1194: 
                   1195:   nbr = ospf_nbr_lookup (oi, iph, ospfh);
                   1196:   if (nbr == NULL)
                   1197:     {
                   1198:       zlog_warn ("Packet[DD]: Unknown Neighbor %s",
                   1199:                 inet_ntoa (ospfh->router_id));
                   1200:       return;
                   1201:     }
                   1202: 
                   1203:   /* Check MTU. */
                   1204:   if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) && 
                   1205:       (ntohs (dd->mtu) > oi->ifp->mtu))
                   1206:     {
                   1207:       zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
                   1208:                 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
                   1209:                 IF_NAME (oi), oi->ifp->mtu);
                   1210:       return;
                   1211:     }
                   1212: 
                   1213:   /* 
                   1214:    * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
                   1215:    * required. In fact at least JunOS sends DD packets with P bit clear. 
                   1216:    * Until proper solution is developped, this hack should help.
                   1217:    *
                   1218:    * Update: According to the RFCs, N bit is specified /only/ for Hello
                   1219:    * options, unfortunately its use in DD options is not specified. Hence some
                   1220:    * implementations follow E-bit semantics and set it in DD options, and some
                   1221:    * treat it as unspecified and hence follow the directive "default for 
                   1222:    * options is clear", ie unset.
                   1223:    *
                   1224:    * Reset the flag, as ospfd follows E-bit semantics.
                   1225:    */
                   1226:   if ( (oi->area->external_routing == OSPF_AREA_NSSA)
                   1227:        && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
                   1228:        && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
                   1229:     {
                   1230:       if (IS_DEBUG_OSPF_EVENT) 
                   1231:         zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
                   1232:                     inet_ntoa (nbr->router_id) );
                   1233:       SET_FLAG (dd->options, OSPF_OPTION_NP);
                   1234:     }
                   1235: 
                   1236: #ifdef REJECT_IF_TBIT_ON
                   1237:   if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
                   1238:     {
                   1239:       /*
                   1240:        * In Hello protocol, optional capability must have checked
                   1241:        * to prevent this T-bit enabled router be my neighbor.
                   1242:        */
                   1243:       zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
                   1244:       return;
                   1245:     }
                   1246: #endif /* REJECT_IF_TBIT_ON */
                   1247: 
                   1248: #ifdef HAVE_OPAQUE_LSA
                   1249:   if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
                   1250:       && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
                   1251:     {
                   1252:       /*
                   1253:        * This node is not configured to handle O-bit, for now.
                   1254:        * Clear it to ignore unsupported capability proposed by neighbor.
                   1255:        */
                   1256:       UNSET_FLAG (dd->options, OSPF_OPTION_O);
                   1257:     }
                   1258: #endif /* HAVE_OPAQUE_LSA */
                   1259: 
                   1260:   /* Add event to thread. */
                   1261:   OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
                   1262: 
                   1263:   /* Process DD packet by neighbor status. */
                   1264:   switch (nbr->state)
                   1265:     {
                   1266:     case NSM_Down:
                   1267:     case NSM_Attempt:
                   1268:     case NSM_TwoWay:
                   1269:       zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
                   1270:                 inet_ntoa(nbr->router_id),
                   1271:                 LOOKUP (ospf_nsm_state_msg, nbr->state));
                   1272:       break;
                   1273:     case NSM_Init:
                   1274:       OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
                   1275:       /* If the new state is ExStart, the processing of the current
                   1276:         packet should then continue in this new state by falling
                   1277:         through to case ExStart below.  */
                   1278:       if (nbr->state != NSM_ExStart)
                   1279:        break;
                   1280:     case NSM_ExStart:
                   1281:       /* Initial DBD */
                   1282:       if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
                   1283:          (size == OSPF_DB_DESC_MIN_SIZE))
                   1284:        {
                   1285:          if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
                   1286:            {
                   1287:              /* We're Slave---obey */
                   1288:              zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
                   1289:                         inet_ntoa(nbr->router_id));
                   1290:              nbr->dd_seqnum = ntohl (dd->dd_seqnum);
                   1291:              
                   1292:              /* Reset I/MS */
                   1293:              UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
                   1294:            }
                   1295:          else
                   1296:            {
                   1297:              /* We're Master, ignore the initial DBD from Slave */
                   1298:              zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
                   1299:                         "ignoring.", inet_ntoa(nbr->router_id));
                   1300:              break;
                   1301:            }
                   1302:        }
                   1303:       /* Ack from the Slave */
                   1304:       else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
                   1305:               ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
                   1306:               IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
                   1307:        {
                   1308:          zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
                   1309:                     inet_ntoa(nbr->router_id));
                   1310:           /* Reset I, leaving MS */
                   1311:           UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
                   1312:        }
                   1313:       else
                   1314:        {
                   1315:          zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
                   1316:                     inet_ntoa(nbr->router_id));
                   1317:          break;
                   1318:        }
                   1319:       
                   1320:       /* This is where the real Options are saved */
                   1321:       nbr->options = dd->options;
                   1322: 
                   1323: #ifdef HAVE_OPAQUE_LSA
                   1324:       if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
                   1325:         {
                   1326:           if (IS_DEBUG_OSPF_EVENT)
                   1327:             zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
                   1328:                       inet_ntoa (nbr->router_id),
                   1329:                       CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
                   1330: 
                   1331:           if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
                   1332:           &&  IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
                   1333:             {
                   1334:               zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
                   1335:                          "Opaque-LSAs cannot be reliably advertised "
                   1336:                          "in this network.",
                   1337:                          inet_ntoa (nbr->router_id));
                   1338:               /* This situation is undesirable, but not a real error. */
                   1339:             }
                   1340:         }
                   1341: #endif /* HAVE_OPAQUE_LSA */
                   1342: 
                   1343:       OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
                   1344: 
                   1345:       /* continue processing rest of packet. */
                   1346:       ospf_db_desc_proc (s, oi, nbr, dd, size);
                   1347:       break;
                   1348:     case NSM_Exchange:
                   1349:       if (ospf_db_desc_is_dup (dd, nbr))
                   1350:        {
                   1351:          if (IS_SET_DD_MS (nbr->dd_flags))
                   1352:            /* Master: discard duplicated DD packet. */
                   1353:            zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
                   1354:                       inet_ntoa (nbr->router_id));
                   1355:          else
                   1356:            /* Slave: cause to retransmit the last Database Description. */
                   1357:            {
                   1358:              zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
                   1359:                         inet_ntoa (nbr->router_id));
                   1360:              ospf_db_desc_resend (nbr);
                   1361:            }
                   1362:          break;
                   1363:        }
                   1364: 
                   1365:       /* Otherwise DD packet should be checked. */
                   1366:       /* Check Master/Slave bit mismatch */
                   1367:       if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
                   1368:        {
                   1369:          zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
                   1370:                     inet_ntoa(nbr->router_id));
                   1371:          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
                   1372:          if (IS_DEBUG_OSPF_EVENT)
                   1373:            zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
                   1374:                        dd->flags, nbr->dd_flags);
                   1375:          break;
                   1376:        }
                   1377: 
                   1378:       /* Check initialize bit is set. */
                   1379:       if (IS_SET_DD_I (dd->flags))
                   1380:        {
                   1381:          zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
                   1382:                     inet_ntoa(nbr->router_id));
                   1383:          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
                   1384:          break;
                   1385:        }
                   1386: 
                   1387:       /* Check DD Options. */
                   1388:       if (dd->options != nbr->options)
                   1389:        {
                   1390: #ifdef ORIGINAL_CODING
                   1391:          /* Save the new options for debugging */
                   1392:          nbr->options = dd->options;
                   1393: #endif /* ORIGINAL_CODING */
                   1394:          zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
                   1395:                     inet_ntoa(nbr->router_id));
                   1396:          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
                   1397:          break;
                   1398:        }
                   1399: 
                   1400:       /* Check DD sequence number. */
                   1401:       if ((IS_SET_DD_MS (nbr->dd_flags) &&
                   1402:           ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
                   1403:          (!IS_SET_DD_MS (nbr->dd_flags) &&
                   1404:           ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
                   1405:        {
                   1406:          zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
                   1407:                     inet_ntoa(nbr->router_id));
                   1408:          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
                   1409:          break;
                   1410:        }
                   1411: 
                   1412:       /* Continue processing rest of packet. */
                   1413:       ospf_db_desc_proc (s, oi, nbr, dd, size);
                   1414:       break;
                   1415:     case NSM_Loading:
                   1416:     case NSM_Full:
                   1417:       if (ospf_db_desc_is_dup (dd, nbr))
                   1418:        {
                   1419:          if (IS_SET_DD_MS (nbr->dd_flags))
                   1420:            {
                   1421:              /* Master should discard duplicate DD packet. */
                   1422:              zlog_info ("Packet[DD]: Neighbor %s duplicated, "
                   1423:                         "packet discarded.",
                   1424:                        inet_ntoa(nbr->router_id));
                   1425:              break;
                   1426:            }
                   1427:          else
                   1428:            {
                   1429:              struct timeval t, now;
                   1430:              quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
                   1431:              t = tv_sub (now, nbr->last_send_ts);
                   1432:              if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
                   1433:                {
                   1434:                  /* In states Loading and Full the slave must resend
                   1435:                     its last Database Description packet in response to
                   1436:                     duplicate Database Description packets received
                   1437:                     from the master.  For this reason the slave must
                   1438:                     wait RouterDeadInterval seconds before freeing the
                   1439:                     last Database Description packet.  Reception of a
                   1440:                     Database Description packet from the master after
                   1441:                     this interval will generate a SeqNumberMismatch
                   1442:                     neighbor event. RFC2328 Section 10.8 */
                   1443:                  ospf_db_desc_resend (nbr);
                   1444:                  break;
                   1445:                }
                   1446:            }
                   1447:        }
                   1448: 
                   1449:       OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
                   1450:       break;
                   1451:     default:
                   1452:       zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
                   1453:                 inet_ntoa(nbr->router_id), nbr->state);
                   1454:       break;
                   1455:     }
                   1456: }
                   1457: 
                   1458: #define OSPF_LSA_KEY_SIZE       12 /* type(4) + id(4) + ar(4) */
                   1459: 
                   1460: /* OSPF Link State Request Read -- RFC2328 Section 10.7. */
                   1461: static void
                   1462: ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
                   1463:             struct stream *s, struct ospf_interface *oi, u_int16_t size)
                   1464: {
                   1465:   struct ospf_neighbor *nbr;
                   1466:   u_int32_t ls_type;
                   1467:   struct in_addr ls_id;
                   1468:   struct in_addr adv_router;
                   1469:   struct ospf_lsa *find;
                   1470:   struct list *ls_upd;
                   1471:   unsigned int length;
                   1472: 
                   1473:   /* Increment statistics. */
                   1474:   oi->ls_req_in++;
                   1475: 
                   1476:   nbr = ospf_nbr_lookup (oi, iph, ospfh);
                   1477:   if (nbr == NULL)
                   1478:     {
                   1479:       zlog_warn ("Link State Request: Unknown Neighbor %s.",
                   1480:                 inet_ntoa (ospfh->router_id));
                   1481:       return;
                   1482:     }
                   1483: 
                   1484:   /* Add event to thread. */
                   1485:   OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
                   1486: 
                   1487:   /* Neighbor State should be Exchange or later. */
                   1488:   if (nbr->state != NSM_Exchange &&
                   1489:       nbr->state != NSM_Loading &&
                   1490:       nbr->state != NSM_Full)
                   1491:     {
                   1492:       zlog_warn ("Link State Request received from %s: "
                   1493:                 "Neighbor state is %s, packet discarded.",
                   1494:                 inet_ntoa (ospfh->router_id),
                   1495:                 LOOKUP (ospf_nsm_state_msg, nbr->state));
                   1496:       return;
                   1497:     }
                   1498: 
                   1499:   /* Send Link State Update for ALL requested LSAs. */
                   1500:   ls_upd = list_new ();
                   1501:   length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
                   1502: 
                   1503:   while (size >= OSPF_LSA_KEY_SIZE)
                   1504:     {
                   1505:       /* Get one slice of Link State Request. */
                   1506:       ls_type = stream_getl (s);
                   1507:       ls_id.s_addr = stream_get_ipv4 (s);
                   1508:       adv_router.s_addr = stream_get_ipv4 (s);
                   1509: 
                   1510:       /* Verify LSA type. */
                   1511:       if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
                   1512:        {
                   1513:          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
                   1514:          list_delete (ls_upd);
                   1515:          return;
                   1516:        }
                   1517: 
                   1518:       /* Search proper LSA in LSDB. */
                   1519:       find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
                   1520:       if (find == NULL)
                   1521:        {
                   1522:          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
                   1523:          list_delete (ls_upd);
                   1524:          return;
                   1525:        }
                   1526: 
                   1527:       /* Packet overflows MTU size, send immediately. */
                   1528:       if (length + ntohs (find->data->length) > ospf_packet_max (oi))
                   1529:        {
                   1530:          if (oi->type == OSPF_IFTYPE_NBMA)
                   1531:            ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
                   1532:          else
                   1533:            ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
                   1534: 
                   1535:          /* Only remove list contents.  Keep ls_upd. */
                   1536:          list_delete_all_node (ls_upd);
                   1537: 
                   1538:          length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
                   1539:        }
                   1540: 
                   1541:       /* Append LSA to update list. */
                   1542:       listnode_add (ls_upd, find);
                   1543:       length += ntohs (find->data->length);
                   1544: 
                   1545:       size -= OSPF_LSA_KEY_SIZE;
                   1546:     }
                   1547: 
                   1548:   /* Send rest of Link State Update. */
                   1549:   if (listcount (ls_upd) > 0)
                   1550:     {
                   1551:       if (oi->type == OSPF_IFTYPE_NBMA)
                   1552:        ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
                   1553:       else
                   1554:        ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
                   1555: 
                   1556:       list_delete (ls_upd);
                   1557:     }
                   1558:   else
                   1559:     list_free (ls_upd);
                   1560: }
                   1561: 
                   1562: /* Get the list of LSAs from Link State Update packet.
                   1563:    And process some validation -- RFC2328 Section 13. (1)-(2). */
                   1564: static struct list *
                   1565: ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
                   1566:                       struct ospf_interface *oi, size_t size)
                   1567: {
                   1568:   u_int16_t count, sum;
                   1569:   u_int32_t length;
                   1570:   struct lsa_header *lsah;
                   1571:   struct ospf_lsa *lsa;
                   1572:   struct list *lsas;
                   1573: 
                   1574:   lsas = list_new ();
                   1575: 
                   1576:   count = stream_getl (s);
                   1577:   size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
                   1578: 
                   1579:   for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
                   1580:        size -= length, stream_forward_getp (s, length), count--)
                   1581:     {
                   1582:       lsah = (struct lsa_header *) STREAM_PNT (s);
                   1583:       length = ntohs (lsah->length);
                   1584: 
                   1585:       if (length > size)
                   1586:        {
                   1587:          zlog_warn ("Link State Update: LSA length exceeds packet size.");
                   1588:          break;
                   1589:        }
                   1590: 
                   1591:       /* Validate the LSA's LS checksum. */
                   1592:       sum = lsah->checksum;
                   1593:       if (sum != ospf_lsa_checksum (lsah))
                   1594:        {
1.1.1.3 ! misho    1595:          /* (bug #685) more details in a one-line message make it possible
        !          1596:           * to identify problem source on the one hand and to have a better
        !          1597:           * chance to compress repeated messages in syslog on the other */
        !          1598:          zlog_warn ("Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
        !          1599:                     sum, lsah->checksum, inet_ntoa (lsah->id),
        !          1600:                     inet_ntoa (nbr->src), inet_ntoa (nbr->router_id),
        !          1601:                     inet_ntoa (lsah->adv_router));
1.1       misho    1602:          continue;
                   1603:        }
                   1604: 
                   1605:       /* Examine the LSA's LS type. */
                   1606:       if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
                   1607:        {
                   1608:          zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
                   1609:          continue;
                   1610:        }
                   1611: 
                   1612:       /*
                   1613:        * What if the received LSA's age is greater than MaxAge?
                   1614:        * Treat it as a MaxAge case -- endo.
                   1615:        */
                   1616:       if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
                   1617:         lsah->ls_age = htons (OSPF_LSA_MAXAGE);
                   1618: 
                   1619: #ifdef HAVE_OPAQUE_LSA
                   1620:       if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
                   1621:         {
                   1622: #ifdef STRICT_OBIT_USAGE_CHECK
                   1623:          if ((IS_OPAQUE_LSA(lsah->type) &&
                   1624:                ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
                   1625:          ||  (! IS_OPAQUE_LSA(lsah->type) &&
                   1626:                CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
                   1627:             {
                   1628:               /*
                   1629:                * This neighbor must know the exact usage of O-bit;
                   1630:                * the bit will be set in Type-9,10,11 LSAs only.
                   1631:                */
                   1632:               zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
                   1633:               continue;
                   1634:             }
                   1635: #endif /* STRICT_OBIT_USAGE_CHECK */
                   1636: 
                   1637:           /* Do not take in AS External Opaque-LSAs if we are a stub. */
                   1638:           if (lsah->type == OSPF_OPAQUE_AS_LSA
                   1639:              && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT) 
                   1640:             {
                   1641:               if (IS_DEBUG_OSPF_EVENT)
                   1642:                 zlog_debug ("LSA[Type%d:%s]: We are a stub, don't take this LSA.", lsah->type, inet_ntoa (lsah->id));
                   1643:               continue;
                   1644:             }
                   1645:         }
                   1646:       else if (IS_OPAQUE_LSA(lsah->type))
                   1647:         {
                   1648:           zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
                   1649:           continue;
                   1650:         }
                   1651: #endif /* HAVE_OPAQUE_LSA */
                   1652: 
                   1653:       /* Create OSPF LSA instance. */
                   1654:       lsa = ospf_lsa_new ();
                   1655: 
                   1656:       /* We may wish to put some error checking if type NSSA comes in
                   1657:          and area not in NSSA mode */
                   1658:       switch (lsah->type)
                   1659:         {
                   1660:         case OSPF_AS_EXTERNAL_LSA:
                   1661: #ifdef HAVE_OPAQUE_LSA
                   1662:         case OSPF_OPAQUE_AS_LSA:
                   1663:           lsa->area = NULL;
                   1664:           break;
                   1665:         case OSPF_OPAQUE_LINK_LSA:
                   1666:           lsa->oi = oi; /* Remember incoming interface for flooding control. */
                   1667:           /* Fallthrough */
                   1668: #endif /* HAVE_OPAQUE_LSA */
                   1669:         default:
                   1670:           lsa->area = oi->area;
                   1671:           break;
                   1672:         }
                   1673: 
                   1674:       lsa->data = ospf_lsa_data_new (length);
                   1675:       memcpy (lsa->data, lsah, length);
                   1676: 
                   1677:       if (IS_DEBUG_OSPF_EVENT)
                   1678:        zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
                   1679:                  lsa->data->type, inet_ntoa (lsa->data->id), lsa);
                   1680:       listnode_add (lsas, lsa);
                   1681:     }
                   1682: 
                   1683:   return lsas;
                   1684: }
                   1685: 
                   1686: /* Cleanup Update list. */
                   1687: static void
                   1688: ospf_upd_list_clean (struct list *lsas)
                   1689: {
                   1690:   struct listnode *node, *nnode;
                   1691:   struct ospf_lsa *lsa;
                   1692: 
                   1693:   for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
                   1694:     ospf_lsa_discard (lsa);
                   1695: 
                   1696:   list_delete (lsas);
                   1697: }
                   1698: 
                   1699: /* OSPF Link State Update message read -- RFC2328 Section 13. */
                   1700: static void
                   1701: ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
                   1702:             struct stream *s, struct ospf_interface *oi, u_int16_t size)
                   1703: {
                   1704:   struct ospf_neighbor *nbr;
                   1705:   struct list *lsas;
                   1706:   struct listnode *node, *nnode;
                   1707:   struct ospf_lsa *lsa = NULL;
                   1708:   /* unsigned long ls_req_found = 0; */
                   1709: 
                   1710:   /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
                   1711: 
                   1712:   /* Increment statistics. */
                   1713:   oi->ls_upd_in++;
                   1714: 
                   1715:   /* Check neighbor. */
                   1716:   nbr = ospf_nbr_lookup (oi, iph, ospfh);
                   1717:   if (nbr == NULL)
                   1718:     {
                   1719:       zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
                   1720:                 inet_ntoa (ospfh->router_id), IF_NAME (oi));
                   1721:       return;
                   1722:     }
                   1723: 
                   1724:   /* Add event to thread. */
                   1725:   OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
                   1726: 
                   1727:   /* Check neighbor state. */
                   1728:   if (nbr->state < NSM_Exchange)
                   1729:     {
                   1730:       zlog_warn ("Link State Update: "
                   1731:                 "Neighbor[%s] state %s is less than Exchange",
                   1732:                 inet_ntoa (ospfh->router_id),
                   1733:                 LOOKUP(ospf_nsm_state_msg, nbr->state));
                   1734:       return;
                   1735:     }
                   1736: 
                   1737:   /* Get list of LSAs from Link State Update packet. - Also perorms Stages 
                   1738:    * 1 (validate LSA checksum) and 2 (check for LSA consistent type) 
                   1739:    * of section 13. 
                   1740:    */
                   1741:   lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
                   1742: 
                   1743: #ifdef HAVE_OPAQUE_LSA
                   1744:   /*
                   1745:    * If self-originated Opaque-LSAs that have flooded before restart
                   1746:    * are contained in the received LSUpd message, corresponding LSReq
                   1747:    * messages to be sent may have to be modified.
                   1748:    * To eliminate possible race conditions such that flushing and normal
                   1749:    * updating for the same LSA would take place alternately, this trick
                   1750:    * must be done before entering to the loop below.
                   1751:    */
                   1752:    /* XXX: Why is this Opaque specific? Either our core code is deficient
                   1753:     * and this should be fixed generally, or Opaque is inventing strawman
                   1754:     * problems */
                   1755:    ospf_opaque_adjust_lsreq (nbr, lsas);
                   1756: #endif /* HAVE_OPAQUE_LSA */
                   1757: 
                   1758: #define DISCARD_LSA(L,N) {\
                   1759:         if (IS_DEBUG_OSPF_EVENT) \
                   1760:           zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p Type-%d", N, lsa, (int) lsa->data->type); \
                   1761:         ospf_lsa_discard (L); \
                   1762:        continue; }
                   1763: 
                   1764:   /* Process each LSA received in the one packet. */
                   1765:   for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
                   1766:     {
                   1767:       struct ospf_lsa *ls_ret, *current;
                   1768:       int ret = 1;
                   1769: 
                   1770:       if (IS_DEBUG_OSPF_NSSA)
                   1771:        {
                   1772:          char buf1[INET_ADDRSTRLEN];
                   1773:          char buf2[INET_ADDRSTRLEN];
                   1774:          char buf3[INET_ADDRSTRLEN];
                   1775: 
                   1776:          zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
                   1777:                  lsa->data->type,
                   1778:                  inet_ntop (AF_INET, &ospfh->router_id,
                   1779:                             buf1, INET_ADDRSTRLEN),
                   1780:                  inet_ntop (AF_INET, &lsa->data->id,
                   1781:                             buf2, INET_ADDRSTRLEN),
                   1782:                  inet_ntop (AF_INET, &lsa->data->adv_router,
                   1783:                             buf3, INET_ADDRSTRLEN));
                   1784:        }
                   1785: 
                   1786:       listnode_delete (lsas, lsa); /* We don't need it in list anymore */
                   1787: 
                   1788:       /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
                   1789: 
                   1790:       /* LSA Type  - Done above by ospf_ls_upd_list_lsa() */
                   1791:    
                   1792:       /* Do not take in AS External LSAs if we are a stub or NSSA. */
                   1793: 
                   1794:       /* Do not take in AS NSSA if this neighbor and we are not NSSA */
                   1795: 
                   1796:       /* Do take in Type-7's if we are an NSSA  */ 
                   1797:  
                   1798:       /* If we are also an ABR, later translate them to a Type-5 packet */
                   1799:  
                   1800:       /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
                   1801:         translate them to a separate Type-5 packet.  */
                   1802: 
                   1803:       if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
                   1804:         /* Reject from STUB or NSSA */
                   1805:         if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT) 
                   1806:          {
                   1807:            if (IS_DEBUG_OSPF_NSSA)
                   1808:              zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
                   1809:            DISCARD_LSA (lsa, 1);
                   1810:          }
                   1811: 
                   1812:       if (lsa->data->type == OSPF_AS_NSSA_LSA)
                   1813:        if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
                   1814:          {
                   1815:            if (IS_DEBUG_OSPF_NSSA)
                   1816:              zlog_debug("Incoming NSSA LSA Discarded:  Not NSSA Area");
                   1817:            DISCARD_LSA (lsa,2);
                   1818:          }
                   1819: 
                   1820:       /* Find the LSA in the current database. */
                   1821: 
                   1822:       current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
                   1823: 
                   1824:       /* If the LSA's LS age is equal to MaxAge, and there is currently
                   1825:         no instance of the LSA in the router's link state database,
                   1826:         and none of router's neighbors are in states Exchange or Loading,
                   1827:         then take the following actions. */
                   1828: 
                   1829:       if (IS_LSA_MAXAGE (lsa) && !current &&
                   1830:          (ospf_nbr_count (oi, NSM_Exchange) +
                   1831:           ospf_nbr_count (oi, NSM_Loading)) == 0)
                   1832:        {
                   1833:          /* Response Link State Acknowledgment. */
                   1834:          ospf_ls_ack_send (nbr, lsa);
                   1835: 
                   1836:          /* Discard LSA. */      
                   1837:          zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
                   1838:                     dump_lsa_key(lsa));
                   1839:           DISCARD_LSA (lsa, 3);
                   1840:        }
                   1841: 
                   1842: #ifdef HAVE_OPAQUE_LSA
                   1843:       if (IS_OPAQUE_LSA (lsa->data->type)
                   1844:       &&  IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
                   1845:         {
                   1846:           /*
                   1847:            * Even if initial flushing seems to be completed, there might
                   1848:            * be a case that self-originated LSA with MaxAge still remain
                   1849:            * in the routing domain.
                   1850:            * Just send an LSAck message to cease retransmission.
                   1851:            */
                   1852:           if (IS_LSA_MAXAGE (lsa))
                   1853:             {
                   1854:               zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
                   1855:               ospf_ls_ack_send (nbr, lsa);
                   1856:               ospf_lsa_discard (lsa);
                   1857: 
                   1858:               if (current != NULL && ! IS_LSA_MAXAGE (current))
                   1859:                 ospf_opaque_lsa_refresh_schedule (current);
                   1860:               continue;
                   1861:             }
                   1862: 
                   1863:           /*
                   1864:            * If an instance of self-originated Opaque-LSA is not found
                   1865:            * in the LSDB, there are some possible cases here.
                   1866:            *
                   1867:            * 1) This node lost opaque-capability after restart.
                   1868:            * 2) Else, a part of opaque-type is no more supported.
                   1869:            * 3) Else, a part of opaque-id is no more supported.
                   1870:            *
                   1871:            * Anyway, it is still this node's responsibility to flush it.
                   1872:            * Otherwise, the LSA instance remains in the routing domain
                   1873:            * until its age reaches to MaxAge.
                   1874:            */
                   1875:           /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
                   1876:           if (current == NULL)
                   1877:             {
                   1878:               if (IS_DEBUG_OSPF_EVENT)
                   1879:                 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
                   1880:                             "not found in the LSDB.", dump_lsa_key (lsa));
                   1881: 
                   1882:               SET_FLAG (lsa->flags, OSPF_LSA_SELF);
                   1883:               
                   1884:               ospf_opaque_self_originated_lsa_received (nbr, lsa);
                   1885:               ospf_ls_ack_send (nbr, lsa);
                   1886:               
                   1887:               continue;
                   1888:             }
                   1889:         }
                   1890: #endif /* HAVE_OPAQUE_LSA */
                   1891: 
                   1892:       /* It might be happen that received LSA is self-originated network LSA, but
                   1893:        * router ID is cahnged. So, we should check if LSA is a network-LSA whose
                   1894:        * Link State ID is one of the router's own IP interface addresses but whose
                   1895:        * Advertising Router is not equal to the router's own Router ID
                   1896:        * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
                   1897:        */
                   1898: 
                   1899:       if(lsa->data->type == OSPF_NETWORK_LSA)
                   1900:       {
                   1901:         struct listnode *oinode, *oinnode;
                   1902:         struct ospf_interface *out_if;
                   1903:         int Flag = 0;
                   1904: 
                   1905:         for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
                   1906:         {
                   1907:           if(out_if == NULL)
                   1908:             break;
                   1909: 
                   1910:           if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
                   1911:               (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
                   1912:           {
                   1913:             if(out_if->network_lsa_self)
                   1914:             {
                   1915:               ospf_lsa_flush_area(lsa,out_if->area);
                   1916:               if(IS_DEBUG_OSPF_EVENT)
                   1917:                 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
                   1918:                             lsa, (int) lsa->data->type);
                   1919:               ospf_lsa_discard (lsa);
                   1920:               Flag = 1;
                   1921:             }
                   1922:             break;
                   1923:           }
                   1924:         }
                   1925:         if(Flag)
                   1926:           continue;
                   1927:       }
                   1928: 
                   1929:       /* (5) Find the instance of this LSA that is currently contained
                   1930:         in the router's link state database.  If there is no
                   1931:         database copy, or the received LSA is more recent than
                   1932:         the database copy the following steps must be performed. */
                   1933: 
                   1934:       if (current == NULL ||
                   1935:          (ret = ospf_lsa_more_recent (current, lsa)) < 0)
                   1936:        {
                   1937:          /* Actual flooding procedure. */
                   1938:          if (ospf_flood (oi->ospf, nbr, current, lsa) < 0)  /* Trap NSSA later. */
                   1939:            DISCARD_LSA (lsa, 4);
                   1940:          continue;
                   1941:        }
                   1942: 
                   1943:       /* (6) Else, If there is an instance of the LSA on the sending
                   1944:         neighbor's Link state request list, an error has occurred in
                   1945:         the Database Exchange process.  In this case, restart the
                   1946:         Database Exchange process by generating the neighbor event
                   1947:         BadLSReq for the sending neighbor and stop processing the
                   1948:         Link State Update packet. */
                   1949: 
                   1950:       if (ospf_ls_request_lookup (nbr, lsa))
                   1951:        {
                   1952:          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
                   1953:          zlog_warn("LSA[%s] instance exists on Link state request list",
                   1954:                    dump_lsa_key(lsa));
                   1955: 
                   1956:          /* Clean list of LSAs. */
                   1957:           ospf_upd_list_clean (lsas);
                   1958:          /* this lsa is not on lsas list already. */
                   1959:          ospf_lsa_discard (lsa);
                   1960:          return;
                   1961:        }
                   1962: 
                   1963:       /* If the received LSA is the same instance as the database copy
                   1964:         (i.e., neither one is more recent) the following two steps
                   1965:         should be performed: */
                   1966: 
                   1967:       if (ret == 0)
                   1968:        {
                   1969:          /* If the LSA is listed in the Link state retransmission list
                   1970:             for the receiving adjacency, the router itself is expecting
                   1971:             an acknowledgment for this LSA.  The router should treat the
                   1972:             received LSA as an acknowledgment by removing the LSA from
                   1973:             the Link state retransmission list.  This is termed an
                   1974:             "implied acknowledgment". */
                   1975: 
                   1976:          ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
                   1977: 
                   1978:          if (ls_ret != NULL)
                   1979:            {
                   1980:              ospf_ls_retransmit_delete (nbr, ls_ret);
                   1981: 
                   1982:              /* Delayed acknowledgment sent if advertisement received
                   1983:                 from Designated Router, otherwise do nothing. */
                   1984:              if (oi->state == ISM_Backup)
                   1985:                if (NBR_IS_DR (nbr))
                   1986:                  listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
                   1987: 
                   1988:               DISCARD_LSA (lsa, 5);
                   1989:            }
                   1990:          else
                   1991:            /* Acknowledge the receipt of the LSA by sending a
                   1992:               Link State Acknowledgment packet back out the receiving
                   1993:               interface. */
                   1994:            {
                   1995:              ospf_ls_ack_send (nbr, lsa);
                   1996:              DISCARD_LSA (lsa, 6);
                   1997:            }
                   1998:        }
                   1999: 
                   2000:       /* The database copy is more recent.  If the database copy
                   2001:         has LS age equal to MaxAge and LS sequence number equal to
                   2002:         MaxSequenceNumber, simply discard the received LSA without
                   2003:         acknowledging it. (In this case, the LSA's LS sequence number is
                   2004:         wrapping, and the MaxSequenceNumber LSA must be completely
                   2005:         flushed before any new LSA instance can be introduced). */
                   2006: 
                   2007:       else if (ret > 0)  /* Database copy is more recent */
                   2008:        { 
                   2009:          if (IS_LSA_MAXAGE (current) &&
                   2010:              current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
                   2011:            {
                   2012:              DISCARD_LSA (lsa, 7);
                   2013:            }
                   2014:          /* Otherwise, as long as the database copy has not been sent in a
                   2015:             Link State Update within the last MinLSArrival seconds, send the
                   2016:             database copy back to the sending neighbor, encapsulated within
                   2017:             a Link State Update Packet. The Link State Update Packet should
                   2018:             be sent directly to the neighbor. In so doing, do not put the
                   2019:             database copy of the LSA on the neighbor's link state
                   2020:             retransmission list, and do not acknowledge the received (less
                   2021:             recent) LSA instance. */
                   2022:          else
                   2023:            {
                   2024:              struct timeval now;
                   2025:              
                   2026:              quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
                   2027:              
                   2028:              if (tv_cmp (tv_sub (now, current->tv_orig), 
                   2029:                          int2tv (OSPF_MIN_LS_ARRIVAL)) >= 0)
                   2030:                /* Trap NSSA type later.*/
                   2031:                ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
                   2032:              DISCARD_LSA (lsa, 8);
                   2033:            }
                   2034:        }
                   2035:     }
                   2036: #undef DISCARD_LSA
                   2037: 
                   2038:   assert (listcount (lsas) == 0);
                   2039:   list_delete (lsas);
                   2040: }
                   2041: 
                   2042: /* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
                   2043: static void
                   2044: ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
                   2045:             struct stream *s, struct ospf_interface *oi, u_int16_t size)
                   2046: {
                   2047:   struct ospf_neighbor *nbr;
                   2048:   
                   2049:   /* increment statistics. */
                   2050:   oi->ls_ack_in++;
                   2051: 
                   2052:   nbr = ospf_nbr_lookup (oi, iph, ospfh);
                   2053:   if (nbr == NULL)
                   2054:     {
                   2055:       zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
                   2056:                 inet_ntoa (ospfh->router_id));
                   2057:       return;
                   2058:     }
                   2059: 
                   2060:   /* Add event to thread. */
                   2061:   OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
                   2062: 
                   2063:   if (nbr->state < NSM_Exchange)
                   2064:     {
                   2065:       zlog_warn ("Link State Acknowledgment: "
                   2066:                 "Neighbor[%s] state %s is less than Exchange",
                   2067:                 inet_ntoa (ospfh->router_id),
                   2068:                 LOOKUP(ospf_nsm_state_msg, nbr->state));
                   2069:       return;
                   2070:     }
                   2071:   
                   2072:   while (size >= OSPF_LSA_HEADER_SIZE)
                   2073:     {
                   2074:       struct ospf_lsa *lsa, *lsr;
                   2075: 
                   2076:       lsa = ospf_lsa_new ();
                   2077:       lsa->data = (struct lsa_header *) STREAM_PNT (s);
                   2078: 
                   2079:       /* lsah = (struct lsa_header *) STREAM_PNT (s); */
                   2080:       size -= OSPF_LSA_HEADER_SIZE;
                   2081:       stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
                   2082: 
                   2083:       if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
                   2084:        {
                   2085:          lsa->data = NULL;
                   2086:          ospf_lsa_discard (lsa);
                   2087:          continue;
                   2088:        }
                   2089: 
                   2090:       lsr = ospf_ls_retransmit_lookup (nbr, lsa);
                   2091: 
                   2092:       if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
                   2093:         {
                   2094: #ifdef HAVE_OPAQUE_LSA
                   2095:           if (IS_OPAQUE_LSA (lsr->data->type))
                   2096:             ospf_opaque_ls_ack_received (nbr, lsr);
                   2097: #endif /* HAVE_OPAQUE_LSA */
                   2098: 
                   2099:           ospf_ls_retransmit_delete (nbr, lsr);
                   2100:         }
                   2101: 
                   2102:       lsa->data = NULL;
                   2103:       ospf_lsa_discard (lsa);
                   2104:     }
                   2105: 
                   2106:   return;
                   2107: }
                   2108: 
                   2109: static struct stream *
                   2110: ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
                   2111: {
                   2112:   int ret;
                   2113:   struct ip *iph;
                   2114:   u_int16_t ip_len;
                   2115:   unsigned int ifindex = 0;
                   2116:   struct iovec iov;
                   2117:   /* Header and data both require alignment. */
                   2118:   char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
                   2119:   struct msghdr msgh;
                   2120: 
                   2121:   memset (&msgh, 0, sizeof (struct msghdr));
                   2122:   msgh.msg_iov = &iov;
                   2123:   msgh.msg_iovlen = 1;
                   2124:   msgh.msg_control = (caddr_t) buff;
                   2125:   msgh.msg_controllen = sizeof (buff);
                   2126:   
                   2127:   ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
                   2128:   if (ret < 0)
                   2129:     {
                   2130:       zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
                   2131:       return NULL;
                   2132:     }
                   2133:   if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
                   2134:     {
                   2135:       zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
                   2136:                "(ip header size is %u)",
                   2137:                ret, (u_int)sizeof(iph));
                   2138:       return NULL;
                   2139:     }
                   2140:   
                   2141:   /* Note that there should not be alignment problems with this assignment
                   2142:      because this is at the beginning of the stream data buffer. */
                   2143:   iph = (struct ip *) STREAM_DATA(ibuf);
                   2144:   sockopt_iphdrincl_swab_systoh (iph);
                   2145:   
                   2146:   ip_len = iph->ip_len;
                   2147:   
1.1.1.3 ! misho    2148: #if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
1.1       misho    2149:   /*
                   2150:    * Kernel network code touches incoming IP header parameters,
                   2151:    * before protocol specific processing.
                   2152:    *
                   2153:    *   1) Convert byteorder to host representation.
                   2154:    *      --> ip_len, ip_id, ip_off
                   2155:    *
                   2156:    *   2) Adjust ip_len to strip IP header size!
                   2157:    *      --> If user process receives entire IP packet via RAW
                   2158:    *          socket, it must consider adding IP header size to
                   2159:    *          the "ip_len" field of "ip" structure.
                   2160:    *
                   2161:    * For more details, see <netinet/ip_input.c>.
                   2162:    */
                   2163:   ip_len = ip_len + (iph->ip_hl << 2);
                   2164: #endif
                   2165:   
                   2166: #if defined(__DragonFly__)
                   2167:   /*
                   2168:    * in DragonFly's raw socket, ip_len/ip_off are read 
                   2169:    * in network byte order.
                   2170:    * As OpenBSD < 200311 adjust ip_len to strip IP header size!
                   2171:    */
                   2172:   ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2);
                   2173: #endif
                   2174: 
                   2175:   ifindex = getsockopt_ifindex (AF_INET, &msgh);
                   2176:   
                   2177:   *ifp = if_lookup_by_index (ifindex);
                   2178: 
                   2179:   if (ret != ip_len)
                   2180:     {
                   2181:       zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
                   2182:                         "but recvmsg returned %d", ip_len, ret);
                   2183:       return NULL;
                   2184:     }
                   2185:   
                   2186:   return ibuf;
                   2187: }
                   2188: 
                   2189: static struct ospf_interface *
                   2190: ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp, 
                   2191:                          struct ip *iph, struct ospf_header *ospfh)
                   2192: {
                   2193:   struct ospf_interface *rcv_oi;
                   2194:   struct ospf_vl_data *vl_data;
                   2195:   struct ospf_area *vl_area;
                   2196:   struct listnode *node;
                   2197: 
                   2198:   if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
                   2199:       !OSPF_IS_AREA_BACKBONE (ospfh))
                   2200:     return NULL;
                   2201: 
                   2202:   /* look for local OSPF interface matching the destination
                   2203:    * to determine Area ID. We presume therefore the destination address
                   2204:    * is unique, or at least (for "unnumbered" links), not used in other 
                   2205:    * areas
                   2206:    */
                   2207:   if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL, 
                   2208:                                               iph->ip_dst)) == NULL)
                   2209:     return NULL;
                   2210: 
                   2211:   for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
                   2212:     {
                   2213:       vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
                   2214:       if (!vl_area)
                   2215:        continue;
                   2216:       
                   2217:       if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
                   2218:          IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
                   2219:        {
                   2220:          if (IS_DEBUG_OSPF_EVENT)
                   2221:            zlog_debug ("associating packet with %s",
                   2222:                       IF_NAME (vl_data->vl_oi));
                   2223:          if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
                   2224:            {
                   2225:              if (IS_DEBUG_OSPF_EVENT)
                   2226:                zlog_debug ("This VL is not up yet, sorry");
                   2227:              return NULL;
                   2228:            }
                   2229:          
                   2230:          return vl_data->vl_oi;
                   2231:        }
                   2232:     }
                   2233: 
                   2234:   if (IS_DEBUG_OSPF_EVENT)
                   2235:     zlog_debug ("couldn't find any VL to associate the packet with");
                   2236:   
                   2237:   return NULL;
                   2238: }
                   2239: 
1.1.1.3 ! misho    2240: static int
1.1       misho    2241: ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
                   2242: {
                   2243:   /* Check match the Area ID of the receiving interface. */
                   2244:   if (OSPF_AREA_SAME (&oi->area, &ospfh))
                   2245:     return 1;
                   2246: 
                   2247:   return 0;
                   2248: }
                   2249: 
                   2250: /* Unbound socket will accept any Raw IP packets if proto is matched.
                   2251:    To prevent it, compare src IP address and i/f address with masking
                   2252:    i/f network mask. */
                   2253: static int
                   2254: ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
                   2255: {
                   2256:   struct in_addr mask, me, him;
                   2257: 
                   2258:   if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
                   2259:       oi->type == OSPF_IFTYPE_VIRTUALLINK)
                   2260:     return 1;
                   2261: 
                   2262:   masklen2ip (oi->address->prefixlen, &mask);
                   2263: 
                   2264:   me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
                   2265:   him.s_addr = ip_src.s_addr & mask.s_addr;
                   2266: 
                   2267:  if (IPV4_ADDR_SAME (&me, &him))
                   2268:    return 1;
                   2269: 
                   2270:  return 0;
                   2271: }
                   2272: 
1.1.1.2   misho    2273: /* Return 1, if the packet is properly authenticated and checksummed,
                   2274:    0 otherwise. In particular, check that AuType header field is valid and
                   2275:    matches the locally configured AuType, and that D.5 requirements are met. */
1.1       misho    2276: static int
1.1.1.2   misho    2277: ospf_check_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
1.1       misho    2278: {
                   2279:   struct crypt_key *ck;
1.1.1.2   misho    2280:   u_int16_t iface_auth_type;
                   2281:   u_int16_t pkt_auth_type = ntohs (ospfh->auth_type);
1.1       misho    2282: 
1.1.1.2   misho    2283:   switch (pkt_auth_type)
                   2284:   {
                   2285:   case OSPF_AUTH_NULL: /* RFC2328 D.5.1 */
                   2286:     if (OSPF_AUTH_NULL != (iface_auth_type = ospf_auth_type (oi)))
1.1       misho    2287:     {
1.1.1.2   misho    2288:       if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
                   2289:         zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Null",
                   2290:                    IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
                   2291:       return 0;
1.1       misho    2292:     }
1.1.1.2   misho    2293:     if (! ospf_check_sum (ospfh))
                   2294:     {
                   2295:       if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
                   2296:         zlog_warn ("interface %s: Null auth OK, but checksum error, Router-ID %s",
                   2297:                    IF_NAME (oi), inet_ntoa (ospfh->router_id));
                   2298:       return 0;
                   2299:     }
                   2300:     return 1;
                   2301:   case OSPF_AUTH_SIMPLE: /* RFC2328 D.5.2 */
                   2302:     if (OSPF_AUTH_SIMPLE != (iface_auth_type = ospf_auth_type (oi)))
                   2303:     {
                   2304:       if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
                   2305:         zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Simple",
                   2306:                    IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
                   2307:       return 0;
                   2308:     }
                   2309:     if (memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
                   2310:     {
                   2311:       if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
                   2312:         zlog_warn ("interface %s: Simple auth failed", IF_NAME (oi));
                   2313:       return 0;
                   2314:     }
                   2315:     if (! ospf_check_sum (ospfh))
                   2316:     {
                   2317:       if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
                   2318:         zlog_warn ("interface %s: Simple auth OK, checksum error, Router-ID %s",
                   2319:                    IF_NAME (oi), inet_ntoa (ospfh->router_id));
                   2320:       return 0;
                   2321:     }
                   2322:     return 1;
                   2323:   case OSPF_AUTH_CRYPTOGRAPHIC: /* RFC2328 D.5.3 */
                   2324:     if (OSPF_AUTH_CRYPTOGRAPHIC != (iface_auth_type = ospf_auth_type (oi)))
                   2325:     {
                   2326:       if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
                   2327:         zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Cryptographic",
                   2328:                    IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
                   2329:       return 0;
                   2330:     }
                   2331:     if (ospfh->checksum)
                   2332:     {
                   2333:       if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
                   2334:         zlog_warn ("interface %s: OSPF header checksum is not 0", IF_NAME (oi));
                   2335:       return 0;
                   2336:     }
                   2337:     /* only MD5 crypto method can pass ospf_packet_examin() */
                   2338:     if
                   2339:     (
                   2340:       NULL == (ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) ||
                   2341:       ospfh->u.crypt.key_id != ck->key_id ||
                   2342:       /* Condition above uses the last key ID on the list, which is
                   2343:          different from what ospf_crypt_key_lookup() does. A bug? */
                   2344:       ! ospf_check_md5_digest (oi, ospfh)
                   2345:     )
                   2346:     {
                   2347:       if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
                   2348:         zlog_warn ("interface %s: MD5 auth failed", IF_NAME (oi));
                   2349:       return 0;
                   2350:     }
                   2351:     return 1;
                   2352:   default:
                   2353:     if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
                   2354:       zlog_warn ("interface %s: invalid packet auth-type (%02x)",
                   2355:                  IF_NAME (oi), pkt_auth_type);
                   2356:     return 0;
                   2357:   }
1.1       misho    2358: }
                   2359: 
                   2360: static int
                   2361: ospf_check_sum (struct ospf_header *ospfh)
                   2362: {
                   2363:   u_int32_t ret;
                   2364:   u_int16_t sum;
                   2365: 
                   2366:   /* clear auth_data for checksum. */
                   2367:   memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
                   2368: 
                   2369:   /* keep checksum and clear. */
                   2370:   sum = ospfh->checksum;
                   2371:   memset (&ospfh->checksum, 0, sizeof (u_int16_t));
                   2372: 
                   2373:   /* calculate checksum. */
                   2374:   ret = in_cksum (ospfh, ntohs (ospfh->length));
                   2375: 
                   2376:   if (ret != sum)
                   2377:     {
                   2378:       zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
                   2379:                 ret, sum);
                   2380:       return 0;
                   2381:     }
                   2382: 
                   2383:   return 1;
                   2384: }
                   2385: 
1.1.1.2   misho    2386: /* Verify, that given link/TOS records are properly sized/aligned and match
                   2387:    Router-LSA "# links" and "# TOS" fields as specified in RFC2328 A.4.2. */
                   2388: static unsigned
                   2389: ospf_router_lsa_links_examin
                   2390: (
                   2391:   struct router_lsa_link * link,
                   2392:   u_int16_t linkbytes,
                   2393:   const u_int16_t num_links
                   2394: )
1.1       misho    2395: {
1.1.1.2   misho    2396:   unsigned counted_links = 0, thislinklen;
                   2397: 
                   2398:   while (linkbytes)
                   2399:   {
                   2400:     thislinklen = OSPF_ROUTER_LSA_LINK_SIZE + 4 * link->m[0].tos_count;
                   2401:     if (thislinklen > linkbytes)
1.1       misho    2402:     {
1.1.1.2   misho    2403:       if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2404:         zlog_debug ("%s: length error in link block #%u", __func__, counted_links);
                   2405:       return MSG_NG;
1.1       misho    2406:     }
1.1.1.2   misho    2407:     link = (struct router_lsa_link *)((caddr_t) link + thislinklen);
                   2408:     linkbytes -= thislinklen;
                   2409:     counted_links++;
                   2410:   }
                   2411:   if (counted_links != num_links)
                   2412:   {
                   2413:     if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2414:       zlog_debug ("%s: %u link blocks declared, %u present",
                   2415:                   __func__, num_links, counted_links);
                   2416:     return MSG_NG;
                   2417:   }
                   2418:   return MSG_OK;
                   2419: }
1.1       misho    2420: 
1.1.1.2   misho    2421: /* Verify, that the given LSA is properly sized/aligned (including type-specific
                   2422:    minimum length constraint). */
                   2423: static unsigned
                   2424: ospf_lsa_examin (struct lsa_header * lsah, const u_int16_t lsalen, const u_char headeronly)
                   2425: {
                   2426:   unsigned ret;
                   2427:   struct router_lsa * rlsa;
                   2428:   if
                   2429:   (
                   2430:     lsah->type < OSPF_MAX_LSA &&
                   2431:     ospf_lsa_minlen[lsah->type] &&
                   2432:     lsalen < OSPF_LSA_HEADER_SIZE + ospf_lsa_minlen[lsah->type]
                   2433:   )
1.1       misho    2434:   {
1.1.1.2   misho    2435:     if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2436:       zlog_debug ("%s: undersized (%u B) %s",
                   2437:                   __func__, lsalen, LOOKUP (ospf_lsa_type_msg, lsah->type));
                   2438:     return MSG_NG;
                   2439:   }
                   2440:   switch (lsah->type)
                   2441:   {
                   2442:   case OSPF_ROUTER_LSA:
                   2443:     /* RFC2328 A.4.2, LSA header + 4 bytes followed by N>=1 (12+)-byte link blocks */
                   2444:     if (headeronly)
                   2445:     {
                   2446:       ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_ROUTER_LSA_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
                   2447:       break;
                   2448:     }
                   2449:     rlsa = (struct router_lsa *) lsah;
                   2450:     ret = ospf_router_lsa_links_examin
                   2451:     (
                   2452:       (struct router_lsa_link *) rlsa->link,
                   2453:       lsalen - OSPF_LSA_HEADER_SIZE - 4, /* skip: basic header, "flags", 0, "# links" */
                   2454:       ntohs (rlsa->links) /* 16 bits */
                   2455:     );
                   2456:     break;
                   2457:   case OSPF_AS_EXTERNAL_LSA:
                   2458:     /* RFC2328 A.4.5, LSA header + 4 bytes followed by N>=1 12-bytes long blocks */
                   2459:   case OSPF_AS_NSSA_LSA:
                   2460:     /* RFC3101 C, idem */
                   2461:     ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_AS_EXTERNAL_LSA_MIN_SIZE) % 12 ? MSG_NG : MSG_OK;
                   2462:     break;
                   2463:   /* Following LSA types are considered OK length-wise as soon as their minimum
                   2464:    * length constraint is met and length of the whole LSA is a multiple of 4
                   2465:    * (basic LSA header size is already a multiple of 4). */
                   2466:   case OSPF_NETWORK_LSA:
                   2467:     /* RFC2328 A.4.3, LSA header + 4 bytes followed by N>=1 router-IDs */
                   2468:   case OSPF_SUMMARY_LSA:
                   2469:   case OSPF_ASBR_SUMMARY_LSA:
                   2470:     /* RFC2328 A.4.4, LSA header + 4 bytes followed by N>=1 4-bytes TOS blocks */
                   2471: #ifdef HAVE_OPAQUE_LSA
                   2472:   case OSPF_OPAQUE_LINK_LSA:
                   2473:   case OSPF_OPAQUE_AREA_LSA:
                   2474:   case OSPF_OPAQUE_AS_LSA:
                   2475:     /* RFC5250 A.2, "some number of octets (of application-specific
                   2476:      * data) padded to 32-bit alignment." This is considered equivalent
                   2477:      * to 4-byte alignment of all other LSA types, see OSPF-ALIGNMENT.txt
                   2478:      * file for the detailed analysis of this passage. */
                   2479: #endif
                   2480:     ret = lsalen % 4 ? MSG_NG : MSG_OK;
                   2481:     break;
                   2482:   default:
                   2483:     if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2484:       zlog_debug ("%s: unsupported LSA type 0x%02x", __func__, lsah->type);
                   2485:     return MSG_NG;
                   2486:   }
                   2487:   if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
                   2488:     zlog_debug ("%s: alignment error in %s",
                   2489:                 __func__, LOOKUP (ospf_lsa_type_msg, lsah->type));
                   2490:   return ret;
                   2491: }
                   2492: 
                   2493: /* Verify if the provided input buffer is a valid sequence of LSAs. This
                   2494:    includes verification of LSA blocks length/alignment and dispatching
                   2495:    of deeper-level checks. */
                   2496: static unsigned
                   2497: ospf_lsaseq_examin
                   2498: (
                   2499:   struct lsa_header *lsah, /* start of buffered data */
                   2500:   size_t length,
                   2501:   const u_char headeronly,
                   2502:   /* When declared_num_lsas is not 0, compare it to the real number of LSAs
                   2503:      and treat the difference as an error. */
                   2504:   const u_int32_t declared_num_lsas
                   2505: )
                   2506: {
                   2507:   u_int32_t counted_lsas = 0;
                   2508: 
                   2509:   while (length)
                   2510:   {
                   2511:     u_int16_t lsalen;
                   2512:     if (length < OSPF_LSA_HEADER_SIZE)
                   2513:     {
                   2514:       if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2515:         zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header",
                   2516:                     __func__, length, counted_lsas);
                   2517:       return MSG_NG;
                   2518:     }
                   2519:     /* save on ntohs() calls here and in the LSA validator */
                   2520:     lsalen = ntohs (lsah->length);
                   2521:     if (lsalen < OSPF_LSA_HEADER_SIZE)
                   2522:     {
                   2523:       if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2524:         zlog_debug ("%s: malformed LSA header #%u, declared length is %u B",
                   2525:                     __func__, counted_lsas, lsalen);
                   2526:       return MSG_NG;
                   2527:     }
                   2528:     if (headeronly)
                   2529:     {
                   2530:       /* less checks here and in ospf_lsa_examin() */
                   2531:       if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 1))
                   2532:       {
                   2533:         if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2534:           zlog_debug ("%s: malformed header-only LSA #%u", __func__, counted_lsas);
                   2535:         return MSG_NG;
                   2536:       }
                   2537:       lsah = (struct lsa_header *) ((caddr_t) lsah + OSPF_LSA_HEADER_SIZE);
                   2538:       length -= OSPF_LSA_HEADER_SIZE;
                   2539:     }
                   2540:     else
                   2541:     {
                   2542:       /* make sure the input buffer is deep enough before further checks */
                   2543:       if (lsalen > length)
                   2544:       {
                   2545:         if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2546:           zlog_debug ("%s: anomaly in LSA #%u: declared length is %u B, buffered length is %zu B",
                   2547:                       __func__, counted_lsas, lsalen, length);
                   2548:         return MSG_NG;
                   2549:       }
                   2550:       if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 0))
                   2551:       {
                   2552:         if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2553:           zlog_debug ("%s: malformed LSA #%u", __func__, counted_lsas);
                   2554:         return MSG_NG;
                   2555:       }
                   2556:       lsah = (struct lsa_header *) ((caddr_t) lsah + lsalen);
                   2557:       length -= lsalen;
                   2558:     }
                   2559:     counted_lsas++;
                   2560:   }
                   2561: 
                   2562:   if (declared_num_lsas && counted_lsas != declared_num_lsas)
                   2563:   {
                   2564:     if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2565:       zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)",
                   2566:                   __func__, declared_num_lsas, counted_lsas);
                   2567:     return MSG_NG;
                   2568:   }
                   2569:   return MSG_OK;
                   2570: }
                   2571: 
                   2572: /* Verify a complete OSPF packet for proper sizing/alignment. */
                   2573: static unsigned
                   2574: ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
                   2575: {
                   2576:   u_int16_t bytesdeclared, bytesauth;
                   2577:   unsigned ret;
                   2578:   struct ospf_ls_update * lsupd;
                   2579: 
                   2580:   /* Length, 1st approximation. */
                   2581:   if (bytesonwire < OSPF_HEADER_SIZE)
                   2582:   {
                   2583:     if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2584:       zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire);
                   2585:     return MSG_NG;
                   2586:   }
                   2587:   /* Now it is safe to access header fields. Performing length check, allow
                   2588:    * for possible extra bytes of crypto auth/padding, which are not counted
                   2589:    * in the OSPF header "length" field. */
                   2590:   if (oh->version != OSPF_VERSION)
                   2591:   {
                   2592:     if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2593:       zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version);
                   2594:     return MSG_NG;
                   2595:   }
                   2596:   bytesdeclared = ntohs (oh->length);
                   2597:   if (ntohs (oh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
                   2598:     bytesauth = 0;
                   2599:   else
                   2600:   {
                   2601:     if (oh->u.crypt.auth_data_len != OSPF_AUTH_MD5_SIZE)
                   2602:     {
                   2603:       if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2604:         zlog_debug ("%s: unsupported crypto auth length (%u B)",
                   2605:                     __func__, oh->u.crypt.auth_data_len);
                   2606:       return MSG_NG;
                   2607:     }
                   2608:     bytesauth = OSPF_AUTH_MD5_SIZE;
                   2609:   }
                   2610:   if (bytesdeclared + bytesauth > bytesonwire)
                   2611:   {
                   2612:     if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2613:       zlog_debug ("%s: packet length error (%u real, %u+%u declared)",
                   2614:                   __func__, bytesonwire, bytesdeclared, bytesauth);
                   2615:     return MSG_NG;
                   2616:   }
                   2617:   /* Length, 2nd approximation. The type-specific constraint is checked
                   2618:      against declared length, not amount of bytes on wire. */
                   2619:   if
                   2620:   (
                   2621:     oh->type >= OSPF_MSG_HELLO &&
                   2622:     oh->type <= OSPF_MSG_LS_ACK &&
                   2623:     bytesdeclared < OSPF_HEADER_SIZE + ospf_packet_minlen[oh->type]
                   2624:   )
                   2625:   {
                   2626:     if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2627:       zlog_debug ("%s: undersized (%u B) %s packet", __func__,
                   2628:                   bytesdeclared, LOOKUP (ospf_packet_type_str, oh->type));
                   2629:     return MSG_NG;
                   2630:   }
                   2631:   switch (oh->type)
                   2632:   {
                   2633:   case OSPF_MSG_HELLO:
                   2634:     /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes followed
                   2635:        by N>=0 router-IDs. */
                   2636:     ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
                   2637:     break;
                   2638:   case OSPF_MSG_DB_DESC:
                   2639:     /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes followed
                   2640:        by N>=0 header-only LSAs. */
                   2641:     ret = ospf_lsaseq_examin
                   2642:     (
                   2643:       (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE),
                   2644:       bytesdeclared - OSPF_HEADER_SIZE - OSPF_DB_DESC_MIN_SIZE,
                   2645:       1, /* header-only LSAs */
                   2646:       0
                   2647:     );
                   2648:     break;
                   2649:   case OSPF_MSG_LS_REQ:
                   2650:     /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes request blocks. */
                   2651:     ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) %
                   2652:       OSPF_LSA_KEY_SIZE ? MSG_NG : MSG_OK;
                   2653:     break;
                   2654:   case OSPF_MSG_LS_UPD:
                   2655:     /* RFC2328 A.3.5, packet header + OSPF_LS_UPD_MIN_SIZE bytes followed
                   2656:        by N>=0 full LSAs (with N declared beforehand). */
                   2657:     lsupd = (struct ospf_ls_update *) ((caddr_t) oh + OSPF_HEADER_SIZE);
                   2658:     ret = ospf_lsaseq_examin
                   2659:     (
                   2660:       (struct lsa_header *) ((caddr_t) lsupd + OSPF_LS_UPD_MIN_SIZE),
                   2661:       bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE,
                   2662:       0, /* full LSAs */
                   2663:       ntohl (lsupd->num_lsas) /* 32 bits */
                   2664:     );
                   2665:     break;
                   2666:   case OSPF_MSG_LS_ACK:
                   2667:     /* RFC2328 A.3.6, packet header followed by N>=0 header-only LSAs. */
                   2668:     ret = ospf_lsaseq_examin
                   2669:     (
                   2670:       (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_LS_ACK_MIN_SIZE),
                   2671:       bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE,
                   2672:       1, /* header-only LSAs */
                   2673:       0
                   2674:     );
                   2675:     break;
                   2676:   default:
                   2677:     if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2678:       zlog_debug ("%s: invalid packet type 0x%02x", __func__, oh->type);
                   2679:     return MSG_NG;
1.1       misho    2680:   }
1.1.1.2   misho    2681:   if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
                   2682:     zlog_debug ("%s: malformed %s packet", __func__, LOOKUP (ospf_packet_type_str, oh->type));
                   2683:   return ret;
                   2684: }
1.1       misho    2685: 
1.1.1.2   misho    2686: /* OSPF Header verification. */
                   2687: static int
                   2688: ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
                   2689:                    struct ip *iph, struct ospf_header *ospfh)
                   2690: {
1.1       misho    2691:   /* Check Area ID. */
                   2692:   if (!ospf_check_area_id (oi, ospfh))
                   2693:     {
                   2694:       zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
                   2695:                 IF_NAME (oi), inet_ntoa (ospfh->area_id));
                   2696:       return -1;
                   2697:     }
                   2698: 
                   2699:   /* Check network mask, Silently discarded. */
                   2700:   if (! ospf_check_network_mask (oi, iph->ip_src))
                   2701:     {
                   2702:       zlog_warn ("interface %s: ospf_read network address is not same [%s]",
                   2703:                 IF_NAME (oi), inet_ntoa (iph->ip_src));
                   2704:       return -1;
                   2705:     }
                   2706: 
1.1.1.2   misho    2707:   /* Check authentication. The function handles logging actions, where required. */
                   2708:   if (! ospf_check_auth (oi, ospfh))
                   2709:     return -1;
1.1       misho    2710: 
                   2711:   return 0;
                   2712: }
                   2713: 
                   2714: /* Starting point of packet process function. */
                   2715: int
                   2716: ospf_read (struct thread *thread)
                   2717: {
                   2718:   int ret;
                   2719:   struct stream *ibuf;
                   2720:   struct ospf *ospf;
                   2721:   struct ospf_interface *oi;
                   2722:   struct ip *iph;
                   2723:   struct ospf_header *ospfh;
                   2724:   u_int16_t length;
                   2725:   struct interface *ifp;
                   2726: 
                   2727:   /* first of all get interface pointer. */
                   2728:   ospf = THREAD_ARG (thread);
                   2729: 
                   2730:   /* prepare for next packet. */
                   2731:   ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
                   2732: 
                   2733:   stream_reset(ospf->ibuf);
                   2734:   if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
                   2735:     return -1;
1.1.1.2   misho    2736:   /* This raw packet is known to be at least as big as its IP header. */
1.1       misho    2737:   
                   2738:   /* Note that there should not be alignment problems with this assignment
                   2739:      because this is at the beginning of the stream data buffer. */
                   2740:   iph = (struct ip *) STREAM_DATA (ibuf);
                   2741:   /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
                   2742: 
                   2743:   if (ifp == NULL)
                   2744:     /* Handle cases where the platform does not support retrieving the ifindex,
                   2745:        and also platforms (such as Solaris 8) that claim to support ifindex
                   2746:        retrieval but do not. */
                   2747:     ifp = if_lookup_address (iph->ip_src);
                   2748:   
                   2749:   if (ifp == NULL)
                   2750:     return 0;
                   2751: 
                   2752:   /* IP Header dump. */
                   2753:     if (IS_DEBUG_OSPF_PACKET(0, RECV))
                   2754:            ospf_ip_header_dump (iph);
                   2755: 
                   2756:   /* Self-originated packet should be discarded silently. */
                   2757:   if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
                   2758:     {
                   2759:       if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2760:         {
                   2761:           zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
                   2762:                      inet_ntoa (iph->ip_src));
                   2763:         }
                   2764:       return 0;
                   2765:     }
                   2766: 
                   2767:   /* Advance from IP header to OSPF header (iph->ip_hl has been verified
                   2768:      by ospf_recv_packet() to be correct). */
                   2769:   stream_forward_getp (ibuf, iph->ip_hl * 4);
                   2770: 
1.1.1.2   misho    2771:   ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
                   2772:   if (MSG_OK != ospf_packet_examin (ospfh, stream_get_endp (ibuf) - stream_get_getp (ibuf)))
1.1       misho    2773:     return -1;
                   2774:   /* Now it is safe to access all fields of OSPF packet header. */
                   2775: 
                   2776:   /* associate packet with ospf interface */
                   2777:   oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
                   2778: 
                   2779:   /* ospf_verify_header() relies on a valid "oi" and thus can be called only
                   2780:      after the passive/backbone/other checks below are passed. These checks
                   2781:      in turn access the fields of unverified "ospfh" structure for their own
                   2782:      purposes and must remain very accurate in doing this. */
                   2783: 
                   2784:   /* If incoming interface is passive one, ignore it. */
                   2785:   if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
                   2786:     {
                   2787:       char buf[3][INET_ADDRSTRLEN];
                   2788: 
                   2789:       if (IS_DEBUG_OSPF_EVENT)
                   2790:        zlog_debug ("ignoring packet from router %s sent to %s, "
                   2791:                    "received on a passive interface, %s",
                   2792:                    inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
                   2793:                    inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
                   2794:                    inet_ntop(AF_INET, &oi->address->u.prefix4,
                   2795:                              buf[2], sizeof(buf[2])));
                   2796: 
                   2797:       if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
                   2798:        {
                   2799:          /* Try to fix multicast membership.
                   2800:           * Some OS:es may have problems in this area,
                   2801:           * make sure it is removed.
                   2802:           */
                   2803:          OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
                   2804:          ospf_if_set_multicast(oi);
                   2805:        }
                   2806:       return 0;
                   2807:   }
                   2808: 
                   2809: 
                   2810:   /* if no local ospf_interface, 
                   2811:    * or header area is backbone but ospf_interface is not
                   2812:    * check for VLINK interface
                   2813:    */
                   2814:   if ( (oi == NULL) ||
                   2815:       (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
                   2816:       && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
                   2817:      )
                   2818:     {
                   2819:       if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
                   2820:         {
                   2821:           if (IS_DEBUG_OSPF_EVENT)
                   2822:             zlog_debug ("Packet from [%s] received on link %s"
                   2823:                         " but no ospf_interface",
                   2824:                         inet_ntoa (iph->ip_src), ifp->name);
                   2825:           return 0;
                   2826:         }
                   2827:     }
                   2828: 
                   2829:   /* else it must be a local ospf interface, check it was received on 
                   2830:    * correct link 
                   2831:    */
                   2832:   else if (oi->ifp != ifp)
                   2833:     {
                   2834:       if (IS_DEBUG_OSPF_EVENT)
                   2835:         zlog_warn ("Packet from [%s] received on wrong link %s",
                   2836:                    inet_ntoa (iph->ip_src), ifp->name); 
                   2837:       return 0;
                   2838:     }
                   2839:   else if (oi->state == ISM_Down)
                   2840:     {
                   2841:       char buf[2][INET_ADDRSTRLEN];
                   2842:       zlog_warn ("Ignoring packet from %s to %s received on interface that is "
                   2843:                 "down [%s]; interface flags are %s",
                   2844:                 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
                   2845:                 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
                   2846:                 ifp->name, if_flag_dump(ifp->flags));
                   2847:       /* Fix multicast memberships? */
                   2848:       if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
                   2849:         OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
                   2850:       else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
                   2851:        OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
                   2852:       if (oi->multicast_memberships)
                   2853:        ospf_if_set_multicast(oi);
                   2854:       return 0;
                   2855:     }
                   2856: 
                   2857:   /*
                   2858:    * If the received packet is destined for AllDRouters, the packet
                   2859:    * should be accepted only if the received ospf interface state is
                   2860:    * either DR or Backup -- endo.
                   2861:    */
                   2862:   if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
                   2863:   && (oi->state != ISM_DR && oi->state != ISM_Backup))
                   2864:     {
                   2865:       zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
                   2866:                  inet_ntoa (iph->ip_src), IF_NAME (oi),
                   2867:                  LOOKUP (ospf_ism_state_msg, oi->state));
                   2868:       /* Try to fix multicast membership. */
                   2869:       SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
                   2870:       ospf_if_set_multicast(oi);
                   2871:       return 0;
                   2872:     }
                   2873: 
                   2874:   /* Verify more OSPF header fields. */
                   2875:   ret = ospf_verify_header (ibuf, oi, iph, ospfh);
                   2876:   if (ret < 0)
                   2877:   {
                   2878:     if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2879:       zlog_debug ("ospf_read[%s]: Header check failed, "
                   2880:                   "dropping.",
                   2881:                   inet_ntoa (iph->ip_src));
                   2882:     return ret;
                   2883:   }
                   2884: 
                   2885:   /* Show debug receiving packet. */
                   2886:   if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
                   2887:     {
                   2888:       if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
                   2889:         {
                   2890:           zlog_debug ("-----------------------------------------------------");
                   2891:           ospf_packet_dump (ibuf);
                   2892:         }
                   2893: 
                   2894:       zlog_debug ("%s received from [%s] via [%s]",
1.1.1.2   misho    2895:                  LOOKUP (ospf_packet_type_str, ospfh->type),
1.1       misho    2896:                  inet_ntoa (ospfh->router_id), IF_NAME (oi));
                   2897:       zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
                   2898:       zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
                   2899: 
                   2900:       if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
                   2901:        zlog_debug ("-----------------------------------------------------");
                   2902:   }
                   2903: 
                   2904:   stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
                   2905: 
                   2906:   /* Adjust size to message length. */
                   2907:   length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
                   2908: 
                   2909:   /* Read rest of the packet and call each sort of packet routine. */
                   2910:   switch (ospfh->type)
                   2911:     {
                   2912:     case OSPF_MSG_HELLO:
                   2913:       ospf_hello (iph, ospfh, ibuf, oi, length);
                   2914:       break;
                   2915:     case OSPF_MSG_DB_DESC:
                   2916:       ospf_db_desc (iph, ospfh, ibuf, oi, length);
                   2917:       break;
                   2918:     case OSPF_MSG_LS_REQ:
                   2919:       ospf_ls_req (iph, ospfh, ibuf, oi, length);
                   2920:       break;
                   2921:     case OSPF_MSG_LS_UPD:
                   2922:       ospf_ls_upd (iph, ospfh, ibuf, oi, length);
                   2923:       break;
                   2924:     case OSPF_MSG_LS_ACK:
                   2925:       ospf_ls_ack (iph, ospfh, ibuf, oi, length);
                   2926:       break;
                   2927:     default:
                   2928:       zlog (NULL, LOG_WARNING,
                   2929:            "interface %s: OSPF packet header type %d is illegal",
                   2930:            IF_NAME (oi), ospfh->type);
                   2931:       break;
                   2932:     }
                   2933: 
                   2934:   return 0;
                   2935: }
                   2936: 
                   2937: /* Make OSPF header. */
                   2938: static void
                   2939: ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
                   2940: {
                   2941:   struct ospf_header *ospfh;
                   2942: 
                   2943:   ospfh = (struct ospf_header *) STREAM_DATA (s);
                   2944: 
                   2945:   ospfh->version = (u_char) OSPF_VERSION;
                   2946:   ospfh->type = (u_char) type;
                   2947: 
                   2948:   ospfh->router_id = oi->ospf->router_id;
                   2949: 
                   2950:   ospfh->checksum = 0;
                   2951:   ospfh->area_id = oi->area->area_id;
                   2952:   ospfh->auth_type = htons (ospf_auth_type (oi));
                   2953: 
                   2954:   memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
                   2955: 
                   2956:   stream_forward_endp (s, OSPF_HEADER_SIZE);
                   2957: }
                   2958: 
                   2959: /* Make Authentication Data. */
                   2960: static int
                   2961: ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
                   2962: {
                   2963:   struct crypt_key *ck;
                   2964: 
                   2965:   switch (ospf_auth_type (oi))
                   2966:     {
                   2967:     case OSPF_AUTH_NULL:
                   2968:       /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
                   2969:       break;
                   2970:     case OSPF_AUTH_SIMPLE:
                   2971:       memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
                   2972:              OSPF_AUTH_SIMPLE_SIZE);
                   2973:       break;
                   2974:     case OSPF_AUTH_CRYPTOGRAPHIC:
                   2975:       /* If key is not set, then set 0. */
                   2976:       if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
                   2977:        {
                   2978:          ospfh->u.crypt.zero = 0;
                   2979:          ospfh->u.crypt.key_id = 0;
                   2980:          ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
                   2981:        }
                   2982:       else
                   2983:        {
                   2984:          ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
                   2985:          ospfh->u.crypt.zero = 0;
                   2986:          ospfh->u.crypt.key_id = ck->key_id;
                   2987:          ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
                   2988:        }
                   2989:       /* note: the seq is done in ospf_make_md5_digest() */
                   2990:       break;
                   2991:     default:
                   2992:       /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
                   2993:       break;
                   2994:     }
                   2995: 
                   2996:   return 0;
                   2997: }
                   2998: 
                   2999: /* Fill rest of OSPF header. */
                   3000: static void
                   3001: ospf_fill_header (struct ospf_interface *oi,
                   3002:                  struct stream *s, u_int16_t length)
                   3003: {
                   3004:   struct ospf_header *ospfh;
                   3005: 
                   3006:   ospfh = (struct ospf_header *) STREAM_DATA (s);
                   3007: 
                   3008:   /* Fill length. */
                   3009:   ospfh->length = htons (length);
                   3010: 
                   3011:   /* Calculate checksum. */
                   3012:   if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
                   3013:     ospfh->checksum = in_cksum (ospfh, length);
                   3014:   else
                   3015:     ospfh->checksum = 0;
                   3016: 
                   3017:   /* Add Authentication Data. */
                   3018:   ospf_make_auth (oi, ospfh);
                   3019: }
                   3020: 
                   3021: static int
                   3022: ospf_make_hello (struct ospf_interface *oi, struct stream *s)
                   3023: {
                   3024:   struct ospf_neighbor *nbr;
                   3025:   struct route_node *rn;
                   3026:   u_int16_t length = OSPF_HELLO_MIN_SIZE;
                   3027:   struct in_addr mask;
                   3028:   unsigned long p;
                   3029:   int flag = 0;
                   3030: 
                   3031:   /* Set netmask of interface. */
                   3032:   if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
                   3033:       oi->type != OSPF_IFTYPE_VIRTUALLINK)
                   3034:     masklen2ip (oi->address->prefixlen, &mask);
                   3035:   else
                   3036:     memset ((char *) &mask, 0, sizeof (struct in_addr));
                   3037:   stream_put_ipv4 (s, mask.s_addr);
                   3038: 
                   3039:   /* Set Hello Interval. */
                   3040:   if (OSPF_IF_PARAM (oi, fast_hello) == 0)
                   3041:     stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
                   3042:   else
                   3043:     stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
                   3044: 
                   3045:   if (IS_DEBUG_OSPF_EVENT)
                   3046:     zlog_debug ("make_hello: options: %x, int: %s",
                   3047:               OPTIONS(oi), IF_NAME (oi));
                   3048: 
                   3049:   /* Set Options. */
                   3050:   stream_putc (s, OPTIONS (oi));
                   3051: 
                   3052:   /* Set Router Priority. */
                   3053:   stream_putc (s, PRIORITY (oi));
                   3054: 
                   3055:   /* Set Router Dead Interval. */
                   3056:   stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
                   3057: 
                   3058:   /* Set Designated Router. */
                   3059:   stream_put_ipv4 (s, DR (oi).s_addr);
                   3060: 
                   3061:   p = stream_get_endp (s);
                   3062: 
                   3063:   /* Set Backup Designated Router. */
                   3064:   stream_put_ipv4 (s, BDR (oi).s_addr);
                   3065: 
                   3066:   /* Add neighbor seen. */
                   3067:   for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
                   3068:     if ((nbr = rn->info))
                   3069:       if (nbr->router_id.s_addr != 0)  /* Ignore 0.0.0.0 node. */
                   3070:        if (nbr->state != NSM_Attempt)  /* Ignore Down neighbor. */
                   3071:        if (nbr->state != NSM_Down)     /* This is myself for DR election. */
                   3072:          if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
                   3073:            {
                   3074:              /* Check neighbor is sane? */
                   3075:              if (nbr->d_router.s_addr != 0
                   3076:                  && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
                   3077:                  && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
                   3078:                flag = 1;
                   3079: 
                   3080:              stream_put_ipv4 (s, nbr->router_id.s_addr);
                   3081:              length += 4;
                   3082:            }
                   3083: 
                   3084:   /* Let neighbor generate BackupSeen. */
                   3085:   if (flag == 1)
                   3086:     stream_putl_at (s, p, 0); /* ipv4 address, normally */
                   3087: 
                   3088:   return length;
                   3089: }
                   3090: 
                   3091: static int
                   3092: ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
                   3093:                   struct stream *s)
                   3094: {
                   3095:   struct ospf_lsa *lsa;
                   3096:   u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
                   3097:   u_char options;
                   3098:   unsigned long pp;
                   3099:   int i;
                   3100:   struct ospf_lsdb *lsdb;
                   3101:   
                   3102:   /* Set Interface MTU. */
                   3103:   if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
                   3104:     stream_putw (s, 0);
                   3105:   else
                   3106:     stream_putw (s, oi->ifp->mtu);
                   3107: 
                   3108:   /* Set Options. */
                   3109:   options = OPTIONS (oi);
                   3110: #ifdef HAVE_OPAQUE_LSA
                   3111:   if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
                   3112:     {
                   3113:       if (IS_SET_DD_I (nbr->dd_flags)
                   3114:       ||  CHECK_FLAG (nbr->options, OSPF_OPTION_O))
                   3115:         /*
                   3116:          * Set O-bit in the outgoing DD packet for capablity negotiation,
                   3117:          * if one of following case is applicable. 
                   3118:          *
                   3119:          * 1) WaitTimer expiration event triggered the neighbor state to
                   3120:          *    change to Exstart, but no (valid) DD packet has received
                   3121:          *    from the neighbor yet.
                   3122:          *
                   3123:          * 2) At least one DD packet with O-bit on has received from the
                   3124:          *    neighbor.
                   3125:          */
                   3126:         SET_FLAG (options, OSPF_OPTION_O);
                   3127:     }
                   3128: #endif /* HAVE_OPAQUE_LSA */
                   3129:   stream_putc (s, options);
                   3130: 
                   3131:   /* DD flags */
                   3132:   pp = stream_get_endp (s);
                   3133:   stream_putc (s, nbr->dd_flags);
                   3134: 
                   3135:   /* Set DD Sequence Number. */
                   3136:   stream_putl (s, nbr->dd_seqnum);
                   3137: 
                   3138:   /* shortcut unneeded walk of (empty) summary LSDBs */
                   3139:   if (ospf_db_summary_isempty (nbr))
                   3140:     goto empty;
                   3141: 
                   3142:   /* Describe LSA Header from Database Summary List. */
                   3143:   lsdb = &nbr->db_sum;
                   3144: 
                   3145:   for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
                   3146:     {
                   3147:       struct route_table *table = lsdb->type[i].db;
                   3148:       struct route_node *rn;
                   3149: 
                   3150:       for (rn = route_top (table); rn; rn = route_next (rn))
                   3151:        if ((lsa = rn->info) != NULL)
                   3152:          {
                   3153: #ifdef HAVE_OPAQUE_LSA
                   3154:             if (IS_OPAQUE_LSA (lsa->data->type)
                   3155:             && (! CHECK_FLAG (options, OSPF_OPTION_O)))
                   3156:               {
                   3157:                 /* Suppress advertising opaque-informations. */
                   3158:                 /* Remove LSA from DB summary list. */
                   3159:                 ospf_lsdb_delete (lsdb, lsa);
                   3160:                 continue;
                   3161:               }
                   3162: #endif /* HAVE_OPAQUE_LSA */
                   3163: 
                   3164:            if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
                   3165:              {
                   3166:                struct lsa_header *lsah;
                   3167:                u_int16_t ls_age;
                   3168:                
                   3169:                /* DD packet overflows interface MTU. */
                   3170:                if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
                   3171:                  break;
                   3172:                
                   3173:                /* Keep pointer to LS age. */
                   3174:                lsah = (struct lsa_header *) (STREAM_DATA (s) +
                   3175:                                              stream_get_endp (s));
                   3176:                
                   3177:                /* Proceed stream pointer. */
                   3178:                stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
                   3179:                length += OSPF_LSA_HEADER_SIZE;
                   3180:                
                   3181:                /* Set LS age. */
                   3182:                ls_age = LS_AGE (lsa);
                   3183:                lsah->ls_age = htons (ls_age);
                   3184:                
                   3185:              }
                   3186:            
                   3187:            /* Remove LSA from DB summary list. */
                   3188:            ospf_lsdb_delete (lsdb, lsa);
                   3189:          }
                   3190:     }
                   3191: 
                   3192:   /* Update 'More' bit */
                   3193:   if (ospf_db_summary_isempty (nbr))
                   3194:     {
                   3195: empty:
                   3196:       if (nbr->state >= NSM_Exchange)
                   3197:         {
                   3198:           UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
                   3199:           /* Rewrite DD flags */
                   3200:           stream_putc_at (s, pp, nbr->dd_flags);
                   3201:         }
                   3202:       else
                   3203:         {
                   3204:           assert (IS_SET_DD_M(nbr->dd_flags));
                   3205:         }
                   3206:     }
                   3207:   return length;
                   3208: }
                   3209: 
                   3210: static int
                   3211: ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
                   3212:                       unsigned long delta, struct ospf_neighbor *nbr,
                   3213:                       struct ospf_lsa *lsa)
                   3214: {
                   3215:   struct ospf_interface *oi;
                   3216: 
                   3217:   oi = nbr->oi;
                   3218: 
                   3219:   /* LS Request packet overflows interface MTU. */
                   3220:   if (*length + delta > ospf_packet_max(oi))
                   3221:     return 0;
                   3222: 
                   3223:   stream_putl (s, lsa->data->type);
                   3224:   stream_put_ipv4 (s, lsa->data->id.s_addr);
                   3225:   stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
                   3226:   
                   3227:   ospf_lsa_unlock (&nbr->ls_req_last);
                   3228:   nbr->ls_req_last = ospf_lsa_lock (lsa);
                   3229:   
                   3230:   *length += 12;
                   3231:   return 1;
                   3232: }
                   3233: 
                   3234: static int
                   3235: ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
                   3236: {
                   3237:   struct ospf_lsa *lsa;
                   3238:   u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
                   3239:   unsigned long delta = stream_get_endp(s)+12;
                   3240:   struct route_table *table;
                   3241:   struct route_node *rn;
                   3242:   int i;
                   3243:   struct ospf_lsdb *lsdb;
                   3244: 
                   3245:   lsdb = &nbr->ls_req;
                   3246: 
                   3247:   for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
                   3248:     {
                   3249:       table = lsdb->type[i].db;
                   3250:       for (rn = route_top (table); rn; rn = route_next (rn))
                   3251:        if ((lsa = (rn->info)) != NULL)
                   3252:          if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
                   3253:            {
                   3254:              route_unlock_node (rn);
                   3255:              break;
                   3256:            }
                   3257:     }
                   3258:   return length;
                   3259: }
                   3260: 
                   3261: static int
                   3262: ls_age_increment (struct ospf_lsa *lsa, int delay)
                   3263: {
                   3264:   int age;
                   3265: 
                   3266:   age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
                   3267: 
                   3268:   return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
                   3269: }
                   3270: 
                   3271: static int
                   3272: ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
                   3273: {
                   3274:   struct ospf_lsa *lsa;
                   3275:   struct listnode *node;
                   3276:   u_int16_t length = 0;
                   3277:   unsigned int size_noauth;
                   3278:   unsigned long delta = stream_get_endp (s);
                   3279:   unsigned long pp;
                   3280:   int count = 0;
                   3281: 
                   3282:   if (IS_DEBUG_OSPF_EVENT)
                   3283:     zlog_debug ("ospf_make_ls_upd: Start");
                   3284: 
                   3285:   pp = stream_get_endp (s);
                   3286:   stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
                   3287:   length += OSPF_LS_UPD_MIN_SIZE;
                   3288: 
                   3289:   /* Calculate amount of packet usable for data. */
                   3290:   size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
                   3291: 
                   3292:   while ((node = listhead (update)) != NULL)
                   3293:     {
                   3294:       struct lsa_header *lsah;
                   3295:       u_int16_t ls_age;
                   3296: 
                   3297:       if (IS_DEBUG_OSPF_EVENT)
                   3298:         zlog_debug ("ospf_make_ls_upd: List Iteration");
                   3299: 
                   3300:       lsa = listgetdata (node);
                   3301: 
                   3302:       assert (lsa->data);
                   3303: 
                   3304:       /* Will it fit? */
                   3305:       if (length + delta + ntohs (lsa->data->length) > size_noauth)
                   3306:         break;
                   3307: 
                   3308:       /* Keep pointer to LS age. */
                   3309:       lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
                   3310: 
                   3311:       /* Put LSA to Link State Request. */
                   3312:       stream_put (s, lsa->data, ntohs (lsa->data->length));
                   3313: 
                   3314:       /* Set LS age. */
                   3315:       /* each hop must increment an lsa_age by transmit_delay 
                   3316:          of OSPF interface */
                   3317:       ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
                   3318:       lsah->ls_age = htons (ls_age);
                   3319: 
                   3320:       length += ntohs (lsa->data->length);
                   3321:       count++;
                   3322: 
                   3323:       list_delete_node (update, node);
                   3324:       ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
                   3325:     }
                   3326: 
                   3327:   /* Now set #LSAs. */
                   3328:   stream_putl_at (s, pp, count);
                   3329: 
                   3330:   if (IS_DEBUG_OSPF_EVENT)
                   3331:     zlog_debug ("ospf_make_ls_upd: Stop");
                   3332:   return length;
                   3333: }
                   3334: 
                   3335: static int
                   3336: ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
                   3337: {
                   3338:   struct listnode *node, *nnode;
                   3339:   u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
                   3340:   unsigned long delta = stream_get_endp(s) + 24;
                   3341:   struct ospf_lsa *lsa;
                   3342: 
                   3343:   for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
                   3344:     {
                   3345:       assert (lsa);
                   3346:       
                   3347:       if (length + delta > ospf_packet_max (oi))
                   3348:        break;
                   3349:       
                   3350:       stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
                   3351:       length += OSPF_LSA_HEADER_SIZE;
                   3352:       
                   3353:       listnode_delete (ack, lsa);
                   3354:       ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
                   3355:     }
                   3356:   
                   3357:   return length;
                   3358: }
                   3359: 
                   3360: static void
                   3361: ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
                   3362: {
                   3363:   struct ospf_packet *op;
                   3364:   u_int16_t length = OSPF_HEADER_SIZE;
                   3365: 
                   3366:   op = ospf_packet_new (oi->ifp->mtu);
                   3367: 
                   3368:   /* Prepare OSPF common header. */
                   3369:   ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
                   3370: 
                   3371:   /* Prepare OSPF Hello body. */
                   3372:   length += ospf_make_hello (oi, op->s);
                   3373: 
                   3374:   /* Fill OSPF header. */
                   3375:   ospf_fill_header (oi, op->s, length);
                   3376: 
                   3377:   /* Set packet length. */
                   3378:   op->length = length;
                   3379: 
                   3380:   op->dst.s_addr = addr;
                   3381: 
                   3382:   /* Add packet to the top of the interface output queue, so that they
                   3383:    * can't get delayed by things like long queues of LS Update packets
                   3384:    */
                   3385:   ospf_packet_add_top (oi, op);
                   3386: 
                   3387:   /* Hook thread to write packet. */
                   3388:   OSPF_ISM_WRITE_ON (oi->ospf);
                   3389: }
                   3390: 
                   3391: static void
                   3392: ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
                   3393: {
                   3394:   struct ospf_interface *oi;
                   3395: 
                   3396:   oi = nbr_nbma->oi;
                   3397:   assert(oi);
                   3398: 
                   3399:   /* If this is passive interface, do not send OSPF Hello. */
                   3400:   if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
                   3401:     return;
                   3402: 
                   3403:   if (oi->type != OSPF_IFTYPE_NBMA)
                   3404:     return;
                   3405: 
                   3406:   if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
                   3407:     return;
                   3408: 
                   3409:   if (PRIORITY(oi) == 0)
                   3410:     return;
                   3411: 
                   3412:   if (nbr_nbma->priority == 0
                   3413:       && oi->state != ISM_DR && oi->state != ISM_Backup)
                   3414:     return;
                   3415: 
                   3416:   ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
                   3417: }
                   3418: 
                   3419: int
                   3420: ospf_poll_timer (struct thread *thread)
                   3421: {
                   3422:   struct ospf_nbr_nbma *nbr_nbma;
                   3423: 
                   3424:   nbr_nbma = THREAD_ARG (thread);
                   3425:   nbr_nbma->t_poll = NULL;
                   3426: 
                   3427:   if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
                   3428:     zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
                   3429:     IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
                   3430: 
                   3431:   ospf_poll_send (nbr_nbma);
                   3432: 
                   3433:   if (nbr_nbma->v_poll > 0)
                   3434:     OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
                   3435:                        nbr_nbma->v_poll);
                   3436: 
                   3437:   return 0;
                   3438: }
                   3439: 
                   3440: 
                   3441: int
                   3442: ospf_hello_reply_timer (struct thread *thread)
                   3443: {
                   3444:   struct ospf_neighbor *nbr;
                   3445: 
                   3446:   nbr = THREAD_ARG (thread);
                   3447:   nbr->t_hello_reply = NULL;
                   3448: 
                   3449:   assert (nbr->oi);
                   3450: 
                   3451:   if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
                   3452:     zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
                   3453:          IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
                   3454: 
                   3455:   ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
                   3456: 
                   3457:   return 0;
                   3458: }
                   3459: 
                   3460: /* Send OSPF Hello. */
                   3461: void
                   3462: ospf_hello_send (struct ospf_interface *oi)
                   3463: {
                   3464:   /* If this is passive interface, do not send OSPF Hello. */
                   3465:   if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
                   3466:     return;
                   3467: 
                   3468:   if (oi->type == OSPF_IFTYPE_NBMA)
                   3469:     {
                   3470:       struct ospf_neighbor *nbr;
                   3471:       struct route_node *rn;
                   3472: 
                   3473:       for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
                   3474:        if ((nbr = rn->info))
                   3475:          if (nbr != oi->nbr_self)
                   3476:            if (nbr->state != NSM_Down)
                   3477:              {
                   3478:                /*  RFC 2328  Section 9.5.1
                   3479:                    If the router is not eligible to become Designated Router,
                   3480:                    it must periodically send Hello Packets to both the
                   3481:                    Designated Router and the Backup Designated Router (if they
                   3482:                    exist).  */
                   3483:                if (PRIORITY(oi) == 0 &&
                   3484:                    IPV4_ADDR_CMP(&DR(oi),  &nbr->address.u.prefix4) &&
                   3485:                    IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
                   3486:                  continue;
                   3487: 
                   3488:                /*  If the router is eligible to become Designated Router, it
                   3489:                    must periodically send Hello Packets to all neighbors that
                   3490:                    are also eligible. In addition, if the router is itself the
                   3491:                    Designated Router or Backup Designated Router, it must also
                   3492:                    send periodic Hello Packets to all other neighbors. */
                   3493: 
                   3494:                if (nbr->priority == 0 && oi->state == ISM_DROther)
                   3495:                  continue;
                   3496:                /* if oi->state == Waiting, send hello to all neighbors */
                   3497:                ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
                   3498:              }
                   3499:     }
                   3500:   else
                   3501:     {
                   3502:       /* Decide destination address. */
                   3503:       if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
                   3504:         ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
                   3505:       else
                   3506:         ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
                   3507:     }
                   3508: }
                   3509: 
                   3510: /* Send OSPF Database Description. */
                   3511: void
                   3512: ospf_db_desc_send (struct ospf_neighbor *nbr)
                   3513: {
                   3514:   struct ospf_interface *oi;
                   3515:   struct ospf_packet *op;
                   3516:   u_int16_t length = OSPF_HEADER_SIZE;
                   3517: 
                   3518:   oi = nbr->oi;
                   3519:   op = ospf_packet_new (oi->ifp->mtu);
                   3520: 
                   3521:   /* Prepare OSPF common header. */
                   3522:   ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
                   3523: 
                   3524:   /* Prepare OSPF Database Description body. */
                   3525:   length += ospf_make_db_desc (oi, nbr, op->s);
                   3526: 
                   3527:   /* Fill OSPF header. */
                   3528:   ospf_fill_header (oi, op->s, length);
                   3529: 
                   3530:   /* Set packet length. */
                   3531:   op->length = length;
                   3532: 
                   3533:   /* Decide destination address. */
                   3534:   if (oi->type == OSPF_IFTYPE_POINTOPOINT) 
                   3535:     op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3536:   else
                   3537:     op->dst = nbr->address.u.prefix4;
                   3538: 
                   3539:   /* Add packet to the interface output queue. */
                   3540:   ospf_packet_add (oi, op);
                   3541: 
                   3542:   /* Hook thread to write packet. */
                   3543:   OSPF_ISM_WRITE_ON (oi->ospf);
                   3544: 
                   3545:   /* Remove old DD packet, then copy new one and keep in neighbor structure. */
                   3546:   if (nbr->last_send)
                   3547:     ospf_packet_free (nbr->last_send);
                   3548:   nbr->last_send = ospf_packet_dup (op);
                   3549:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
                   3550: }
                   3551: 
                   3552: /* Re-send Database Description. */
                   3553: void
                   3554: ospf_db_desc_resend (struct ospf_neighbor *nbr)
                   3555: {
                   3556:   struct ospf_interface *oi;
                   3557: 
                   3558:   oi = nbr->oi;
                   3559: 
                   3560:   /* Add packet to the interface output queue. */
                   3561:   ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
                   3562: 
                   3563:   /* Hook thread to write packet. */
                   3564:   OSPF_ISM_WRITE_ON (oi->ospf);
                   3565: }
                   3566: 
                   3567: /* Send Link State Request. */
                   3568: void
                   3569: ospf_ls_req_send (struct ospf_neighbor *nbr)
                   3570: {
                   3571:   struct ospf_interface *oi;
                   3572:   struct ospf_packet *op;
                   3573:   u_int16_t length = OSPF_HEADER_SIZE;
                   3574: 
                   3575:   oi = nbr->oi;
                   3576:   op = ospf_packet_new (oi->ifp->mtu);
                   3577: 
                   3578:   /* Prepare OSPF common header. */
                   3579:   ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
                   3580: 
                   3581:   /* Prepare OSPF Link State Request body. */
                   3582:   length += ospf_make_ls_req (nbr, op->s);
                   3583:   if (length == OSPF_HEADER_SIZE)
                   3584:     {
                   3585:       ospf_packet_free (op);
                   3586:       return;
                   3587:     }
                   3588: 
                   3589:   /* Fill OSPF header. */
                   3590:   ospf_fill_header (oi, op->s, length);
                   3591: 
                   3592:   /* Set packet length. */
                   3593:   op->length = length;
                   3594: 
                   3595:   /* Decide destination address. */
                   3596:   if (oi->type == OSPF_IFTYPE_POINTOPOINT) 
                   3597:     op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3598:   else
                   3599:     op->dst = nbr->address.u.prefix4;
                   3600: 
                   3601:   /* Add packet to the interface output queue. */
                   3602:   ospf_packet_add (oi, op);
                   3603: 
                   3604:   /* Hook thread to write packet. */
                   3605:   OSPF_ISM_WRITE_ON (oi->ospf);
                   3606: 
                   3607:   /* Add Link State Request Retransmission Timer. */
                   3608:   OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
                   3609: }
                   3610: 
                   3611: /* Send Link State Update with an LSA. */
                   3612: void
                   3613: ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
                   3614:                      int flag)
                   3615: {
                   3616:   struct list *update;
                   3617: 
                   3618:   update = list_new ();
                   3619: 
                   3620:   listnode_add (update, lsa);
                   3621:   ospf_ls_upd_send (nbr, update, flag);
                   3622: 
                   3623:   list_delete (update);
                   3624: }
                   3625: 
                   3626: /* Determine size for packet. Must be at least big enough to accomodate next
                   3627:  * LSA on list, which may be bigger than MTU size.
                   3628:  *
                   3629:  * Return pointer to new ospf_packet
                   3630:  * NULL if we can not allocate, eg because LSA is bigger than imposed limit
                   3631:  * on packet sizes (in which case offending LSA is deleted from update list)
                   3632:  */
                   3633: static struct ospf_packet *
                   3634: ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
                   3635: {
                   3636:   struct ospf_lsa *lsa;
                   3637:   struct listnode *ln;
                   3638:   size_t size;
                   3639:   static char warned = 0;
                   3640: 
                   3641:   lsa = listgetdata((ln = listhead (update)));
                   3642:   assert (lsa->data);
                   3643: 
                   3644:   if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
                   3645:       > ospf_packet_max (oi))
                   3646:     {
                   3647:       if (!warned)
                   3648:         {
                   3649:           zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
                   3650:                      "will need to fragment. Not optimal. Try divide up"
                   3651:                      " your network with areas. Use 'debug ospf packet send'"
                   3652:                      " to see details, or look at 'show ip ospf database ..'");
                   3653:           warned = 1;
                   3654:         }
                   3655: 
                   3656:       if (IS_DEBUG_OSPF_PACKET (0, SEND))
                   3657:         zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
                   3658:                    " %d bytes originated by %s, will be fragmented!",
                   3659:                    inet_ntoa (lsa->data->id),
                   3660:                    ntohs (lsa->data->length),
                   3661:                    inet_ntoa (lsa->data->adv_router));
                   3662: 
                   3663:       /* 
                   3664:        * Allocate just enough to fit this LSA only, to avoid including other
                   3665:        * LSAs in fragmented LSA Updates.
                   3666:        */
                   3667:       size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
                   3668:              + OSPF_LS_UPD_MIN_SIZE;
                   3669:     }
                   3670:   else
                   3671:     size = oi->ifp->mtu;
                   3672: 
                   3673:   if (size > OSPF_MAX_PACKET_SIZE)
                   3674:     {
                   3675:       zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
                   3676:                  " %d bytes, packet size %ld, dropping it completely."
                   3677:                  " OSPF routing is broken!",
                   3678:                  inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
                   3679:                  (long int) size);
                   3680:       list_delete_node (update, ln);
                   3681:       return NULL;
                   3682:     }
                   3683: 
                   3684:   /* IP header is built up separately by ospf_write(). This means, that we must
                   3685:    * reduce the "affordable" size just calculated by length of an IP header.
                   3686:    * This makes sure, that even if we manage to fill the payload with LSA data
                   3687:    * completely, the final packet (our data plus IP header) still fits into
                   3688:    * outgoing interface MTU. This correction isn't really meaningful for an
                   3689:    * oversized LSA, but for consistency the correction is done for both cases.
                   3690:    *
                   3691:    * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
                   3692:    */
                   3693:   return ospf_packet_new (size - sizeof (struct ip));
                   3694: }
                   3695: 
                   3696: static void
                   3697: ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
                   3698:                        struct in_addr addr)
                   3699: {
                   3700:   struct ospf_packet *op;
                   3701:   u_int16_t length = OSPF_HEADER_SIZE;
                   3702: 
                   3703:   if (IS_DEBUG_OSPF_EVENT)
                   3704:     zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
                   3705:   
                   3706:   op = ospf_ls_upd_packet_new (update, oi);
                   3707: 
                   3708:   /* Prepare OSPF common header. */
                   3709:   ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
                   3710: 
                   3711:   /* Prepare OSPF Link State Update body.
                   3712:    * Includes Type-7 translation. 
                   3713:    */
                   3714:   length += ospf_make_ls_upd (oi, update, op->s);
                   3715: 
                   3716:   /* Fill OSPF header. */
                   3717:   ospf_fill_header (oi, op->s, length);
                   3718: 
                   3719:   /* Set packet length. */
                   3720:   op->length = length;
                   3721: 
                   3722:   /* Decide destination address. */
                   3723:   if (oi->type == OSPF_IFTYPE_POINTOPOINT) 
                   3724:     op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3725:   else
                   3726:     op->dst.s_addr = addr.s_addr;
                   3727: 
                   3728:   /* Add packet to the interface output queue. */
                   3729:   ospf_packet_add (oi, op);
                   3730: 
                   3731:   /* Hook thread to write packet. */
                   3732:   OSPF_ISM_WRITE_ON (oi->ospf);
                   3733: }
                   3734: 
                   3735: static int
                   3736: ospf_ls_upd_send_queue_event (struct thread *thread)
                   3737: {
                   3738:   struct ospf_interface *oi = THREAD_ARG(thread);
                   3739:   struct route_node *rn;
                   3740:   struct route_node *rnext;
                   3741:   struct list *update;
                   3742:   char again = 0;
                   3743:   
                   3744:   oi->t_ls_upd_event = NULL;
                   3745: 
                   3746:   if (IS_DEBUG_OSPF_EVENT)
                   3747:     zlog_debug ("ospf_ls_upd_send_queue start");
                   3748: 
                   3749:   for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
                   3750:     {
                   3751:       rnext = route_next (rn);
                   3752:       
                   3753:       if (rn->info == NULL)
                   3754:         continue;
                   3755:       
                   3756:       update = (struct list *)rn->info;
                   3757: 
                   3758:       ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
                   3759:       
                   3760:       /* list might not be empty. */
                   3761:       if (listcount(update) == 0)
                   3762:         {
                   3763:           list_delete (rn->info);
                   3764:           rn->info = NULL;
                   3765:           route_unlock_node (rn);
                   3766:         }
                   3767:       else
                   3768:         again = 1;
                   3769:     }
                   3770: 
                   3771:   if (again != 0)
                   3772:     {
                   3773:       if (IS_DEBUG_OSPF_EVENT)
                   3774:         zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
                   3775:                    " %d nodes to try again, raising new event", again);
                   3776:       oi->t_ls_upd_event = 
                   3777:         thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
                   3778:     }
                   3779: 
                   3780:   if (IS_DEBUG_OSPF_EVENT)
                   3781:     zlog_debug ("ospf_ls_upd_send_queue stop");
                   3782:   
                   3783:   return 0;
                   3784: }
                   3785: 
                   3786: void
                   3787: ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
                   3788: {
                   3789:   struct ospf_interface *oi;
                   3790:   struct ospf_lsa *lsa;
                   3791:   struct prefix_ipv4 p;
                   3792:   struct route_node *rn;
                   3793:   struct listnode *node;
                   3794:   
                   3795:   oi = nbr->oi;
                   3796: 
                   3797:   p.family = AF_INET;
                   3798:   p.prefixlen = IPV4_MAX_BITLEN;
                   3799:   
                   3800:   /* Decide destination address. */
                   3801:   if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
                   3802:     p.prefix = oi->vl_data->peer_addr;
                   3803:   else if (oi->type == OSPF_IFTYPE_POINTOPOINT) 
                   3804:      p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3805:   else if (flag == OSPF_SEND_PACKET_DIRECT)
                   3806:      p.prefix = nbr->address.u.prefix4;
                   3807:   else if (oi->state == ISM_DR || oi->state == ISM_Backup)
                   3808:      p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3809:   else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
                   3810:      p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3811:   else
                   3812:      p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
                   3813: 
                   3814:   if (oi->type == OSPF_IFTYPE_NBMA)
                   3815:     {
                   3816:       if (flag == OSPF_SEND_PACKET_INDIRECT)
                   3817:        zlog_warn ("* LS-Update is directly sent on NBMA network.");
                   3818:       if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
                   3819:        zlog_warn ("* LS-Update is sent to myself.");
                   3820:     }
                   3821: 
                   3822:   rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
                   3823: 
                   3824:   if (rn->info == NULL)
                   3825:     rn->info = list_new ();
                   3826: 
                   3827:   for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
                   3828:     listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
                   3829: 
                   3830:   if (oi->t_ls_upd_event == NULL)
                   3831:     oi->t_ls_upd_event =
                   3832:       thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
                   3833: }
                   3834: 
                   3835: static void
                   3836: ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
                   3837:                       struct in_addr dst)
                   3838: {
                   3839:   struct ospf_packet *op;
                   3840:   u_int16_t length = OSPF_HEADER_SIZE;
                   3841: 
                   3842:   op = ospf_packet_new (oi->ifp->mtu);
                   3843: 
                   3844:   /* Prepare OSPF common header. */
                   3845:   ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
                   3846: 
                   3847:   /* Prepare OSPF Link State Acknowledgment body. */
                   3848:   length += ospf_make_ls_ack (oi, ack, op->s);
                   3849: 
                   3850:   /* Fill OSPF header. */
                   3851:   ospf_fill_header (oi, op->s, length);
                   3852: 
                   3853:   /* Set packet length. */
                   3854:   op->length = length;
                   3855: 
                   3856:   /* Set destination IP address. */
                   3857:   op->dst = dst;
                   3858:   
                   3859:   /* Add packet to the interface output queue. */
                   3860:   ospf_packet_add (oi, op);
                   3861: 
                   3862:   /* Hook thread to write packet. */
                   3863:   OSPF_ISM_WRITE_ON (oi->ospf);
                   3864: }
                   3865: 
                   3866: static int
                   3867: ospf_ls_ack_send_event (struct thread *thread)
                   3868: {
                   3869:   struct ospf_interface *oi = THREAD_ARG (thread);
                   3870: 
                   3871:   oi->t_ls_ack_direct = NULL;
                   3872:   
                   3873:   while (listcount (oi->ls_ack_direct.ls_ack))
                   3874:     ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
                   3875:                           oi->ls_ack_direct.dst);
                   3876: 
                   3877:   return 0;
                   3878: }
                   3879: 
                   3880: void
                   3881: ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
                   3882: {
                   3883:   struct ospf_interface *oi = nbr->oi;
                   3884: 
                   3885:   if (listcount (oi->ls_ack_direct.ls_ack) == 0)
                   3886:     oi->ls_ack_direct.dst = nbr->address.u.prefix4;
                   3887:   
                   3888:   listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
                   3889:   
                   3890:   if (oi->t_ls_ack_direct == NULL)
                   3891:     oi->t_ls_ack_direct =
                   3892:       thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
                   3893: }
                   3894: 
                   3895: /* Send Link State Acknowledgment delayed. */
                   3896: void
                   3897: ospf_ls_ack_send_delayed (struct ospf_interface *oi)
                   3898: {
                   3899:   struct in_addr dst;
                   3900:   
                   3901:   /* Decide destination address. */
                   3902:   /* RFC2328 Section 13.5                           On non-broadcast
                   3903:        networks, delayed Link State Acknowledgment packets must be
                   3904:        unicast separately over each adjacency (i.e., neighbor whose
                   3905:        state is >= Exchange).  */
                   3906:   if (oi->type == OSPF_IFTYPE_NBMA)
                   3907:     {
                   3908:       struct ospf_neighbor *nbr;
                   3909:       struct route_node *rn;
                   3910: 
                   3911:       for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
                   3912:        if ((nbr = rn->info) != NULL)
                   3913:          if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
                   3914:            while (listcount (oi->ls_ack))
                   3915:              ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
                   3916:       return;
                   3917:     }
                   3918:   if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
                   3919:     dst.s_addr = oi->vl_data->peer_addr.s_addr;
                   3920:   else if (oi->state == ISM_DR || oi->state == ISM_Backup)
                   3921:     dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3922:   else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
                   3923:     dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3924:   else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
                   3925:     dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3926:   else
                   3927:     dst.s_addr = htonl (OSPF_ALLDROUTERS);
                   3928: 
                   3929:   while (listcount (oi->ls_ack))
                   3930:     ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
                   3931: }

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