Annotation of embedaddon/libnet/sample/bgp4_update.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:  *
                      3:  * libnet 1.1
                      4:  * Build a BGP4 update message with what you want as payload
                      5:  *
1.1.1.2 ! misho       6:  * Copyright (c) 2003 Frédéric Raynal <pappy@security-labs.org>
1.1       misho       7:  * All rights reserved.
                      8:  *
                      9:  * Examples:
                     10:  *
                     11:  *   empty BGP UPDATE message:
                     12:  * 
                     13:  *   # ./bgp4_update -s 1.1.1.1 -d 2.2.2.2                      
                     14:  *   libnet 1.1 packet shaping: BGP4 update + payload[raw]
                     15:  *   Wrote 63 byte TCP packet; check the wire.
                     16:  *     
                     17:  *   13:44:29.216135 1.1.1.1.26214 > 2.2.2.2.179: S [tcp sum ok] 
                     18:  *            16843009:16843032(23) win 32767: BGP (ttl 64, id 242, len 63)
                     19:  *   0x0000   4500 003f 00f2 0000 4006 73c2 0101 0101        E..?....@.s.....
                     20:  *   0x0010   0202 0202 6666 00b3 0101 0101 0202 0202        ....ff..........
                     21:  *   0x0020   5002 7fff b288 0000 0101 0101 0101 0101        P...............
                     22:  *   0x0030   0101 0101 0101 0101 0017 0200 0000 00          ...............
                     23:  *   
                     24:  *
                     25:  *   BGP UPDATE with Path Attributes and Unfeasible Routes Length
                     26:  *
                     27:  *   # ./bgp4_update -s 1.1.1.1 -d 2.2.2.2 -a `printf "\x01\x02\x03"` -A 3 -W 13
                     28:  *   libnet 1.1 packet shaping: BGP4 update + payload[raw]
                     29:  *   Wrote 79 byte TCP packet; check the wire.
                     30:  *   
                     31:  *   13:45:59.579901 1.1.1.1.26214 > 2.2.2.2.179: S [tcp sum ok] 
                     32:  *            16843009:16843048(39) win 32767: BGP (ttl 64, id 242, len 79)
                     33:  *   0x0000   4500 004f 00f2 0000 4006 73b2 0101 0101        E..O....@.s.....
                     34:  *   0x0010   0202 0202 6666 00b3 0101 0101 0202 0202        ....ff..........
                     35:  *   0x0020   5002 7fff 199b 0000 0101 0101 0101 0101        P...............
                     36:  *   0x0030   0101 0101 0101 0101 0027 0200 0d41 4141        .........'...AAA
                     37:  *   0x0040   4141 4141 4141 4141 4141 0003 0102 03          AAAAAAAAAA.....
                     38:  *
                     39:  *
                     40:  *  BGP UPDATE with Reachability Information
                     41:  *
                     42:  *   # ./bgp4_update -s 1.1.1.1 -d 2.2.2.2 -I 7                 
                     43:  *   libnet 1.1 packet shaping: BGP4 update + payload[raw]
                     44:  *   Wrote 70 byte TCP packet; check the wire.
                     45:  *   
                     46:  *   13:49:02.829225 1.1.1.1.26214 > 2.2.2.2.179: S [tcp sum ok] 
                     47:  *            16843009:16843039(30) win 32767: BGP (ttl 64, id 242, len 70)
                     48:  *   0x0000   4500 0046 00f2 0000 4006 73bb 0101 0101        E..F....@.s.....
                     49:  *   0x0010   0202 0202 6666 00b3 0101 0101 0202 0202        ....ff..........
                     50:  *   0x0020   5002 7fff e86d 0000 0101 0101 0101 0101        P....m..........
                     51:  *   0x0030   0101 0101 0101 0101 001e 0200 0000 0043        ...............C
                     52:  *   0x0040   4343 4343 4343                                 CCCCCC
                     53:  *
                     54:  *
                     55:  * Redistribution and use in source and binary forms, with or without
                     56:  * modification, are permitted provided that the following conditions
                     57:  * are met:
                     58:  * 1. Redistributions of source code must retain the above copyright
                     59:  *    notice, this list of conditions and the following disclaimer.
                     60:  * 2. Redistributions in binary form must reproduce the above copyright
                     61:  *    notice, this list of conditions and the following disclaimer in the
                     62:  *    documentation and/or other materials provided with the distribution.
                     63:  *
                     64:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     65:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     66:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     67:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     68:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     69:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     70:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     71:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     72:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     73:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     74:  * SUCH DAMAGE.
                     75:  *
                     76:  */
                     77: #if (HAVE_CONFIG_H)
                     78: #include "../include/config.h"
                     79: #endif
                     80: #include "./libnet_test.h"
                     81: 
                     82: 
                     83: #define set_ptr_and_size(ptr, size, val, flag)                                 \
                     84:     if (size && !ptr)                                                          \
                     85:     {                                                                          \
                     86:        ptr = (u_char *)malloc(size);                                          \
                     87:        if (!ptr)                                                              \
                     88:        {                                                                      \
                     89:            printf("memory allocation failed (%u bytes requested)\n", size);   \
                     90:            goto bad;                                                          \
                     91:        }                                                                      \
                     92:        memset(ptr, val, size);                                                \
                     93:         flag = 1;                                                              \
                     94:     }                                                                          \
                     95:                                                                                \
                     96:     if (ptr && !size)                                                          \
                     97:     {                                                                          \
                     98:        size = strlen(ptr);                                                    \
                     99:     }                                                                          
                    100: 
                    101: 
                    102: 
                    103: int
                    104: main(int argc, char *argv[])
                    105: {
                    106:     int c;
                    107:     libnet_t *l;
                    108:     u_long src_ip, dst_ip, length;
                    109:     libnet_ptag_t t = 0;
                    110:     char errbuf[LIBNET_ERRBUF_SIZE];
                    111:     u_char *payload = NULL;
                    112:     u_long payload_s = 0;
                    113:     u_char marker[LIBNET_BGP4_MARKER_SIZE];
                    114: 
                    115:     u_short u_rt_l = 0;
                    116:     u_char *withdraw_rt = NULL;
                    117:     char flag_w = 0;
                    118:     u_short attr_l = 0;
                    119:     u_char *attr = NULL;
                    120:     char flag_a = 0;
                    121:     u_short info_l = 0;
                    122:     u_char *info = NULL;
                    123:     char flag_i = 0;
                    124: 
                    125:     printf("libnet 1.1 packet shaping: BGP4 update + payload[raw]\n");
                    126: 
                    127:     /*
                    128:      *  Initialize the library.  Root priviledges are required.
                    129:      */
                    130:     l = libnet_init(
                    131:             LIBNET_RAW4,                            /* injection type */
                    132:             NULL,                                   /* network interface */
                    133:             errbuf);                                /* error buffer */
                    134: 
                    135:     if (l == NULL)
                    136:     {
                    137:         fprintf(stderr, "libnet_init() failed: %s", errbuf);
                    138:         exit(EXIT_FAILURE); 
                    139:     }
                    140: 
                    141:     src_ip  = 0;
                    142:     dst_ip  = 0;
                    143:     memset(marker, 0x1, LIBNET_BGP4_MARKER_SIZE);
                    144: 
                    145:     while ((c = getopt(argc, argv, "d:s:t:m:p:w:W:a:A:i:I:")) != EOF)
                    146:     {
                    147:         switch (c)
                    148:         {
                    149:             /*
                    150:              *  We expect the input to be of the form `ip.ip.ip.ip.port`.  We
                    151:              *  point cp to the last dot of the IP address/port string and
                    152:              *  then seperate them with a NULL byte.  The optarg now points to
                    153:              *  just the IP address, and cp points to the port.
                    154:              */
                    155:             case 'd':
                    156:                 if ((dst_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1)
                    157:                 {
                    158:                     fprintf(stderr, "Bad destination IP address: %s\n", optarg);
                    159:                     exit(EXIT_FAILURE);
                    160:                 }
                    161:                 break;
                    162: 
                    163:             case 's':
                    164:                 if ((src_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1)
                    165:                 {
                    166:                     fprintf(stderr, "Bad source IP address: %s\n", optarg);
                    167:                     exit(EXIT_FAILURE);
                    168:                 }
                    169:                 break;
                    170: 
                    171:            case 'p':
                    172:                payload = optarg;
                    173:                payload_s = strlen(payload);
                    174:                break;
                    175: 
                    176:            case 'w':
                    177:                withdraw_rt = optarg;
                    178:                break;
                    179: 
                    180:            case 'W':
                    181:                u_rt_l = atoi(optarg);
                    182:                break;
                    183: 
                    184:            case 'a':
                    185:                attr = optarg;
                    186:                break;
                    187: 
                    188:            case 'A':
                    189:                attr_l = atoi(optarg);
                    190:                break;
                    191: 
                    192:            case 'i':
                    193:                info = optarg;
                    194:                break;
                    195: 
                    196:            case 'I':
                    197:                info_l = atoi(optarg);
                    198:                break;
                    199: 
                    200:             default:
                    201:                 exit(EXIT_FAILURE);
                    202:         }
                    203:     }
                    204: 
                    205:     if (!src_ip || !dst_ip)
                    206:     {
                    207:         usage(argv[0]);
                    208:        goto bad;
                    209:     }
                    210: 
                    211:     set_ptr_and_size(withdraw_rt, u_rt_l, 0x41, flag_w);
                    212:     set_ptr_and_size(attr, attr_l, 0x42, flag_a);
                    213:     set_ptr_and_size(info, info_l, 0x43, flag_i);
                    214: 
                    215:   /*
                    216:    * BGP4 update messages are "dynamic" are fields have variable size. The only 
                    217:    * sizes we know are those for the 2 first fields ... so we need to count them
                    218:    * plus their value.
                    219:    */
                    220:     length = LIBNET_BGP4_UPDATE_H + u_rt_l + attr_l + info_l + payload_s;
                    221:     t = libnet_build_bgp4_update(
                    222:        u_rt_l,                                     /* Unfeasible Routes Length */   
                    223:        withdraw_rt,                                /* Withdrawn Routes */
                    224:        attr_l,                                     /* Total Path Attribute Length */
                    225:        attr,                                       /* Path Attributes */
                    226:        info_l,                                     /* Network Layer Reachability Information length */
                    227:        info,                                       /* Network Layer Reachability Information */
                    228:         payload,                                    /* payload */
                    229:         payload_s,                                  /* payload size */
                    230:         l,                                          /* libnet handle */
                    231:         0);                                         /* libnet id */
                    232:     if (t == -1)
                    233:     {
                    234:         fprintf(stderr, "Can't build BGP4 update header: %s\n", libnet_geterror(l));
                    235:         goto bad;
                    236:     }
                    237: 
                    238:     length+=LIBNET_BGP4_HEADER_H;
                    239:     t = libnet_build_bgp4_header(
                    240:        marker,                                     /* marker */   
                    241:        length,                                     /* length */
                    242:        LIBNET_BGP4_UPDATE,                         /* message type */
                    243:         NULL,                                       /* payload */
                    244:         0,                                          /* payload size */
                    245:         l,                                          /* libnet handle */
                    246:         0);                                         /* libnet id */
                    247:     if (t == -1)
                    248:     {
                    249:         fprintf(stderr, "Can't build BGP4 header: %s\n", libnet_geterror(l));
                    250:         goto bad;
                    251:     }
                    252: 
                    253:     length+=LIBNET_TCP_H;
                    254:     t = libnet_build_tcp(
                    255:         0x6666,                                     /* source port */
                    256:         179,                                        /* destination port */
                    257:         0x01010101,                                 /* sequence number */
                    258:         0x02020202,                                 /* acknowledgement num */
                    259:         TH_SYN,                                     /* control flags */
                    260:         32767,                                      /* window size */
                    261:         0,                                          /* checksum */
                    262:         0,                                          /* urgent pointer */
                    263:        length,                                     /* TCP packet size */
                    264:         NULL,                                       /* payload */
                    265:         0,                                          /* payload size */
                    266:         l,                                          /* libnet handle */
                    267:         0);                                         /* libnet id */
                    268:     if (t == -1)
                    269:     {
                    270:         fprintf(stderr, "Can't build TCP header: %s\n", libnet_geterror(l));
                    271:         goto bad;
                    272:     }
                    273: 
                    274:     length+=LIBNET_IPV4_H;
                    275:     t = libnet_build_ipv4(
                    276:         length,                                     /* length */
                    277:         0,                                          /* TOS */
                    278:         242,                                        /* IP ID */
                    279:         0,                                          /* IP Frag */
                    280:         64,                                         /* TTL */
                    281:         IPPROTO_TCP,                                /* protocol */
                    282:         0,                                          /* checksum */
                    283:         src_ip,                                     /* source IP */
                    284:         dst_ip,                                     /* destination IP */
                    285:         NULL,                                       /* payload */
                    286:         0,                                          /* payload size */
                    287:         l,                                          /* libnet handle */
                    288:         0);                                         /* libnet id */
                    289:     if (t == -1)
                    290:     {
                    291:         fprintf(stderr, "Can't build IP header: %s\n", libnet_geterror(l));
                    292:         goto bad;
                    293:     }
                    294: 
                    295:     /*
                    296:      *  Write it to the wire.
                    297:      */
                    298:     c = libnet_write(l);
                    299:     if (c == -1)
                    300:     {
                    301:         fprintf(stderr, "Write error: %s\n", libnet_geterror(l));
                    302:         goto bad;
                    303:     }
                    304:     else
                    305:     {
                    306:         fprintf(stderr, "Wrote %d byte TCP packet; check the wire.\n", c);
                    307:     }
                    308: 
                    309:     if (flag_w) free(withdraw_rt);
                    310:     if (flag_a) free(attr);
                    311:     if (flag_i) free(info);
                    312: 
                    313:     libnet_destroy(l);
                    314:     return (EXIT_SUCCESS);
                    315: bad:
                    316:     if (flag_w) free(withdraw_rt);
                    317:     if (flag_a) free(attr);
                    318:     if (flag_i) free(info);
                    319: 
                    320:     libnet_destroy(l);
                    321:     return (EXIT_FAILURE);
                    322: }
                    323: 
                    324: void
                    325: usage(char *name)
                    326: {
                    327:     fprintf(stderr,
                    328:         "usage: %s -s source_ip -d destination_ip \n"
                    329:         "          [-m marker] [-p payload] [-S payload size]\n"
                    330:        "          [-w Withdrawn Routes] [-W Unfeasible Routes Length]\n"
                    331:        "          [-a Path Attributes] [-A Attribute Length]\n"
                    332:        "          [-i Reachability Information] [-I Reachability Information length]\n",
                    333:         name);
                    334: }
                    335: 
                    336: 
                    337: /* EOF */

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