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

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

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