File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospfd / ospf_packet.c
Revision 1.1.1.5 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:12 2016 UTC (7 years, 8 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

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

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