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

    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>