Annotation of embedaddon/libnet/sample/dhcp_discover.c, revision 1.1.1.1
1.1 misho 1: /*
2: * $Id: dhcp_discover.c,v 1.3 2004/01/03 20:31:01 mike Exp $
3: *
4: * libnet 1.1
5: * Build a DHCP discover packet
6: * To view: /usr/sbin/tcpdump -vvvvven -s 4096 'port 67 or port 68'
7: *
8: * Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
9: * All rights reserved.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30: * SUCH DAMAGE.
31: *
32: */
33:
34: #if (HAVE_CONFIG_H)
35: #include "../include/config.h"
36: #endif
37: #include "./libnet_test.h"
38: #ifdef __WIN32__
39: #include "../include/win32/getopt.h"
40: #endif
41:
42: void
43: usage(char *prog)
44: {
45: fprintf(stderr, "Usage: %s interface\n", prog);
46: exit(1);
47: }
48:
49:
50: int
51: main(int argc, char *argv[])
52: {
53: char *intf;
54: u_long src_ip, options_len, orig_len;
55: int i;
56:
57: libnet_t *l;
58: libnet_ptag_t t;
59: libnet_ptag_t ip;
60: libnet_ptag_t udp;
61: libnet_ptag_t dhcp;
62: struct libnet_ether_addr *ethaddr;
63: struct libnet_stats ls;
64:
65: char errbuf[LIBNET_ERRBUF_SIZE];
66:
67: u_char options_req[] = { LIBNET_DHCP_SUBNETMASK , LIBNET_DHCP_BROADCASTADDR , LIBNET_DHCP_TIMEOFFSET , LIBNET_DHCP_ROUTER , LIBNET_DHCP_DOMAINNAME , LIBNET_DHCP_DNS , LIBNET_DHCP_HOSTNAME };
68: u_char *options;
69: u_char enet_dst[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
70: u_char *tmp;
71:
72: // have to specify interface
73: if (argc != 2)
74: usage(argv[0]);
75: intf = argv[1];
76:
77: l = libnet_init(
78: LIBNET_LINK, // injection type
79: intf, // network interface
80: errbuf); // errbuf
81: if (!l)
82: {
83: fprintf(stderr, "libnet_init: %s", errbuf);
84: exit(EXIT_FAILURE);
85: }
86: else {
87: src_ip = libnet_get_ipaddr4(l);;
88:
89: if ((ethaddr = libnet_get_hwaddr(l)) == NULL)
90: {
91: fprintf(stderr, "libnet_get_hwaddr: %s\n", libnet_geterror(l));
92: exit(EXIT_FAILURE);
93: }
94:
95: printf("ip addr : %s\n", libnet_addr2name4(src_ip, LIBNET_DONT_RESOLVE));
96: printf("eth addr : ");
97: for (i = 0; i < 6; i++) {
98: printf("%2.2x", ethaddr->ether_addr_octet[i]);
99: if (i != 5) {
100: printf(":");
101: }
102: }
103: printf("\n");
104:
105:
106: // build options packet
107: i = 0;
108: options_len = 3; // update total payload size
109:
110: // we are a discover packet
111: options = malloc(3);
112: options[i++] = LIBNET_DHCP_MESSAGETYPE; // type
113: options[i++] = 1; // len
114: options[i++] = LIBNET_DHCP_MSGDISCOVER; // data
115:
116: orig_len = options_len;
117: options_len += sizeof(options_req) + 2; // update total payload size
118:
119: // workaround for realloc on old machines
120: // options = realloc(options, options_len); // resize options buffer
121: tmp = malloc(options_len);
122: memcpy(tmp, options, orig_len);
123: free(options);
124: options = tmp;
125:
126: // we are going to request some parameters
127: options[i++] = LIBNET_DHCP_PARAMREQUEST; // type
128: options[i++] = sizeof(options_req); // len
129: memcpy(options + i, options_req, sizeof(options_req)); // data
130: i += sizeof(options_req);
131:
132: // if we have an ip already, let's request it.
133: if (src_ip)
134: {
135: orig_len = options_len;
136: options_len += 2 + sizeof(src_ip);
137:
138: // workaround for realloc on old machines
139: // options = realloc(options, options_len);
140: tmp = malloc(options_len);
141: memcpy(tmp, options, orig_len);
142: free(options);
143: options = tmp;
144:
145: options[i++] = LIBNET_DHCP_DISCOVERADDR; // type
146: options[i++] = sizeof(src_ip); // len
147: memcpy(options + i, (char *)&src_ip, sizeof(src_ip));// data
148: i += sizeof(src_ip);
149: }
150:
151: // end our options packet
152: // workaround for realloc on old machines
153: // options = realloc(options, options_len); // resize options buffer
154: orig_len = options_len;
155: options_len += 1;
156: tmp = malloc(options_len);
157: memcpy(tmp, options, orig_len);
158: free(options);
159: options = tmp;
160: options[i++] = LIBNET_DHCP_END;
161:
162:
163: // make sure we are at least the minimum length, if not fill
164: // this could go in libnet, but we will leave it in the app for now
165: if (options_len + LIBNET_DHCPV4_H < LIBNET_BOOTP_MIN_LEN)
166: {
167: orig_len = options_len;
168: options_len = LIBNET_BOOTP_MIN_LEN - LIBNET_DHCPV4_H;
169:
170: // workaround for realloc on old machines
171: // options = realloc(options, options_len);
172: tmp = malloc(options_len);
173: memcpy(tmp, options, orig_len);
174: free(options);
175: options = tmp;
176:
177: memset(options + i, 0, options_len - i);
178: }
179:
180: // the goodies are here
181: dhcp = libnet_build_dhcpv4(
182: LIBNET_DHCP_REQUEST, // opcode
183: 1, // hardware type
184: 6, // hardware address length
185: 0, // hop count
186: 0xdeadbeef, // transaction id
187: 0, // seconds since bootstrap
188: 0x8000, // flags
189: 0, // client ip
190: 0, // your ip
191: 0, // server ip
192: 0, // gateway ip
193: ethaddr->ether_addr_octet, // client hardware addr
194: NULL, // server host name
195: NULL, // boot file
196: options, // dhcp options stuck in payload since it is dynamic
197: options_len, // length of options
198: l, // libnet handle
199: 0); // libnet id
200:
201: // wrap it
202: udp = libnet_build_udp(
203: 68, // source port
204: 67, // destination port
205: LIBNET_UDP_H + LIBNET_DHCPV4_H + options_len, // packet size
206: 0, // checksum
207: NULL, // payload
208: 0, // payload size
209: l, // libnet handle
210: 0); // libnet id
211:
212: // hook me up with some ipv4
213: ip = libnet_build_ipv4(
214: LIBNET_IPV4_H + LIBNET_UDP_H + LIBNET_DHCPV4_H
215: + options_len, // length
216: 0x10, // TOS
217: 0, // IP ID
218: 0, // IP Frag
219: 16, // TTL
220: IPPROTO_UDP, // protocol
221: 0, // checksum
222: src_ip, // src ip
223: inet_addr("255.255.255.255"), // destination ip
224: NULL, // payload
225: 0, // payload size
226: l, // libnet handle
227: 0); // libnet id
228:
229: // we can just autobuild since we arent doing anything tricky
230: t = libnet_autobuild_ethernet(
231: enet_dst, // ethernet destination
232: ETHERTYPE_IP, // protocol type
233: l); // libnet handle
234:
235: // write to the wire
236: if (libnet_write(l) == -1)
237: {
238: fprintf(stderr, " %s: libnet_write: %s\n", argv[0],
239: strerror(errno));
240: exit(EXIT_FAILURE);
241: }
242:
243: // fill and print stats
244: libnet_stats(l, &ls);
245: fprintf(stderr, "Packets sent: %lld\n"
246: "Packet errors: %lld\n"
247: "Bytes written: %lld\n",
248: ls.packets_sent, ls.packet_errors, ls.bytes_written);
249: libnet_destroy(l);
250:
251: // free mem
252: free(options);
253:
254: exit(0);
255: }
256: exit(0);
257: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>