File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libnet / src / libnet_build_ospf.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:14:23 2012 UTC (12 years, 4 months ago) by misho
Branches: libnet, MAIN
CVS tags: v1_1_2_1, HEAD
libnet

    1: /*
    2:  *  $Id: libnet_build_ospf.c,v 1.1.1.1 2012/02/21 22:14:23 misho Exp $
    3:  *
    4:  *  libnet
    5:  *  libnet_build_ospf.c - OSPF packet assembler
    6:  *
    7:  *  Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
    8:  *  All rights reserved.
    9:  *
   10:  *  Copyright (c) 1999, 2000 Andrew Reiter <areiter@bindview.com>
   11:  *  Bindview Development
   12:  *
   13:  * Redistribution and use in source and binary forms, with or without
   14:  * modification, are permitted provided that the following conditions
   15:  * are met:
   16:  * 1. Redistributions of source code must retain the above copyright
   17:  *    notice, this list of conditions and the following disclaimer.
   18:  * 2. Redistributions in binary form must reproduce the above copyright
   19:  *    notice, this list of conditions and the following disclaimer in the
   20:  *    documentation and/or other materials provided with the distribution.
   21:  *
   22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32:  * SUCH DAMAGE.
   33:  *
   34:  */
   35: 
   36: #if (HAVE_CONFIG_H)
   37: #include "../include/config.h"
   38: #endif
   39: #if (!(_WIN32) || (__CYGWIN__)) 
   40: #include "../include/libnet.h"
   41: #else
   42: #include "../include/win32/libnet.h"
   43: #endif
   44: 
   45: libnet_ptag_t
   46: libnet_build_ospfv2(u_int16_t len, u_int8_t type, u_int32_t rtr_id, 
   47: u_int32_t area_id, u_int16_t sum, u_int16_t autype, u_int8_t *payload, 
   48: u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
   49: {
   50:     u_int32_t n, h;
   51:     libnet_pblock_t *p;
   52:     struct libnet_ospf_hdr ospf_hdr;
   53: 
   54:     if (l == NULL)
   55:     { 
   56:         return (-1);
   57:     } 
   58:  
   59:     n = LIBNET_OSPF_H + payload_s;
   60:     h = LIBNET_OSPF_H + payload_s + len;
   61: 
   62:     /*
   63:      *  Find the existing protocol block if a ptag is specified, or create
   64:      *  a new one.
   65:      */
   66:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_H);
   67:     if (p == NULL)
   68:     {
   69:         return (-1);
   70:     }
   71:     
   72:     memset(&ospf_hdr, 0, sizeof(ospf_hdr));
   73:     ospf_hdr.ospf_v               = 2;              /* OSPF version 2 */
   74:     ospf_hdr.ospf_type            = type;           /* Type of pkt */
   75:     ospf_hdr.ospf_len             = htons(h);       /* Pkt len */
   76:     ospf_hdr.ospf_rtr_id.s_addr   = htonl(rtr_id);  /* Router ID */
   77:     ospf_hdr.ospf_area_id.s_addr  = htonl(area_id); /* Area ID */
   78:     ospf_hdr.ospf_sum             = (sum ? htons(sum) : 0);
   79:     ospf_hdr.ospf_auth_type       = htons(autype);  /* Type of auth */
   80: 
   81:     n = libnet_pblock_append(l, p, (u_int8_t *)&ospf_hdr, LIBNET_OSPF_H);
   82:     if (n == -1)
   83:     {
   84:         goto bad;
   85:     }
   86: 
   87:     if ((payload && !payload_s) || (!payload && payload_s))
   88:     {
   89:          snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
   90: 			     "%s(): payload inconsistency\n", __func__);
   91:         goto bad;
   92:     }
   93:  
   94:     if (payload && payload_s)
   95:     {
   96:         n = libnet_pblock_append(l, p, payload, payload_s);
   97:         if (n == -1)
   98:         {
   99:             goto bad;
  100:         }
  101:     }
  102: 
  103:     if (sum == 0)
  104:     {
  105:         /*
  106:          *  If checksum is zero, by default libnet will compute a checksum
  107:          *  for the user.  The programmer can override this by calling
  108:          *  libnet_toggle_checksum(l, ptag, 1);
  109:          */
  110:         libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM);
  111:     }
  112:     return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_OSPF_H));
  113: bad:
  114:     libnet_pblock_delete(l, p);
  115:     return (-1);
  116: }
  117: 
  118: 
  119: libnet_ptag_t
  120: libnet_build_ospfv2_hello(u_int32_t netmask, u_int16_t interval, u_int8_t opts, 
  121: u_int8_t priority, u_int32_t dead_int, u_int32_t des_rtr, u_int32_t bkup_rtr,
  122: u_int32_t neighbor, u_int8_t *payload, u_int32_t payload_s, libnet_t *l,
  123: libnet_ptag_t ptag)
  124: {
  125:     u_int32_t n, h;
  126:     libnet_pblock_t *p;
  127:     struct libnet_ospf_hello_hdr hello_hdr;
  128: 
  129:     if (l == NULL)
  130:     { 
  131:         return (-1);
  132:     } 
  133: 
  134:     n = LIBNET_OSPF_HELLO_H + payload_s;
  135:     h = 0;
  136: 
  137:     /*
  138:      *  Find the existing protocol block if a ptag is specified, or create
  139:      *  a new one.
  140:      */
  141:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_HELLO_H);
  142:     if (p == NULL)
  143:     {
  144:         return (-1);
  145:     }
  146:     
  147:     memset(&hello_hdr, 0, sizeof(hello_hdr));
  148:     hello_hdr.hello_nmask.s_addr    = htonl(netmask);  /* Netmask */
  149:     hello_hdr.hello_intrvl          = htons(interval);	/* # seconds since last packet sent */
  150:     hello_hdr.hello_opts            = opts;     /* OSPF_* options */
  151:     hello_hdr.hello_rtr_pri         = priority; /* If 0, can't be backup */
  152:     hello_hdr.hello_dead_intvl      = htonl(dead_int); /* Time til router is deemed down */
  153:     hello_hdr.hello_des_rtr.s_addr  = htonl(des_rtr);	/* Networks designated router */
  154:     hello_hdr.hello_bkup_rtr.s_addr = htonl(bkup_rtr); /* Networks backup router */
  155:     hello_hdr.hello_nbr.s_addr      = htonl(neighbor);
  156: 
  157:     n = libnet_pblock_append(l, p, (u_int8_t *)&hello_hdr, LIBNET_OSPF_HELLO_H);
  158:     if (n == -1)
  159:     {
  160:         goto bad;
  161:     }
  162: 
  163:     if ((payload && !payload_s) || (!payload && payload_s))
  164:     {
  165:          snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  166: 			     "%s(): payload inconsistency\n", __func__);
  167:         goto bad;
  168:     }
  169:  
  170:     if (payload && payload_s)
  171:     {
  172:         n = libnet_pblock_append(l, p, payload, payload_s);
  173:         if (n == -1)
  174:         {
  175:             goto bad;
  176:         }
  177:     }
  178:  
  179:     return (ptag ? ptag : libnet_pblock_update(l, p, h, 
  180:             LIBNET_PBLOCK_OSPF_HELLO_H));
  181: bad:
  182:     libnet_pblock_delete(l, p);
  183:     return (-1);
  184: }
  185: 
  186: 
  187: libnet_ptag_t
  188: libnet_build_ospfv2_dbd(u_int16_t dgram_len, u_int8_t opts, u_int8_t type,
  189: u_int32_t seqnum, u_int8_t *payload, u_int32_t payload_s, libnet_t *l,
  190: libnet_ptag_t ptag)
  191: {
  192:     u_int32_t n, h;
  193:     libnet_pblock_t *p;
  194:     struct libnet_dbd_hdr dbd_hdr;
  195: 
  196:     if (l == NULL)
  197:     { 
  198:         return (-1);
  199:     } 
  200: 
  201:     n = LIBNET_OSPF_DBD_H + payload_s;
  202:     h = 0;
  203: 
  204:     /*
  205:      *  Find the existing protocol block if a ptag is specified, or create
  206:      *  a new one.
  207:      */
  208:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_DBD_H);
  209:     if (p == NULL)
  210:     {
  211:         return (-1);
  212:     }
  213:     
  214:     memset(&dbd_hdr, 0, sizeof(dbd_hdr));
  215:     dbd_hdr.dbd_mtu_len	= htons(dgram_len); /* Max length of IP packet IF can use */
  216:     dbd_hdr.dbd_opts    = opts;	            /* OSPF_* options */
  217:     dbd_hdr.dbd_type    = type;	            /* Type of exchange occuring */
  218:     dbd_hdr.dbd_seq     = htonl(seqnum);    /* DBD sequence number */
  219: 
  220:     n = libnet_pblock_append(l, p, (u_int8_t *)&dbd_hdr, LIBNET_OSPF_DBD_H);
  221:     if (n == -1)
  222:     {
  223:         goto bad;
  224:     }
  225: 
  226:     if ((payload && !payload_s) || (!payload && payload_s))
  227:     {
  228:          snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  229: 			     "%s(): payload inconsistency\n", __func__);
  230:         goto bad;
  231:     }
  232:  
  233:     if (payload && payload_s)
  234:     {
  235:         n = libnet_pblock_append(l, p, payload, payload_s);
  236:         if (n == -1)
  237:         {
  238:             goto bad; 
  239:         }
  240:     }
  241: 
  242:     return (ptag ? ptag : libnet_pblock_update(l, p, h, 
  243:             LIBNET_PBLOCK_OSPF_DBD_H));
  244: bad:
  245:     libnet_pblock_delete(l, p);
  246:     return (-1);
  247: }
  248: 
  249: 
  250: libnet_ptag_t
  251: libnet_build_ospfv2_lsr(u_int32_t type, u_int lsid, u_int32_t advrtr, 
  252: u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
  253: {
  254:     u_int32_t n, h;
  255:     libnet_pblock_t *p;
  256:     struct libnet_lsr_hdr lsr_hdr;
  257: 
  258:     if (l == NULL)
  259:     { 
  260:         return (-1);
  261:     } 
  262: 
  263:     n = LIBNET_OSPF_LSR_H + payload_s;
  264:     h = 0;
  265: 
  266:     /*
  267:      *  Find the existing protocol block if a ptag is specified, or create
  268:      *  a new one.
  269:      */
  270:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_LSR_H);
  271:     if (p == NULL)
  272:     {
  273:         return (-1);
  274:     }
  275: 
  276:     memset(&lsr_hdr, 0, sizeof(lsr_hdr));
  277:     lsr_hdr.lsr_type         = htonl(type);     /* Type of LS being requested */
  278:     lsr_hdr.lsr_lsid	     = htonl(lsid);     /* Link State ID */
  279:     lsr_hdr.lsr_adrtr.s_addr = htonl(advrtr);   /* Advertising router */
  280: 
  281:     n = libnet_pblock_append(l, p, (u_int8_t *)&lsr_hdr, LIBNET_OSPF_LSR_H);
  282:     if (n == -1)
  283:     {
  284:         goto bad;
  285:     }
  286: 
  287:     if ((payload && !payload_s) || (!payload && payload_s))
  288:     {
  289:          snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  290: 			     "%s(): payload inconsistency\n", __func__);
  291:         goto bad;
  292:     }
  293:  
  294:     if (payload && payload_s)
  295:     {
  296:         n = libnet_pblock_append(l, p, payload, payload_s);
  297:         if (n == -1)
  298:         {
  299:             goto bad;
  300:         }
  301:     }
  302: 
  303:     return (ptag ? ptag : libnet_pblock_update(l, p, h, 
  304:             LIBNET_PBLOCK_OSPF_LSR_H));
  305: bad:
  306:     libnet_pblock_delete(l, p);
  307:     return (-1);
  308: }
  309: 
  310: 
  311: libnet_ptag_t
  312: libnet_build_ospfv2_lsu(u_int32_t num, u_int8_t *payload, u_int32_t payload_s,
  313: libnet_t *l, libnet_ptag_t ptag)
  314: {
  315:     u_int32_t n, h;
  316:     libnet_pblock_t *p;
  317:     struct libnet_lsu_hdr lh_hdr;
  318: 
  319:     if (l == NULL)
  320:     { 
  321:         return (-1);
  322:     } 
  323: 
  324:     n = LIBNET_OSPF_LSU_H + payload_s;
  325:     h = 0;
  326: 
  327:     /*
  328:      *  Find the existing protocol block if a ptag is specified, or create
  329:      *  a new one.
  330:      */
  331:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_LSU_H);
  332:     if (p == NULL)
  333:     {
  334:         return (-1);
  335:     }
  336: 
  337:     memset(&lh_hdr, 0, sizeof(lh_hdr));
  338:     lh_hdr.lsu_num = htonl(num);   /* Number of LSAs that will be bcasted */
  339: 
  340:     n = libnet_pblock_append(l, p, (u_int8_t *)&lh_hdr, LIBNET_OSPF_LSU_H);
  341:     if (n == -1)
  342:     {
  343:         goto bad;
  344:     }
  345: 
  346:     if ((payload && !payload_s) || (!payload && payload_s))
  347:     {
  348:          snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  349:                  "%s(): payload inconsistency\n", __func__);
  350:         goto bad;
  351:     }
  352:  
  353:     if (payload && payload_s)
  354:     {
  355:         n = libnet_pblock_append(l, p, payload, payload_s);
  356:         if (n == -1)
  357:         {
  358:             goto bad;
  359:         }
  360:     }
  361: 
  362:     return (ptag ? ptag : libnet_pblock_update(l, p, h, 
  363:             LIBNET_PBLOCK_OSPF_LSU_H));
  364: bad:
  365:     libnet_pblock_delete(l, p);
  366:     return (-1);
  367: }
  368: 
  369: 
  370: libnet_ptag_t
  371: libnet_build_ospfv2_lsa(u_int16_t age, u_int8_t opts, u_int8_t type, u_int lsid,
  372: u_int32_t advrtr, u_int32_t seqnum, u_int16_t sum, u_int16_t len,
  373: u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
  374: {
  375:     u_int32_t n, h;
  376:     libnet_pblock_t *p;
  377:     struct libnet_lsa_hdr lsa_hdr;
  378: 
  379:     if (l == NULL)
  380:     { 
  381:         return (-1);
  382:     } 
  383: 
  384:     n = LIBNET_OSPF_LSA_H + payload_s;
  385:     h = len + payload_s;
  386: 
  387:     /*
  388:      *  Find the existing protocol block if a ptag is specified, or create
  389:      *  a new one.
  390:      */
  391:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_LSA_H);
  392:     if (p == NULL)
  393:     {
  394:         return (-1);
  395:     }
  396: 
  397:     memset(&lsa_hdr, 0, sizeof(lsa_hdr));
  398:     lsa_hdr.lsa_age         = htons(age);
  399:     lsa_hdr.lsa_opts        = opts;
  400:     lsa_hdr.lsa_type        = type;
  401:     lsa_hdr.lsa_id          = htonl(lsid);
  402:     lsa_hdr.lsa_adv.s_addr  = htonl(advrtr);
  403:     lsa_hdr.lsa_seq         = htonl(seqnum);
  404:     lsa_hdr.lsa_sum         = (sum ? htons(sum) : 0);
  405:     lsa_hdr.lsa_len         = htons(h);
  406: 
  407:     n = libnet_pblock_append(l, p, (u_int8_t *)&lsa_hdr, LIBNET_OSPF_LSA_H);
  408:     if (n == -1)
  409:     {
  410:         goto bad;
  411:     }
  412: 
  413:     if ((payload && !payload_s) || (!payload && payload_s))
  414:     {
  415:          snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  416: 			     "%s(): payload inconsistency\n", __func__);
  417:         goto bad;
  418:     }
  419:  
  420:     if (payload && payload_s)
  421:     {
  422:         n = libnet_pblock_append(l, p, payload, payload_s);
  423:         if (n == -1)
  424:         {
  425:             goto bad;
  426:         }
  427:     }
  428: 
  429:     if (sum == 0)
  430:     {
  431:         /*
  432:          *  If checksum is zero, by default libnet will compute a checksum
  433:          *  for the user.  The programmer can override this by calling
  434:          *  libnet_toggle_checksum(l, ptag, 1);
  435:          */
  436:         libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM);
  437:     }
  438:     return (ptag ? ptag : libnet_pblock_update(l, p, h, 
  439:             LIBNET_PBLOCK_OSPF_LSA_H));
  440: bad:
  441:     libnet_pblock_delete(l, p);
  442:     return (-1);
  443: }
  444: 
  445: 
  446: libnet_ptag_t
  447: libnet_build_ospfv2_lsa_rtr(u_int16_t flags, u_int16_t num, u_int32_t id,
  448: u_int32_t data, u_int8_t type, u_int8_t tos, u_int16_t metric,
  449: u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
  450: {
  451:     u_int32_t n, h;
  452:     libnet_pblock_t *p;
  453:     struct libnet_rtr_lsa_hdr rtr_lsa_hdr;
  454: 
  455:     if (l == NULL)
  456:     { 
  457:         return (-1);
  458:     } 
  459: 
  460:     n = LIBNET_OSPF_LS_RTR_H + payload_s;
  461:     h = 0;
  462: 
  463:     /*
  464:      *  Find the existing protocol block if a ptag is specified, or create
  465:      *  a new one.
  466:      */
  467:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_LS_RTR_H);
  468:     if (p == NULL)
  469:     {
  470:         return (-1);
  471:     }
  472: 
  473:     memset(&rtr_lsa_hdr, 0, sizeof(rtr_lsa_hdr));
  474:     rtr_lsa_hdr.rtr_flags       = htons(flags);
  475:     rtr_lsa_hdr.rtr_num         = htons(num);
  476:     rtr_lsa_hdr.rtr_link_id     = htonl(id);
  477:     rtr_lsa_hdr.rtr_link_data   = htonl(data);
  478:     rtr_lsa_hdr.rtr_type        = type;
  479:     rtr_lsa_hdr.rtr_tos_num     = tos;
  480:     rtr_lsa_hdr.rtr_metric      = htons(metric);
  481: 
  482:     n = libnet_pblock_append(l, p, (u_int8_t *)&rtr_lsa_hdr,
  483:             LIBNET_OSPF_LS_RTR_H);
  484:     if (n == -1)
  485:     {
  486:         goto bad;
  487:     }
  488: 
  489:     if ((payload && !payload_s) || (!payload && payload_s))
  490:     {
  491:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  492:                 "%s(): payload inconsistency\n", __func__);
  493:         goto bad;
  494:     }
  495:  
  496:     if (payload && payload_s)
  497:     {
  498:         n = libnet_pblock_append(l, p, payload, payload_s);
  499:         if (n == -1)
  500:         {
  501:             goto bad;
  502:         }
  503:     }
  504: 
  505:     return (ptag ? ptag : libnet_pblock_update(l, p, h, 
  506:             LIBNET_PBLOCK_LS_RTR_H));
  507: bad:
  508:     libnet_pblock_delete(l, p);
  509:     return (-1);
  510: }
  511: 
  512: 
  513: libnet_ptag_t
  514: libnet_build_ospfv2_lsa_net(u_int32_t nmask, u_int32_t rtrid,
  515: u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
  516: {
  517:     u_int32_t n, h;
  518:     libnet_pblock_t *p;
  519:     struct libnet_net_lsa_hdr net_lsa_hdr;
  520: 
  521:     if (l == NULL)
  522:     { 
  523:         return (-1);
  524:     } 
  525: 
  526:     n = LIBNET_OSPF_LS_NET_H + payload_s;
  527:     h = 0;
  528: 
  529:     /*
  530:      *  Find the existing protocol block if a ptag is specified, or create
  531:      *  a new one.
  532:      */
  533:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_LS_NET_H);
  534:     if (p == NULL)
  535:     {
  536:         return (-1);
  537:     }
  538: 
  539:     memset(&net_lsa_hdr, 0, sizeof(net_lsa_hdr));
  540:     net_lsa_hdr.net_nmask.s_addr    = htonl(nmask);
  541:     net_lsa_hdr.net_rtr_id          = htonl(rtrid);
  542: 
  543:     n = libnet_pblock_append(l, p, (u_int8_t *)&net_lsa_hdr,
  544:             LIBNET_OSPF_LS_NET_H);
  545:     if (n == -1)
  546:     {
  547:         goto bad;
  548:     }
  549: 
  550:     if ((payload && !payload_s) || (!payload && payload_s))
  551:     {
  552:          snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  553: 			     "%s(): payload inconsistency\n", __func__);
  554:         goto bad;
  555:     }
  556:  
  557:     if (payload && payload_s)
  558:     {
  559:         n = libnet_pblock_append(l, p, payload, payload_s);
  560:         if (n == -1)
  561:         {
  562:             goto bad;
  563:         }
  564:     }
  565: 
  566:     return (ptag ? ptag : libnet_pblock_update(l, p, h, 
  567:             LIBNET_PBLOCK_LS_NET_H));
  568: bad:
  569:     libnet_pblock_delete(l, p);
  570:     return (-1);
  571: }
  572: 
  573: 
  574: libnet_ptag_t
  575: libnet_build_ospfv2_lsa_sum(u_int32_t nmask, u_int32_t metric, u_int tos, 
  576: u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
  577: {
  578:     u_int32_t n, h;
  579:     libnet_pblock_t *p;
  580:     struct libnet_sum_lsa_hdr sum_lsa_hdr;
  581: 
  582:     if (l == NULL)
  583:     { 
  584:         return (-1);
  585:     } 
  586: 
  587:     n = LIBNET_OSPF_LS_SUM_H + payload_s;
  588:     h = 0;
  589: 
  590:     /*
  591:      *  Find the existing protocol block if a ptag is specified, or create
  592:      *  a new one.
  593:      */
  594:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_LS_SUM_H);
  595:     if (p == NULL)
  596:     {
  597:         return (-1);
  598:     }
  599: 
  600:     memset(&sum_lsa_hdr, 0, sizeof(sum_lsa_hdr));
  601:     sum_lsa_hdr.sum_nmask.s_addr    = htonl(nmask);
  602:     sum_lsa_hdr.sum_metric          = htonl(metric);
  603:     sum_lsa_hdr.sum_tos_metric      = htonl(tos);
  604: 
  605:     n = libnet_pblock_append(l, p, (u_int8_t *)&sum_lsa_hdr,
  606:             LIBNET_OSPF_LS_SUM_H);
  607:     if (n == -1)
  608:     {
  609:         goto bad;
  610:     }
  611: 
  612:     if ((payload && !payload_s) || (!payload && payload_s))
  613:     {
  614:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  615:                 "%s(): payload inconsistency\n", __func__);
  616:         goto bad;
  617:     }
  618:  
  619:     if (payload && payload_s)
  620:     {
  621:         n = libnet_pblock_append(l, p, payload, payload_s);
  622:         if (n == -1)
  623:         {
  624:            goto bad;
  625:         }
  626:     }
  627: 
  628:     return (ptag ? ptag : libnet_pblock_update(l, p, h, 
  629:             LIBNET_PBLOCK_LS_SUM_H));
  630: bad:
  631:     libnet_pblock_delete(l, p);
  632:     return (-1);
  633: }
  634: 
  635: 
  636: libnet_ptag_t
  637: libnet_build_ospfv2_lsa_as(u_int32_t nmask, u_int metric, u_int32_t fwdaddr,
  638: u_int32_t tag, u_int8_t *payload, u_int32_t payload_s, libnet_t *l,
  639: libnet_ptag_t ptag)
  640: {
  641:     u_int32_t n, h;
  642:     libnet_pblock_t *p;
  643:     struct libnet_as_lsa_hdr as_lsa_hdr;
  644: 
  645:     if (l == NULL)
  646:     { 
  647:         return (-1);
  648:     } 
  649:    
  650:     n = LIBNET_OSPF_LS_AS_EXT_H + payload_s;
  651:     h = 0;
  652: 
  653:     /*
  654:      *  Find the existing protocol block if a ptag is specified, or create
  655:      *  a new one.
  656:      */
  657:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_LS_AS_EXT_H);
  658:     if (p == NULL)
  659:     {
  660:         return (-1);
  661:     }
  662: 
  663:     memset(&as_lsa_hdr, 0, sizeof(as_lsa_hdr));
  664:     as_lsa_hdr.as_nmask.s_addr      = htonl(nmask);
  665:     as_lsa_hdr.as_metric            = htonl(metric);
  666:     as_lsa_hdr.as_fwd_addr.s_addr   = htonl(fwdaddr);
  667:     as_lsa_hdr.as_rte_tag           = htonl(tag);
  668: 
  669:     n = libnet_pblock_append(l, p, (u_int8_t *)&as_lsa_hdr,
  670:             LIBNET_OSPF_LS_AS_EXT_H);
  671:     if (n == -1)
  672:     {
  673:         goto bad;
  674:     }
  675: 
  676:     if ((payload && !payload_s) || (!payload && payload_s))
  677:     {
  678:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  679:                 "%s(): payload inconsistency\n", __func__);
  680:         goto bad;
  681:     }
  682:  
  683:     if (payload && payload_s)
  684:     {
  685:         n = libnet_pblock_append(l, p, payload, payload_s);
  686:         if (n == -1)
  687:         {
  688:             goto bad;
  689:         }
  690:     }
  691: 
  692:     return (ptag ? ptag : libnet_pblock_update(l, p, h, 
  693:             LIBNET_PBLOCK_LS_AS_EXT_H));
  694: bad:
  695:     libnet_pblock_delete(l, p);
  696:     return (-1);
  697: }
  698: 
  699: /* EOF */

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