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 */ 293340d773SGleb Smirnoff 303340d773SGleb Smirnoff /* \summary: IPv6 DHCP printer */ 313340d773SGleb Smirnoff 329afd0c29SBill Fenner /* 335b0fe478SBruce M Simpson * RFC3315: DHCPv6 345b0fe478SBruce M Simpson * supported DHCPv6 options: 35d03c0883SXin LI * RFC3319: Session Initiation Protocol (SIP) Servers options, 36d03c0883SXin LI * RFC3633: IPv6 Prefix options, 37d03c0883SXin LI * RFC3646: DNS Configuration options, 38d03c0883SXin LI * RFC3898: Network Information Service (NIS) Configuration options, 39d03c0883SXin LI * RFC4075: Simple Network Time Protocol (SNTP) Configuration option, 40d03c0883SXin LI * RFC4242: Information Refresh Time option, 41d03c0883SXin LI * RFC4280: Broadcast and Multicast Control Servers options, 423c602fabSXin LI * RFC5908: Network Time Protocol (NTP) Server Option for DHCPv6 43d03c0883SXin LI * RFC6334: Dual-Stack Lite option, 449afd0c29SBill Fenner */ 45b0453382SBill Fenner 46b0453382SBill Fenner #ifdef HAVE_CONFIG_H 47b0453382SBill Fenner #include "config.h" 48b0453382SBill Fenner #endif 49b0453382SBill Fenner 503340d773SGleb Smirnoff #include <netdissect-stdinc.h> 51b0453382SBill Fenner 52b0453382SBill Fenner #include <stdio.h> 53b0453382SBill Fenner #include <string.h> 54b0453382SBill Fenner 553340d773SGleb Smirnoff #include "netdissect.h" 56b0453382SBill Fenner #include "addrtoname.h" 575b0fe478SBruce M Simpson #include "extract.h" 585b0fe478SBruce M Simpson 595b0fe478SBruce M Simpson /* lease duration */ 603c602fabSXin LI #define DHCP6_DURATION_INFINITE 0xffffffff 61b0453382SBill Fenner 629afd0c29SBill Fenner /* Error Values */ 639afd0c29SBill Fenner #define DH6ERR_FAILURE 16 649afd0c29SBill Fenner #define DH6ERR_AUTHFAIL 17 659afd0c29SBill Fenner #define DH6ERR_POORLYFORMED 18 669afd0c29SBill Fenner #define DH6ERR_UNAVAIL 19 679afd0c29SBill Fenner #define DH6ERR_OPTUNAVAIL 20 68b0453382SBill Fenner 699afd0c29SBill Fenner /* Message type */ 705b0fe478SBruce M Simpson #define DH6_SOLICIT 1 715b0fe478SBruce M Simpson #define DH6_ADVERTISE 2 725b0fe478SBruce M Simpson #define DH6_REQUEST 3 735b0fe478SBruce M Simpson #define DH6_CONFIRM 4 745b0fe478SBruce M Simpson #define DH6_RENEW 5 755b0fe478SBruce M Simpson #define DH6_REBIND 6 769afd0c29SBill Fenner #define DH6_REPLY 7 775b0fe478SBruce M Simpson #define DH6_RELEASE 8 785b0fe478SBruce M Simpson #define DH6_DECLINE 9 795b0fe478SBruce M Simpson #define DH6_RECONFIGURE 10 809afd0c29SBill Fenner #define DH6_INFORM_REQ 11 815b0fe478SBruce M Simpson #define DH6_RELAY_FORW 12 825b0fe478SBruce M Simpson #define DH6_RELAY_REPLY 13 83a5779b6eSRui Paulo #define DH6_LEASEQUERY 14 84a5779b6eSRui Paulo #define DH6_LQ_REPLY 15 85b0453382SBill Fenner 863c602fabSXin LI static const struct tok dh6_msgtype_str[] = { 873c602fabSXin LI { DH6_SOLICIT, "solicit" }, 883c602fabSXin LI { DH6_ADVERTISE, "advertise" }, 893c602fabSXin LI { DH6_REQUEST, "request" }, 903c602fabSXin LI { DH6_CONFIRM, "confirm" }, 913c602fabSXin LI { DH6_RENEW, "renew" }, 923c602fabSXin LI { DH6_REBIND, "rebind" }, 933c602fabSXin LI { DH6_REPLY, "reply" }, 943c602fabSXin LI { DH6_RELEASE, "release" }, 953c602fabSXin LI { DH6_DECLINE, "decline" }, 963c602fabSXin LI { DH6_RECONFIGURE, "reconfigure" }, 973c602fabSXin LI { DH6_INFORM_REQ, "inf-req" }, 983c602fabSXin LI { DH6_RELAY_FORW, "relay-fwd" }, 993c602fabSXin LI { DH6_RELAY_REPLY, "relay-reply" }, 1003c602fabSXin LI { DH6_LEASEQUERY, "leasequery" }, 1013c602fabSXin LI { DH6_LQ_REPLY, "leasequery-reply" }, 1023c602fabSXin LI { 0, NULL } 1033c602fabSXin LI }; 1043c602fabSXin LI 1059afd0c29SBill Fenner /* DHCP6 base packet format */ 1069afd0c29SBill Fenner struct dhcp6 { 1079afd0c29SBill Fenner union { 1083340d773SGleb Smirnoff nd_uint8_t m; 1093340d773SGleb Smirnoff nd_uint32_t x; 1109afd0c29SBill Fenner } dh6_msgtypexid; 1119afd0c29SBill Fenner /* options follow */ 1125b0fe478SBruce M Simpson }; 1139afd0c29SBill Fenner #define dh6_msgtype dh6_msgtypexid.m 1149afd0c29SBill Fenner #define dh6_xid dh6_msgtypexid.x 1159afd0c29SBill Fenner #define DH6_XIDMASK 0x00ffffff 116b0453382SBill Fenner 1175b0fe478SBruce M Simpson /* DHCPv6 relay messages */ 1185b0fe478SBruce M Simpson struct dhcp6_relay { 1193340d773SGleb Smirnoff nd_uint8_t dh6relay_msgtype; 1203340d773SGleb Smirnoff nd_uint8_t dh6relay_hcnt; 1213340d773SGleb Smirnoff nd_uint8_t dh6relay_linkaddr[16]; /* XXX: badly aligned */ 1223340d773SGleb Smirnoff nd_uint8_t dh6relay_peeraddr[16]; 1235b0fe478SBruce M Simpson /* options follow */ 1245b0fe478SBruce M Simpson }; 1255b0fe478SBruce M Simpson 1265b0fe478SBruce M Simpson /* options */ 1275b0fe478SBruce M Simpson #define DH6OPT_CLIENTID 1 1285b0fe478SBruce M Simpson #define DH6OPT_SERVERID 2 1295b0fe478SBruce M Simpson #define DH6OPT_IA_NA 3 130b5bfcb5dSMax Laier #define DH6OPT_IA_TA 4 131b5bfcb5dSMax Laier #define DH6OPT_IA_ADDR 5 1325b0fe478SBruce M Simpson #define DH6OPT_ORO 6 1335b0fe478SBruce M Simpson #define DH6OPT_PREFERENCE 7 1345b0fe478SBruce M Simpson # define DH6OPT_PREF_MAX 255 1355b0fe478SBruce M Simpson #define DH6OPT_ELAPSED_TIME 8 1365b0fe478SBruce M Simpson #define DH6OPT_RELAY_MSG 9 1375b0fe478SBruce M Simpson /*#define DH6OPT_SERVER_MSG 10 deprecated */ 1385b0fe478SBruce M Simpson #define DH6OPT_AUTH 11 1391de50e9fSSam Leffler # define DH6OPT_AUTHPROTO_DELAYED 2 1401de50e9fSSam Leffler # define DH6OPT_AUTHPROTO_RECONFIG 3 1411de50e9fSSam Leffler # define DH6OPT_AUTHALG_HMACMD5 1 1421de50e9fSSam Leffler # define DH6OPT_AUTHRDM_MONOCOUNTER 0 1431de50e9fSSam Leffler # define DH6OPT_AUTHRECONFIG_KEY 1 1441de50e9fSSam Leffler # define DH6OPT_AUTHRECONFIG_HMACMD5 2 1455b0fe478SBruce M Simpson #define DH6OPT_UNICAST 12 1465b0fe478SBruce M Simpson #define DH6OPT_STATUS_CODE 13 1475b0fe478SBruce M Simpson # define DH6OPT_STCODE_SUCCESS 0 1485b0fe478SBruce M Simpson # define DH6OPT_STCODE_UNSPECFAIL 1 1495b0fe478SBruce M Simpson # define DH6OPT_STCODE_NOADDRAVAIL 2 1505b0fe478SBruce M Simpson # define DH6OPT_STCODE_NOBINDING 3 1515b0fe478SBruce M Simpson # define DH6OPT_STCODE_NOTONLINK 4 1525b0fe478SBruce M Simpson # define DH6OPT_STCODE_USEMULTICAST 5 1535b0fe478SBruce M Simpson # define DH6OPT_STCODE_NOPREFIXAVAIL 6 154a5779b6eSRui Paulo # define DH6OPT_STCODE_UNKNOWNQUERYTYPE 7 155a5779b6eSRui Paulo # define DH6OPT_STCODE_MALFORMEDQUERY 8 156a5779b6eSRui Paulo # define DH6OPT_STCODE_NOTCONFIGURED 9 157a5779b6eSRui Paulo # define DH6OPT_STCODE_NOTALLOWED 10 1585b0fe478SBruce M Simpson #define DH6OPT_RAPID_COMMIT 14 1595b0fe478SBruce M Simpson #define DH6OPT_USER_CLASS 15 1605b0fe478SBruce M Simpson #define DH6OPT_VENDOR_CLASS 16 1615b0fe478SBruce M Simpson #define DH6OPT_VENDOR_OPTS 17 1625b0fe478SBruce M Simpson #define DH6OPT_INTERFACE_ID 18 1635b0fe478SBruce M Simpson #define DH6OPT_RECONF_MSG 19 1645b0fe478SBruce M Simpson #define DH6OPT_RECONF_ACCEPT 20 1655b0fe478SBruce M Simpson #define DH6OPT_SIP_SERVER_D 21 1665b0fe478SBruce M Simpson #define DH6OPT_SIP_SERVER_A 22 1673c602fabSXin LI #define DH6OPT_DNS_SERVERS 23 1683c602fabSXin LI #define DH6OPT_DOMAIN_LIST 24 1691de50e9fSSam Leffler #define DH6OPT_IA_PD 25 1701de50e9fSSam Leffler #define DH6OPT_IA_PD_PREFIX 26 171b5bfcb5dSMax Laier #define DH6OPT_NIS_SERVERS 27 172b5bfcb5dSMax Laier #define DH6OPT_NISP_SERVERS 28 173b5bfcb5dSMax Laier #define DH6OPT_NIS_NAME 29 174b5bfcb5dSMax Laier #define DH6OPT_NISP_NAME 30 1753c602fabSXin LI #define DH6OPT_SNTP_SERVERS 31 176b5bfcb5dSMax Laier #define DH6OPT_LIFETIME 32 177b5bfcb5dSMax Laier #define DH6OPT_BCMCS_SERVER_D 33 178b5bfcb5dSMax Laier #define DH6OPT_BCMCS_SERVER_A 34 179b5bfcb5dSMax Laier #define DH6OPT_GEOCONF_CIVIC 36 180b5bfcb5dSMax Laier #define DH6OPT_REMOTE_ID 37 181b5bfcb5dSMax Laier #define DH6OPT_SUBSCRIBER_ID 38 182b5bfcb5dSMax Laier #define DH6OPT_CLIENT_FQDN 39 183a5779b6eSRui Paulo #define DH6OPT_PANA_AGENT 40 184a5779b6eSRui Paulo #define DH6OPT_NEW_POSIX_TIMEZONE 41 185a5779b6eSRui Paulo #define DH6OPT_NEW_TZDB_TIMEZONE 42 186a5779b6eSRui Paulo #define DH6OPT_ERO 43 187a5779b6eSRui Paulo #define DH6OPT_LQ_QUERY 44 188a5779b6eSRui Paulo #define DH6OPT_CLIENT_DATA 45 189a5779b6eSRui Paulo #define DH6OPT_CLT_TIME 46 190a5779b6eSRui Paulo #define DH6OPT_LQ_RELAY_DATA 47 191a5779b6eSRui Paulo #define DH6OPT_LQ_CLIENT_LINK 48 1923c602fabSXin LI #define DH6OPT_NTP_SERVER 56 1933c602fabSXin LI # define DH6OPT_NTP_SUBOPTION_SRV_ADDR 1 1943c602fabSXin LI # define DH6OPT_NTP_SUBOPTION_MC_ADDR 2 1953c602fabSXin LI # define DH6OPT_NTP_SUBOPTION_SRV_FQDN 3 196d03c0883SXin LI #define DH6OPT_AFTR_NAME 64 1973340d773SGleb Smirnoff #define DH6OPT_MUDURL 112 1985b0fe478SBruce M Simpson 1993c602fabSXin LI static const struct tok dh6opt_str[] = { 2003c602fabSXin LI { DH6OPT_CLIENTID, "client-ID" }, 2013c602fabSXin LI { DH6OPT_SERVERID, "server-ID" }, 2023c602fabSXin LI { DH6OPT_IA_NA, "IA_NA" }, 2033c602fabSXin LI { DH6OPT_IA_TA, "IA_TA" }, 2043c602fabSXin LI { DH6OPT_IA_ADDR, "IA_ADDR" }, 2053c602fabSXin LI { DH6OPT_ORO, "option-request" }, 2063c602fabSXin LI { DH6OPT_PREFERENCE, "preference" }, 2073c602fabSXin LI { DH6OPT_ELAPSED_TIME, "elapsed-time" }, 2083c602fabSXin LI { DH6OPT_RELAY_MSG, "relay-message" }, 2093c602fabSXin LI { DH6OPT_AUTH, "authentication" }, 2103c602fabSXin LI { DH6OPT_UNICAST, "server-unicast" }, 2113c602fabSXin LI { DH6OPT_STATUS_CODE, "status-code" }, 2123c602fabSXin LI { DH6OPT_RAPID_COMMIT, "rapid-commit" }, 2133c602fabSXin LI { DH6OPT_USER_CLASS, "user-class" }, 2143c602fabSXin LI { DH6OPT_VENDOR_CLASS, "vendor-class" }, 2153c602fabSXin LI { DH6OPT_VENDOR_OPTS, "vendor-specific-info" }, 2163c602fabSXin LI { DH6OPT_INTERFACE_ID, "interface-ID" }, 2173c602fabSXin LI { DH6OPT_RECONF_MSG, "reconfigure-message" }, 2183c602fabSXin LI { DH6OPT_RECONF_ACCEPT, "reconfigure-accept" }, 2193c602fabSXin LI { DH6OPT_SIP_SERVER_D, "SIP-servers-domain" }, 2203c602fabSXin LI { DH6OPT_SIP_SERVER_A, "SIP-servers-address" }, 2213c602fabSXin LI { DH6OPT_DNS_SERVERS, "DNS-server" }, 2223c602fabSXin LI { DH6OPT_DOMAIN_LIST, "DNS-search-list" }, 2233c602fabSXin LI { DH6OPT_IA_PD, "IA_PD" }, 2243c602fabSXin LI { DH6OPT_IA_PD_PREFIX, "IA_PD-prefix" }, 2253c602fabSXin LI { DH6OPT_SNTP_SERVERS, "SNTP-servers" }, 2263c602fabSXin LI { DH6OPT_LIFETIME, "lifetime" }, 2273c602fabSXin LI { DH6OPT_NIS_SERVERS, "NIS-server" }, 2283c602fabSXin LI { DH6OPT_NISP_SERVERS, "NIS+-server" }, 2293c602fabSXin LI { DH6OPT_NIS_NAME, "NIS-domain-name" }, 2303c602fabSXin LI { DH6OPT_NISP_NAME, "NIS+-domain-name" }, 2313c602fabSXin LI { DH6OPT_BCMCS_SERVER_D, "BCMCS-domain-name" }, 2323c602fabSXin LI { DH6OPT_BCMCS_SERVER_A, "BCMCS-server" }, 2333c602fabSXin LI { DH6OPT_GEOCONF_CIVIC, "Geoconf-Civic" }, 2343c602fabSXin LI { DH6OPT_REMOTE_ID, "Remote-ID" }, 2353c602fabSXin LI { DH6OPT_SUBSCRIBER_ID, "Subscriber-ID" }, 2363c602fabSXin LI { DH6OPT_CLIENT_FQDN, "Client-FQDN" }, 2373c602fabSXin LI { DH6OPT_PANA_AGENT, "PANA-agent" }, 2383c602fabSXin LI { DH6OPT_NEW_POSIX_TIMEZONE, "POSIX-timezone" }, 2393c602fabSXin LI { DH6OPT_NEW_TZDB_TIMEZONE, "POSIX-tz-database" }, 2403c602fabSXin LI { DH6OPT_ERO, "Echo-request-option" }, 2413c602fabSXin LI { DH6OPT_LQ_QUERY, "Lease-query" }, 2423c602fabSXin LI { DH6OPT_CLIENT_DATA, "LQ-client-data" }, 2433c602fabSXin LI { DH6OPT_CLT_TIME, "Clt-time" }, 2443c602fabSXin LI { DH6OPT_LQ_RELAY_DATA, "LQ-relay-data" }, 2453c602fabSXin LI { DH6OPT_LQ_CLIENT_LINK, "LQ-client-link" }, 2463c602fabSXin LI { DH6OPT_NTP_SERVER, "NTP-server" }, 2473c602fabSXin LI { DH6OPT_AFTR_NAME, "AFTR-Name" }, 2483340d773SGleb Smirnoff { DH6OPT_MUDURL, "MUD-URL" }, 2493c602fabSXin LI { 0, NULL } 2503c602fabSXin LI }; 2513c602fabSXin LI 2523c602fabSXin LI static const struct tok dh6opt_stcode_str[] = { 2533340d773SGleb Smirnoff { DH6OPT_STCODE_SUCCESS, "Success" }, /* RFC3315 */ 2543340d773SGleb Smirnoff { DH6OPT_STCODE_UNSPECFAIL, "UnspecFail" }, /* RFC3315 */ 2553340d773SGleb Smirnoff { DH6OPT_STCODE_NOADDRAVAIL, "NoAddrsAvail" }, /* RFC3315 */ 2563340d773SGleb Smirnoff { DH6OPT_STCODE_NOBINDING, "NoBinding" }, /* RFC3315 */ 2573340d773SGleb Smirnoff { DH6OPT_STCODE_NOTONLINK, "NotOnLink" }, /* RFC3315 */ 2583340d773SGleb Smirnoff { DH6OPT_STCODE_USEMULTICAST, "UseMulticast" }, /* RFC3315 */ 2593340d773SGleb Smirnoff { DH6OPT_STCODE_NOPREFIXAVAIL, "NoPrefixAvail" }, /* RFC3633 */ 2603340d773SGleb Smirnoff { DH6OPT_STCODE_UNKNOWNQUERYTYPE, "UnknownQueryType" }, /* RFC5007 */ 2613340d773SGleb Smirnoff { DH6OPT_STCODE_MALFORMEDQUERY, "MalformedQuery" }, /* RFC5007 */ 2623340d773SGleb Smirnoff { DH6OPT_STCODE_NOTCONFIGURED, "NotConfigured" }, /* RFC5007 */ 2633340d773SGleb Smirnoff { DH6OPT_STCODE_NOTALLOWED, "NotAllowed" }, /* RFC5007 */ 2643c602fabSXin LI { 0, NULL } 2653c602fabSXin LI }; 2663c602fabSXin LI 2679afd0c29SBill Fenner struct dhcp6opt { 2683340d773SGleb Smirnoff nd_uint16_t dh6opt_type; 2693340d773SGleb Smirnoff nd_uint16_t dh6opt_len; 2709afd0c29SBill Fenner /* type-dependent data follows */ 2715b0fe478SBruce M Simpson }; 2725b0fe478SBruce M Simpson 2735b0fe478SBruce M Simpson static const char * 2743c602fabSXin LI dhcp6stcode(const uint16_t code) 2755b0fe478SBruce M Simpson { 2763c602fabSXin LI return code > 255 ? "INVALID code" : tok2str(dh6opt_stcode_str, "code%u", code); 2775b0fe478SBruce M Simpson } 2785b0fe478SBruce M Simpson 279b0453382SBill Fenner static void 2803c602fabSXin LI dhcp6opt_print(netdissect_options *ndo, 2813c602fabSXin LI const u_char *cp, const u_char *ep) 282b0453382SBill Fenner { 2833c602fabSXin LI const struct dhcp6opt *dh6o; 2843c602fabSXin LI const u_char *tp; 2855b0fe478SBruce M Simpson size_t i; 2863c602fabSXin LI uint16_t opttype; 2879afd0c29SBill Fenner size_t optlen; 2883c602fabSXin LI uint8_t auth_proto; 2891de50e9fSSam Leffler u_int authinfolen, authrealmlen; 2903c602fabSXin LI int remain_len; /* Length of remaining options */ 2913c602fabSXin LI int label_len; /* Label length */ 2923c602fabSXin LI uint16_t subopt_code; 2933c602fabSXin LI uint16_t subopt_len; 294b0453382SBill Fenner 295b0453382SBill Fenner if (cp == ep) 296b0453382SBill Fenner return; 297b0453382SBill Fenner while (cp < ep) { 2985b0fe478SBruce M Simpson if (ep < cp + sizeof(*dh6o)) 299b0453382SBill Fenner goto trunc; 3003340d773SGleb Smirnoff dh6o = (const struct dhcp6opt *)cp; 3013c602fabSXin LI ND_TCHECK(*dh6o); 3025b0fe478SBruce M Simpson optlen = EXTRACT_16BITS(&dh6o->dh6opt_len); 3035b0fe478SBruce M Simpson if (ep < cp + sizeof(*dh6o) + optlen) 304b0453382SBill Fenner goto trunc; 3055b0fe478SBruce M Simpson opttype = EXTRACT_16BITS(&dh6o->dh6opt_type); 3063c602fabSXin LI ND_PRINT((ndo, " (%s", tok2str(dh6opt_str, "opt_%u", opttype))); 3073340d773SGleb Smirnoff ND_TCHECK2(*(cp + sizeof(*dh6o)), optlen); 3085b0fe478SBruce M Simpson switch (opttype) { 3095b0fe478SBruce M Simpson case DH6OPT_CLIENTID: 3105b0fe478SBruce M Simpson case DH6OPT_SERVERID: 3119afd0c29SBill Fenner if (optlen < 2) { 3129afd0c29SBill Fenner /*(*/ 3133c602fabSXin LI ND_PRINT((ndo, " ?)")); 314b0453382SBill Fenner break; 315b0453382SBill Fenner } 3163340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 3175b0fe478SBruce M Simpson switch (EXTRACT_16BITS(tp)) { 3189afd0c29SBill Fenner case 1: 3199afd0c29SBill Fenner if (optlen >= 2 + 6) { 3203c602fabSXin LI ND_PRINT((ndo, " hwaddr/time type %u time %u ", 3215b0fe478SBruce M Simpson EXTRACT_16BITS(&tp[2]), 3223c602fabSXin LI EXTRACT_32BITS(&tp[4]))); 3239afd0c29SBill Fenner for (i = 8; i < optlen; i++) 3243c602fabSXin LI ND_PRINT((ndo, "%02x", tp[i])); 3259afd0c29SBill Fenner /*(*/ 3263c602fabSXin LI ND_PRINT((ndo, ")")); 3279afd0c29SBill Fenner } else { 3289afd0c29SBill Fenner /*(*/ 3293c602fabSXin LI ND_PRINT((ndo, " ?)")); 3309afd0c29SBill Fenner } 3319afd0c29SBill Fenner break; 3329afd0c29SBill Fenner case 2: 3339afd0c29SBill Fenner if (optlen >= 2 + 8) { 3343c602fabSXin LI ND_PRINT((ndo, " vid ")); 3359afd0c29SBill Fenner for (i = 2; i < 2 + 8; i++) 3363c602fabSXin LI ND_PRINT((ndo, "%02x", tp[i])); 3379afd0c29SBill Fenner /*(*/ 3383c602fabSXin LI ND_PRINT((ndo, ")")); 3399afd0c29SBill Fenner } else { 3409afd0c29SBill Fenner /*(*/ 3413c602fabSXin LI ND_PRINT((ndo, " ?)")); 3429afd0c29SBill Fenner } 3439afd0c29SBill Fenner break; 3449afd0c29SBill Fenner case 3: 3459afd0c29SBill Fenner if (optlen >= 2 + 2) { 3463c602fabSXin LI ND_PRINT((ndo, " hwaddr type %u ", 3473c602fabSXin LI EXTRACT_16BITS(&tp[2]))); 3489afd0c29SBill Fenner for (i = 4; i < optlen; i++) 3493c602fabSXin LI ND_PRINT((ndo, "%02x", tp[i])); 3509afd0c29SBill Fenner /*(*/ 3513c602fabSXin LI ND_PRINT((ndo, ")")); 3529afd0c29SBill Fenner } else { 3539afd0c29SBill Fenner /*(*/ 3543c602fabSXin LI ND_PRINT((ndo, " ?)")); 3559afd0c29SBill Fenner } 3569afd0c29SBill Fenner break; 3575b0fe478SBruce M Simpson default: 3583c602fabSXin LI ND_PRINT((ndo, " type %d)", EXTRACT_16BITS(tp))); 3595b0fe478SBruce M Simpson break; 3605b0fe478SBruce M Simpson } 3615b0fe478SBruce M Simpson break; 362b5bfcb5dSMax Laier case DH6OPT_IA_ADDR: 36327df3f5dSRui Paulo if (optlen < 24) { 36427df3f5dSRui Paulo /*(*/ 3653c602fabSXin LI ND_PRINT((ndo, " ?)")); 366b5bfcb5dSMax Laier break; 367b5bfcb5dSMax Laier } 3683340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 3693c602fabSXin LI ND_PRINT((ndo, " %s", ip6addr_string(ndo, &tp[0]))); 3703c602fabSXin LI ND_PRINT((ndo, " pltime:%u vltime:%u", 37127df3f5dSRui Paulo EXTRACT_32BITS(&tp[16]), 3723c602fabSXin LI EXTRACT_32BITS(&tp[20]))); 37327df3f5dSRui Paulo if (optlen > 24) { 374b5bfcb5dSMax Laier /* there are sub-options */ 3753c602fabSXin LI dhcp6opt_print(ndo, tp + 24, tp + optlen); 376b5bfcb5dSMax Laier } 3773c602fabSXin LI ND_PRINT((ndo, ")")); 378b5bfcb5dSMax Laier break; 3795b0fe478SBruce M Simpson case DH6OPT_ORO: 380a5779b6eSRui Paulo case DH6OPT_ERO: 3815b0fe478SBruce M Simpson if (optlen % 2) { 3823c602fabSXin LI ND_PRINT((ndo, " ?)")); 3835b0fe478SBruce M Simpson break; 3845b0fe478SBruce M Simpson } 3853340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 3865b0fe478SBruce M Simpson for (i = 0; i < optlen; i += 2) { 3873c602fabSXin LI ND_PRINT((ndo, " %s", 3883c602fabSXin LI tok2str(dh6opt_str, "opt_%u", EXTRACT_16BITS(&tp[i])))); 3895b0fe478SBruce M Simpson } 3903c602fabSXin LI ND_PRINT((ndo, ")")); 3915b0fe478SBruce M Simpson break; 3925b0fe478SBruce M Simpson case DH6OPT_PREFERENCE: 3935b0fe478SBruce M Simpson if (optlen != 1) { 3943c602fabSXin LI ND_PRINT((ndo, " ?)")); 3955b0fe478SBruce M Simpson break; 3965b0fe478SBruce M Simpson } 3973340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 3983c602fabSXin LI ND_PRINT((ndo, " %d)", *tp)); 3995b0fe478SBruce M Simpson break; 4005b0fe478SBruce M Simpson case DH6OPT_ELAPSED_TIME: 4015b0fe478SBruce M Simpson if (optlen != 2) { 4023c602fabSXin LI ND_PRINT((ndo, " ?)")); 4035b0fe478SBruce M Simpson break; 4045b0fe478SBruce M Simpson } 4053340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 4063c602fabSXin LI ND_PRINT((ndo, " %d)", EXTRACT_16BITS(tp))); 4075b0fe478SBruce M Simpson break; 4085b0fe478SBruce M Simpson case DH6OPT_RELAY_MSG: 4093c602fabSXin LI ND_PRINT((ndo, " (")); 4103340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 4113c602fabSXin LI dhcp6_print(ndo, tp, optlen); 4123c602fabSXin LI ND_PRINT((ndo, ")")); 4135b0fe478SBruce M Simpson break; 4141de50e9fSSam Leffler case DH6OPT_AUTH: 41527df3f5dSRui Paulo if (optlen < 11) { 4163c602fabSXin LI ND_PRINT((ndo, " ?)")); 4171de50e9fSSam Leffler break; 4181de50e9fSSam Leffler } 4193340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 42027df3f5dSRui Paulo auth_proto = *tp; 42127df3f5dSRui Paulo switch (auth_proto) { 4221de50e9fSSam Leffler case DH6OPT_AUTHPROTO_DELAYED: 4233c602fabSXin LI ND_PRINT((ndo, " proto: delayed")); 4241de50e9fSSam Leffler break; 4251de50e9fSSam Leffler case DH6OPT_AUTHPROTO_RECONFIG: 4263c602fabSXin LI ND_PRINT((ndo, " proto: reconfigure")); 4271de50e9fSSam Leffler break; 4281de50e9fSSam Leffler default: 4293c602fabSXin LI ND_PRINT((ndo, " proto: %d", auth_proto)); 4301de50e9fSSam Leffler break; 4311de50e9fSSam Leffler } 43227df3f5dSRui Paulo tp++; 43327df3f5dSRui Paulo switch (*tp) { 4341de50e9fSSam Leffler case DH6OPT_AUTHALG_HMACMD5: 4351de50e9fSSam Leffler /* XXX: may depend on the protocol */ 4363c602fabSXin LI ND_PRINT((ndo, ", alg: HMAC-MD5")); 4371de50e9fSSam Leffler break; 4381de50e9fSSam Leffler default: 4393c602fabSXin LI ND_PRINT((ndo, ", alg: %d", *tp)); 4401de50e9fSSam Leffler break; 4411de50e9fSSam Leffler } 44227df3f5dSRui Paulo tp++; 44327df3f5dSRui Paulo switch (*tp) { 4441de50e9fSSam Leffler case DH6OPT_AUTHRDM_MONOCOUNTER: 4453c602fabSXin LI ND_PRINT((ndo, ", RDM: mono")); 4461de50e9fSSam Leffler break; 4471de50e9fSSam Leffler default: 4483c602fabSXin LI ND_PRINT((ndo, ", RDM: %d", *tp)); 4491de50e9fSSam Leffler break; 4501de50e9fSSam Leffler } 45127df3f5dSRui Paulo tp++; 4523c602fabSXin LI ND_PRINT((ndo, ", RD:")); 45327df3f5dSRui Paulo for (i = 0; i < 4; i++, tp += 2) 4543c602fabSXin LI ND_PRINT((ndo, " %04x", EXTRACT_16BITS(tp))); 4551de50e9fSSam Leffler 4561de50e9fSSam Leffler /* protocol dependent part */ 45727df3f5dSRui Paulo authinfolen = optlen - 11; 45827df3f5dSRui Paulo switch (auth_proto) { 4591de50e9fSSam Leffler case DH6OPT_AUTHPROTO_DELAYED: 4601de50e9fSSam Leffler if (authinfolen == 0) 4611de50e9fSSam Leffler break; 4621de50e9fSSam Leffler if (authinfolen < 20) { 4633c602fabSXin LI ND_PRINT((ndo, " ??")); 4641de50e9fSSam Leffler break; 4651de50e9fSSam Leffler } 4661de50e9fSSam Leffler authrealmlen = authinfolen - 20; 4671de50e9fSSam Leffler if (authrealmlen > 0) { 4683c602fabSXin LI ND_PRINT((ndo, ", realm: ")); 4691de50e9fSSam Leffler } 4701de50e9fSSam Leffler for (i = 0; i < authrealmlen; i++, tp++) 4713c602fabSXin LI ND_PRINT((ndo, "%02x", *tp)); 4723c602fabSXin LI ND_PRINT((ndo, ", key ID: %08x", EXTRACT_32BITS(tp))); 4731de50e9fSSam Leffler tp += 4; 4743c602fabSXin LI ND_PRINT((ndo, ", HMAC-MD5:")); 4751de50e9fSSam Leffler for (i = 0; i < 4; i++, tp+= 4) 4763c602fabSXin LI ND_PRINT((ndo, " %08x", EXTRACT_32BITS(tp))); 4771de50e9fSSam Leffler break; 4781de50e9fSSam Leffler case DH6OPT_AUTHPROTO_RECONFIG: 4791de50e9fSSam Leffler if (authinfolen != 17) { 4803c602fabSXin LI ND_PRINT((ndo, " ??")); 4811de50e9fSSam Leffler break; 4821de50e9fSSam Leffler } 4831de50e9fSSam Leffler switch (*tp++) { 4841de50e9fSSam Leffler case DH6OPT_AUTHRECONFIG_KEY: 4853c602fabSXin LI ND_PRINT((ndo, " reconfig-key")); 4861de50e9fSSam Leffler break; 4871de50e9fSSam Leffler case DH6OPT_AUTHRECONFIG_HMACMD5: 4883c602fabSXin LI ND_PRINT((ndo, " type: HMAC-MD5")); 4891de50e9fSSam Leffler break; 4901de50e9fSSam Leffler default: 4913c602fabSXin LI ND_PRINT((ndo, " type: ??")); 4921de50e9fSSam Leffler break; 4931de50e9fSSam Leffler } 4943c602fabSXin LI ND_PRINT((ndo, " value:")); 4951de50e9fSSam Leffler for (i = 0; i < 4; i++, tp+= 4) 4963c602fabSXin LI ND_PRINT((ndo, " %08x", EXTRACT_32BITS(tp))); 4971de50e9fSSam Leffler break; 4981de50e9fSSam Leffler default: 4993c602fabSXin LI ND_PRINT((ndo, " ??")); 5001de50e9fSSam Leffler break; 5011de50e9fSSam Leffler } 5021de50e9fSSam Leffler 5033c602fabSXin LI ND_PRINT((ndo, ")")); 5041de50e9fSSam Leffler break; 5055b0fe478SBruce M Simpson case DH6OPT_RAPID_COMMIT: /* nothing todo */ 5063c602fabSXin LI ND_PRINT((ndo, ")")); 5075b0fe478SBruce M Simpson break; 5085b0fe478SBruce M Simpson case DH6OPT_INTERFACE_ID: 509a5779b6eSRui Paulo case DH6OPT_SUBSCRIBER_ID: 5105b0fe478SBruce M Simpson /* 5115b0fe478SBruce M Simpson * Since we cannot predict the encoding, print hex dump 5125b0fe478SBruce M Simpson * at most 10 characters. 5135b0fe478SBruce M Simpson */ 5143340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 5153c602fabSXin LI ND_PRINT((ndo, " ")); 5165b0fe478SBruce M Simpson for (i = 0; i < optlen && i < 10; i++) 5173c602fabSXin LI ND_PRINT((ndo, "%02x", tp[i])); 5183c602fabSXin LI ND_PRINT((ndo, "...)")); 5195b0fe478SBruce M Simpson break; 5205b0fe478SBruce M Simpson case DH6OPT_RECONF_MSG: 521*0bff6a5aSEd Maste if (optlen != 1) { 522*0bff6a5aSEd Maste ND_PRINT((ndo, " ?)")); 523*0bff6a5aSEd Maste break; 524*0bff6a5aSEd Maste } 5253340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 5265b0fe478SBruce M Simpson switch (*tp) { 5275b0fe478SBruce M Simpson case DH6_RENEW: 5283c602fabSXin LI ND_PRINT((ndo, " for renew)")); 5295b0fe478SBruce M Simpson break; 5305b0fe478SBruce M Simpson case DH6_INFORM_REQ: 5313c602fabSXin LI ND_PRINT((ndo, " for inf-req)")); 5325b0fe478SBruce M Simpson break; 5335b0fe478SBruce M Simpson default: 5343c602fabSXin LI ND_PRINT((ndo, " for ?\?\?(%02x))", *tp)); 5355b0fe478SBruce M Simpson break; 5365b0fe478SBruce M Simpson } 5375b0fe478SBruce M Simpson break; 5385b0fe478SBruce M Simpson case DH6OPT_RECONF_ACCEPT: /* nothing todo */ 5393c602fabSXin LI ND_PRINT((ndo, ")")); 5405b0fe478SBruce M Simpson break; 5415b0fe478SBruce M Simpson case DH6OPT_SIP_SERVER_A: 5423c602fabSXin LI case DH6OPT_DNS_SERVERS: 5433c602fabSXin LI case DH6OPT_SNTP_SERVERS: 544b5bfcb5dSMax Laier case DH6OPT_NIS_SERVERS: 545b5bfcb5dSMax Laier case DH6OPT_NISP_SERVERS: 546b5bfcb5dSMax Laier case DH6OPT_BCMCS_SERVER_A: 547a5779b6eSRui Paulo case DH6OPT_PANA_AGENT: 548a5779b6eSRui Paulo case DH6OPT_LQ_CLIENT_LINK: 5499afd0c29SBill Fenner if (optlen % 16) { 5503c602fabSXin LI ND_PRINT((ndo, " ?)")); 5519afd0c29SBill Fenner break; 5529afd0c29SBill Fenner } 5533340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 5549afd0c29SBill Fenner for (i = 0; i < optlen; i += 16) 5553c602fabSXin LI ND_PRINT((ndo, " %s", ip6addr_string(ndo, &tp[i]))); 5563c602fabSXin LI ND_PRINT((ndo, ")")); 5573c602fabSXin LI break; 5583c602fabSXin LI case DH6OPT_SIP_SERVER_D: 5593c602fabSXin LI case DH6OPT_DOMAIN_LIST: 5603340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 5613c602fabSXin LI while (tp < cp + sizeof(*dh6o) + optlen) { 5623c602fabSXin LI ND_PRINT((ndo, " ")); 5633c602fabSXin LI if ((tp = ns_nprint(ndo, tp, cp + sizeof(*dh6o) + optlen)) == NULL) 5643c602fabSXin LI goto trunc; 5653c602fabSXin LI } 5663c602fabSXin LI ND_PRINT((ndo, ")")); 5675b0fe478SBruce M Simpson break; 5685b0fe478SBruce M Simpson case DH6OPT_STATUS_CODE: 5695b0fe478SBruce M Simpson if (optlen < 2) { 5703c602fabSXin LI ND_PRINT((ndo, " ?)")); 5715b0fe478SBruce M Simpson break; 5725b0fe478SBruce M Simpson } 5733340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 5743c602fabSXin LI ND_PRINT((ndo, " %s)", dhcp6stcode(EXTRACT_16BITS(&tp[0])))); 5755b0fe478SBruce M Simpson break; 5765b0fe478SBruce M Simpson case DH6OPT_IA_NA: 5775b0fe478SBruce M Simpson case DH6OPT_IA_PD: 57827df3f5dSRui Paulo if (optlen < 12) { 5793c602fabSXin LI ND_PRINT((ndo, " ?)")); 5805b0fe478SBruce M Simpson break; 5815b0fe478SBruce M Simpson } 5823340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 5833c602fabSXin LI ND_PRINT((ndo, " IAID:%u T1:%u T2:%u", 58427df3f5dSRui Paulo EXTRACT_32BITS(&tp[0]), 58527df3f5dSRui Paulo EXTRACT_32BITS(&tp[4]), 5863c602fabSXin LI EXTRACT_32BITS(&tp[8]))); 58727df3f5dSRui Paulo if (optlen > 12) { 5885b0fe478SBruce M Simpson /* there are sub-options */ 5893c602fabSXin LI dhcp6opt_print(ndo, tp + 12, tp + optlen); 5905b0fe478SBruce M Simpson } 5913c602fabSXin LI ND_PRINT((ndo, ")")); 5925b0fe478SBruce M Simpson break; 593a5779b6eSRui Paulo case DH6OPT_IA_TA: 594a5779b6eSRui Paulo if (optlen < 4) { 5953c602fabSXin LI ND_PRINT((ndo, " ?)")); 596a5779b6eSRui Paulo break; 597a5779b6eSRui Paulo } 5983340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 5993c602fabSXin LI ND_PRINT((ndo, " IAID:%u", EXTRACT_32BITS(tp))); 600a5779b6eSRui Paulo if (optlen > 4) { 601a5779b6eSRui Paulo /* there are sub-options */ 6023c602fabSXin LI dhcp6opt_print(ndo, tp + 4, tp + optlen); 603a5779b6eSRui Paulo } 6043c602fabSXin LI ND_PRINT((ndo, ")")); 605a5779b6eSRui Paulo break; 6065b0fe478SBruce M Simpson case DH6OPT_IA_PD_PREFIX: 60727df3f5dSRui Paulo if (optlen < 25) { 6083c602fabSXin LI ND_PRINT((ndo, " ?)")); 6095b0fe478SBruce M Simpson break; 6105b0fe478SBruce M Simpson } 6113340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 6123c602fabSXin LI ND_PRINT((ndo, " %s/%d", ip6addr_string(ndo, &tp[9]), tp[8])); 6133c602fabSXin LI ND_PRINT((ndo, " pltime:%u vltime:%u", 61427df3f5dSRui Paulo EXTRACT_32BITS(&tp[0]), 6153c602fabSXin LI EXTRACT_32BITS(&tp[4]))); 61627df3f5dSRui Paulo if (optlen > 25) { 6175b0fe478SBruce M Simpson /* there are sub-options */ 6183c602fabSXin LI dhcp6opt_print(ndo, tp + 25, tp + optlen); 6195b0fe478SBruce M Simpson } 6203c602fabSXin LI ND_PRINT((ndo, ")")); 6215b0fe478SBruce M Simpson break; 6221de50e9fSSam Leffler case DH6OPT_LIFETIME: 623a5779b6eSRui Paulo case DH6OPT_CLT_TIME: 6241de50e9fSSam Leffler if (optlen != 4) { 6253c602fabSXin LI ND_PRINT((ndo, " ?)")); 6261de50e9fSSam Leffler break; 6271de50e9fSSam Leffler } 6283340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 6293c602fabSXin LI ND_PRINT((ndo, " %d)", EXTRACT_32BITS(tp))); 6301de50e9fSSam Leffler break; 631a5779b6eSRui Paulo case DH6OPT_REMOTE_ID: 632a5779b6eSRui Paulo if (optlen < 4) { 6333c602fabSXin LI ND_PRINT((ndo, " ?)")); 634a5779b6eSRui Paulo break; 635a5779b6eSRui Paulo } 6363340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 6373c602fabSXin LI ND_PRINT((ndo, " %d ", EXTRACT_32BITS(tp))); 638a5779b6eSRui Paulo /* 639a5779b6eSRui Paulo * Print hex dump first 10 characters. 640a5779b6eSRui Paulo */ 641a5779b6eSRui Paulo for (i = 4; i < optlen && i < 14; i++) 6423c602fabSXin LI ND_PRINT((ndo, "%02x", tp[i])); 6433c602fabSXin LI ND_PRINT((ndo, "...)")); 644a5779b6eSRui Paulo break; 645a5779b6eSRui Paulo case DH6OPT_LQ_QUERY: 646a5779b6eSRui Paulo if (optlen < 17) { 6473c602fabSXin LI ND_PRINT((ndo, " ?)")); 648a5779b6eSRui Paulo break; 649a5779b6eSRui Paulo } 6503340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 651a5779b6eSRui Paulo switch (*tp) { 652a5779b6eSRui Paulo case 1: 6533c602fabSXin LI ND_PRINT((ndo, " by-address")); 654a5779b6eSRui Paulo break; 655a5779b6eSRui Paulo case 2: 6563c602fabSXin LI ND_PRINT((ndo, " by-clientID")); 657a5779b6eSRui Paulo break; 658a5779b6eSRui Paulo default: 6593c602fabSXin LI ND_PRINT((ndo, " type_%d", (int)*tp)); 660a5779b6eSRui Paulo break; 661a5779b6eSRui Paulo } 6623c602fabSXin LI ND_PRINT((ndo, " %s", ip6addr_string(ndo, &tp[1]))); 663a5779b6eSRui Paulo if (optlen > 17) { 664a5779b6eSRui Paulo /* there are query-options */ 6653c602fabSXin LI dhcp6opt_print(ndo, tp + 17, tp + optlen); 666a5779b6eSRui Paulo } 6673c602fabSXin LI ND_PRINT((ndo, ")")); 668a5779b6eSRui Paulo break; 669a5779b6eSRui Paulo case DH6OPT_CLIENT_DATA: 6703340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 671a5779b6eSRui Paulo if (optlen > 0) { 672a5779b6eSRui Paulo /* there are encapsulated options */ 6733c602fabSXin LI dhcp6opt_print(ndo, tp, tp + optlen); 674a5779b6eSRui Paulo } 6753c602fabSXin LI ND_PRINT((ndo, ")")); 676a5779b6eSRui Paulo break; 677a5779b6eSRui Paulo case DH6OPT_LQ_RELAY_DATA: 678a5779b6eSRui Paulo if (optlen < 16) { 6793c602fabSXin LI ND_PRINT((ndo, " ?)")); 680a5779b6eSRui Paulo break; 681a5779b6eSRui Paulo } 6823340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 6833c602fabSXin LI ND_PRINT((ndo, " %s ", ip6addr_string(ndo, &tp[0]))); 684a5779b6eSRui Paulo /* 685a5779b6eSRui Paulo * Print hex dump first 10 characters. 686a5779b6eSRui Paulo */ 687a5779b6eSRui Paulo for (i = 16; i < optlen && i < 26; i++) 6883c602fabSXin LI ND_PRINT((ndo, "%02x", tp[i])); 6893c602fabSXin LI ND_PRINT((ndo, "...)")); 690a5779b6eSRui Paulo break; 6913c602fabSXin LI case DH6OPT_NTP_SERVER: 6923c602fabSXin LI if (optlen < 4) { 6933c602fabSXin LI ND_PRINT((ndo, " ?)")); 694d03c0883SXin LI break; 695d03c0883SXin LI } 6963340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 6973c602fabSXin LI while (tp < cp + sizeof(*dh6o) + optlen - 4) { 6983c602fabSXin LI subopt_code = EXTRACT_16BITS(tp); 6993c602fabSXin LI tp += 2; 7003c602fabSXin LI subopt_len = EXTRACT_16BITS(tp); 7013c602fabSXin LI tp += 2; 7023c602fabSXin LI if (tp + subopt_len > cp + sizeof(*dh6o) + optlen) 7033c602fabSXin LI goto trunc; 7043c602fabSXin LI ND_PRINT((ndo, " subopt:%d", subopt_code)); 7053c602fabSXin LI switch (subopt_code) { 7063c602fabSXin LI case DH6OPT_NTP_SUBOPTION_SRV_ADDR: 7073c602fabSXin LI case DH6OPT_NTP_SUBOPTION_MC_ADDR: 7083c602fabSXin LI if (subopt_len != 16) { 7093c602fabSXin LI ND_PRINT((ndo, " ?")); 7103c602fabSXin LI break; 7113c602fabSXin LI } 7123c602fabSXin LI ND_PRINT((ndo, " %s", ip6addr_string(ndo, &tp[0]))); 7133c602fabSXin LI break; 7143c602fabSXin LI case DH6OPT_NTP_SUBOPTION_SRV_FQDN: 7153c602fabSXin LI ND_PRINT((ndo, " ")); 7163c602fabSXin LI if (ns_nprint(ndo, tp, tp + subopt_len) == NULL) 7173c602fabSXin LI goto trunc; 7183c602fabSXin LI break; 7193c602fabSXin LI default: 7203c602fabSXin LI ND_PRINT((ndo, " ?")); 7213c602fabSXin LI break; 7223c602fabSXin LI } 7233c602fabSXin LI tp += subopt_len; 7243c602fabSXin LI } 7253c602fabSXin LI ND_PRINT((ndo, ")")); 7263c602fabSXin LI break; 7273c602fabSXin LI case DH6OPT_AFTR_NAME: 7283c602fabSXin LI if (optlen < 3) { 7293c602fabSXin LI ND_PRINT((ndo, " ?)")); 7303c602fabSXin LI break; 7313c602fabSXin LI } 7323340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 7333c602fabSXin LI remain_len = optlen; 7343c602fabSXin LI ND_PRINT((ndo, " ")); 735d03c0883SXin LI /* Encoding is described in section 3.1 of RFC 1035 */ 736d03c0883SXin LI while (remain_len && *tp) { 737d03c0883SXin LI label_len = *tp++; 738d03c0883SXin LI if (label_len < remain_len - 1) { 7393340d773SGleb Smirnoff (void)fn_printn(ndo, tp, label_len, NULL); 740d03c0883SXin LI tp += label_len; 741d03c0883SXin LI remain_len -= (label_len + 1); 7423c602fabSXin LI if(*tp) ND_PRINT((ndo, ".")); 743d03c0883SXin LI } else { 7443c602fabSXin LI ND_PRINT((ndo, " ?")); 745d03c0883SXin LI break; 746d03c0883SXin LI } 747d03c0883SXin LI } 7483c602fabSXin LI ND_PRINT((ndo, ")")); 749d03c0883SXin LI break; 7503340d773SGleb Smirnoff case DH6OPT_NEW_POSIX_TIMEZONE: /* all three of these options */ 7513340d773SGleb Smirnoff case DH6OPT_NEW_TZDB_TIMEZONE: /* are encoded similarly */ 7523340d773SGleb Smirnoff case DH6OPT_MUDURL: /* although GMT might not work */ 7533340d773SGleb Smirnoff if (optlen < 5) { 7543340d773SGleb Smirnoff ND_PRINT((ndo, " ?)")); 7553340d773SGleb Smirnoff break; 7563340d773SGleb Smirnoff } 7573340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 7583340d773SGleb Smirnoff ND_PRINT((ndo, "=")); 7593340d773SGleb Smirnoff (void)fn_printn(ndo, tp, (u_int)optlen, NULL); 7603340d773SGleb Smirnoff ND_PRINT((ndo, ")")); 7613340d773SGleb Smirnoff break; 7623340d773SGleb Smirnoff 7639afd0c29SBill Fenner default: 7643c602fabSXin LI ND_PRINT((ndo, ")")); 7659afd0c29SBill Fenner break; 7669afd0c29SBill Fenner } 7679afd0c29SBill Fenner 7689afd0c29SBill Fenner cp += sizeof(*dh6o) + optlen; 769b0453382SBill Fenner } 770b0453382SBill Fenner return; 771b0453382SBill Fenner 772b0453382SBill Fenner trunc: 7733c602fabSXin LI ND_PRINT((ndo, "[|dhcp6ext]")); 774b0453382SBill Fenner } 775b0453382SBill Fenner 776b0453382SBill Fenner /* 7779afd0c29SBill Fenner * Print dhcp6 packets 778b0453382SBill Fenner */ 779b0453382SBill Fenner void 7803c602fabSXin LI dhcp6_print(netdissect_options *ndo, 7813c602fabSXin LI const u_char *cp, u_int length) 782b0453382SBill Fenner { 7833340d773SGleb Smirnoff const struct dhcp6 *dh6; 7843340d773SGleb Smirnoff const struct dhcp6_relay *dh6relay; 7855b0fe478SBruce M Simpson const u_char *ep; 7863340d773SGleb Smirnoff const u_char *extp; 7879afd0c29SBill Fenner const char *name; 788b0453382SBill Fenner 7893c602fabSXin LI ND_PRINT((ndo, "dhcp6")); 790b0453382SBill Fenner 7913340d773SGleb Smirnoff ep = (const u_char *)ndo->ndo_snapend; 7925b0fe478SBruce M Simpson if (cp + length < ep) 7935b0fe478SBruce M Simpson ep = cp + length; 794b0453382SBill Fenner 7953340d773SGleb Smirnoff dh6 = (const struct dhcp6 *)cp; 7963340d773SGleb Smirnoff dh6relay = (const struct dhcp6_relay *)cp; 7973c602fabSXin LI ND_TCHECK(dh6->dh6_xid); 7983c602fabSXin LI name = tok2str(dh6_msgtype_str, "msgtype-%u", dh6->dh6_msgtype); 7999afd0c29SBill Fenner 8003c602fabSXin LI if (!ndo->ndo_vflag) { 8013c602fabSXin LI ND_PRINT((ndo, " %s", name)); 8029afd0c29SBill Fenner return; 803b0453382SBill Fenner } 8049afd0c29SBill Fenner 8059afd0c29SBill Fenner /* XXX relay agent messages have to be handled differently */ 8069afd0c29SBill Fenner 8073c602fabSXin LI ND_PRINT((ndo, " %s (", name)); /*)*/ 8085b0fe478SBruce M Simpson if (dh6->dh6_msgtype != DH6_RELAY_FORW && 8095b0fe478SBruce M Simpson dh6->dh6_msgtype != DH6_RELAY_REPLY) { 8103c602fabSXin LI ND_PRINT((ndo, "xid=%x", EXTRACT_32BITS(&dh6->dh6_xid) & DH6_XIDMASK)); 8113340d773SGleb Smirnoff extp = (const u_char *)(dh6 + 1); 8123c602fabSXin LI dhcp6opt_print(ndo, extp, ep); 8135b0fe478SBruce M Simpson } else { /* relay messages */ 8145b0fe478SBruce M Simpson struct in6_addr addr6; 8155b0fe478SBruce M Simpson 8163c602fabSXin LI ND_TCHECK(dh6relay->dh6relay_peeraddr); 8175b0fe478SBruce M Simpson 8185b0fe478SBruce M Simpson memcpy(&addr6, dh6relay->dh6relay_linkaddr, sizeof (addr6)); 8193c602fabSXin LI ND_PRINT((ndo, "linkaddr=%s", ip6addr_string(ndo, &addr6))); 8205b0fe478SBruce M Simpson 8215b0fe478SBruce M Simpson memcpy(&addr6, dh6relay->dh6relay_peeraddr, sizeof (addr6)); 8223c602fabSXin LI ND_PRINT((ndo, " peeraddr=%s", ip6addr_string(ndo, &addr6))); 8235b0fe478SBruce M Simpson 8243340d773SGleb Smirnoff dhcp6opt_print(ndo, (const u_char *)(dh6relay + 1), ep); 8255b0fe478SBruce M Simpson } 826685295f4SBill Fenner /*(*/ 8273c602fabSXin LI ND_PRINT((ndo, ")")); 828b0453382SBill Fenner return; 829b0453382SBill Fenner 830b0453382SBill Fenner trunc: 8313c602fabSXin LI ND_PRINT((ndo, "[|dhcp6]")); 832b0453382SBill Fenner } 833