Annotation of embedaddon/libnet/sample/dhcp_discover.c, revision 1.1.1.3
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: #include "./libnet_test.h"
35:
36: void
37: usage(char *prog)
38: {
39: fprintf(stderr, "Usage: %s interface\n", prog);
40: exit(1);
41: }
42:
43:
44: int
45: main(int argc, char *argv[])
46: {
47: char *intf;
48: u_long src_ip, options_len, orig_len;
49: int i;
50:
51: libnet_t *l;
52: libnet_ptag_t t;
53: libnet_ptag_t ip;
54: libnet_ptag_t udp;
55: libnet_ptag_t dhcp;
56: struct libnet_ether_addr *ethaddr;
57: struct libnet_stats ls;
58:
59: char errbuf[LIBNET_ERRBUF_SIZE];
60:
1.1.1.2 misho 61: u_char options_req[] = { LIBNET_DHCP_SUBNETMASK,
62: LIBNET_DHCP_BROADCASTADDR, LIBNET_DHCP_TIMEOFFSET,
63: LIBNET_DHCP_ROUTER, LIBNET_DHCP_DOMAINNAME,
64: LIBNET_DHCP_DNS, LIBNET_DHCP_HOSTNAME };
1.1 misho 65: u_char *options;
66: u_char enet_dst[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
67: u_char *tmp;
68:
69: if (argc != 2)
1.1.1.2 misho 70: {
1.1 misho 71: usage(argv[0]);
1.1.1.2 misho 72: }
1.1 misho 73: intf = argv[1];
74:
1.1.1.2 misho 75: l = libnet_init(LIBNET_LINK, intf, errbuf);
1.1 misho 76: if (!l)
77: {
78: fprintf(stderr, "libnet_init: %s", errbuf);
79: exit(EXIT_FAILURE);
80: }
1.1.1.2 misho 81: else
82: {
1.1 misho 83: src_ip = libnet_get_ipaddr4(l);;
84:
85: if ((ethaddr = libnet_get_hwaddr(l)) == NULL)
86: {
87: fprintf(stderr, "libnet_get_hwaddr: %s\n", libnet_geterror(l));
88: exit(EXIT_FAILURE);
89: }
90:
1.1.1.2 misho 91: printf("ip addr : %s\n", libnet_addr2name4(src_ip,
92: LIBNET_DONT_RESOLVE));
1.1 misho 93: printf("eth addr : ");
1.1.1.2 misho 94: for (i = 0; i < 6; i++)
95: {
1.1 misho 96: printf("%2.2x", ethaddr->ether_addr_octet[i]);
1.1.1.2 misho 97: if (i != 5)
98: {
1.1 misho 99: printf(":");
100: }
101: }
102: printf("\n");
103:
104:
1.1.1.2 misho 105: /* build options packet */
1.1 misho 106: i = 0;
1.1.1.2 misho 107: /* update total payload size */
108: options_len = 3;
1.1 misho 109:
1.1.1.2 misho 110: /* we are a discover packet */
1.1 misho 111: options = malloc(3);
1.1.1.2 misho 112: options[i++] = LIBNET_DHCP_MESSAGETYPE; /* type */
113: options[i++] = 1; /* len */
114: options[i++] = LIBNET_DHCP_MSGDISCOVER; /* data */
1.1 misho 115:
116: orig_len = options_len;
1.1.1.2 misho 117: /* update total payload size */
118: options_len += sizeof(options_req) + 2;
1.1 misho 119:
120: tmp = malloc(options_len);
121: memcpy(tmp, options, orig_len);
122: free(options);
123: options = tmp;
124:
1.1.1.2 misho 125: /* we are going to request some parameters */
126: options[i++] = LIBNET_DHCP_PARAMREQUEST; /* type */
127: options[i++] = sizeof(options_req); /* len */
128: memcpy(options + i, options_req, sizeof(options_req)); /* data */
1.1 misho 129: i += sizeof(options_req);
130:
1.1.1.2 misho 131: /* if we have an ip already, let's request it. */
1.1 misho 132: if (src_ip)
133: {
134: orig_len = options_len;
135: options_len += 2 + sizeof(src_ip);
136:
137: tmp = malloc(options_len);
138: memcpy(tmp, options, orig_len);
139: free(options);
140: options = tmp;
141:
1.1.1.2 misho 142: options[i++] = LIBNET_DHCP_DISCOVERADDR; /* type */
143: options[i++] = sizeof(src_ip); /* len */
144: memcpy(options + i, (char *)&src_ip, sizeof(src_ip)); /* data */
1.1 misho 145: i += sizeof(src_ip);
146: }
147:
1.1.1.2 misho 148: /* end our options packet */
1.1 misho 149: orig_len = options_len;
150: options_len += 1;
151: tmp = malloc(options_len);
152: memcpy(tmp, options, orig_len);
153: free(options);
154: options = tmp;
155: options[i++] = LIBNET_DHCP_END;
156:
157:
1.1.1.2 misho 158: /* make sure we are at least the minimum length, if not fill */
159: /* this could go in libnet, but we will leave it in the app for now */
1.1 misho 160: if (options_len + LIBNET_DHCPV4_H < LIBNET_BOOTP_MIN_LEN)
161: {
162: orig_len = options_len;
163: options_len = LIBNET_BOOTP_MIN_LEN - LIBNET_DHCPV4_H;
164:
165: tmp = malloc(options_len);
166: memcpy(tmp, options, orig_len);
167: free(options);
168: options = tmp;
169:
170: memset(options + i, 0, options_len - i);
171: }
172:
173: dhcp = libnet_build_dhcpv4(
1.1.1.2 misho 174: LIBNET_DHCP_REQUEST, /* opcode */
175: 1, /* hardware type */
176: 6, /* hardware address length */
177: 0, /* hop count */
178: 0xdeadbeef, /* transaction id */
179: 0, /* seconds since bootstrap */
180: 0x8000, /* flags */
181: 0, /* client ip */
182: 0, /* your ip */
183: 0, /* server ip */
184: 0, /* gateway ip */
185: ethaddr->ether_addr_octet, /* client hardware addr */
186: NULL, /* server host name */
187: NULL, /* boot file */
188: options, /* dhcp options in payload */
189: options_len, /* length of options */
190: l, /* libnet context */
191: 0); /* libnet ptag */
1.1 misho 192:
193: udp = libnet_build_udp(
1.1.1.2 misho 194: 68, /* source port */
195: 67, /* destination port */
196: LIBNET_UDP_H + LIBNET_DHCPV4_H + options_len, /* packet size */
197: 0, /* checksum */
198: NULL, /* payload */
199: 0, /* payload size */
200: l, /* libnet context */
201: 0); /* libnet ptag */
1.1 misho 202:
203: ip = libnet_build_ipv4(
204: LIBNET_IPV4_H + LIBNET_UDP_H + LIBNET_DHCPV4_H
1.1.1.2 misho 205: + options_len, /* length */
206: 0x10, /* TOS */
207: 0, /* IP ID */
208: 0, /* IP Frag */
209: 16, /* TTL */
210: IPPROTO_UDP, /* protocol */
211: 0, /* checksum */
212: src_ip, /* src ip */
213: inet_addr("255.255.255.255"), /* destination ip */
214: NULL, /* payload */
215: 0, /* payload size */
216: l, /* libnet context */
217: 0); /* libnet ptag */
1.1 misho 218:
219: t = libnet_autobuild_ethernet(
1.1.1.2 misho 220: enet_dst, /* ethernet destination */
221: ETHERTYPE_IP, /* protocol type */
222: l); /* libnet context */
1.1 misho 223:
224: if (libnet_write(l) == -1)
225: {
226: fprintf(stderr, " %s: libnet_write: %s\n", argv[0],
227: strerror(errno));
228: exit(EXIT_FAILURE);
229: }
230:
231: libnet_stats(l, &ls);
232: fprintf(stderr, "Packets sent: %lld\n"
233: "Packet errors: %lld\n"
234: "Bytes written: %lld\n",
1.1.1.3 ! misho 235: (long long)ls.packets_sent, (long long)ls.packet_errors,
! 236: (long long)ls.bytes_written);
1.1 misho 237: libnet_destroy(l);
238:
239: free(options);
240:
241: exit(0);
242: }
243: exit(0);
244: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>