1 /* 2 * Copyright (C) 1998 and 1999 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the project nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 /* 30 * RFC3315: DHCPv6 31 * supported DHCPv6 options: 32 * RFC3319, 33 * RFC3633, 34 * RFC3646, 35 * draft-ietf-dhc-dhcpv6-opt-timeconfig-03.txt, 36 * draft-ietf-dhc-lifetime-00.txt, 37 */ 38 39 #ifndef lint 40 static const char rcsid[] _U_ = 41 "@(#) $Header: /tcpdump/master/tcpdump/print-dhcp6.c,v 1.35 2004/07/06 22:16:03 guy Exp $"; 42 #endif 43 44 #ifdef HAVE_CONFIG_H 45 #include "config.h" 46 #endif 47 48 #include <tcpdump-stdinc.h> 49 50 #include <stdio.h> 51 #include <string.h> 52 53 #include "interface.h" 54 #include "addrtoname.h" 55 #include "extract.h" 56 57 /* lease duration */ 58 #define DHCP6_DURATITION_INFINITE 0xffffffff 59 60 /* Error Values */ 61 #define DH6ERR_FAILURE 16 62 #define DH6ERR_AUTHFAIL 17 63 #define DH6ERR_POORLYFORMED 18 64 #define DH6ERR_UNAVAIL 19 65 #define DH6ERR_OPTUNAVAIL 20 66 67 /* Message type */ 68 #define DH6_SOLICIT 1 69 #define DH6_ADVERTISE 2 70 #define DH6_REQUEST 3 71 #define DH6_CONFIRM 4 72 #define DH6_RENEW 5 73 #define DH6_REBIND 6 74 #define DH6_REPLY 7 75 #define DH6_RELEASE 8 76 #define DH6_DECLINE 9 77 #define DH6_RECONFIGURE 10 78 #define DH6_INFORM_REQ 11 79 #define DH6_RELAY_FORW 12 80 #define DH6_RELAY_REPLY 13 81 82 /* DHCP6 base packet format */ 83 struct dhcp6 { 84 union { 85 u_int8_t m; 86 u_int32_t x; 87 } dh6_msgtypexid; 88 /* options follow */ 89 }; 90 #define dh6_msgtype dh6_msgtypexid.m 91 #define dh6_xid dh6_msgtypexid.x 92 #define DH6_XIDMASK 0x00ffffff 93 94 /* DHCPv6 relay messages */ 95 struct dhcp6_relay { 96 u_int8_t dh6relay_msgtype; 97 u_int8_t dh6relay_hcnt; 98 u_int8_t dh6relay_linkaddr[16]; /* XXX: badly aligned */ 99 u_int8_t dh6relay_peeraddr[16]; 100 /* options follow */ 101 }; 102 103 /* options */ 104 #define DH6OPT_CLIENTID 1 105 #define DH6OPT_SERVERID 2 106 #define DH6OPT_IA_NA 3 107 #define DH6OPT_IA_TMP 4 108 #define DH6OPT_IADDR 5 109 #define DH6OPT_ORO 6 110 #define DH6OPT_PREFERENCE 7 111 # define DH6OPT_PREF_MAX 255 112 #define DH6OPT_ELAPSED_TIME 8 113 #define DH6OPT_RELAY_MSG 9 114 /*#define DH6OPT_SERVER_MSG 10 deprecated */ 115 #define DH6OPT_AUTH 11 116 # define DH6OPT_AUTHPROTO_DELAYED 2 117 # define DH6OPT_AUTHPROTO_RECONFIG 3 118 # define DH6OPT_AUTHALG_HMACMD5 1 119 # define DH6OPT_AUTHRDM_MONOCOUNTER 0 120 # define DH6OPT_AUTHRECONFIG_KEY 1 121 # define DH6OPT_AUTHRECONFIG_HMACMD5 2 122 #define DH6OPT_UNICAST 12 123 #define DH6OPT_STATUS_CODE 13 124 # define DH6OPT_STCODE_SUCCESS 0 125 # define DH6OPT_STCODE_UNSPECFAIL 1 126 # define DH6OPT_STCODE_NOADDRAVAIL 2 127 # define DH6OPT_STCODE_NOBINDING 3 128 # define DH6OPT_STCODE_NOTONLINK 4 129 # define DH6OPT_STCODE_USEMULTICAST 5 130 # define DH6OPT_STCODE_NOPREFIXAVAIL 6 131 #define DH6OPT_RAPID_COMMIT 14 132 #define DH6OPT_USER_CLASS 15 133 #define DH6OPT_VENDOR_CLASS 16 134 #define DH6OPT_VENDOR_OPTS 17 135 #define DH6OPT_INTERFACE_ID 18 136 #define DH6OPT_RECONF_MSG 19 137 #define DH6OPT_RECONF_ACCEPT 20 138 #define DH6OPT_SIP_SERVER_D 21 139 #define DH6OPT_SIP_SERVER_A 22 140 #define DH6OPT_DNS 23 141 #define DH6OPT_DNSNAME 24 142 #define DH6OPT_IA_PD 25 143 #define DH6OPT_IA_PD_PREFIX 26 144 145 /* 146 * The old prefix delegation option used in the service specification document 147 * (200206xx version) by NTT Communications. 148 */ 149 #define DH6OPT_PREFIX_DELEGATION 30 150 #define DH6OPT_PREFIX_INFORMATION 31 151 #define DH6OPT_PREFIX_REQUEST 32 152 153 /* 154 * The following one is an unassigned number. 155 * We temporarily use values as of KAME snap 20040322. 156 */ 157 #define DH6OPT_NTP_SERVERS 35 158 #define DH6OPT_LIFETIME 36 159 160 struct dhcp6opt { 161 u_int16_t dh6opt_type; 162 u_int16_t dh6opt_len; 163 /* type-dependent data follows */ 164 }; 165 166 struct dhcp6_ia { 167 u_int16_t dh6opt_ia_type; 168 u_int16_t dh6opt_ia_len; 169 u_int32_t dh6opt_ia_iaid; 170 u_int32_t dh6opt_ia_t1; 171 u_int32_t dh6opt_ia_t2; 172 }; 173 174 struct dhcp6_ia_prefix { 175 u_int16_t dh6opt_ia_prefix_type; 176 u_int16_t dh6opt_ia_prefix_len; 177 u_int32_t dh6opt_ia_prefix_pltime; 178 u_int32_t dh6opt_ia_prefix_vltime; 179 u_int8_t dh6opt_ia_prefix_plen; 180 struct in6_addr dh6opt_ia_prefix_addr; 181 } __attribute__ ((__packed__)); 182 183 struct dhcp6_auth { 184 u_int16_t dh6opt_auth_type; 185 u_int16_t dh6opt_auth_len; 186 u_int8_t dh6opt_auth_proto; 187 u_int8_t dh6opt_auth_alg; 188 u_int8_t dh6opt_auth_rdm; 189 u_int8_t dh6opt_auth_rdinfo[8]; 190 /* authentication information follows */ 191 } __attribute__ ((__packed__)); 192 193 static const char * 194 dhcp6opt_name(int type) 195 { 196 static char genstr[sizeof("opt_65535") + 1]; /* XXX thread unsafe */ 197 198 if (type > 65535) 199 return "INVALID option"; 200 201 switch(type) { 202 case DH6OPT_CLIENTID: 203 return "client ID"; 204 case DH6OPT_SERVERID: 205 return "server ID"; 206 case DH6OPT_IA_NA: 207 return "IA_NA"; 208 case DH6OPT_ORO: 209 return "option request"; 210 case DH6OPT_PREFERENCE: 211 return "preference"; 212 case DH6OPT_ELAPSED_TIME: 213 return "elapsed time"; 214 case DH6OPT_RELAY_MSG: 215 return "relay message"; 216 case DH6OPT_AUTH: 217 return "authentication"; 218 case DH6OPT_UNICAST: 219 return "server unicast"; 220 case DH6OPT_STATUS_CODE: 221 return "status code"; 222 case DH6OPT_RAPID_COMMIT: 223 return "rapid commit"; 224 case DH6OPT_USER_CLASS: 225 return "user class"; 226 case DH6OPT_VENDOR_CLASS: 227 return "vendor class"; 228 case DH6OPT_VENDOR_OPTS: 229 return "vendor-specific info"; 230 case DH6OPT_INTERFACE_ID: 231 return "interface ID"; 232 case DH6OPT_RECONF_MSG: 233 return "reconfigure message"; 234 case DH6OPT_RECONF_ACCEPT: 235 return "reconfigure accept"; 236 case DH6OPT_SIP_SERVER_D: 237 return "SIP servers domain"; 238 case DH6OPT_SIP_SERVER_A: 239 return "SIP servers address"; 240 case DH6OPT_DNS: 241 return "DNS"; 242 case DH6OPT_DNSNAME: 243 return "DNS name"; 244 case DH6OPT_PREFIX_DELEGATION: 245 return "prefix delegation"; 246 case DH6OPT_PREFIX_INFORMATION: 247 return "prefix information"; 248 case DH6OPT_IA_PD: 249 return "IA_PD"; 250 case DH6OPT_IA_PD_PREFIX: 251 return "IA_PD prefix"; 252 case DH6OPT_NTP_SERVERS: 253 return "NTP Server"; 254 case DH6OPT_LIFETIME: 255 return "lifetime"; 256 default: 257 snprintf(genstr, sizeof(genstr), "opt_%d", type); 258 return(genstr); 259 } 260 } 261 262 static const char * 263 dhcp6stcode(int code) 264 { 265 static char genstr[sizeof("code255") + 1]; /* XXX thread unsafe */ 266 267 if (code > 255) 268 return "INVALID code"; 269 270 switch(code) { 271 case DH6OPT_STCODE_SUCCESS: 272 return "success"; 273 case DH6OPT_STCODE_UNSPECFAIL: 274 return "unspec failure"; 275 case DH6OPT_STCODE_NOADDRAVAIL: 276 return "no addresses"; 277 case DH6OPT_STCODE_NOBINDING: 278 return "no binding"; 279 case DH6OPT_STCODE_NOTONLINK: 280 return "not on-link"; 281 case DH6OPT_STCODE_USEMULTICAST: 282 return "use multicast"; 283 case DH6OPT_STCODE_NOPREFIXAVAIL: 284 return "no prefixes"; 285 default: 286 snprintf(genstr, sizeof(genstr), "code%d", code); 287 return(genstr); 288 } 289 } 290 291 static void 292 dhcp6opt_print(const u_char *cp, const u_char *ep) 293 { 294 struct dhcp6opt *dh6o; 295 u_char *tp; 296 size_t i; 297 u_int16_t opttype; 298 size_t optlen; 299 u_int16_t val16; 300 u_int32_t val32; 301 struct in6_addr addr6; 302 struct dhcp6_ia ia; 303 struct dhcp6_ia_prefix ia_prefix; 304 struct dhcp6_auth authopt; 305 u_int authinfolen, authrealmlen; 306 307 if (cp == ep) 308 return; 309 while (cp < ep) { 310 if (ep < cp + sizeof(*dh6o)) 311 goto trunc; 312 dh6o = (struct dhcp6opt *)cp; 313 optlen = EXTRACT_16BITS(&dh6o->dh6opt_len); 314 if (ep < cp + sizeof(*dh6o) + optlen) 315 goto trunc; 316 opttype = EXTRACT_16BITS(&dh6o->dh6opt_type); 317 printf(" (%s", dhcp6opt_name(opttype)); 318 switch (opttype) { 319 case DH6OPT_CLIENTID: 320 case DH6OPT_SERVERID: 321 if (optlen < 2) { 322 /*(*/ 323 printf(" ?)"); 324 break; 325 } 326 tp = (u_char *)(dh6o + 1); 327 switch (EXTRACT_16BITS(tp)) { 328 case 1: 329 if (optlen >= 2 + 6) { 330 printf(" hwaddr/time type %u time %u ", 331 EXTRACT_16BITS(&tp[2]), 332 EXTRACT_32BITS(&tp[4])); 333 for (i = 8; i < optlen; i++) 334 printf("%02x", tp[i]); 335 /*(*/ 336 printf(")"); 337 } else { 338 /*(*/ 339 printf(" ?)"); 340 } 341 break; 342 case 2: 343 if (optlen >= 2 + 8) { 344 printf(" vid "); 345 for (i = 2; i < 2 + 8; i++) 346 printf("%02x", tp[i]); 347 /*(*/ 348 printf(")"); 349 } else { 350 /*(*/ 351 printf(" ?)"); 352 } 353 break; 354 case 3: 355 if (optlen >= 2 + 2) { 356 printf(" hwaddr type %u ", 357 EXTRACT_16BITS(&tp[2])); 358 for (i = 4; i < optlen; i++) 359 printf("%02x", tp[i]); 360 /*(*/ 361 printf(")"); 362 } else { 363 /*(*/ 364 printf(" ?)"); 365 } 366 break; 367 default: 368 printf(" type %d)", EXTRACT_16BITS(tp)); 369 break; 370 } 371 break; 372 case DH6OPT_ORO: 373 if (optlen % 2) { 374 printf(" ?)"); 375 break; 376 } 377 tp = (u_char *)(dh6o + 1); 378 for (i = 0; i < optlen; i += 2) { 379 u_int16_t opt; 380 381 memcpy(&opt, &tp[i], sizeof(opt)); 382 printf(" %s", dhcp6opt_name(ntohs(opt))); 383 } 384 printf(")"); 385 break; 386 case DH6OPT_PREFERENCE: 387 if (optlen != 1) { 388 printf(" ?)"); 389 break; 390 } 391 printf(" %d)", *((u_char *)(dh6o + 1) + 1)); 392 break; 393 case DH6OPT_ELAPSED_TIME: 394 if (optlen != 2) { 395 printf(" ?)"); 396 break; 397 } 398 memcpy(&val16, dh6o + 1, sizeof(val16)); 399 val16 = ntohs(val16); 400 printf(" %d)", (int)val16); 401 break; 402 case DH6OPT_RELAY_MSG: 403 printf(" ("); 404 dhcp6_print((const u_char *)(dh6o + 1), optlen); 405 printf(")"); 406 break; 407 case DH6OPT_AUTH: 408 if (optlen < sizeof(authopt) - sizeof(*dh6o)) { 409 printf(" ?)"); 410 break; 411 } 412 memcpy(&authopt, dh6o, sizeof(authopt)); 413 switch (authopt.dh6opt_auth_proto) { 414 case DH6OPT_AUTHPROTO_DELAYED: 415 printf(" proto: delayed"); 416 break; 417 case DH6OPT_AUTHPROTO_RECONFIG: 418 printf(" proto: reconfigure"); 419 break; 420 default: 421 printf(" proto: %d", 422 authopt.dh6opt_auth_proto); 423 break; 424 } 425 switch (authopt.dh6opt_auth_alg) { 426 case DH6OPT_AUTHALG_HMACMD5: 427 /* XXX: may depend on the protocol */ 428 printf(", alg: HMAC-MD5"); 429 break; 430 default: 431 printf(", alg: %d", authopt.dh6opt_auth_alg); 432 break; 433 } 434 switch (authopt.dh6opt_auth_rdm) { 435 case DH6OPT_AUTHRDM_MONOCOUNTER: 436 printf(", RDM: mono"); 437 break; 438 default: 439 printf(", RDM: %d", authopt.dh6opt_auth_rdm); 440 break; 441 } 442 tp = (u_char *)&authopt.dh6opt_auth_rdinfo; 443 printf(", RD:"); 444 for (i = 0; i < 4; i++, tp += sizeof(val16)) 445 printf(" %04x", EXTRACT_16BITS(tp)); 446 447 /* protocol dependent part */ 448 tp = (u_char *)dh6o + sizeof(authopt); 449 authinfolen = 450 optlen + sizeof(*dh6o) - sizeof(authopt); 451 switch (authopt.dh6opt_auth_proto) { 452 case DH6OPT_AUTHPROTO_DELAYED: 453 if (authinfolen == 0) 454 break; 455 if (authinfolen < 20) { 456 printf(" ??"); 457 break; 458 } 459 authrealmlen = authinfolen - 20; 460 if (authrealmlen > 0) { 461 printf(", realm: "); 462 } 463 for (i = 0; i < authrealmlen; i++, tp++) 464 printf("%02x", *tp); 465 printf(", key ID: %08x", EXTRACT_32BITS(tp)); 466 tp += 4; 467 printf(", HMAC-MD5:"); 468 for (i = 0; i < 4; i++, tp+= 4) 469 printf(" %08x", EXTRACT_32BITS(tp)); 470 break; 471 case DH6OPT_AUTHPROTO_RECONFIG: 472 if (authinfolen != 17) { 473 printf(" ??"); 474 break; 475 } 476 switch (*tp++) { 477 case DH6OPT_AUTHRECONFIG_KEY: 478 printf(" reconfig-key"); 479 break; 480 case DH6OPT_AUTHRECONFIG_HMACMD5: 481 printf(" type: HMAC-MD5"); 482 break; 483 default: 484 printf(" type: ??"); 485 break; 486 } 487 printf(" value:"); 488 for (i = 0; i < 4; i++, tp+= 4) 489 printf(" %08x", EXTRACT_32BITS(tp)); 490 break; 491 default: 492 printf(" ??"); 493 break; 494 } 495 496 printf(")"); 497 break; 498 case DH6OPT_RAPID_COMMIT: /* nothing todo */ 499 printf(")"); 500 break; 501 case DH6OPT_INTERFACE_ID: 502 /* 503 * Since we cannot predict the encoding, print hex dump 504 * at most 10 characters. 505 */ 506 for (i = 0; i < optlen && i < 10; i++) 507 printf("%02x", ((u_char *)(dh6o + 1))[i]); 508 break; 509 case DH6OPT_RECONF_MSG: 510 tp = (u_char *)(dh6o + 1); 511 switch (*tp) { 512 case DH6_RENEW: 513 printf(" for renew)"); 514 break; 515 case DH6_INFORM_REQ: 516 printf(" for inf-req)"); 517 break; 518 default: 519 printf(" for ?\?\?(%02x))", *tp); 520 break; 521 } 522 break; 523 case DH6OPT_RECONF_ACCEPT: /* nothing todo */ 524 printf(")"); 525 break; 526 case DH6OPT_SIP_SERVER_A: 527 case DH6OPT_DNS: 528 case DH6OPT_NTP_SERVERS: 529 if (optlen % 16) { 530 printf(" ?)"); 531 break; 532 } 533 tp = (u_char *)(dh6o + 1); 534 for (i = 0; i < optlen; i += 16) 535 printf(" %s", ip6addr_string(&tp[i])); 536 printf(")"); 537 break; 538 case DH6OPT_PREFIX_DELEGATION: 539 dhcp6opt_print((u_char *)(dh6o + 1), 540 (u_char *)(dh6o + 1) + optlen); 541 printf(")"); 542 break; 543 case DH6OPT_PREFIX_INFORMATION: 544 if (optlen % 21) 545 printf(" ?)"); 546 memcpy(&addr6, (u_char *)(dh6o + 1) + 5, 547 sizeof(addr6)); 548 printf(" %s/%d", ip6addr_string(&addr6), 549 (int)*((u_char *)(dh6o + 1) + 4)); 550 memcpy(&val32, dh6o + 1, sizeof(val32)); 551 val32 = ntohl(val32); 552 if (val32 == DHCP6_DURATITION_INFINITE) 553 printf(" lease-duration: infinite)"); 554 else 555 printf(" lease-duration: %u)", val32); 556 break; 557 case DH6OPT_STATUS_CODE: 558 if (optlen < 2) { 559 printf(" ?)"); 560 break; 561 } 562 memcpy(&val16, (u_char *)(dh6o + 1), sizeof(val16)); 563 val16 = ntohs(val16); 564 printf(" %s)", dhcp6stcode(val16)); 565 break; 566 case DH6OPT_IA_NA: 567 case DH6OPT_IA_PD: 568 if (optlen < sizeof(ia) - 4) { 569 printf(" ?)"); 570 break; 571 } 572 memcpy(&ia, (u_char *)dh6o, sizeof(ia)); 573 ia.dh6opt_ia_iaid = ntohl(ia.dh6opt_ia_iaid); 574 ia.dh6opt_ia_t1 = ntohl(ia.dh6opt_ia_t1); 575 ia.dh6opt_ia_t2 = ntohl(ia.dh6opt_ia_t2); 576 printf(" IAID:%lu T1:%lu T2:%lu", 577 (unsigned long)ia.dh6opt_ia_iaid, 578 (unsigned long)ia.dh6opt_ia_t1, 579 (unsigned long)ia.dh6opt_ia_t2); 580 if (optlen > sizeof(ia) - 4) { 581 /* there are sub-options */ 582 dhcp6opt_print((u_char *)dh6o + sizeof(ia), 583 (u_char *)(dh6o + 1) + optlen); 584 } 585 printf(")"); 586 break; 587 case DH6OPT_IA_PD_PREFIX: 588 if (optlen < sizeof(ia_prefix) - 4) { 589 printf(" ?)"); 590 break; 591 } 592 memcpy(&ia_prefix, (u_char *)dh6o, sizeof(ia_prefix)); 593 printf(" %s/%d", 594 ip6addr_string(&ia_prefix.dh6opt_ia_prefix_addr), 595 ia_prefix.dh6opt_ia_prefix_plen); 596 ia_prefix.dh6opt_ia_prefix_pltime = 597 ntohl(ia_prefix.dh6opt_ia_prefix_pltime); 598 ia_prefix.dh6opt_ia_prefix_vltime = 599 ntohl(ia_prefix.dh6opt_ia_prefix_vltime); 600 printf(" pltime:%lu vltime:%lu", 601 (unsigned long)ia_prefix.dh6opt_ia_prefix_pltime, 602 (unsigned long)ia_prefix.dh6opt_ia_prefix_vltime); 603 if (optlen > sizeof(ia_prefix) - 4) { 604 /* there are sub-options */ 605 dhcp6opt_print((u_char *)dh6o + 606 sizeof(ia_prefix), 607 (u_char *)(dh6o + 1) + optlen); 608 } 609 printf(")"); 610 break; 611 case DH6OPT_LIFETIME: 612 if (optlen != 4) { 613 printf(" ?)"); 614 break; 615 } 616 memcpy(&val32, dh6o + 1, sizeof(val32)); 617 val32 = ntohl(val32); 618 printf(" %d)", (int)val32); 619 break; 620 default: 621 printf(")"); 622 break; 623 } 624 625 cp += sizeof(*dh6o) + optlen; 626 } 627 return; 628 629 trunc: 630 printf("[|dhcp6ext]"); 631 } 632 633 /* 634 * Print dhcp6 packets 635 */ 636 void 637 dhcp6_print(const u_char *cp, u_int length) 638 { 639 struct dhcp6 *dh6; 640 struct dhcp6_relay *dh6relay; 641 const u_char *ep; 642 u_char *extp; 643 const char *name; 644 645 printf("dhcp6"); 646 647 ep = (u_char *)snapend; 648 if (cp + length < ep) 649 ep = cp + length; 650 651 dh6 = (struct dhcp6 *)cp; 652 dh6relay = (struct dhcp6_relay *)cp; 653 TCHECK(dh6->dh6_xid); 654 switch (dh6->dh6_msgtype) { 655 case DH6_SOLICIT: 656 name = "solicit"; 657 break; 658 case DH6_ADVERTISE: 659 name = "advertise"; 660 break; 661 case DH6_REQUEST: 662 name = "request"; 663 break; 664 case DH6_CONFIRM: 665 name = "confirm"; 666 break; 667 case DH6_RENEW: 668 name = "renew"; 669 break; 670 case DH6_REBIND: 671 name = "rebind"; 672 break; 673 case DH6_REPLY: 674 name = "reply"; 675 break; 676 case DH6_RELEASE: 677 name = "release"; 678 break; 679 case DH6_DECLINE: 680 name = "decline"; 681 break; 682 case DH6_RECONFIGURE: 683 name = "reconfigure"; 684 break; 685 case DH6_INFORM_REQ: 686 name= "inf-req"; 687 break; 688 case DH6_RELAY_FORW: 689 name= "relay-fwd"; 690 break; 691 case DH6_RELAY_REPLY: 692 name= "relay-reply"; 693 break; 694 default: 695 name = NULL; 696 break; 697 } 698 699 if (!vflag) { 700 if (name) 701 printf(" %s", name); 702 else if (dh6->dh6_msgtype != DH6_RELAY_FORW && 703 dh6->dh6_msgtype != DH6_RELAY_REPLY) { 704 printf(" msgtype-%u", dh6->dh6_msgtype); 705 } 706 return; 707 } 708 709 /* XXX relay agent messages have to be handled differently */ 710 711 if (name) 712 printf(" %s (", name); /*)*/ 713 else 714 printf(" msgtype-%u (", dh6->dh6_msgtype); /*)*/ 715 if (dh6->dh6_msgtype != DH6_RELAY_FORW && 716 dh6->dh6_msgtype != DH6_RELAY_REPLY) { 717 printf("xid=%x", EXTRACT_32BITS(&dh6->dh6_xid) & DH6_XIDMASK); 718 extp = (u_char *)(dh6 + 1); 719 dhcp6opt_print(extp, ep); 720 } else { /* relay messages */ 721 struct in6_addr addr6; 722 723 TCHECK(dh6relay->dh6relay_peeraddr); 724 725 memcpy(&addr6, dh6relay->dh6relay_linkaddr, sizeof (addr6)); 726 printf("linkaddr=%s", ip6addr_string(&addr6)); 727 728 memcpy(&addr6, dh6relay->dh6relay_peeraddr, sizeof (addr6)); 729 printf(" peeraddr=%s", ip6addr_string(&addr6)); 730 731 dhcp6opt_print((u_char *)(dh6relay + 1), ep); 732 } 733 /*(*/ 734 printf(")"); 735 return; 736 737 trunc: 738 printf("[|dhcp6]"); 739 } 740