File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospfd / ospf_packet.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jul 21 23:54:40 2013 UTC (10 years, 11 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, HEAD
0.99.22

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

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