1b0453382SBill Fenner /* 2b0453382SBill Fenner * Copyright (C) 1998 and 1999 WIDE Project. 3b0453382SBill Fenner * All rights reserved. 4b0453382SBill Fenner * 5b0453382SBill Fenner * Redistribution and use in source and binary forms, with or without 6b0453382SBill Fenner * modification, are permitted provided that the following conditions 7b0453382SBill Fenner * are met: 8b0453382SBill Fenner * 1. Redistributions of source code must retain the above copyright 9b0453382SBill Fenner * notice, this list of conditions and the following disclaimer. 10b0453382SBill Fenner * 2. Redistributions in binary form must reproduce the above copyright 11b0453382SBill Fenner * notice, this list of conditions and the following disclaimer in the 12b0453382SBill Fenner * documentation and/or other materials provided with the distribution. 13b0453382SBill Fenner * 3. Neither the name of the project nor the names of its contributors 14b0453382SBill Fenner * may be used to endorse or promote products derived from this software 15b0453382SBill Fenner * without specific prior written permission. 16b0453382SBill Fenner * 17b0453382SBill Fenner * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 18b0453382SBill Fenner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19b0453382SBill Fenner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20b0453382SBill Fenner * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 21b0453382SBill Fenner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22b0453382SBill Fenner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23b0453382SBill Fenner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24b0453382SBill Fenner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25b0453382SBill Fenner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26b0453382SBill Fenner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27b0453382SBill Fenner * SUCH DAMAGE. 28b0453382SBill Fenner */ 299afd0c29SBill Fenner /* 309afd0c29SBill Fenner * draft-ietf-dhc-dhcpv6-22.txt 319afd0c29SBill Fenner */ 32b0453382SBill Fenner 33b0453382SBill Fenner #ifndef lint 34b0453382SBill Fenner static const char rcsid[] = 359afd0c29SBill Fenner "@(#) $Header: /tcpdump/master/tcpdump/print-dhcp6.c,v 1.14.4.2 2002/06/01 23:51:12 guy Exp $"; 36b0453382SBill Fenner #endif 37b0453382SBill Fenner 38b0453382SBill Fenner #ifdef HAVE_CONFIG_H 39b0453382SBill Fenner #include "config.h" 40b0453382SBill Fenner #endif 41b0453382SBill Fenner 42b0453382SBill Fenner #include <sys/param.h> 43b0453382SBill Fenner #include <sys/time.h> 44b0453382SBill Fenner #include <sys/socket.h> 45b0453382SBill Fenner 46b0453382SBill Fenner #include <netinet/in.h> 47b0453382SBill Fenner 48b0453382SBill Fenner #include <ctype.h> 49b0453382SBill Fenner #include <stdio.h> 50b0453382SBill Fenner #include <string.h> 51b0453382SBill Fenner #include <arpa/inet.h> 52b0453382SBill Fenner 53b0453382SBill Fenner #include "interface.h" 54b0453382SBill Fenner #include "addrtoname.h" 55b0453382SBill Fenner 569afd0c29SBill Fenner /* Error Values */ 579afd0c29SBill Fenner #define DH6ERR_FAILURE 16 589afd0c29SBill Fenner #define DH6ERR_AUTHFAIL 17 599afd0c29SBill Fenner #define DH6ERR_POORLYFORMED 18 609afd0c29SBill Fenner #define DH6ERR_UNAVAIL 19 619afd0c29SBill Fenner #define DH6ERR_OPTUNAVAIL 20 62b0453382SBill Fenner 639afd0c29SBill Fenner /* Message type */ 649afd0c29SBill Fenner #define DH6_REPLY 7 659afd0c29SBill Fenner #define DH6_INFORM_REQ 11 66b0453382SBill Fenner 679afd0c29SBill Fenner /* DHCP6 base packet format */ 689afd0c29SBill Fenner struct dhcp6 { 699afd0c29SBill Fenner union { 709afd0c29SBill Fenner u_int8_t m; 719afd0c29SBill Fenner u_int32_t x; 729afd0c29SBill Fenner } dh6_msgtypexid; 739afd0c29SBill Fenner struct in6_addr dh6_servaddr; 749afd0c29SBill Fenner /* options follow */ 759afd0c29SBill Fenner } __attribute__ ((__packed__)); 769afd0c29SBill Fenner #define dh6_msgtype dh6_msgtypexid.m 779afd0c29SBill Fenner #define dh6_xid dh6_msgtypexid.x 789afd0c29SBill Fenner #define DH6_XIDMASK 0x00ffffff 79b0453382SBill Fenner 809afd0c29SBill Fenner /* option */ 819afd0c29SBill Fenner #define DH6OPT_DUID 1 /* TBD */ 829afd0c29SBill Fenner #define DH6OPT_DNS 11 /* TBD */ 839afd0c29SBill Fenner struct dhcp6opt { 849afd0c29SBill Fenner u_int16_t dh6opt_type; 859afd0c29SBill Fenner u_int16_t dh6opt_len; 869afd0c29SBill Fenner /* type-dependent data follows */ 879afd0c29SBill Fenner } __attribute__ ((__packed__)); 88b0453382SBill Fenner 89b0453382SBill Fenner static void 909afd0c29SBill Fenner dhcp6opt_print(u_char *cp, u_char *ep) 91b0453382SBill Fenner { 929afd0c29SBill Fenner struct dhcp6opt *dh6o; 939afd0c29SBill Fenner u_char *tp; 94b0453382SBill Fenner int i; 959afd0c29SBill Fenner size_t optlen; 96b0453382SBill Fenner 97b0453382SBill Fenner if (cp == ep) 98b0453382SBill Fenner return; 99b0453382SBill Fenner while (cp < ep) { 1009afd0c29SBill Fenner if (ep - cp < sizeof(*dh6o)) 101b0453382SBill Fenner goto trunc; 1029afd0c29SBill Fenner dh6o = (struct dhcp6opt *)cp; 1039afd0c29SBill Fenner optlen = ntohs(dh6o->dh6opt_len); 1049afd0c29SBill Fenner if (ep - cp < sizeof(*dh6o) + optlen) 105b0453382SBill Fenner goto trunc; 1069afd0c29SBill Fenner switch (ntohs(dh6o->dh6opt_type)) { 1079afd0c29SBill Fenner case DH6OPT_DUID: 1089afd0c29SBill Fenner printf(" (duid"); /*)*/ 1099afd0c29SBill Fenner if (optlen < 2) { 1109afd0c29SBill Fenner /*(*/ 1119afd0c29SBill Fenner printf(" ??)"); 112b0453382SBill Fenner break; 113b0453382SBill Fenner } 1149afd0c29SBill Fenner tp = (u_char *)(dh6o + 1); 1159afd0c29SBill Fenner switch (ntohs(*(u_int16_t *)tp)) { 1169afd0c29SBill Fenner case 1: 1179afd0c29SBill Fenner if (optlen >= 2 + 6) { 1189afd0c29SBill Fenner printf(" hwaddr/time time %u type %u ", 1199afd0c29SBill Fenner ntohl(*(u_int32_t *)&tp[2]), 1209afd0c29SBill Fenner ntohs(*(u_int16_t *)&tp[6])); 1219afd0c29SBill Fenner for (i = 8; i < optlen; i++) 1229afd0c29SBill Fenner printf("%02x", tp[i]); 1239afd0c29SBill Fenner /*(*/ 124b0453382SBill Fenner printf(")"); 1259afd0c29SBill Fenner } else { 1269afd0c29SBill Fenner /*(*/ 1279afd0c29SBill Fenner printf(" ??)"); 1289afd0c29SBill Fenner } 1299afd0c29SBill Fenner break; 1309afd0c29SBill Fenner case 2: 1319afd0c29SBill Fenner if (optlen >= 2 + 8) { 1329afd0c29SBill Fenner printf(" vid "); 1339afd0c29SBill Fenner for (i = 2; i < 2 + 8; i++) 1349afd0c29SBill Fenner printf("%02x", tp[i]); 1359afd0c29SBill Fenner /*(*/ 1369afd0c29SBill Fenner printf(")"); 1379afd0c29SBill Fenner } else { 1389afd0c29SBill Fenner /*(*/ 1399afd0c29SBill Fenner printf(" ??)"); 1409afd0c29SBill Fenner } 1419afd0c29SBill Fenner break; 1429afd0c29SBill Fenner case 3: 1439afd0c29SBill Fenner if (optlen >= 2 + 2) { 1449afd0c29SBill Fenner printf(" hwaddr type %u ", 1459afd0c29SBill Fenner ntohs(*(u_int16_t *)&tp[2])); 1469afd0c29SBill Fenner for (i = 4; i < optlen; i++) 1479afd0c29SBill Fenner printf("%02x", tp[i]); 1489afd0c29SBill Fenner /*(*/ 1499afd0c29SBill Fenner printf(")"); 1509afd0c29SBill Fenner } else { 1519afd0c29SBill Fenner /*(*/ 1529afd0c29SBill Fenner printf(" ??)"); 1539afd0c29SBill Fenner } 1549afd0c29SBill Fenner } 1559afd0c29SBill Fenner break; 1569afd0c29SBill Fenner case DH6OPT_DNS: 1579afd0c29SBill Fenner printf(" (dnsserver"); /*)*/ 1589afd0c29SBill Fenner if (optlen % 16) { 1599afd0c29SBill Fenner /*(*/ 1609afd0c29SBill Fenner printf(" ??)"); 1619afd0c29SBill Fenner break; 1629afd0c29SBill Fenner } 1639afd0c29SBill Fenner tp = (u_char *)(dh6o + 1); 1649afd0c29SBill Fenner for (i = 0; i < optlen; i += 16) 1659afd0c29SBill Fenner printf(" %s", ip6addr_string(&tp[i])); 1669afd0c29SBill Fenner /*(*/ 1679afd0c29SBill Fenner printf(")"); 1689afd0c29SBill Fenner default: 1699afd0c29SBill Fenner printf(" (opt-%u)", ntohs(dh6o->dh6opt_type)); 1709afd0c29SBill Fenner break; 1719afd0c29SBill Fenner } 1729afd0c29SBill Fenner 1739afd0c29SBill Fenner cp += sizeof(*dh6o) + optlen; 174b0453382SBill Fenner } 175b0453382SBill Fenner return; 176b0453382SBill Fenner 177b0453382SBill Fenner trunc: 178b0453382SBill Fenner printf("[|dhcp6ext]"); 179b0453382SBill Fenner } 180b0453382SBill Fenner 181b0453382SBill Fenner /* 1829afd0c29SBill Fenner * Print dhcp6 packets 183b0453382SBill Fenner */ 184b0453382SBill Fenner void 185b0453382SBill Fenner dhcp6_print(register const u_char *cp, u_int length, 186685295f4SBill Fenner u_int16_t sport, u_int16_t dport) 187b0453382SBill Fenner { 1889afd0c29SBill Fenner struct dhcp6 *dh6; 189b0453382SBill Fenner u_char *ep; 190b0453382SBill Fenner u_char *extp; 1919afd0c29SBill Fenner const char *name; 192b0453382SBill Fenner 193b0453382SBill Fenner printf("dhcp6"); 194b0453382SBill Fenner 195b0453382SBill Fenner ep = (u_char *)snapend; 196b0453382SBill Fenner 1979afd0c29SBill Fenner dh6 = (struct dhcp6 *)cp; 1989afd0c29SBill Fenner TCHECK(dh6->dh6_servaddr); 199b0453382SBill Fenner switch (dh6->dh6_msgtype) { 200b0453382SBill Fenner case DH6_REPLY: 2019afd0c29SBill Fenner name = "reply"; 2029afd0c29SBill Fenner break; 2039afd0c29SBill Fenner case DH6_INFORM_REQ: 2049afd0c29SBill Fenner name= "inf-req"; 2059afd0c29SBill Fenner break; 2069afd0c29SBill Fenner default: 2079afd0c29SBill Fenner name = NULL; 208b0453382SBill Fenner break; 209b0453382SBill Fenner } 2109afd0c29SBill Fenner 2119afd0c29SBill Fenner if (!vflag) { 2129afd0c29SBill Fenner if (name) 2139afd0c29SBill Fenner printf(" %s", name); 2149afd0c29SBill Fenner else 2159afd0c29SBill Fenner printf(" msgtype-%u", dh6->dh6_msgtype); 2169afd0c29SBill Fenner return; 217b0453382SBill Fenner } 2189afd0c29SBill Fenner 2199afd0c29SBill Fenner /* XXX relay agent messages have to be handled differently */ 2209afd0c29SBill Fenner 2219afd0c29SBill Fenner if (name) 2229afd0c29SBill Fenner printf(" %s (", name); /*)*/ 2239afd0c29SBill Fenner else 2249afd0c29SBill Fenner printf(" msgtype-%u (", dh6->dh6_msgtype); /*)*/ 2259afd0c29SBill Fenner printf("xid=%x", ntohl(dh6->dh6_xid) & DH6_XIDMASK); 2269afd0c29SBill Fenner printf(" server=%s", ip6addr_string(&dh6->dh6_servaddr)); 2279afd0c29SBill Fenner extp = (u_char *)(dh6 + 1); 2289afd0c29SBill Fenner dhcp6opt_print(extp, ep); 229685295f4SBill Fenner /*(*/ 230b0453382SBill Fenner printf(")"); 231b0453382SBill Fenner return; 232b0453382SBill Fenner 233b0453382SBill Fenner trunc: 2349afd0c29SBill Fenner printf("[|dhcp6]"); 235b0453382SBill Fenner } 236