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>