Annotation of embedaddon/libnet/sample/dhcp_discover.c, revision 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>