Annotation of embedaddon/libnet/sample/test_ipv4_options.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Regression test for bugs in ipv4 ip_offset and h_len handling, such as
                      3:  *   http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=418975
                      4:  *
                      5:  * Copyright (c) 2009 Sam Roberts <sroberts@wurldtech.com>
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     19:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     23:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     27:  * SUCH DAMAGE.
                     28:  *
                     29:  */
                     30: #if (HAVE_CONFIG_H)
                     31: #include "../include/config.h"
                     32: #endif
                     33: #include "./libnet_test.h"
                     34: 
                     35: #include <assert.h>
                     36: 
                     37: static void assert_eq_(long have, long want, const char* file, int line) {
                     38:     if(have != want) {
                     39:         printf("%s:%d: fail - have %ld want %ld\n", file, line, have, want);
                     40:         abort();
                     41:     }
                     42: }
                     43: #define assert_eq(have, want) assert_eq_(have, want, __FILE__, __LINE__)
                     44: 
                     45: 
                     46: static void print_pblocks(libnet_t* l)
                     47: {
                     48:     libnet_pblock_t* p = l->protocol_blocks;
                     49: 
                     50:     while(p) {
                     51:         printf("  tag %2d flags %d type %20s/%#x buf %p b_len %2u h_len %2u copied %2u\n",
                     52:                 p->ptag, p->flags,
                     53:                 libnet_diag_dump_pblock_type(p->type), p->type,
                     54:                 p->buf, p->b_len, p->h_len, p->copied);
                     55:         p = p->next;
                     56:     }
                     57:     printf("  link_offset %d aligner %d total_size %u nblocks %d\n",
                     58:             l->link_offset, l->aligner, l->total_size, l->n_pblocks);
                     59: 
                     60: }
                     61: 
                     62: static void ptag_error(libnet_t* l, int ptag)
                     63: {
                     64:     if(ptag <= 0) {
                     65:         printf("error: %s\n", libnet_geterror(l));
                     66:     }
                     67:     assert(ptag > 0);
                     68: }
                     69: 
                     70: static int build_ipo(libnet_t* l, libnet_ptag_t ptag, int payload_s)
                     71: {
                     72:     uint8_t* payload = malloc(payload_s);
                     73:     assert(payload);
                     74:     memset(payload, '\x88', payload_s);
                     75: 
                     76:     ptag = libnet_build_ipv4_options(payload, payload_s, l, ptag);
                     77: 
                     78:     ptag_error(l, ptag);
                     79: 
                     80:     free(payload);
                     81: 
                     82:     return ptag;
                     83: }
                     84: 
                     85: static int build_ipv4(libnet_t* l, libnet_ptag_t ptag, int payload_s, int ip_len)
                     86: {
                     87:     u_long src_ip = 0xf101f1f1;
                     88:     u_long dst_ip = 0xf102f1f1;
                     89:     uint8_t* payload = malloc(payload_s);
                     90:     assert(payload);
                     91:     memset(payload, '\x99', payload_s);
                     92: 
                     93:     if(!ip_len) {
                     94:         ip_len = LIBNET_IPV4_H + payload_s;
                     95:     }
                     96: 
                     97:     ptag = libnet_build_ipv4(
                     98:         ip_len,                                     /* length */
                     99:         0,                                          /* TOS */
                    100:         0xbbbb,                                     /* IP ID */
                    101:         0,                                          /* IP Frag */
                    102:         0xcc,                                       /* TTL */
                    103:         IPPROTO_UDP,                                /* protocol */
                    104:         0,                                          /* checksum */
                    105:         src_ip,                                     /* source IP */
                    106:         dst_ip,                                     /* destination IP */
                    107:         payload_s ? payload : NULL,                 /* payload */
                    108:         payload_s,                                  /* payload size */
                    109:         l,                                          /* libnet handle */
                    110:         ptag);                                      /* libnet id */
                    111: 
                    112:     ptag_error(l, ptag);
                    113: 
                    114:     free(payload);
                    115: 
                    116:     return ptag;
                    117: }
                    118: 
                    119: static int build_ethernet(libnet_t* l, libnet_ptag_t ptag)
                    120: {
                    121:     uint8_t enet_src[6] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11};
                    122:     uint8_t enet_dst[6] = {0x22, 0x22, 0x22, 0x22, 0x22, 0x22};
                    123: 
                    124:     ptag = libnet_build_ethernet(
                    125:         enet_dst,                                   /* ethernet destination */
                    126:         enet_src,                                   /* ethernet source */
                    127:         ETHERTYPE_IP,                               /* protocol type */
                    128:         NULL,                                       /* payload */
                    129:         0,                                          /* payload size */
                    130:         l,                                          /* libnet handle */
                    131:         ptag);                                      /* libnet id */
                    132: 
                    133:     ptag_error(l, ptag);
                    134: 
                    135:     return ptag;
                    136: }
                    137: 
                    138: static
                    139: void assert_lengths(libnet_t* l, int ip_len, int ip_ihl, int payload_s)
                    140: {
                    141:     uint8_t* pkt1 = NULL;
                    142:     uint32_t pkt1_sz = 0;
                    143:     struct libnet_ipv4_hdr* h1;
                    144:     uint8_t* payload = NULL;
                    145: 
                    146: 
                    147:     int r = libnet_pblock_coalesce(l, &pkt1, &pkt1_sz);
                    148:     assert(r >= 0);
                    149: 
                    150:     print_pblocks(l);
                    151: 
                    152:     libnet_diag_dump_hex(pkt1, 14, 1, stdout);
                    153:     libnet_diag_dump_hex(pkt1+14, pkt1_sz-14, 1, stdout);
                    154: 
                    155:     /* check ip IHL value, total ip pkt length, and options value */
                    156:     h1 = (struct libnet_ipv4_hdr*) (pkt1+14);
                    157:     assert_eq(h1->ip_hl, ip_ihl); 
                    158:     assert_eq(ntohs(h1->ip_len), ip_len);
                    159: 
                    160:     payload = ((uint8_t*) h1) + ip_ihl * 4;
                    161:     if(payload_s > 0) {
                    162:         assert(payload[0] == (uint8_t)'\x99');
                    163:         assert(payload[payload_s-1] == (uint8_t)'\x99');
                    164:     }
                    165: }
                    166: 
                    167: int
                    168: main(int argc, char *argv[])
                    169: {
                    170:     libnet_t *l;
                    171:     char *device = "eth0";
                    172:     char errbuf[LIBNET_ERRBUF_SIZE];
                    173:     libnet_ptag_t ipo_ptag = 0;
                    174:     libnet_ptag_t ip_ptag = 0;
                    175:     libnet_ptag_t eth_ptag = 0;
                    176:     int ip_len = 0;
                    177: 
                    178:     l = libnet_init( LIBNET_LINK, device, errbuf);
                    179: 
                    180:     assert(l);
                    181: 
                    182:     printf("Packet: options=4, payload=0\n");
                    183: 
                    184:     ip_len = 20 + 4 + 0; /* ip + options + payload */
                    185:     ipo_ptag = build_ipo(l, ipo_ptag, 4);
                    186:     ip_ptag = build_ipv4(l, ip_ptag, 0, 24);
                    187:     eth_ptag = build_ethernet(l, eth_ptag);
                    188: 
                    189:     assert_lengths(l, 24, 6, 0);
                    190: 
                    191:     ipo_ptag = ip_ptag = eth_ptag = 0;
                    192: 
                    193:     libnet_clear_packet(l);
                    194: 
                    195:     printf("Packet: options=3, payload=1\n");
                    196: 
                    197:     ip_len = 20 + 4 + 1; /* ip + options + payload */
                    198:     ipo_ptag = build_ipo(l, ipo_ptag, 3);
                    199:     ip_ptag = build_ipv4(l, ip_ptag, 1, 25);
                    200:     eth_ptag = build_ethernet(l, eth_ptag);
                    201: 
                    202:     assert_lengths(l, 25, 6, 1);
                    203: 
                    204:     ipo_ptag = ip_ptag = eth_ptag = 0;
                    205: 
                    206:     libnet_clear_packet(l);
                    207: 
                    208:     printf("Packet: options=3, payload=1\n");
                    209: 
                    210:     ip_len = 20 + 4 + 1; /* ip + options + payload */
                    211:     ipo_ptag = build_ipo(l, ipo_ptag, 3);
                    212:     ip_ptag = build_ipv4(l, ip_ptag, 1, ip_len);
                    213:     eth_ptag = build_ethernet(l, eth_ptag);
                    214: 
                    215:     assert_lengths(l, 25, 6, 1);
                    216: 
                    217:     printf("... modify -> options=40\n");
                    218: 
                    219:     ip_len = 20 + 40 + 1; /* ip + options + payload */
                    220:     ipo_ptag = build_ipo(l, ipo_ptag, 40);
                    221: 
                    222:     assert_lengths(l, ip_len, 15, 1);
                    223: 
                    224:     printf("... modify -> options=0\n");
                    225: 
                    226:     ip_len = 20 + 0 + 1; /* ip + options + payload */
                    227:     ipo_ptag = build_ipo(l, ipo_ptag, 0);
                    228: 
                    229:     assert_lengths(l, ip_len, 5, 1);
                    230: 
                    231:     printf("... modify -> options=5\n");
                    232: 
                    233:     ip_len = 20 + 8 + 1; /* ip + options + payload */
                    234:     ipo_ptag = build_ipo(l, ipo_ptag, 5);
                    235: 
                    236:     assert_lengths(l, ip_len, 7, 1);
                    237: 
                    238:     printf("... modify -> ip_payload=5\n");
                    239: 
                    240:     ip_len = 20 + 8 + 5; /* ip + options + payload */
                    241:     ip_ptag = build_ipv4(l, ip_ptag, 5, ip_len);
                    242: 
                    243:     assert_lengths(l, ip_len, 7, 1);
                    244: 
                    245:     ipo_ptag = ip_ptag = eth_ptag = 0;
                    246: 
                    247:     libnet_clear_packet(l);
                    248: 
                    249: 
                    250:     return (EXIT_SUCCESS);
                    251: }
                    252: 

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