Annotation of embedaddon/libnet/sample/test_ipv4.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 print_pblocks(libnet_t* l)
38: {
39: libnet_pblock_t* p = l->protocol_blocks;
40:
41: while(p) {
42: /* h_len is header length for checksumming? "chksum length"? */
43: printf(" tag %d flags %d type %20s/%#x buf %p b_len %2u h_len %2u copied %2u\n",
44: p->ptag, p->flags,
45: libnet_diag_dump_pblock_type(p->type), p->type,
46: p->buf, p->b_len, p->h_len, p->copied);
47: p = p->next;
48: }
49: printf(" link_offset %d aligner %d total_size %u nblocks %d\n",
50: l->link_offset, l->aligner, l->total_size, l->n_pblocks);
51:
52: }
53:
54: static int build_ipv4(libnet_t* l, libnet_ptag_t ip_ptag, int payload_s)
55: {
56: u_long src_ip = 0xf101f1f1;
57: u_long dst_ip = 0xf102f1f1;
58: uint8_t* payload = malloc(payload_s);
59: assert(payload);
60: memset(payload, '\x00', payload_s);
61:
62: ip_ptag = libnet_build_ipv4(
63: LIBNET_IPV4_H + payload_s, /* length */
64: 0, /* TOS */
65: 0xbbbb, /* IP ID */
66: 0, /* IP Frag */
67: 0xcc, /* TTL */
68: IPPROTO_UDP, /* protocol */
69: 0, /* checksum */
70: src_ip, /* source IP */
71: dst_ip, /* destination IP */
72: payload, /* payload */
73: payload_s, /* payload size */
74: l, /* libnet handle */
75: ip_ptag); /* libnet id */
76:
77: assert(ip_ptag > 0);
78:
79: free(payload);
80:
81: return ip_ptag;
82: }
83:
84: int
85: main(int argc, char *argv[])
86: {
87: libnet_t *l;
88: int r;
89: char *device = "eth0";
90: uint8_t enet_src[6] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11};
91: uint8_t enet_dst[6] = {0x22, 0x22, 0x22, 0x22, 0x22, 0x22};
92: char errbuf[LIBNET_ERRBUF_SIZE];
93: libnet_ptag_t ip_ptag = 0;
94: libnet_ptag_t eth_ptag = 0;
95: int pkt1_payload = 10;
96: uint8_t* pkt1 = NULL;
97: uint32_t pkt1_sz = 0;
98: struct libnet_ipv4_hdr* h1;
99: int pkt2_payload = 2;
100: uint8_t* pkt2 = NULL;
101: uint32_t pkt2_sz = 0;
102: struct libnet_ipv4_hdr* h2;
103:
104:
105:
106: l = libnet_init( LIBNET_LINK, device, errbuf);
107:
108: assert(l);
109:
110: /* Bug is triggered when rebuilding the ipv4 blocks with smaller payload.
111: * If change in payload size is larger than 20 (iph) + 14 (ether) +
112: * aligner, it will cause checksum to be written into the unallocated
113: * memory before the packet, possibly corrupting glib's memory allocation
114: * structures.
115: */
116:
117: printf("Packet 1:\n");
118:
119: ip_ptag = build_ipv4(l, ip_ptag, pkt1_payload);
120:
121: eth_ptag = libnet_build_ethernet(
122: enet_dst, /* ethernet destination */
123: enet_src, /* ethernet source */
124: ETHERTYPE_IP, /* protocol type */
125: NULL, /* payload */
126: 0, /* payload size */
127: l, /* libnet handle */
128: 0); /* libnet id */
129: assert(eth_ptag > 0);
130:
131: r = libnet_pblock_coalesce(l, &pkt1, &pkt1_sz);
132: assert(r >= 0);
133:
134: print_pblocks(l);
135:
136: libnet_diag_dump_hex(pkt1, 14, 0, stdout);
137: libnet_diag_dump_hex(pkt1+14, pkt1_sz-14, 0, stdout);
138:
139: printf("Packet 2:\n");
140:
141: ip_ptag = build_ipv4(l, ip_ptag, pkt2_payload);
142:
143: r = libnet_pblock_coalesce(l, &pkt2, &pkt2_sz);
144: assert(r >= 0);
145:
146: print_pblocks(l);
147:
148: libnet_diag_dump_hex(pkt2, 14, 0, stdout);
149: libnet_diag_dump_hex(pkt2+14, pkt2_sz-14, 0, stdout);
150:
151: /* Packets should differ only in the total length and cksum. */
152: h1 = (struct libnet_ipv4_hdr*) (pkt1+14);
153: h2 = (struct libnet_ipv4_hdr*) (pkt2+14);
154:
155: assert(h1->ip_len == htons(20+pkt1_payload));
156: assert(h2->ip_len == htons(20+pkt2_payload));
157:
158: h1->ip_len = h2->ip_len = 0x5555;
159: h1->ip_sum = h2->ip_sum = 0x6666;
160:
161: assert(memcmp(pkt1, pkt2, 14 + 20) == 0);
162:
163: return (EXIT_SUCCESS);
164: }
165:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>