print-dhcp6.c revision 127668
156893Sfenner/* 256893Sfenner * Copyright (C) 1998 and 1999 WIDE Project. 356893Sfenner * All rights reserved. 4127668Sbms * 556893Sfenner * Redistribution and use in source and binary forms, with or without 656893Sfenner * modification, are permitted provided that the following conditions 756893Sfenner * are met: 856893Sfenner * 1. Redistributions of source code must retain the above copyright 956893Sfenner * notice, this list of conditions and the following disclaimer. 1056893Sfenner * 2. Redistributions in binary form must reproduce the above copyright 1156893Sfenner * notice, this list of conditions and the following disclaimer in the 1256893Sfenner * documentation and/or other materials provided with the distribution. 1356893Sfenner * 3. Neither the name of the project nor the names of its contributors 1456893Sfenner * may be used to endorse or promote products derived from this software 1556893Sfenner * without specific prior written permission. 16127668Sbms * 1756893Sfenner * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 1856893Sfenner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1956893Sfenner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2056893Sfenner * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2156893Sfenner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2256893Sfenner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2356893Sfenner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2456893Sfenner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2556893Sfenner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2656893Sfenner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2756893Sfenner * SUCH DAMAGE. 2856893Sfenner */ 29111726Sfenner/* 30127668Sbms * RFC3315: DHCPv6 31127668Sbms * supported DHCPv6 options: 32127668Sbms * RFC3319, 33127668Sbms * draft-ietf-dhc-dhcpv6-opt-dnsconfig-04.txt, 34127668Sbms * draft-ietf-dhc-dhcpv6-opt-prefix-delegation-05.txt 35127668Sbms * draft-ietf-dhc-dhcpv6-opt-timeconfig-02.txt, 36111726Sfenner */ 3756893Sfenner 3856893Sfenner#ifndef lint 39127668Sbmsstatic const char rcsid[] _U_ = 40127668Sbms "@(#) $Header: /tcpdump/master/tcpdump/print-dhcp6.c,v 1.27.2.4 2003/11/18 23:26:14 guy Exp $"; 4156893Sfenner#endif 4256893Sfenner 4356893Sfenner#ifdef HAVE_CONFIG_H 4456893Sfenner#include "config.h" 4556893Sfenner#endif 4656893Sfenner 47127668Sbms#include <tcpdump-stdinc.h> 4856893Sfenner 4956893Sfenner#include <stdio.h> 5056893Sfenner#include <string.h> 5156893Sfenner 5256893Sfenner#include "interface.h" 5356893Sfenner#include "addrtoname.h" 54127668Sbms#include "extract.h" 5556893Sfenner 56127668Sbms/* lease duration */ 57127668Sbms#define DHCP6_DURATITION_INFINITE 0xffffffff 58127668Sbms 59111726Sfenner/* Error Values */ 60111726Sfenner#define DH6ERR_FAILURE 16 61111726Sfenner#define DH6ERR_AUTHFAIL 17 62111726Sfenner#define DH6ERR_POORLYFORMED 18 63111726Sfenner#define DH6ERR_UNAVAIL 19 64111726Sfenner#define DH6ERR_OPTUNAVAIL 20 6556893Sfenner 66111726Sfenner/* Message type */ 67127668Sbms#define DH6_SOLICIT 1 68127668Sbms#define DH6_ADVERTISE 2 69127668Sbms#define DH6_REQUEST 3 70127668Sbms#define DH6_CONFIRM 4 71127668Sbms#define DH6_RENEW 5 72127668Sbms#define DH6_REBIND 6 73111726Sfenner#define DH6_REPLY 7 74127668Sbms#define DH6_RELEASE 8 75127668Sbms#define DH6_DECLINE 9 76127668Sbms#define DH6_RECONFIGURE 10 77111726Sfenner#define DH6_INFORM_REQ 11 78127668Sbms#define DH6_RELAY_FORW 12 79127668Sbms#define DH6_RELAY_REPLY 13 8056893Sfenner 81111726Sfenner/* DHCP6 base packet format */ 82111726Sfennerstruct dhcp6 { 83111726Sfenner union { 84111726Sfenner u_int8_t m; 85111726Sfenner u_int32_t x; 86111726Sfenner } dh6_msgtypexid; 87111726Sfenner /* options follow */ 88127668Sbms}; 89111726Sfenner#define dh6_msgtype dh6_msgtypexid.m 90111726Sfenner#define dh6_xid dh6_msgtypexid.x 91111726Sfenner#define DH6_XIDMASK 0x00ffffff 9256893Sfenner 93127668Sbms/* DHCPv6 relay messages */ 94127668Sbmsstruct dhcp6_relay { 95127668Sbms u_int8_t dh6relay_msgtype; 96127668Sbms u_int8_t dh6relay_hcnt; 97127668Sbms u_int8_t dh6relay_linkaddr[16]; /* XXX: badly aligned */ 98127668Sbms u_int8_t dh6relay_peeraddr[16]; 99127668Sbms /* options follow */ 100127668Sbms}; 101127668Sbms 102127668Sbms/* options */ 103127668Sbms#define DH6OPT_CLIENTID 1 104127668Sbms#define DH6OPT_SERVERID 2 105127668Sbms#define DH6OPT_IA_NA 3 106127668Sbms#define DH6OPT_IA_TMP 4 107127668Sbms#define DH6OPT_IADDR 5 108127668Sbms#define DH6OPT_ORO 6 109127668Sbms#define DH6OPT_PREFERENCE 7 110127668Sbms# define DH6OPT_PREF_UNDEF -1 111127668Sbms# define DH6OPT_PREF_MAX 255 112127668Sbms#define DH6OPT_ELAPSED_TIME 8 113127668Sbms#define DH6OPT_RELAY_MSG 9 114127668Sbms/*#define DH6OPT_SERVER_MSG 10 deprecated */ 115127668Sbms#define DH6OPT_AUTH 11 116127668Sbms#define DH6OPT_UNICAST 12 117127668Sbms#define DH6OPT_STATUS_CODE 13 118127668Sbms# define DH6OPT_STCODE_SUCCESS 0 119127668Sbms# define DH6OPT_STCODE_UNSPECFAIL 1 120127668Sbms# define DH6OPT_STCODE_NOADDRAVAIL 2 121127668Sbms# define DH6OPT_STCODE_NOBINDING 3 122127668Sbms# define DH6OPT_STCODE_NOTONLINK 4 123127668Sbms# define DH6OPT_STCODE_USEMULTICAST 5 124127668Sbms# define DH6OPT_STCODE_NOPREFIXAVAIL 6 125127668Sbms#define DH6OPT_RAPID_COMMIT 14 126127668Sbms#define DH6OPT_USER_CLASS 15 127127668Sbms#define DH6OPT_VENDOR_CLASS 16 128127668Sbms#define DH6OPT_VENDOR_OPTS 17 129127668Sbms#define DH6OPT_INTERFACE_ID 18 130127668Sbms#define DH6OPT_RECONF_MSG 19 131127668Sbms#define DH6OPT_RECONF_ACCEPT 20 132127668Sbms#define DH6OPT_SIP_SERVER_D 21 133127668Sbms#define DH6OPT_SIP_SERVER_A 22 134127668Sbms#define DH6OPT_DNS 23 135127668Sbms#define DH6OPT_DNSNAME 24 136127668Sbms 137127668Sbms/* 138127668Sbms * The option type has not been assigned for the following options. 139127668Sbms * We temporarily adopt values used in the service specification document 140127668Sbms * (200206xx version) by NTT Communications. 141127668Sbms * Note that we'll change the following definitions if different type values 142127668Sbms * are officially assigned. 143127668Sbms */ 144127668Sbms#define DH6OPT_PREFIX_DELEGATION 30 145127668Sbms#define DH6OPT_PREFIX_INFORMATION 31 146127668Sbms#define DH6OPT_PREFIX_REQUEST 32 147127668Sbms 148127668Sbms/* 149127668Sbms * The followings are also unassigned numbers. 150127668Sbms * We temporarily use values as of KAME snap 20031013. 151127668Sbms */ 152127668Sbms#define DH6OPT_IA_PD 33 153127668Sbms#define DH6OPT_IA_PD_PREFIX 34 154127668Sbms#define DH6OPT_NTP_SERVERS 35 155127668Sbms 156111726Sfennerstruct dhcp6opt { 157111726Sfenner u_int16_t dh6opt_type; 158111726Sfenner u_int16_t dh6opt_len; 159111726Sfenner /* type-dependent data follows */ 160127668Sbms}; 16156893Sfenner 162127668Sbmsstruct dhcp6_ia { 163127668Sbms u_int16_t dh6opt_ia_type; 164127668Sbms u_int16_t dh6opt_ia_len; 165127668Sbms u_int32_t dh6opt_ia_iaid; 166127668Sbms u_int32_t dh6opt_ia_t1; 167127668Sbms u_int32_t dh6opt_ia_t2; 168127668Sbms}; 169127668Sbms 170127668Sbmsstruct dhcp6_ia_prefix { 171127668Sbms u_int16_t dh6opt_ia_prefix_type; 172127668Sbms u_int16_t dh6opt_ia_prefix_len; 173127668Sbms u_int32_t dh6opt_ia_prefix_pltime; 174127668Sbms u_int32_t dh6opt_ia_prefix_vltime; 175127668Sbms u_int8_t dh6opt_ia_prefix_plen; 176127668Sbms struct in6_addr dh6opt_ia_prefix_addr; 177127668Sbms} __attribute__ ((__packed__)); 178127668Sbms 179127668Sbmsstatic const char * 180127668Sbmsdhcp6opt_name(int type) 181127668Sbms{ 182127668Sbms static char genstr[sizeof("opt_65535") + 1]; /* XXX thread unsafe */ 183127668Sbms 184127668Sbms if (type > 65535) 185127668Sbms return "INVALID option"; 186127668Sbms 187127668Sbms switch(type) { 188127668Sbms case DH6OPT_CLIENTID: 189127668Sbms return "client ID"; 190127668Sbms case DH6OPT_SERVERID: 191127668Sbms return "server ID"; 192127668Sbms case DH6OPT_IA_NA: 193127668Sbms return "IA_NA"; 194127668Sbms case DH6OPT_ORO: 195127668Sbms return "option request"; 196127668Sbms case DH6OPT_PREFERENCE: 197127668Sbms return "preference"; 198127668Sbms case DH6OPT_ELAPSED_TIME: 199127668Sbms return "elapsed time"; 200127668Sbms case DH6OPT_RELAY_MSG: 201127668Sbms return "relay message"; 202127668Sbms case DH6OPT_STATUS_CODE: 203127668Sbms return "status code"; 204127668Sbms case DH6OPT_RAPID_COMMIT: 205127668Sbms return "rapid commit"; 206127668Sbms case DH6OPT_INTERFACE_ID: 207127668Sbms return "interface ID"; 208127668Sbms case DH6OPT_RECONF_MSG: 209127668Sbms return "reconfigure message"; 210127668Sbms case DH6OPT_RECONF_ACCEPT: 211127668Sbms return "reconfigure accept"; 212127668Sbms case DH6OPT_SIP_SERVER_D: 213127668Sbms return "SIP Servers Domain"; 214127668Sbms case DH6OPT_SIP_SERVER_A: 215127668Sbms return "SIP Servers Address"; 216127668Sbms case DH6OPT_DNS: 217127668Sbms return "DNS"; 218127668Sbms case DH6OPT_PREFIX_DELEGATION: 219127668Sbms return "prefix delegation"; 220127668Sbms case DH6OPT_PREFIX_INFORMATION: 221127668Sbms return "prefix information"; 222127668Sbms case DH6OPT_IA_PD: 223127668Sbms return "IA_PD"; 224127668Sbms case DH6OPT_IA_PD_PREFIX: 225127668Sbms return "IA_PD prefix"; 226127668Sbms case DH6OPT_NTP_SERVERS: 227127668Sbms return "NTP Server"; 228127668Sbms default: 229127668Sbms snprintf(genstr, sizeof(genstr), "opt_%d", type); 230127668Sbms return(genstr); 231127668Sbms } 232127668Sbms} 233127668Sbms 234127668Sbmsstatic const char * 235127668Sbmsdhcp6stcode(int code) 236127668Sbms{ 237127668Sbms static char genstr[sizeof("code255") + 1]; /* XXX thread unsafe */ 238127668Sbms 239127668Sbms if (code > 255) 240127668Sbms return "INVALID code"; 241127668Sbms 242127668Sbms switch(code) { 243127668Sbms case DH6OPT_STCODE_SUCCESS: 244127668Sbms return "success"; 245127668Sbms case DH6OPT_STCODE_UNSPECFAIL: 246127668Sbms return "unspec failure"; 247127668Sbms case DH6OPT_STCODE_NOADDRAVAIL: 248127668Sbms return "no addresses"; 249127668Sbms case DH6OPT_STCODE_NOBINDING: 250127668Sbms return "no binding"; 251127668Sbms case DH6OPT_STCODE_NOTONLINK: 252127668Sbms return "not on-link"; 253127668Sbms case DH6OPT_STCODE_USEMULTICAST: 254127668Sbms return "use multicast"; 255127668Sbms case DH6OPT_STCODE_NOPREFIXAVAIL: 256127668Sbms return "no prefixes"; 257127668Sbms default: 258127668Sbms snprintf(genstr, sizeof(genstr), "code%d", code); 259127668Sbms return(genstr); 260127668Sbms } 261127668Sbms} 262127668Sbms 26356893Sfennerstatic void 264127668Sbmsdhcp6opt_print(const u_char *cp, const u_char *ep) 26556893Sfenner{ 266111726Sfenner struct dhcp6opt *dh6o; 267111726Sfenner u_char *tp; 268127668Sbms size_t i; 269127668Sbms u_int16_t opttype; 270111726Sfenner size_t optlen; 271127668Sbms u_int16_t val16; 272127668Sbms u_int32_t val32; 273127668Sbms struct in6_addr addr6; 274127668Sbms struct dhcp6_ia ia; 275127668Sbms struct dhcp6_ia_prefix ia_prefix; 27656893Sfenner 27756893Sfenner if (cp == ep) 27856893Sfenner return; 27956893Sfenner while (cp < ep) { 280127668Sbms if (ep < cp + sizeof(*dh6o)) 281111726Sfenner goto trunc; 282111726Sfenner dh6o = (struct dhcp6opt *)cp; 283127668Sbms optlen = EXTRACT_16BITS(&dh6o->dh6opt_len); 284127668Sbms if (ep < cp + sizeof(*dh6o) + optlen) 285111726Sfenner goto trunc; 286127668Sbms opttype = EXTRACT_16BITS(&dh6o->dh6opt_type); 287127668Sbms printf(" (%s", dhcp6opt_name(opttype)); 288127668Sbms switch (opttype) { 289127668Sbms case DH6OPT_CLIENTID: 290127668Sbms case DH6OPT_SERVERID: 291111726Sfenner if (optlen < 2) { 292111726Sfenner /*(*/ 293127668Sbms printf(" ?)"); 294111726Sfenner break; 295111726Sfenner } 296111726Sfenner tp = (u_char *)(dh6o + 1); 297127668Sbms switch (EXTRACT_16BITS(tp)) { 298111726Sfenner case 1: 299111726Sfenner if (optlen >= 2 + 6) { 300127668Sbms printf(" hwaddr/time type %u time %u ", 301127668Sbms EXTRACT_16BITS(&tp[2]), 302127668Sbms EXTRACT_32BITS(&tp[4])); 303111726Sfenner for (i = 8; i < optlen; i++) 304111726Sfenner printf("%02x", tp[i]); 305111726Sfenner /*(*/ 306111726Sfenner printf(")"); 307111726Sfenner } else { 308111726Sfenner /*(*/ 309127668Sbms printf(" ?)"); 310111726Sfenner } 311111726Sfenner break; 312111726Sfenner case 2: 313111726Sfenner if (optlen >= 2 + 8) { 314111726Sfenner printf(" vid "); 315111726Sfenner for (i = 2; i < 2 + 8; i++) 316111726Sfenner printf("%02x", tp[i]); 317111726Sfenner /*(*/ 318111726Sfenner printf(")"); 319111726Sfenner } else { 320111726Sfenner /*(*/ 321127668Sbms printf(" ?)"); 322111726Sfenner } 323111726Sfenner break; 324111726Sfenner case 3: 325111726Sfenner if (optlen >= 2 + 2) { 326111726Sfenner printf(" hwaddr type %u ", 327127668Sbms EXTRACT_16BITS(&tp[2])); 328111726Sfenner for (i = 4; i < optlen; i++) 329111726Sfenner printf("%02x", tp[i]); 330111726Sfenner /*(*/ 331111726Sfenner printf(")"); 332111726Sfenner } else { 333111726Sfenner /*(*/ 334127668Sbms printf(" ?)"); 335111726Sfenner } 336127668Sbms break; 337127668Sbms default: 338127668Sbms printf(" type %d)", EXTRACT_16BITS(tp)); 339127668Sbms break; 340111726Sfenner } 34175115Sfenner break; 342127668Sbms case DH6OPT_ORO: 343127668Sbms if (optlen % 2) { 344127668Sbms printf(" ?)"); 345127668Sbms break; 346127668Sbms } 347127668Sbms tp = (u_char *)(dh6o + 1); 348127668Sbms for (i = 0; i < optlen; i += 2) { 349127668Sbms u_int16_t opt; 350127668Sbms 351127668Sbms memcpy(&opt, &tp[i], sizeof(opt)); 352127668Sbms printf(" %s", dhcp6opt_name(ntohs(opt))); 353127668Sbms } 354127668Sbms printf(")"); 355127668Sbms break; 356127668Sbms case DH6OPT_PREFERENCE: 357127668Sbms if (optlen != 1) { 358127668Sbms printf(" ?)"); 359127668Sbms break; 360127668Sbms } 361127668Sbms printf(" %d)", *((u_char *)(dh6o + 1) + 1)); 362127668Sbms break; 363127668Sbms case DH6OPT_ELAPSED_TIME: 364127668Sbms if (optlen != 2) { 365127668Sbms printf(" ?)"); 366127668Sbms break; 367127668Sbms } 368127668Sbms memcpy(&val16, dh6o + 1, sizeof(val16)); 369127668Sbms val16 = ntohs(val16); 370127668Sbms printf(" %d)", (int)val16); 371127668Sbms break; 372127668Sbms case DH6OPT_RELAY_MSG: 373127668Sbms printf(" ("); 374127668Sbms dhcp6_print((const u_char *)(dh6o + 1), optlen); 375127668Sbms printf(")"); 376127668Sbms break; 377127668Sbms case DH6OPT_RAPID_COMMIT: /* nothing todo */ 378127668Sbms printf(")"); 379127668Sbms break; 380127668Sbms case DH6OPT_INTERFACE_ID: 381127668Sbms /* 382127668Sbms * Since we cannot predict the encoding, print hex dump 383127668Sbms * at most 10 characters. 384127668Sbms */ 385127668Sbms for (i = 0; i < optlen && i < 10; i++) 386127668Sbms printf("%02x", ((u_char *)(dh6o + 1))[i]); 387127668Sbms break; 388127668Sbms case DH6OPT_RECONF_MSG: 389127668Sbms tp = (u_char *)(dh6o + 1); 390127668Sbms switch (*tp) { 391127668Sbms case DH6_RENEW: 392127668Sbms printf(" for renew)"); 393127668Sbms break; 394127668Sbms case DH6_INFORM_REQ: 395127668Sbms printf(" for inf-req)"); 396127668Sbms break; 397127668Sbms default: 398127668Sbms printf(" for ?\?\?(%02x))", *tp); 399127668Sbms break; 400127668Sbms } 401127668Sbms break; 402127668Sbms case DH6OPT_RECONF_ACCEPT: /* nothing todo */ 403127668Sbms printf(")"); 404127668Sbms break; 405127668Sbms case DH6OPT_SIP_SERVER_A: 406111726Sfenner case DH6OPT_DNS: 407127668Sbms case DH6OPT_NTP_SERVERS: 408111726Sfenner if (optlen % 16) { 409127668Sbms printf(" ?)"); 410111726Sfenner break; 411111726Sfenner } 412111726Sfenner tp = (u_char *)(dh6o + 1); 413111726Sfenner for (i = 0; i < optlen; i += 16) 414111726Sfenner printf(" %s", ip6addr_string(&tp[i])); 415111726Sfenner printf(")"); 416127668Sbms break; 417127668Sbms case DH6OPT_PREFIX_DELEGATION: 418127668Sbms dhcp6opt_print((u_char *)(dh6o + 1), 419127668Sbms (u_char *)(dh6o + 1) + optlen); 420127668Sbms printf(")"); 421127668Sbms break; 422127668Sbms case DH6OPT_PREFIX_INFORMATION: 423127668Sbms if (optlen % 21) 424127668Sbms printf(" ?)"); 425127668Sbms memcpy(&addr6, (u_char *)(dh6o + 1) + 5, 426127668Sbms sizeof(addr6)); 427127668Sbms printf(" %s/%d", ip6addr_string(&addr6), 428127668Sbms (int)*((u_char *)(dh6o + 1) + 4)); 429127668Sbms memcpy(&val32, dh6o + 1, sizeof(val32)); 430127668Sbms val32 = ntohl(val32); 431127668Sbms if (val32 == DHCP6_DURATITION_INFINITE) 432127668Sbms printf(" lease-duration: infinite)"); 433127668Sbms else 434127668Sbms printf(" lease-duration: %u)", val32); 435127668Sbms break; 436127668Sbms case DH6OPT_STATUS_CODE: 437127668Sbms if (optlen < 2) { 438127668Sbms printf(" ?)"); 439127668Sbms break; 440127668Sbms } 441127668Sbms memcpy(&val16, (u_char *)(dh6o + 1), sizeof(val16)); 442127668Sbms val16 = ntohs(val16); 443127668Sbms printf(" %s)", dhcp6stcode(val16)); 444127668Sbms break; 445127668Sbms case DH6OPT_IA_NA: 446127668Sbms case DH6OPT_IA_PD: 447127668Sbms if (optlen < sizeof(ia) - 4) { 448127668Sbms printf(" ?)"); 449127668Sbms break; 450127668Sbms } 451127668Sbms memcpy(&ia, (u_char *)dh6o, sizeof(ia)); 452127668Sbms ia.dh6opt_ia_iaid = ntohl(ia.dh6opt_ia_iaid); 453127668Sbms ia.dh6opt_ia_t1 = ntohl(ia.dh6opt_ia_t1); 454127668Sbms ia.dh6opt_ia_t2 = ntohl(ia.dh6opt_ia_t2); 455127668Sbms printf(" IAID:%lu T1:%lu T2:%lu", 456127668Sbms (unsigned long)ia.dh6opt_ia_iaid, 457127668Sbms (unsigned long)ia.dh6opt_ia_t1, 458127668Sbms (unsigned long)ia.dh6opt_ia_t2); 459127668Sbms if (optlen > sizeof(ia) - 4) { 460127668Sbms /* there are sub-options */ 461127668Sbms dhcp6opt_print((u_char *)dh6o + sizeof(ia), 462127668Sbms (u_char *)(dh6o + 1) + optlen); 463127668Sbms } 464127668Sbms printf(")"); 465127668Sbms break; 466127668Sbms case DH6OPT_IA_PD_PREFIX: 467127668Sbms if (optlen < sizeof(ia_prefix) - 4) { 468127668Sbms printf(" ?)"); 469127668Sbms break; 470127668Sbms } 471127668Sbms memcpy(&ia_prefix, (u_char *)dh6o, sizeof(ia_prefix)); 472127668Sbms printf(" %s/%d", 473127668Sbms ip6addr_string(&ia_prefix.dh6opt_ia_prefix_addr), 474127668Sbms ia_prefix.dh6opt_ia_prefix_plen); 475127668Sbms ia_prefix.dh6opt_ia_prefix_pltime = 476127668Sbms ntohl(ia_prefix.dh6opt_ia_prefix_pltime); 477127668Sbms ia_prefix.dh6opt_ia_prefix_vltime = 478127668Sbms ntohl(ia_prefix.dh6opt_ia_prefix_vltime); 479127668Sbms printf(" pltime:%lu vltime:%lu", 480127668Sbms (unsigned long)ia_prefix.dh6opt_ia_prefix_pltime, 481127668Sbms (unsigned long)ia_prefix.dh6opt_ia_prefix_vltime); 482127668Sbms if (optlen > sizeof(ia_prefix) - 4) { 483127668Sbms /* there are sub-options */ 484127668Sbms dhcp6opt_print((u_char *)dh6o + 485127668Sbms sizeof(ia_prefix), 486127668Sbms (u_char *)(dh6o + 1) + optlen); 487127668Sbms } 488127668Sbms printf(")"); 489127668Sbms break; 49056893Sfenner default: 491127668Sbms printf(")"); 49256893Sfenner break; 49356893Sfenner } 49456893Sfenner 495111726Sfenner cp += sizeof(*dh6o) + optlen; 49656893Sfenner } 49756893Sfenner return; 49856893Sfenner 49956893Sfennertrunc: 50056893Sfenner printf("[|dhcp6ext]"); 50156893Sfenner} 50256893Sfenner 50356893Sfenner/* 504111726Sfenner * Print dhcp6 packets 50556893Sfenner */ 50656893Sfennervoid 507127668Sbmsdhcp6_print(const u_char *cp, u_int length) 50856893Sfenner{ 509111726Sfenner struct dhcp6 *dh6; 510127668Sbms struct dhcp6_relay *dh6relay; 511127668Sbms const u_char *ep; 51256893Sfenner u_char *extp; 513111726Sfenner const char *name; 51456893Sfenner 51556893Sfenner printf("dhcp6"); 51656893Sfenner 51756893Sfenner ep = (u_char *)snapend; 518127668Sbms if (cp + length < ep) 519127668Sbms ep = cp + length; 52056893Sfenner 521111726Sfenner dh6 = (struct dhcp6 *)cp; 522127668Sbms dh6relay = (struct dhcp6_relay *)cp; 523127668Sbms TCHECK(dh6->dh6_xid); 52456893Sfenner switch (dh6->dh6_msgtype) { 525127668Sbms case DH6_SOLICIT: 526127668Sbms name = "solicit"; 527127668Sbms break; 528127668Sbms case DH6_ADVERTISE: 529127668Sbms name = "advertise"; 530127668Sbms break; 531127668Sbms case DH6_REQUEST: 532127668Sbms name = "request"; 533127668Sbms break; 534127668Sbms case DH6_CONFIRM: 535127668Sbms name = "confirm"; 536127668Sbms break; 537127668Sbms case DH6_RENEW: 538127668Sbms name = "renew"; 539127668Sbms break; 540127668Sbms case DH6_REBIND: 541127668Sbms name = "rebind"; 542127668Sbms break; 54356893Sfenner case DH6_REPLY: 544111726Sfenner name = "reply"; 54556893Sfenner break; 546127668Sbms case DH6_RELEASE: 547127668Sbms name = "release"; 548127668Sbms break; 549127668Sbms case DH6_DECLINE: 550127668Sbms name = "decline"; 551127668Sbms break; 552127668Sbms case DH6_RECONFIGURE: 553127668Sbms name = "reconfigure"; 554127668Sbms break; 555111726Sfenner case DH6_INFORM_REQ: 556111726Sfenner name= "inf-req"; 55756893Sfenner break; 558127668Sbms case DH6_RELAY_FORW: 559127668Sbms name= "relay-fwd"; 560127668Sbms break; 561127668Sbms case DH6_RELAY_REPLY: 562127668Sbms name= "relay-reply"; 563127668Sbms break; 564111726Sfenner default: 565111726Sfenner name = NULL; 56656893Sfenner break; 56756893Sfenner } 568111726Sfenner 569111726Sfenner if (!vflag) { 570111726Sfenner if (name) 571111726Sfenner printf(" %s", name); 572127668Sbms else if (dh6->dh6_msgtype != DH6_RELAY_FORW && 573127668Sbms dh6->dh6_msgtype != DH6_RELAY_REPLY) { 574111726Sfenner printf(" msgtype-%u", dh6->dh6_msgtype); 575127668Sbms } 576111726Sfenner return; 577111726Sfenner } 578111726Sfenner 579111726Sfenner /* XXX relay agent messages have to be handled differently */ 580111726Sfenner 581111726Sfenner if (name) 582111726Sfenner printf(" %s (", name); /*)*/ 583111726Sfenner else 584111726Sfenner printf(" msgtype-%u (", dh6->dh6_msgtype); /*)*/ 585127668Sbms if (dh6->dh6_msgtype != DH6_RELAY_FORW && 586127668Sbms dh6->dh6_msgtype != DH6_RELAY_REPLY) { 587127668Sbms printf("xid=%x", EXTRACT_32BITS(&dh6->dh6_xid) & DH6_XIDMASK); 588127668Sbms extp = (u_char *)(dh6 + 1); 589127668Sbms dhcp6opt_print(extp, ep); 590127668Sbms } else { /* relay messages */ 591127668Sbms struct in6_addr addr6; 592127668Sbms 593127668Sbms TCHECK(dh6relay->dh6relay_peeraddr); 594127668Sbms 595127668Sbms memcpy(&addr6, dh6relay->dh6relay_linkaddr, sizeof (addr6)); 596127668Sbms printf("linkaddr=%s", ip6addr_string(&addr6)); 597127668Sbms 598127668Sbms memcpy(&addr6, dh6relay->dh6relay_peeraddr, sizeof (addr6)); 599127668Sbms printf(" peeraddr=%s", ip6addr_string(&addr6)); 600127668Sbms 601127668Sbms dhcp6opt_print((u_char *)(dh6relay + 1), ep); 602127668Sbms } 603111726Sfenner /*(*/ 604111726Sfenner printf(")"); 60556893Sfenner return; 60656893Sfenner 60756893Sfennertrunc: 608111726Sfenner printf("[|dhcp6]"); 60956893Sfenner} 610