File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libnet / src / libnet_build_bgp.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Sep 27 11:11:38 2023 UTC (9 months ago) by misho
Branches: libnet, MAIN
CVS tags: v1_2p1, HEAD
Version 1.2p1

    1: /*
    2:  *  $Id: libnet_build_bgp.c,v 1.1.1.3 2023/09/27 11:11:38 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: #include "common.h"
   34: 
   35: libnet_ptag_t
   36: libnet_build_bgp4_header(uint8_t marker[LIBNET_BGP4_MARKER_SIZE],
   37: uint16_t len, uint8_t type, const uint8_t *payload, uint32_t payload_s,
   38: libnet_t *l, libnet_ptag_t ptag)
   39: {
   40:     uint32_t n, h;
   41:     libnet_pblock_t *p;
   42:     struct libnet_bgp4_header_hdr bgp4_hdr;
   43: 
   44:     if (l == NULL)
   45:     { 
   46:         return (-1);
   47:     } 
   48: 
   49:     n = LIBNET_BGP4_HEADER_H + payload_s;   /* size of memory block */
   50:     h = 0;                                  /* BGP headers have no checksum */
   51: 
   52:     /*
   53:      *  Find the existing protocol block if a ptag is specified, or create
   54:      *  a new one.
   55:      */
   56:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_BGP4_HEADER_H);
   57:     if (p == NULL)
   58:     {
   59:         return (-1);
   60:     }
   61: 
   62:     memset(&bgp4_hdr, 0, sizeof(bgp4_hdr));
   63:     memcpy(bgp4_hdr.marker, marker, LIBNET_BGP4_MARKER_SIZE * sizeof(uint8_t));
   64:     bgp4_hdr.len = htons(len);
   65:     bgp4_hdr.type = type;
   66: 
   67:     n = libnet_pblock_append(l, p, (uint8_t *)&bgp4_hdr, LIBNET_BGP4_HEADER_H);
   68:     if (n == -1)
   69:     {
   70:         goto bad;
   71:     }
   72: 
   73:     /* boilerplate payload sanity check / append macro */
   74:     LIBNET_DO_PAYLOAD(l, p);
   75:  
   76:     return (ptag ? ptag : libnet_pblock_update(l, p, h,
   77:             LIBNET_PBLOCK_BGP4_HEADER_H));
   78: bad:
   79:     libnet_pblock_delete(l, p);
   80:     return (-1);
   81: }
   82: 
   83: libnet_ptag_t
   84: libnet_build_bgp4_open(uint8_t version, uint16_t src_as, uint16_t hold_time,
   85: uint32_t bgp_id, uint8_t opt_len, const uint8_t *payload, uint32_t payload_s,
   86: libnet_t *l, libnet_ptag_t ptag)
   87: {
   88:     uint32_t n, h;
   89:     libnet_pblock_t *p;
   90:     uint16_t val;
   91: 
   92:     if (l == NULL)
   93:     { 
   94:         return (-1);
   95:     } 
   96: 
   97:     n = LIBNET_BGP4_OPEN_H + payload_s;     /* size of memory block */
   98:     h = 0;                                  /* BGP msg have no checksum */
   99: 
  100:     /*
  101:      *  Find the existing protocol block if a ptag is specified, or create
  102:      *  a new one.
  103:      */
  104:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_BGP4_OPEN_H);
  105:     if (p == NULL)
  106:     {
  107:         return (-1);
  108:     }
  109: 
  110:     /* for memory alignment reason, we need to append each field separately */
  111:     n = libnet_pblock_append(l, p, (uint8_t *)&version, sizeof (version));
  112:     if (n == -1)
  113:     {
  114:         goto bad;
  115:     }
  116: 
  117:     val = htons(src_as);
  118:     n = libnet_pblock_append(l, p, (uint8_t *)&val, sizeof(src_as));
  119:     if (n == -1)
  120:     {
  121:         goto bad;
  122:     }
  123: 
  124:     val = htons(hold_time);
  125:     n = libnet_pblock_append(l, p, (uint8_t *)&val, sizeof(hold_time));
  126:     if (n == -1)
  127:     {
  128:         goto bad;
  129:     }
  130: 
  131:     n = htonl(bgp_id);
  132:     n = libnet_pblock_append(l, p, (uint8_t *)&n, sizeof(bgp_id));
  133:     if (n == -1)
  134:     {
  135:         goto bad;
  136:     }
  137: 
  138:     n = libnet_pblock_append(l, p, (uint8_t *)&opt_len, sizeof(opt_len));
  139:     if (n == -1)
  140:     {
  141:         goto bad;
  142:     }
  143: 
  144:     /* boilerplate payload sanity check / append macro */
  145:     LIBNET_DO_PAYLOAD(l, p);
  146:  
  147:     return (ptag ? ptag : libnet_pblock_update(l, p, h,
  148:            LIBNET_PBLOCK_BGP4_OPEN_H));
  149: bad:
  150:     libnet_pblock_delete(l, p);
  151:     return (-1);
  152: }
  153: 
  154: libnet_ptag_t
  155: libnet_build_bgp4_update(uint16_t unfeasible_rt_len, const uint8_t *withdrawn_rt,
  156: uint16_t total_path_attr_len, const uint8_t *path_attributes, uint16_t info_len,
  157: uint8_t *reachability_info, const uint8_t *payload, uint32_t payload_s,
  158: libnet_t *l, libnet_ptag_t ptag)
  159: {
  160:     uint32_t n, h;
  161:     libnet_pblock_t *p;
  162:     uint16_t length;
  163: 
  164:     if (l == NULL)
  165:     { 
  166:         return (-1);
  167:     } 
  168: 
  169:     /* size of memory block */
  170:     n = LIBNET_BGP4_UPDATE_H + unfeasible_rt_len + total_path_attr_len +
  171:             info_len + payload_s;
  172: 
  173:     /* BGP msg have no checksum */
  174:     h = 0;                                  
  175: 
  176:     /*
  177:      *  Find the existing protocol block if a ptag is specified, or create
  178:      *  a new one.
  179:      */
  180:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_BGP4_UPDATE_H);
  181:     if (p == NULL)
  182:     {
  183:         return (-1);
  184:     }
  185: 
  186:     /* for memory alignment reason, we need to append each field separately */
  187:     length = htons(unfeasible_rt_len);
  188:     n = libnet_pblock_append(l, p, (uint8_t *)&length,
  189:         sizeof (unfeasible_rt_len));
  190:     if (n == -1)
  191:     {
  192:         goto bad;
  193:     }
  194: 
  195:     if (unfeasible_rt_len && withdrawn_rt)
  196:     {
  197: 	n = libnet_pblock_append(l, p, withdrawn_rt, unfeasible_rt_len);
  198: 	if (n == -1)
  199: 	{
  200: 	    goto bad;
  201: 	}
  202:     }
  203: 
  204:     length = htons(total_path_attr_len);
  205:     n = libnet_pblock_append(l, p, (uint8_t *)&length,
  206:             sizeof (total_path_attr_len));
  207:     if (n == -1)
  208:     {
  209:         goto bad;
  210:     }
  211: 
  212:     if (total_path_attr_len && path_attributes)
  213:     {
  214: 	n = libnet_pblock_append(l, p, path_attributes, total_path_attr_len);
  215: 	if (n == -1)
  216: 	{
  217: 	    goto bad;
  218: 	}
  219:     }
  220: 
  221:     if (info_len && reachability_info)
  222:     {
  223: 	n = libnet_pblock_append(l, p, reachability_info, info_len);
  224: 	if (n == -1)
  225: 	{
  226: 	    goto bad;
  227: 	}
  228:     }
  229: 
  230:     /* boilerplate payload sanity check / append macro */
  231:     LIBNET_DO_PAYLOAD(l, p);
  232:  
  233:     return (ptag ? ptag : libnet_pblock_update(l, p, h,
  234:             LIBNET_PBLOCK_BGP4_UPDATE_H));
  235: bad:
  236:     libnet_pblock_delete(l, p);
  237:     return (-1);
  238: }
  239: 
  240: libnet_ptag_t
  241: libnet_build_bgp4_notification(uint8_t err_code, uint8_t err_subcode,
  242: const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
  243: {
  244:     uint32_t n, h;
  245:     libnet_pblock_t *p;
  246:     struct libnet_bgp4_notification_hdr bgp4_hdr;
  247: 
  248:     if (l == NULL)
  249:     { 
  250:         return (-1);
  251:     } 
  252: 
  253:     n =  LIBNET_BGP4_NOTIFICATION_H + + payload_s;    /* size of memory block */
  254:     h = 0; 
  255: 
  256:     /*
  257:      *  Find the existing protocol block if a ptag is specified, or create
  258:      *  a new one.
  259:      */
  260:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_BGP4_NOTIFICATION_H);
  261:     if (p == NULL)
  262:     {
  263:         return (-1);
  264:     }
  265: 
  266:     memset(&bgp4_hdr, 0, sizeof(bgp4_hdr));
  267:     bgp4_hdr.err_code    = err_code;
  268:     bgp4_hdr.err_subcode = err_subcode;
  269: 
  270:     n = libnet_pblock_append(l, p, (uint8_t *)&bgp4_hdr,
  271:             LIBNET_BGP4_NOTIFICATION_H);
  272:     if (n == -1)
  273:     {
  274:         goto bad;
  275:     }
  276: 
  277:     /* boilerplate payload sanity check / append macro */
  278:     LIBNET_DO_PAYLOAD(l, p);
  279:     
  280:     return (ptag ? ptag : libnet_pblock_update(l, p, h,
  281:             LIBNET_PBLOCK_BGP4_NOTIFICATION_H));
  282: bad:
  283:     libnet_pblock_delete(l, p);
  284:     return (-1);
  285: }
  286: 
  287: /**
  288:  * Local Variables:
  289:  *  indent-tabs-mode: nil
  290:  *  c-file-style: "stroustrup"
  291:  * End:
  292:  */

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