File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libnet / src / libnet_build_bgp.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 11:54:42 2013 UTC (11 years ago) by misho
Branches: libnet, MAIN
CVS tags: v1_1_6p5, v1_1_6p4, v1_1_6p0, v1_1_6, HEAD
1.1.6

    1: /*
    2:  *  $Id: libnet_build_bgp.c,v 1.1.1.2 2013/07/22 11:54:42 misho Exp $
    3:  *
    4:  *  libnet
    5:  *  libnet_build_bgp.c - BGP packet assembler (RFC 1771)
    6:  *
    7:  *  Copyright (c) 2003 Frederic Raynal <pappy@security-labs.org>
    8:  *  All rights reserved.
    9:  *
   10:  * Redistribution and use in source and binary forms, with or without
   11:  * modification, are permitted provided that the following conditions
   12:  * are met:
   13:  * 1. Redistributions of source code must retain the above copyright
   14:  *    notice, this list of conditions and the following disclaimer.
   15:  * 2. Redistributions in binary form must reproduce the above copyright
   16:  *    notice, this list of conditions and the following disclaimer in the
   17:  *    documentation and/or other materials provided with the distribution.
   18:  *
   19:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29:  * SUCH DAMAGE.
   30:  *
   31:  */
   32: 
   33: #if (HAVE_CONFIG_H)
   34: #include "../include/config.h"
   35: #endif
   36: #if (!(_WIN32) || (__CYGWIN__)) 
   37: #include "../include/libnet.h"
   38: #else
   39: #include "../include/win32/libnet.h"
   40: #endif
   41: 
   42: libnet_ptag_t
   43: libnet_build_bgp4_header(uint8_t marker[LIBNET_BGP4_MARKER_SIZE],
   44: uint16_t len, uint8_t type, const uint8_t *payload, uint32_t payload_s,
   45: libnet_t *l, libnet_ptag_t ptag)
   46: {
   47:     uint32_t n, h;
   48:     libnet_pblock_t *p;
   49:     struct libnet_bgp4_header_hdr bgp4_hdr;
   50: 
   51:     if (l == NULL)
   52:     { 
   53:         return (-1);
   54:     } 
   55: 
   56:     n = LIBNET_BGP4_HEADER_H + payload_s;   /* size of memory block */
   57:     h = 0;                                  /* BGP headers have no checksum */
   58: 
   59:     /*
   60:      *  Find the existing protocol block if a ptag is specified, or create
   61:      *  a new one.
   62:      */
   63:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_BGP4_HEADER_H);
   64:     if (p == NULL)
   65:     {
   66:         return (-1);
   67:     }
   68: 
   69:     memset(&bgp4_hdr, 0, sizeof(bgp4_hdr));
   70:     memcpy(bgp4_hdr.marker, marker, LIBNET_BGP4_MARKER_SIZE * sizeof(uint8_t));
   71:     bgp4_hdr.len = htons(len);
   72:     bgp4_hdr.type = type;
   73: 
   74:     n = libnet_pblock_append(l, p, (uint8_t *)&bgp4_hdr, LIBNET_BGP4_HEADER_H);
   75:     if (n == -1)
   76:     {
   77:         goto bad;
   78:     }
   79: 
   80:     /* boilerplate payload sanity check / append macro */
   81:     LIBNET_DO_PAYLOAD(l, p);
   82:  
   83:     return (ptag ? ptag : libnet_pblock_update(l, p, h,
   84:             LIBNET_PBLOCK_BGP4_HEADER_H));
   85: bad:
   86:     libnet_pblock_delete(l, p);
   87:     return (-1);
   88: }
   89: 
   90: libnet_ptag_t
   91: libnet_build_bgp4_open(uint8_t version, uint16_t src_as, uint16_t hold_time,
   92: uint32_t bgp_id, uint8_t opt_len, const uint8_t *payload, uint32_t payload_s,
   93: libnet_t *l, libnet_ptag_t ptag)
   94: {
   95:     uint32_t n, h;
   96:     libnet_pblock_t *p;
   97:     uint16_t val;
   98: 
   99:     if (l == NULL)
  100:     { 
  101:         return (-1);
  102:     } 
  103: 
  104:     n = LIBNET_BGP4_OPEN_H + payload_s;     /* size of memory block */
  105:     h = 0;                                  /* BGP msg have no checksum */
  106: 
  107:     /*
  108:      *  Find the existing protocol block if a ptag is specified, or create
  109:      *  a new one.
  110:      */
  111:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_BGP4_OPEN_H);
  112:     if (p == NULL)
  113:     {
  114:         return (-1);
  115:     }
  116: 
  117:     /* for memory alignment reason, we need to append each field separately */
  118:     n = libnet_pblock_append(l, p, (uint8_t *)&version, sizeof (version));
  119:     if (n == -1)
  120:     {
  121:         goto bad;
  122:     }
  123: 
  124:     val = htons(src_as);
  125:     n = libnet_pblock_append(l, p, (uint8_t *)&val, sizeof(src_as));
  126:     if (n == -1)
  127:     {
  128:         goto bad;
  129:     }
  130: 
  131:     val = htons(hold_time);
  132:     n = libnet_pblock_append(l, p, (uint8_t *)&val, sizeof(hold_time));
  133:     if (n == -1)
  134:     {
  135:         goto bad;
  136:     }
  137: 
  138:     n = htonl(bgp_id);
  139:     n = libnet_pblock_append(l, p, (uint8_t *)&n, sizeof(bgp_id));
  140:     if (n == -1)
  141:     {
  142:         goto bad;
  143:     }
  144: 
  145:     n = libnet_pblock_append(l, p, (uint8_t *)&opt_len, sizeof(opt_len));
  146:     if (n == -1)
  147:     {
  148:         goto bad;
  149:     }
  150: 
  151:     /* boilerplate payload sanity check / append macro */
  152:     LIBNET_DO_PAYLOAD(l, p);
  153:  
  154:     return (ptag ? ptag : libnet_pblock_update(l, p, h,
  155:            LIBNET_PBLOCK_BGP4_OPEN_H));
  156: bad:
  157:     libnet_pblock_delete(l, p);
  158:     return (-1);
  159: }
  160: 
  161: libnet_ptag_t
  162: libnet_build_bgp4_update(uint16_t unfeasible_rt_len, const uint8_t *withdrawn_rt,
  163: uint16_t total_path_attr_len, const uint8_t *path_attributes, uint16_t info_len,
  164: uint8_t *reachability_info, const uint8_t *payload, uint32_t payload_s,
  165: libnet_t *l, libnet_ptag_t ptag)
  166: {
  167:     uint32_t n, h;
  168:     libnet_pblock_t *p;
  169:     uint16_t length;
  170: 
  171:     if (l == NULL)
  172:     { 
  173:         return (-1);
  174:     } 
  175: 
  176:     /* size of memory block */
  177:     n = LIBNET_BGP4_UPDATE_H + unfeasible_rt_len + total_path_attr_len +
  178:             info_len + payload_s;
  179: 
  180:     /* BGP msg have no checksum */
  181:     h = 0;                                  
  182: 
  183:     /*
  184:      *  Find the existing protocol block if a ptag is specified, or create
  185:      *  a new one.
  186:      */
  187:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_BGP4_UPDATE_H);
  188:     if (p == NULL)
  189:     {
  190:         return (-1);
  191:     }
  192: 
  193:     /* for memory alignment reason, we need to append each field separately */
  194:     length = htons(unfeasible_rt_len);
  195:     n = libnet_pblock_append(l, p, (uint8_t *)&length,
  196:         sizeof (unfeasible_rt_len));
  197:     if (n == -1)
  198:     {
  199:         goto bad;
  200:     }
  201: 
  202:     if (unfeasible_rt_len && withdrawn_rt)
  203:     {
  204: 	n = libnet_pblock_append(l, p, withdrawn_rt, unfeasible_rt_len);
  205: 	if (n == -1)
  206: 	{
  207: 	    goto bad;
  208: 	}
  209:     }
  210: 
  211:     length = htons(total_path_attr_len);
  212:     n = libnet_pblock_append(l, p, (uint8_t *)&length,
  213:             sizeof (total_path_attr_len));
  214:     if (n == -1)
  215:     {
  216:         goto bad;
  217:     }
  218: 
  219:     if (total_path_attr_len && path_attributes)
  220:     {
  221: 	n = libnet_pblock_append(l, p, path_attributes, total_path_attr_len);
  222: 	if (n == -1)
  223: 	{
  224: 	    goto bad;
  225: 	}
  226:     }
  227: 
  228:     if (info_len && reachability_info)
  229:     {
  230: 	n = libnet_pblock_append(l, p, reachability_info, info_len);
  231: 	if (n == -1)
  232: 	{
  233: 	    goto bad;
  234: 	}
  235:     }
  236: 
  237:     /* boilerplate payload sanity check / append macro */
  238:     LIBNET_DO_PAYLOAD(l, p);
  239:  
  240:     return (ptag ? ptag : libnet_pblock_update(l, p, h,
  241:             LIBNET_PBLOCK_BGP4_UPDATE_H));
  242: bad:
  243:     libnet_pblock_delete(l, p);
  244:     return (-1);
  245: }
  246: 
  247: libnet_ptag_t
  248: libnet_build_bgp4_notification(uint8_t err_code, uint8_t err_subcode,
  249: const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
  250: {
  251:     uint32_t n, h;
  252:     libnet_pblock_t *p;
  253:     struct libnet_bgp4_notification_hdr bgp4_hdr;
  254: 
  255:     if (l == NULL)
  256:     { 
  257:         return (-1);
  258:     } 
  259: 
  260:     n =  LIBNET_BGP4_NOTIFICATION_H + + payload_s;    /* size of memory block */
  261:     h = 0; 
  262: 
  263:     /*
  264:      *  Find the existing protocol block if a ptag is specified, or create
  265:      *  a new one.
  266:      */
  267:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_BGP4_NOTIFICATION_H);
  268:     if (p == NULL)
  269:     {
  270:         return (-1);
  271:     }
  272: 
  273:     memset(&bgp4_hdr, 0, sizeof(bgp4_hdr));
  274:     bgp4_hdr.err_code    = err_code;
  275:     bgp4_hdr.err_subcode = err_subcode;
  276: 
  277:     n = libnet_pblock_append(l, p, (uint8_t *)&bgp4_hdr,
  278:             LIBNET_BGP4_NOTIFICATION_H);
  279:     if (n == -1)
  280:     {
  281:         goto bad;
  282:     }
  283: 
  284:     /* boilerplate payload sanity check / append macro */
  285:     LIBNET_DO_PAYLOAD(l, p);
  286:     
  287:     return (ptag ? ptag : libnet_pblock_update(l, p, h,
  288:             LIBNET_PBLOCK_BGP4_NOTIFICATION_H));
  289: bad:
  290:     libnet_pblock_delete(l, p);
  291:     return (-1);
  292: }
  293: 
  294: /* EOF */

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