File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospfd / ospf_packet.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 11:53:41 2012 UTC (12 years, 1 month ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_20_1, HEAD
quagga 0.99.20.1

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

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