Annotation of embedaddon/libnet/sample/test_ipv4_options.c, revision 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>