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