dhcpdump-1.8/000075500000000000000000000000001207704751500131745ustar00rootroot00000000000000dhcpdump-1.8/CHANGES000064400000000000000000000025611207704751500141730ustar00rootroot00000000000000$Id: CHANGES,v 1.11 2004/10/31 11:22:58 mavetju Exp $ version 1.8 - Use pcap instead of tcpdump output version 1.7 - Support for tcpdump 3.8.x version 1.6 - Option 82, submitted by Phil Pennock - Add fflush(), submitted by Gary Colman - Fix problem with padding, they were not handled properly and caused old memory to be reused. version 1.5 - better input checking regarding validity of the header of the UDP packet (bug anton.holleman@nominum.com) - Added some DHCP options I found on the INIA website. I can't parse all of them yet since I'm not sure how they look like. version 1.4 - added auto-configure script - fixed problem with strsep() under Solaris - added FILES, CONTACT version 1.3 - added chaddr filter, contributed by Peter Apian-Bennewitz - client-identifier is now printed as long as it is. (bug anton.holleman@nominum.com) version 1.2 - forgot to update the man-page. version 1.1 - Sometimes, specially with bootp-packets, the option-packet would contain rubbish data which dhcpdump tried to parse. And that caused an overflow in the arrays, which caused a segfault. - Added more tables so the numerical values of fields (like network type, requested parameter list) are not only numeric anymore. - Better layout of hex-strings. version 1.0 - Initial release dhcpdump-1.8/CONTACT000064400000000000000000000006301207704751500142110ustar00rootroot00000000000000$Id: CONTACT,v 1.2 2004/10/31 11:22:58 mavetju Exp $ HOW TO CONTACT Via email: edwin@mavetju.org Via snail-mail: Edwin Groothuis 15 / 18 Ocean Street Cronulla NSW 2230 AUSTRALIA I have two mailing-lists: announce@lists.mavetju.org <- low traffic announcements only questions@lists.mavetju.org <- general questions See http://www.mavetju.org/contacts.php on how to subscribe to them. dhcpdump-1.8/FILES000064400000000000000000000013461207704751500137650ustar00rootroot00000000000000$Id: FILES,v 1.1 2002/01/26 14:18:18 mavetju Exp $ General ------- CHANGES - Change log CONTACT - How to contact me FILES - This file LICENSE - License under which this software is distributed Auto-configuration ------------------ Makefile.am - My Makefile-template configure.in - My configure-template depcomp - (Needed by configure) install-sh - (Needed by configure) missing - (Needed by configure) mkinstalldirs - (Needed by configure) Source-files ------------ dhcpdump.1 - Man-page, obtained from dhcpdump.pod dhcp_options.h - Tables with dhcp-packet-field values and their readable descriptions dhcpdump.c - The source-file dhcpdump.pod - The original man-file strsep.c - SunOS/Solaris doesn't have strsep dhcpdump-1.8/LICENSE000064400000000000000000000024331207704751500142030ustar00rootroot00000000000000 Copyright 2001, 2002 by Edwin Groothuis, edwin@mavetju.org All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. dhcpdump-1.8/Makefile000064400000000000000000000006641207704751500146420ustar00rootroot00000000000000CFLAGS= -Wall -g LDFLAGS= -g LIBS= -lpcap all: dhcpdump dhcpdump.8 clean: -rm dhcpdump.o dhcpdump dhcpdump.8 dhcpdump.8: dhcpdump.pod Makefile pod2man --section 8 \ --date "23 June 2008" \ --name "DHCPDUMP" \ --center "User Contributed Software" \ dhcpdump.pod dhcpdump.8 dhcpdump: dhcpdump.o ${CC} ${LDFLAGS} -o $@ dhcpdump.o ${LIBS} dhcpdump.o: dhcpdump.c dhcp_options.h Makefile ${CC} ${CFLAGS} -c -o $@ dhcpdump.c dhcpdump-1.8/dhcp_options.h000064400000000000000000000204071207704751500160410ustar00rootroot00000000000000// // $Id: dhcp_options.h,v 1.4 2004/10/31 11:22:58 mavetju Exp $ // // // this list was stolen from The DHCP Handbook by Droms and Lemon, Appendix D // // The first comment is the number, the last parameter is if it's verbosed const char *dhcp_options[] = { /* 0 */ "pad", /* 1 */ "Subnet mask", /**/ /* 2 */ "Time offset", /**/ /* 3 */ "Routers", /**/ /* 4 */ "Time server", /**/ /* 5 */ "Name server", /**/ /* 6 */ "DNS server", /**/ /* 7 */ "Log server", /**/ /* 8 */ "Cookie server", /**/ /* 9 */ "LPR server", /**/ /* 10 */ "Impress server", /**/ /* 11 */ "Resource location server", /**/ /* 12 */ "Host name", /**/ /* 13 */ "Boot file size", /**/ /* 14 */ "Merit dump file", /**/ /* 15 */ "Domainname", /**/ /* 16 */ "Swap server", /**/ /* 17 */ "Root path", /**/ /* 18 */ "Extensions path", /**/ /* 19 */ "IP forwarding", /**/ /* 20 */ "Non-local source routing", /**/ /* 21 */ "Policy filter", /**/ /* 22 */ "Maximum datagram reassembly size", /**/ /* 23 */ "Default IP TTL", /**/ /* 24 */ "Path MTU aging timeout", /**/ /* 25 */ "Path MTU plateau table", /**/ /* 26 */ "Interface MTU", /**/ /* 27 */ "All subnets local", /**/ /* 28 */ "Broadcast address", /**/ /* 29 */ "Perform mask discovery", /**/ /* 30 */ "Mask supplier", /**/ /* 31 */ "Perform router discovery", /**/ /* 32 */ "Router solicitation", /**/ /* 33 */ "Static route", /**/ /* 34 */ "Trailer encapsulation", /**/ /* 35 */ "ARP cache timeout", /**/ /* 36 */ "Ethernet encapsulation", /**/ /* 37 */ "TCP default TTL", /**/ /* 38 */ "TCP keepalive interval", /**/ /* 39 */ "TCP keepalive garbage", /**/ /* 40 */ "NIS domain", /**/ /* 41 */ "NIS servers", /**/ /* 42 */ "NTP servers", /**/ /* 43 */ "Vendor specific info", /**/ /* 44 */ "NetBIOS name server", /**/ /* 45 */ "NetBIOS datagram distribution server", /**/ /* 46 */ "NetBIOS node type", /**/ /* 47 */ "NetBIOS scope", /**/ /* 48 */ "X Window System font server", /**/ /* 49 */ "X Window System display server", /**/ /* 50 */ "Request IP address", /**/ /* 51 */ "IP address leasetime", /**/ /* 52 */ "Option overload", /**/ /* 53 */ "DHCP message type", /**/ /* 54 */ "Server identifier", /**/ /* 55 */ "Parameter Request List", /**/ /* 56 */ "Message", /**/ /* 57 */ "Maximum DHCP message size", /**/ /* 58 */ "T1", /**/ /* 59 */ "T2", /**/ /* 60 */ "Vendor class identifier", /**/ /* 61 */ "Client-identifier", /**/ /* 62 */ "Netware/IP domain name", /**/ /* 63 */ "Netware/IP domain information", /**/ /* 64 */ "NIS+ domain", /**/ /* 65 */ "NIS+ servers", /**/ /* 66 */ "TFTP server name", /**/ /* 67 */ "Bootfile name", /**/ /* 68 */ "Mobile IP home agent", /**/ /* 69 */ "SMTP server", /**/ /* 70 */ "POP3 server", /**/ /* 71 */ "NNTP server", /**/ /* 72 */ "WWW server", /**/ /* 73 */ "Finger server", /**/ /* 74 */ "IRC server", /**/ /* 75 */ "StreetTalk server", /**/ /* 76 */ "StreetTalk directory assistance server", /**/ /* 77 */ "User-class Identification", /* 78 */ "SLP-directory-agent", /* 79 */ "SLP-service-scope", /* 80 */ "Naming Authority", /* 81 */ "Client FQDN", /**/ /* 82 */ "Relay Agent Information", /* 83 */ "Agent Remote ID", /* 84 */ "Agent Subnet Mask", /* 85 */ "NDS server", /**/ /* 86 */ "NDS tree name", /**/ /* 87 */ "NDS context", /**/ /* 88 */ "IEEE 1003.1 POSIX", /* 89 */ "FQDN", /* 90 */ "Authentication", /* 91 */ "Vines TCP/IP", /* 92 */ "Server Selection", /* 93 */ "Client System", /* 94 */ "Client NDI", /* 95 */ "LDAP", /* 96 */ "IPv6 Transitions", /* 97 */ "UUID/GUID", /* 98 */ "UPA servers", /* 99 */ "???", /* 100 */ "Printer Name", /* 101 */ "MDHCP", /* 102 */ "???", /* 103 */ "???", /* 104 */ "???", /* 105 */ "???", /* 106 */ "???", /* 107 */ "???", /* 108 */ "Swap Path", /* 109 */ "???", /* 110 */ "IPX Compatability", /* 111 */ "???", /* 112 */ "Netinfo Address", /* 113 */ "Netinfo Tag", /* 114 */ "URL", /* 115 */ "DHCP Failover", /* 116 */ "DHCP Autoconfiguration", /* 117 */ "Name Service Search", /* 118 */ "Subnet selection", /* 119 */ "Domain Search", /* 120 */ "SIP Servers DHCP Option", /* 121 */ "Classless Static Route", /* 122 */ "???", /* 123 */ "???", /* 124 */ "???", /* 125 */ "???", /* 126 */ "Extension", /* 127 */ "Extension", /* 128 */ "???", /* 129 */ "???", /* 130 */ "???", /* 131 */ "???", /* 132 */ "???", /* 133 */ "???", /* 134 */ "???", /* 135 */ "???", /* 136 */ "???", /* 137 */ "???", /* 138 */ "???", /* 139 */ "???", /* 140 */ "???", /* 141 */ "???", /* 142 */ "???", /* 143 */ "???", /* 144 */ "HP - TFTP file", /* 145 */ "???", /* 146 */ "???", /* 147 */ "???", /* 148 */ "???", /* 149 */ "???", /* 150 */ "???", /* 151 */ "???", /* 152 */ "???", /* 153 */ "???", /* 154 */ "???", /* 155 */ "???", /* 156 */ "???", /* 157 */ "???", /* 158 */ "???", /* 159 */ "???", /* 160 */ "???", /* 161 */ "???", /* 162 */ "???", /* 163 */ "???", /* 164 */ "???", /* 165 */ "???", /* 166 */ "???", /* 167 */ "???", /* 168 */ "???", /* 169 */ "???", /* 170 */ "???", /* 171 */ "???", /* 172 */ "???", /* 173 */ "???", /* 174 */ "???", /* 175 */ "???", /* 176 */ "???", /* 177 */ "???", /* 178 */ "???", /* 179 */ "???", /* 180 */ "???", /* 181 */ "???", /* 182 */ "???", /* 183 */ "???", /* 184 */ "???", /* 185 */ "???", /* 186 */ "???", /* 187 */ "???", /* 188 */ "???", /* 189 */ "???", /* 190 */ "???", /* 191 */ "???", /* 192 */ "???", /* 193 */ "???", /* 194 */ "???", /* 195 */ "???", /* 196 */ "???", /* 197 */ "???", /* 198 */ "???", /* 199 */ "???", /* 200 */ "???", /* 201 */ "???", /* 202 */ "???", /* 203 */ "???", /* 204 */ "???", /* 205 */ "???", /* 206 */ "???", /* 207 */ "???", /* 208 */ "???", /* 209 */ "???", /* 210 */ "Authenticate", /* 211 */ "???", /* 212 */ "???", /* 213 */ "???", /* 214 */ "???", /* 215 */ "???", /* 216 */ "???", /* 217 */ "???", /* 218 */ "???", /* 219 */ "???", /* 220 */ "???", /* 221 */ "???", /* 222 */ "???", /* 223 */ "???", /* 224 */ "???", /* 225 */ "???", /* 226 */ "???", /* 227 */ "???", /* 228 */ "???", /* 229 */ "???", /* 230 */ "???", /* 231 */ "???", /* 232 */ "???", /* 233 */ "???", /* 234 */ "???", /* 235 */ "???", /* 236 */ "???", /* 237 */ "???", /* 238 */ "???", /* 239 */ "???", /* 240 */ "???", /* 241 */ "???", /* 242 */ "???", /* 243 */ "???", /* 244 */ "???", /* 245 */ "???", /* 246 */ "???", /* 247 */ "???", /* 248 */ "???", /* 249 */ "MSFT - Classless route", /* 250 */ "???", /* 251 */ "???", /* 252 */ "MSFT - WinSock Proxy Auto Detect", /* 253 */ "???", /* 254 */ "???", /* 255 */ "End"}; const char *dhcp_message_types[] = { "wrong specified", /* 1 */ "DHCPDISCOVER", /* 2 */ "DHCPOFFER", /* 3 */ "DHCPREQUEST", /* 4 */ "DHCPDECLINE", /* 5 */ "DHCPACK", /* 6 */ "DHCPNAK", /* 7 */ "DHCPRELEASE", /* 8 */ "DHCPINFORM" }; const char *netbios_node_type[] = { /* 0 */ "none", /* 1 */ "B-node", /* 2 */ "P-node", /* 3 */ "", /* 4 */ "M-node", /* 5 */ "", /* 6 */ "", /* 7 */ "", /* 8 */ "H-node" }; const char *option_overload[] = { /* 0 **/ "unspecified", /* 1 */ "file field holds options", /* 2 */ "sname field holds options", /* 3 */ "file and sname field holds options" }; const char *enabledisable[] = { /* 0 */ "disabled", /* 1 */ "enabled" }; const char *ethernet_encapsulation[] = { /* 0 */ "Ethernet version 2", /* 1 */ "IEEE 802.3" }; const char *operands[] = { /* 0 */ "wrong specified", /* 1 */ "BOOTPREQUEST", /* 2 */ "BOOTPREPLY" }; /* * From RFC 3046 */ const char *relayagent_suboptions[] = { /* 0 */ "", /* 1 */ "Circuit-ID", /* 2 */ "Remote-ID" }; /* * Copied from RFC1700 */ const char *htypes[] = { /* 0 */ "wrong specified", /* 1 */ "Ethernet", /* 2 */ "Experimental Ethernet", /* 3 */ "Amateur Radio AX.25", /* 4 */ "Proteon ProNET Token Ring", /* 5 */ "Chaos", /* 6 */ "IEEE 802 Networks", /* 7 */ "ARCNET", /* 8 */ "Hyperchannel", /* 9 */ "Lanstar", /* 10 */ "Autonet Short Address", /* 11 */ "LocalTalk", /* 12 */ "LocalNet", /* 13 */ "Ultra link", /* 14 */ "SMDS", /* 15 */ "Frame Relay", /* 16 */ "ATM", /* 17 */ "HDLC", /* 18 */ "Fibre Channel", /* 19 */ "ATM", /* 20 */ "Serial Line", /* 21 */ "ATM" }; dhcpdump-1.8/dhcpdump.c000064400000000000000000000341211207704751500151450ustar00rootroot00000000000000// DHCPDUMP // // Usage: tcpdump -s 1518 -lenx port bootps or port bootpc | dhcpdump // // note 1: how does this work for FDDI / PPP links? // note 2: what is this number 14? // // $Id: dhcpdump.c,v 1.12 2004/10/31 11:22:58 mavetju Exp $ // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dhcp_options.h" #ifndef HAVE_STRSEP #include "strsep.c" #endif #define SPERW (7 * 24 * 3600) #define SPERD (24 * 3600) #define SPERH (3600) #define SPERM (60) #define LARGESTRING 1024 // header variables u_char timestamp[40]; // timestamp on header u_char mac_origin[40]; // mac address of origin u_char mac_destination[40]; // mac address of destination u_char ip_origin[40]; // ip address of origin u_char ip_destination[40]; // ip address of destination int max_data_len; // maximum size of a packet int tcpdump_style = -1; char errbuf[PCAP_ERRBUF_SIZE]; char *hmask = NULL; regex_t preg; int check_ch(u_char *data, int data_len); int readheader(u_char *buf); int readdata(u_char *buf, u_char *data, int *data_len); int printdata(u_char *data, int data_len); void pcap_callback(u_char *user, const struct pcap_pkthdr *h, const u_char *sp); void printIPaddress(u_char *data); void printIPaddressAddress(u_char *data); void printIPaddressMask(u_char *data); void print8bits(u_char *data); void print16bits(u_char *data); void print32bits(u_char *data); void printTime8(u_char *data); void printTime32(u_char *data); void printReqParmList(u_char *data, int len); void printHexColon(u_char *data, int len); void printHex(u_char *data, int len); void printHexString(u_char *data, int len); void usage() { printf("Usage: $0 <-i interface> [-h macaddress]\n"); exit(0); } int main(int argc, char **argv) { int i; pcap_t *cap; struct bpf_program fp; char *interface = NULL; for (i = 1; i < argc; i++) { if (argv[i] == NULL || argv[i][0] != '-') break; switch (argv[i][1]) { case 'h': hmask = argv[++i]; break; case 'i': interface = argv[++i]; break; default: fprintf(stderr, "%s: %c: uknown option\n", argv[0], argv[i][1]); usage(); } } if (interface == NULL) usage(); if (hmask) regcomp(&preg, hmask, REG_EXTENDED | REG_ICASE | REG_NOSUB); if ((cap = pcap_open_live(interface, 1500, 1, 100, errbuf)) == NULL) errx(1, "pcap_open_live(): %s", errbuf); if (pcap_compile(cap, &fp, "udp and (port bootpc or port bootps)", 0, 0) < 0) errx(1,"pcap_compile: %s", pcap_geterr(cap)); if (pcap_setfilter(cap, &fp) < 0) errx(1,"pcap_setfilter: %s", pcap_geterr(cap)); if (pcap_loop(cap, 0, pcap_callback, NULL) < 0) errx(1,"pcap_loop(%s): %s", interface, pcap_geterr(cap)); return 0; } void pcap_callback(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) { struct ether_header *eh; struct ip *ip; struct udphdr *udp; int offset = 0; if (h->caplen < ETHER_HDR_LEN) { printf("Ignored too short ethernet packet: %d bytes\n", h->caplen); return; } eh = (struct ether_header *)(sp + offset); offset += ETHER_HDR_LEN; // Check for IPv4 packets if (eh->ether_type != 8) { printf("Ignored non IPv4 packet: %d\n", eh->ether_type); return; } // Check for length if (h->caplen < offset + sizeof(struct ip)) { printf("Ignored too short IPv4 packet: %d bytes\n", h->caplen); return; } ip = (struct ip *)(sp + offset); offset += sizeof(struct ip); udp = (struct udphdr *)(sp + offset); offset += sizeof(struct udphdr); { struct timeval tp; gettimeofday(&tp, NULL); strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S.", localtime(&(tp.tv_sec))); sprintf(timestamp + strlen(timestamp), "%03ld", tp.tv_usec / 1000); } strcpy(mac_origin, ether_ntoa((struct ether_addr *)eh->ether_shost)); strcpy(mac_destination, ether_ntoa((struct ether_addr *)eh->ether_dhost)); strcpy(ip_origin, (u_char *)inet_ntoa(ip->ip_src)); strcpy(ip_destination, (u_char *)inet_ntoa(ip->ip_dst)); if (hmask && check_ch((u_char *)(sp + offset), ntohs(udp->uh_ulen))) return; printdata((u_char *)(sp + offset), ntohs(udp->uh_ulen)); } // check for matching CHADDR (Peter Apian-Bennewitz ) int check_ch(u_char *data, int data_len) { char ch_ip[50]; if (data_len<43) return(0); sprintf(ch_ip, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:" "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", data[28], data[29], data[30], data[31], data[32], data[33], data[34], data[35], data[36], data[37], data[38], data[39], data[40], data[41], data[42], data[43]); return (regexec(&preg, ch_ip, 0, NULL, 0)); } // print the data as an IP address void printIPaddress(u_char *data) { printf("%d.%d.%d.%d", data[0], data[1], data[2], data[3]); } // print the data as an IP address and an IP address void printIPaddressAddress(u_char *data) { printf("%d.%d.%d.%d %d.%d.%d.%d", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); } // print the data as an IP address and mask void printIPaddressMask(u_char *data) { printf("%d.%d.%d.%d/%d.%d.%d.%d", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); } // prints a value of 8 bits (1 byte) void print8bits(u_char *data) { printf("%d", data[0]); } // prints a value of 16 bits (2 bytes) void print16bits(u_char *data) { printf("%d", (data[0] << 8) + data[1]); } // prints a value of 32 bits (4 bytes) void print32bits(u_char *data) { printf("%d", (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]); } // print the data as a 8bits time-value void printTime8(u_char *data) { int t = data[0]; printf("%d (", t); if (t > SPERW) { printf("%dw", t / (SPERW)); t %= SPERW; } if (t > SPERD) { printf("%dd", t / (SPERD)); t %= SPERD; } if (t > SPERH) { printf("%dh", t / (SPERH)); t %= SPERH; } if (t > SPERM) { printf("%dm", t / (SPERM)); t %= SPERM; } if (t > 0) printf("%ds", t); printf(")"); } // print the data as a 32bits time-value void printTime32(u_char *data) { int t = (data[0] << 24) + (data[1] << 16) + (data[2] <<8 ) + data[3]; printf("%d (", t); if (t > SPERW) { printf("%dw", t / (SPERW)); t %= SPERW; } if (t > SPERD) { printf("%dd", t / (SPERD)); t %= SPERD; } if (t > SPERH) { printf("%dh", t / (SPERH)); t %= SPERH; } if (t > SPERM) { printf("%dm", t / (SPERM)); t %= SPERM; } if (t > 0) printf("%ds", t); printf(")"); } // print the data as a hex-list, with the translation into ascii behind it void printHexString(u_char *data, int len) { int i, j, k; for (i = 0; i <= len / 8; i++) { for (j = 0; j < 8; j++) { if (i * 8 + j >= len) break; printf("%02x", data[i * 8 + j]); } for (k = j; k < 8; k++) printf(" "); printf(" "); for (j = 0; j < 8; j++) { char c = data[i * 8 + j]; if (i * 8 + j >= len) break; printf("%c", isprint(c) ? c : '.'); } if (i * 8 + j < len) printf("\n\t\t\t\t\t "); } } // print the data as a hex-list, without the translation into ascii behind it void printHex(u_char *data, int len) { int i, j; for (i = 0; i <= len / 8; i++) { for (j = 0; j < 8; j++) { if (i * 8 + j >= len) break; printf("%02x", data[i * 8 + j]); } if (i * 8 + j < len) printf("\n\t\t\t\t\t "); } } // print the data as a hex-list seperated by colons void printHexColon(u_char *data, int len) { int i; for (i = 0; i < len; i++) { if (i != 0 ) printf(":"); printf("%02x", data[i]); } } // print the list of requested parameters void printReqParmList(u_char *data, int len) { int i; for (i = 0; i < len; i++) { printf("%3d (%s)\n", data[i], dhcp_options[data[i]]); printf("\t\t\t\t\t "); } } // print the header and the options. int printdata(u_char *data, int data_len) { int j, i; u_char buf[LARGESTRING]; if (data_len == 0) return 0; printf( " TIME: %s\n", timestamp); printf( " IP: %s (%s) > %s (%s)\n", ip_origin, mac_origin, ip_destination, mac_destination); printf( " OP: %d (%s)\n", data[0], operands[data[0]]); printf( " HTYPE: %d (%s)\n", data[1], htypes[data[1]]); printf( " HLEN: %d\n", data[2]); printf( " HOPS: %d\n", data[3]); printf( " XID: %02x%02x%02x%02x\n", data[4], data[5], data[6], data[7]); printf( " SECS: "); print16bits(data + 8); printf("\n FLAGS: %x\n", 255 * data[10] + data[11]); printf( "CIADDR: "); printIPaddress(data + 12); printf("\nYIADDR: "); printIPaddress(data + 16); printf("\nSIADDR: "); printIPaddress(data + 20); printf("\nGIADDR: "); printIPaddress(data + 24); printf("\nCHADDR: "); printHexColon(data+28, 16); printf("\n SNAME: %s.\n", data + 44); printf( " FNAME: %s.\n", data + 108); j = 236; j += 4; /* cookie */ while (j < data_len && data[j] != 255) { printf("OPTION: %3d (%3d) %-26s", data[j], data[j + 1], dhcp_options[data[j]]); switch (data[j]) { default: printHexString(data + j + 2, data[j + 1]); break; case 0: // pad break; case 1: // Subnetmask case 3: // Routers case 16: // Swap server case 28: // Broadcast address case 32: // Router solicitation case 50: // Requested IP address case 54: // Server identifier printIPaddress(data + j + 2); break; case 12: // Hostname case 14: // Merit dump file case 15: // Domain name case 17: // Root Path case 18: // Extensions path case 40: // NIS domain case 56: // Message case 62: // Netware/IP domain name case 64: // NIS+ domain case 66: // TFTP server name case 67: // bootfile name case 60: // Domain name case 86: // NDS Tree name case 87: // NDS context strncpy(buf, &data[j + 2], data[j + 1]); buf[data[j + 1]] = 0; printf("%s", buf); break; case 4: // Time servers case 5: // Name servers case 6: // DNS server case 7: // Log server case 8: // Cookie server case 9: // LPR server case 10: // Impress server case 11: // Resource location server case 41: // NIS servers case 42: // NTP servers case 44: // NetBIOS name server case 45: // NetBIOS datagram distribution server case 48: // X Window System font server case 49: // X Window System display server case 65: // NIS+ servers case 68: // Mobile IP home agent case 69: // SMTP server case 70: // POP3 server case 71: // NNTP server case 72: // WWW server case 73: // Finger server case 74: // IRC server case 75: // StreetTalk server case 76: // StreetTalk directory assistance server case 85: // NDS server for (i = 0; i < data[j + 1] / 4; i++) { if (i != 0) printf(","); printIPaddress(data + j + 2 + i * 4); } break; case 21: // Policy filter for (i = 0; i < data[j + 1] / 8; i++) { if (i != 0) printf(","); printIPaddressMask(data + j + 2 + i * 8); } break; case 33: // Static route for (i = 0; i < data[j + 1] / 8; i++) { if (i != 0) printf(","); printIPaddressAddress(data + j + 2 + i * 8); } break; case 25: // Path MTU plateau table for (i = 0; i < data[j + 1] / 2; i++) { if (i != 0) printf(","); print16bits(data + j + 2 + i * 2); } break; case 13: // bootfile size case 22: // Maximum datagram reassembly size case 26: // Interface MTU case 57: // Maximum DHCP message size print16bits(data + j + 2); break; case 19: // IP forwarding enabled/disable case 20: // Non-local source routing case 27: // All subnets local case 29: // Perform mask discovery case 30: // Mask supplier case 31: // Perform router discovery case 34: // Trailer encapsulation case 39: // TCP keepalive garbage printf("%d (%s)", data[j + 2], enabledisable[data[j + 2]]); break; case 23: // Default IP TTL printTime8(data + j + 2); break; case 37: // TCP default TTL print8bits(data + j + 2); break; case 43: // Vendor specific info case 47: // NetBIOS scope (no idea how it looks like) printHexString(data + j + 2, data[j + 1]); break; case 46: // NetBIOS over TCP/IP node type printf("%d (%s)", data[j + 2], netbios_node_type[data[j + 2]]); break; case 2: // Time offset case 24: // Path MTU aging timeout case 35: // ARP cache timeout case 38: // TCP keepalive interval case 51: // IP address leasetime case 58: // T1 case 59: // T2 printTime32(data + j + 2); break; case 36: // Ethernet encapsulation printf("%d (%s)", data[j + 2], data[j +2 ] > sizeof(ethernet_encapsulation) ? "*wrong value*" : ethernet_encapsulation[data[j + 2]]); break; case 52: // Option overload printf("%d (%s)", data[j + 2], data[j + 2] > sizeof(option_overload) ? "*wrong value*" : option_overload[data[j + 2]]); break; case 53: // DHCP message type printf("%d (%s)", data[j + 2], data[j + 2] > sizeof(dhcp_message_types) ? "*wrong value*" : dhcp_message_types[data[j + 2]]); break; case 55: // Parameter Request List printReqParmList(data + j + 2, data[j + 1]); break; case 63: // Netware/IP domain information printHex(data + j + 2, data[j + 1]); break; case 61: // Client identifier printHexColon(data + j + 2, data[j + 1]); break; case 81: // Client FQDN print8bits(data + j + 2); printf("-"); print8bits(data + j + 3); printf("-"); print8bits(data + j + 4); printf(" "); strncpy(buf, &data[j + 5], data[j + 1] - 3); buf[data[j + 1] - 3]=0; printf("%s", buf); break; case 82: // Relay Agent Information printf("\n"); for (i = j + 2; i < j + data[j + 1]; ) { printf("%-17s %-13s ", " ", data[i] > sizeof(relayagent_suboptions) ? "*wrong value*" : relayagent_suboptions[data[i]]); if (i + data[i + 1] > j + data[j + 1]) { printf("*MALFORMED -- TOO LARGE*\n"); break; } printHexColon(data + i + 2, data[i + 1]); i += data[i + 1]; } break; } printf("\n"); /* // This might go wrong if a mallformed packet is received. // Maybe from a bogus server which is instructed to reply // with invalid data and thus causing an exploit. // My head hurts... but I think it's solved by the checking // for j - DHCP packet dumper =head1 SYNOPSIS B [B<-h> I] B<-i> I =head1 DESCRIPTION This command parses the output of tcpdump to display the dhcp-packets for easier checking and debugging. =head1 USAGE S If you want to filter a specific Client Hardware Address (CHADDR), then you can specifiy it as a regular expressions: S This will display only the packets with Client Hardware Addresses which start with 00:c0:4f. =head1 OUTPUT TIME: 15:45:02.084272 IP: 0.0.0.0.68 (0:c0:4f:82:ac:7f) > 255.255.255.255.67 (ff:ff:ff:ff:ff:ff) OP: 1 (BOOTPREQUEST) HTYPE: 1 (Ethernet) HLEN: 6 HOPS: 0 XID: 28f61b03 SECS: 0 FLAGS: 0 CIADDR: 0.0.0.0 YIADDR: 0.0.0.0 SIADDR: 0.0.0.0 GIADDR: 0.0.0.0 CHADDR: 00:c0:4f:82:ac:7f:00:00:00:00:00:00:00:00:00:00 SNAME: . FNAME: . OPTION: 53 ( 1) DHCP message type 3 (DHCPREQUEST) OPTION: 54 ( 4) Server identifier 130.139.64.101 OPTION: 50 ( 4) Request IP address 130.139.64.143 OPTION: 55 ( 7) Parameter Request List 1 (Subnet mask) 3 (Routers) 58 (T1) 59 (T2) At the option field, the first field is the value of the option, the second one (between brackets) is the length of the option-datafield, the third field is the name of the option, the fourth field is the data of the option. =head1 RETURN VALUES Always 0. =head1 NOTES Privileged access is often needed for accessing the interface. =head1 BUGS Not all the parameter options are printed verbose, because of lack of documentation. Not all the options are tested, because of lack of clients/servers with these options. If you have a dump of one of them, please send them to me and I'll incorperate them. =head1 THANKS TO Ralph Droms and Ted Lemons "The DHCP Handbook", ISBN 1-57870-137-6. Peter Apian-Bennewitz for his Client Hardware Address filtering =head1 AUTHOR Edwin Groothuis, edwin@mavetju.org (http://www.mavetju.org) =head1 SEE ALSO dhcpd(8), tcpdump(1), RFC2132 dhcpdump-1.8/strsep.c000064400000000000000000000061201207704751500146570ustar00rootroot00000000000000// // $Id: strsep.c,v 1.1 2002/01/26 13:19:04 mavetju Exp $ // // strsep() for Solaris, which doesn't have it by default. // /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #ifndef lint static const char rcsid[] = "$FreeBSD: src/lib/libc/string/strsep.c,v 1.2.12.1 2001/07/09 23:30:07 obrien Exp $"; #endif /* * Get next token from string *stringp, where tokens are possibly-empty * strings separated by characters from delim. * * Writes NULs into the string at *stringp to end tokens. * delim need not remain constant from call to call. * On return, *stringp points past the last NUL written (if there might * be further tokens), or is NULL (if there are definitely no more tokens). * * If *stringp is NULL, strsep returns NULL. */ char * strsep(stringp, delim) register char **stringp; register const char *delim; { register char *s; register const char *spanp; register int c, sc; char *tok; if ((s = *stringp) == NULL) return (NULL); for (tok = s;;) { c = *s++; spanp = delim; do { if ((sc = *spanp++) == c) { if (c == 0) s = NULL; else s[-1] = 0; *stringp = s; return (tok); } } while (sc != 0); } /* NOTREACHED */ }