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 46ee67461eSJoseph Mingrone #include <config.h> 47b0453382SBill Fenner 48ee67461eSJoseph Mingrone #include "netdissect-stdinc.h" 49b0453382SBill Fenner 503340d773SGleb Smirnoff #include "netdissect.h" 51b0453382SBill Fenner #include "addrtoname.h" 525b0fe478SBruce M Simpson #include "extract.h" 535b0fe478SBruce M Simpson 545b0fe478SBruce M Simpson /* lease duration */ 553c602fabSXin LI #define DHCP6_DURATION_INFINITE 0xffffffff 56b0453382SBill Fenner 579afd0c29SBill Fenner /* Error Values */ 589afd0c29SBill Fenner #define DH6ERR_FAILURE 16 599afd0c29SBill Fenner #define DH6ERR_AUTHFAIL 17 609afd0c29SBill Fenner #define DH6ERR_POORLYFORMED 18 619afd0c29SBill Fenner #define DH6ERR_UNAVAIL 19 629afd0c29SBill Fenner #define DH6ERR_OPTUNAVAIL 20 63b0453382SBill Fenner 649afd0c29SBill Fenner /* Message type */ 655b0fe478SBruce M Simpson #define DH6_SOLICIT 1 665b0fe478SBruce M Simpson #define DH6_ADVERTISE 2 675b0fe478SBruce M Simpson #define DH6_REQUEST 3 685b0fe478SBruce M Simpson #define DH6_CONFIRM 4 695b0fe478SBruce M Simpson #define DH6_RENEW 5 705b0fe478SBruce M Simpson #define DH6_REBIND 6 719afd0c29SBill Fenner #define DH6_REPLY 7 725b0fe478SBruce M Simpson #define DH6_RELEASE 8 735b0fe478SBruce M Simpson #define DH6_DECLINE 9 745b0fe478SBruce M Simpson #define DH6_RECONFIGURE 10 759afd0c29SBill Fenner #define DH6_INFORM_REQ 11 765b0fe478SBruce M Simpson #define DH6_RELAY_FORW 12 775b0fe478SBruce M Simpson #define DH6_RELAY_REPLY 13 78a5779b6eSRui Paulo #define DH6_LEASEQUERY 14 79a5779b6eSRui Paulo #define DH6_LQ_REPLY 15 80b0453382SBill Fenner 813c602fabSXin LI static const struct tok dh6_msgtype_str[] = { 823c602fabSXin LI { DH6_SOLICIT, "solicit" }, 833c602fabSXin LI { DH6_ADVERTISE, "advertise" }, 843c602fabSXin LI { DH6_REQUEST, "request" }, 853c602fabSXin LI { DH6_CONFIRM, "confirm" }, 863c602fabSXin LI { DH6_RENEW, "renew" }, 873c602fabSXin LI { DH6_REBIND, "rebind" }, 883c602fabSXin LI { DH6_REPLY, "reply" }, 893c602fabSXin LI { DH6_RELEASE, "release" }, 903c602fabSXin LI { DH6_DECLINE, "decline" }, 913c602fabSXin LI { DH6_RECONFIGURE, "reconfigure" }, 923c602fabSXin LI { DH6_INFORM_REQ, "inf-req" }, 933c602fabSXin LI { DH6_RELAY_FORW, "relay-fwd" }, 943c602fabSXin LI { DH6_RELAY_REPLY, "relay-reply" }, 953c602fabSXin LI { DH6_LEASEQUERY, "leasequery" }, 963c602fabSXin LI { DH6_LQ_REPLY, "leasequery-reply" }, 973c602fabSXin LI { 0, NULL } 983c602fabSXin LI }; 993c602fabSXin LI 1009afd0c29SBill Fenner /* DHCP6 base packet format */ 1019afd0c29SBill Fenner struct dhcp6 { 1029afd0c29SBill Fenner union { 103ee67461eSJoseph Mingrone nd_uint8_t msgtype; 104ee67461eSJoseph Mingrone nd_uint32_t xid; 1059afd0c29SBill Fenner } dh6_msgtypexid; 1069afd0c29SBill Fenner /* options follow */ 1075b0fe478SBruce M Simpson }; 1089afd0c29SBill Fenner #define DH6_XIDMASK 0x00ffffff 109b0453382SBill Fenner 1105b0fe478SBruce M Simpson /* DHCPv6 relay messages */ 1115b0fe478SBruce M Simpson struct dhcp6_relay { 1123340d773SGleb Smirnoff nd_uint8_t dh6relay_msgtype; 1133340d773SGleb Smirnoff nd_uint8_t dh6relay_hcnt; 114ee67461eSJoseph Mingrone nd_ipv6 dh6relay_linkaddr; /* XXX: badly aligned */ 115ee67461eSJoseph Mingrone nd_ipv6 dh6relay_peeraddr; 1165b0fe478SBruce M Simpson /* options follow */ 1175b0fe478SBruce M Simpson }; 1185b0fe478SBruce M Simpson 1195b0fe478SBruce M Simpson /* options */ 1205b0fe478SBruce M Simpson #define DH6OPT_CLIENTID 1 1215b0fe478SBruce M Simpson #define DH6OPT_SERVERID 2 122*0a7e5f1fSJoseph Mingrone # define DUID_LLT 1 /* RFC8415 */ 123*0a7e5f1fSJoseph Mingrone # define DUID_EN 2 /* RFC8415 */ 124*0a7e5f1fSJoseph Mingrone # define DUID_LL 3 /* RFC8415 */ 125*0a7e5f1fSJoseph Mingrone # define DUID_UUID 4 /* RFC6355 */ 1265b0fe478SBruce M Simpson #define DH6OPT_IA_NA 3 127b5bfcb5dSMax Laier #define DH6OPT_IA_TA 4 128b5bfcb5dSMax Laier #define DH6OPT_IA_ADDR 5 1295b0fe478SBruce M Simpson #define DH6OPT_ORO 6 1305b0fe478SBruce M Simpson #define DH6OPT_PREFERENCE 7 1315b0fe478SBruce M Simpson # define DH6OPT_PREF_MAX 255 1325b0fe478SBruce M Simpson #define DH6OPT_ELAPSED_TIME 8 1335b0fe478SBruce M Simpson #define DH6OPT_RELAY_MSG 9 1345b0fe478SBruce M Simpson /*#define DH6OPT_SERVER_MSG 10 deprecated */ 1355b0fe478SBruce M Simpson #define DH6OPT_AUTH 11 1361de50e9fSSam Leffler # define DH6OPT_AUTHPROTO_DELAYED 2 1371de50e9fSSam Leffler # define DH6OPT_AUTHPROTO_RECONFIG 3 1381de50e9fSSam Leffler # define DH6OPT_AUTHALG_HMACMD5 1 1391de50e9fSSam Leffler # define DH6OPT_AUTHRDM_MONOCOUNTER 0 1401de50e9fSSam Leffler # define DH6OPT_AUTHRECONFIG_KEY 1 1411de50e9fSSam Leffler # define DH6OPT_AUTHRECONFIG_HMACMD5 2 1425b0fe478SBruce M Simpson #define DH6OPT_UNICAST 12 1435b0fe478SBruce M Simpson #define DH6OPT_STATUS_CODE 13 1445b0fe478SBruce M Simpson # define DH6OPT_STCODE_SUCCESS 0 1455b0fe478SBruce M Simpson # define DH6OPT_STCODE_UNSPECFAIL 1 1465b0fe478SBruce M Simpson # define DH6OPT_STCODE_NOADDRAVAIL 2 1475b0fe478SBruce M Simpson # define DH6OPT_STCODE_NOBINDING 3 1485b0fe478SBruce M Simpson # define DH6OPT_STCODE_NOTONLINK 4 1495b0fe478SBruce M Simpson # define DH6OPT_STCODE_USEMULTICAST 5 1505b0fe478SBruce M Simpson # define DH6OPT_STCODE_NOPREFIXAVAIL 6 151a5779b6eSRui Paulo # define DH6OPT_STCODE_UNKNOWNQUERYTYPE 7 152a5779b6eSRui Paulo # define DH6OPT_STCODE_MALFORMEDQUERY 8 153a5779b6eSRui Paulo # define DH6OPT_STCODE_NOTCONFIGURED 9 154a5779b6eSRui Paulo # define DH6OPT_STCODE_NOTALLOWED 10 1555b0fe478SBruce M Simpson #define DH6OPT_RAPID_COMMIT 14 1565b0fe478SBruce M Simpson #define DH6OPT_USER_CLASS 15 1575b0fe478SBruce M Simpson #define DH6OPT_VENDOR_CLASS 16 1585b0fe478SBruce M Simpson #define DH6OPT_VENDOR_OPTS 17 1595b0fe478SBruce M Simpson #define DH6OPT_INTERFACE_ID 18 1605b0fe478SBruce M Simpson #define DH6OPT_RECONF_MSG 19 1615b0fe478SBruce M Simpson #define DH6OPT_RECONF_ACCEPT 20 1625b0fe478SBruce M Simpson #define DH6OPT_SIP_SERVER_D 21 1635b0fe478SBruce M Simpson #define DH6OPT_SIP_SERVER_A 22 1643c602fabSXin LI #define DH6OPT_DNS_SERVERS 23 1653c602fabSXin LI #define DH6OPT_DOMAIN_LIST 24 1661de50e9fSSam Leffler #define DH6OPT_IA_PD 25 1671de50e9fSSam Leffler #define DH6OPT_IA_PD_PREFIX 26 168b5bfcb5dSMax Laier #define DH6OPT_NIS_SERVERS 27 169b5bfcb5dSMax Laier #define DH6OPT_NISP_SERVERS 28 170b5bfcb5dSMax Laier #define DH6OPT_NIS_NAME 29 171b5bfcb5dSMax Laier #define DH6OPT_NISP_NAME 30 1723c602fabSXin LI #define DH6OPT_SNTP_SERVERS 31 173b5bfcb5dSMax Laier #define DH6OPT_LIFETIME 32 174b5bfcb5dSMax Laier #define DH6OPT_BCMCS_SERVER_D 33 175b5bfcb5dSMax Laier #define DH6OPT_BCMCS_SERVER_A 34 176b5bfcb5dSMax Laier #define DH6OPT_GEOCONF_CIVIC 36 177b5bfcb5dSMax Laier #define DH6OPT_REMOTE_ID 37 178b5bfcb5dSMax Laier #define DH6OPT_SUBSCRIBER_ID 38 179b5bfcb5dSMax Laier #define DH6OPT_CLIENT_FQDN 39 180a5779b6eSRui Paulo #define DH6OPT_PANA_AGENT 40 181a5779b6eSRui Paulo #define DH6OPT_NEW_POSIX_TIMEZONE 41 182a5779b6eSRui Paulo #define DH6OPT_NEW_TZDB_TIMEZONE 42 183a5779b6eSRui Paulo #define DH6OPT_ERO 43 184a5779b6eSRui Paulo #define DH6OPT_LQ_QUERY 44 185a5779b6eSRui Paulo #define DH6OPT_CLIENT_DATA 45 186a5779b6eSRui Paulo #define DH6OPT_CLT_TIME 46 187a5779b6eSRui Paulo #define DH6OPT_LQ_RELAY_DATA 47 188a5779b6eSRui Paulo #define DH6OPT_LQ_CLIENT_LINK 48 1893c602fabSXin LI #define DH6OPT_NTP_SERVER 56 1903c602fabSXin LI # define DH6OPT_NTP_SUBOPTION_SRV_ADDR 1 1913c602fabSXin LI # define DH6OPT_NTP_SUBOPTION_MC_ADDR 2 1923c602fabSXin LI # define DH6OPT_NTP_SUBOPTION_SRV_FQDN 3 193*0a7e5f1fSJoseph Mingrone #define DH6OPT_BOOTFILE_URL 59 /* RFC5970 */ 194d03c0883SXin LI #define DH6OPT_AFTR_NAME 64 1953340d773SGleb Smirnoff #define DH6OPT_MUDURL 112 196*0a7e5f1fSJoseph Mingrone #define DH6OPT_SZTP_REDIRECT 136 /* RFC8572 */ 1975b0fe478SBruce M Simpson 1983c602fabSXin LI static const struct tok dh6opt_str[] = { 1993c602fabSXin LI { DH6OPT_CLIENTID, "client-ID" }, 2003c602fabSXin LI { DH6OPT_SERVERID, "server-ID" }, 2013c602fabSXin LI { DH6OPT_IA_NA, "IA_NA" }, 2023c602fabSXin LI { DH6OPT_IA_TA, "IA_TA" }, 2033c602fabSXin LI { DH6OPT_IA_ADDR, "IA_ADDR" }, 2043c602fabSXin LI { DH6OPT_ORO, "option-request" }, 2053c602fabSXin LI { DH6OPT_PREFERENCE, "preference" }, 2063c602fabSXin LI { DH6OPT_ELAPSED_TIME, "elapsed-time" }, 2073c602fabSXin LI { DH6OPT_RELAY_MSG, "relay-message" }, 2083c602fabSXin LI { DH6OPT_AUTH, "authentication" }, 2093c602fabSXin LI { DH6OPT_UNICAST, "server-unicast" }, 2103c602fabSXin LI { DH6OPT_STATUS_CODE, "status-code" }, 2113c602fabSXin LI { DH6OPT_RAPID_COMMIT, "rapid-commit" }, 2123c602fabSXin LI { DH6OPT_USER_CLASS, "user-class" }, 2133c602fabSXin LI { DH6OPT_VENDOR_CLASS, "vendor-class" }, 2143c602fabSXin LI { DH6OPT_VENDOR_OPTS, "vendor-specific-info" }, 2153c602fabSXin LI { DH6OPT_INTERFACE_ID, "interface-ID" }, 2163c602fabSXin LI { DH6OPT_RECONF_MSG, "reconfigure-message" }, 2173c602fabSXin LI { DH6OPT_RECONF_ACCEPT, "reconfigure-accept" }, 2183c602fabSXin LI { DH6OPT_SIP_SERVER_D, "SIP-servers-domain" }, 2193c602fabSXin LI { DH6OPT_SIP_SERVER_A, "SIP-servers-address" }, 2203c602fabSXin LI { DH6OPT_DNS_SERVERS, "DNS-server" }, 2213c602fabSXin LI { DH6OPT_DOMAIN_LIST, "DNS-search-list" }, 2223c602fabSXin LI { DH6OPT_IA_PD, "IA_PD" }, 2233c602fabSXin LI { DH6OPT_IA_PD_PREFIX, "IA_PD-prefix" }, 2243c602fabSXin LI { DH6OPT_SNTP_SERVERS, "SNTP-servers" }, 2253c602fabSXin LI { DH6OPT_LIFETIME, "lifetime" }, 2263c602fabSXin LI { DH6OPT_NIS_SERVERS, "NIS-server" }, 2273c602fabSXin LI { DH6OPT_NISP_SERVERS, "NIS+-server" }, 2283c602fabSXin LI { DH6OPT_NIS_NAME, "NIS-domain-name" }, 2293c602fabSXin LI { DH6OPT_NISP_NAME, "NIS+-domain-name" }, 2303c602fabSXin LI { DH6OPT_BCMCS_SERVER_D, "BCMCS-domain-name" }, 2313c602fabSXin LI { DH6OPT_BCMCS_SERVER_A, "BCMCS-server" }, 2323c602fabSXin LI { DH6OPT_GEOCONF_CIVIC, "Geoconf-Civic" }, 2333c602fabSXin LI { DH6OPT_REMOTE_ID, "Remote-ID" }, 2343c602fabSXin LI { DH6OPT_SUBSCRIBER_ID, "Subscriber-ID" }, 2353c602fabSXin LI { DH6OPT_CLIENT_FQDN, "Client-FQDN" }, 2363c602fabSXin LI { DH6OPT_PANA_AGENT, "PANA-agent" }, 2373c602fabSXin LI { DH6OPT_NEW_POSIX_TIMEZONE, "POSIX-timezone" }, 2383c602fabSXin LI { DH6OPT_NEW_TZDB_TIMEZONE, "POSIX-tz-database" }, 2393c602fabSXin LI { DH6OPT_ERO, "Echo-request-option" }, 2403c602fabSXin LI { DH6OPT_LQ_QUERY, "Lease-query" }, 2413c602fabSXin LI { DH6OPT_CLIENT_DATA, "LQ-client-data" }, 2423c602fabSXin LI { DH6OPT_CLT_TIME, "Clt-time" }, 2433c602fabSXin LI { DH6OPT_LQ_RELAY_DATA, "LQ-relay-data" }, 2443c602fabSXin LI { DH6OPT_LQ_CLIENT_LINK, "LQ-client-link" }, 2453c602fabSXin LI { DH6OPT_NTP_SERVER, "NTP-server" }, 246*0a7e5f1fSJoseph Mingrone { DH6OPT_BOOTFILE_URL, "Bootfile-URL" }, 2473c602fabSXin LI { DH6OPT_AFTR_NAME, "AFTR-Name" }, 2483340d773SGleb Smirnoff { DH6OPT_MUDURL, "MUD-URL" }, 249*0a7e5f1fSJoseph Mingrone { DH6OPT_SZTP_REDIRECT, "SZTP-redirect" }, 2503c602fabSXin LI { 0, NULL } 2513c602fabSXin LI }; 2523c602fabSXin LI 2533c602fabSXin LI static const struct tok dh6opt_stcode_str[] = { 2543340d773SGleb Smirnoff { DH6OPT_STCODE_SUCCESS, "Success" }, /* RFC3315 */ 2553340d773SGleb Smirnoff { DH6OPT_STCODE_UNSPECFAIL, "UnspecFail" }, /* RFC3315 */ 2563340d773SGleb Smirnoff { DH6OPT_STCODE_NOADDRAVAIL, "NoAddrsAvail" }, /* RFC3315 */ 2573340d773SGleb Smirnoff { DH6OPT_STCODE_NOBINDING, "NoBinding" }, /* RFC3315 */ 2583340d773SGleb Smirnoff { DH6OPT_STCODE_NOTONLINK, "NotOnLink" }, /* RFC3315 */ 2593340d773SGleb Smirnoff { DH6OPT_STCODE_USEMULTICAST, "UseMulticast" }, /* RFC3315 */ 2603340d773SGleb Smirnoff { DH6OPT_STCODE_NOPREFIXAVAIL, "NoPrefixAvail" }, /* RFC3633 */ 2613340d773SGleb Smirnoff { DH6OPT_STCODE_UNKNOWNQUERYTYPE, "UnknownQueryType" }, /* RFC5007 */ 2623340d773SGleb Smirnoff { DH6OPT_STCODE_MALFORMEDQUERY, "MalformedQuery" }, /* RFC5007 */ 2633340d773SGleb Smirnoff { DH6OPT_STCODE_NOTCONFIGURED, "NotConfigured" }, /* RFC5007 */ 2643340d773SGleb Smirnoff { DH6OPT_STCODE_NOTALLOWED, "NotAllowed" }, /* RFC5007 */ 2653c602fabSXin LI { 0, NULL } 2663c602fabSXin LI }; 2673c602fabSXin LI 2689afd0c29SBill Fenner struct dhcp6opt { 2693340d773SGleb Smirnoff nd_uint16_t dh6opt_type; 2703340d773SGleb Smirnoff nd_uint16_t dh6opt_len; 2719afd0c29SBill Fenner /* type-dependent data follows */ 2725b0fe478SBruce M Simpson }; 2735b0fe478SBruce M Simpson 2745b0fe478SBruce M Simpson static const char * 2753c602fabSXin LI dhcp6stcode(const uint16_t code) 2765b0fe478SBruce M Simpson { 2773c602fabSXin LI return code > 255 ? "INVALID code" : tok2str(dh6opt_stcode_str, "code%u", code); 2785b0fe478SBruce M Simpson } 2795b0fe478SBruce M Simpson 280b0453382SBill Fenner static void 2813c602fabSXin LI dhcp6opt_print(netdissect_options *ndo, 2823c602fabSXin LI const u_char *cp, const u_char *ep) 283b0453382SBill Fenner { 2843c602fabSXin LI const struct dhcp6opt *dh6o; 2853c602fabSXin LI const u_char *tp; 286ee67461eSJoseph Mingrone u_int i; 2873c602fabSXin LI uint16_t opttype; 288ee67461eSJoseph Mingrone uint16_t optlen; 2893c602fabSXin LI uint8_t auth_proto; 290ee67461eSJoseph Mingrone uint8_t auth_alg; 291ee67461eSJoseph Mingrone uint8_t auth_rdm; 2921de50e9fSSam Leffler u_int authinfolen, authrealmlen; 293ee67461eSJoseph Mingrone u_int remain_len; /* Length of remaining options */ 294ee67461eSJoseph Mingrone u_int label_len; /* Label length */ 2953c602fabSXin LI uint16_t subopt_code; 2963c602fabSXin LI uint16_t subopt_len; 297ee67461eSJoseph Mingrone uint8_t dh6_reconf_type; 298ee67461eSJoseph Mingrone uint8_t dh6_lq_query_type; 299*0a7e5f1fSJoseph Mingrone u_int first_list_value; 300*0a7e5f1fSJoseph Mingrone uint16_t remainder_len; 301b0453382SBill Fenner 302b0453382SBill Fenner if (cp == ep) 303b0453382SBill Fenner return; 304b0453382SBill Fenner while (cp < ep) { 3055b0fe478SBruce M Simpson if (ep < cp + sizeof(*dh6o)) 306b0453382SBill Fenner goto trunc; 3073340d773SGleb Smirnoff dh6o = (const struct dhcp6opt *)cp; 308ee67461eSJoseph Mingrone ND_TCHECK_SIZE(dh6o); 309ee67461eSJoseph Mingrone optlen = GET_BE_U_2(dh6o->dh6opt_len); 3105b0fe478SBruce M Simpson if (ep < cp + sizeof(*dh6o) + optlen) 311b0453382SBill Fenner goto trunc; 312ee67461eSJoseph Mingrone opttype = GET_BE_U_2(dh6o->dh6opt_type); 313ee67461eSJoseph Mingrone ND_PRINT(" (%s", tok2str(dh6opt_str, "opt_%u", opttype)); 314ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp + sizeof(*dh6o), optlen); 3155b0fe478SBruce M Simpson switch (opttype) { 3165b0fe478SBruce M Simpson case DH6OPT_CLIENTID: 3175b0fe478SBruce M Simpson case DH6OPT_SERVERID: 3189afd0c29SBill Fenner if (optlen < 2) { 3199afd0c29SBill Fenner /*(*/ 320ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 321b0453382SBill Fenner break; 322b0453382SBill Fenner } 3233340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 324ee67461eSJoseph Mingrone switch (GET_BE_U_2(tp)) { 325*0a7e5f1fSJoseph Mingrone case DUID_LLT: 3269afd0c29SBill Fenner if (optlen >= 2 + 6) { 327ee67461eSJoseph Mingrone ND_PRINT(" hwaddr/time type %u time %u ", 328ee67461eSJoseph Mingrone GET_BE_U_2(tp + 2), 329ee67461eSJoseph Mingrone GET_BE_U_4(tp + 4)); 3309afd0c29SBill Fenner for (i = 8; i < optlen; i++) 331ee67461eSJoseph Mingrone ND_PRINT("%02x", 332ee67461eSJoseph Mingrone GET_U_1(tp + i)); 3339afd0c29SBill Fenner /*(*/ 334ee67461eSJoseph Mingrone ND_PRINT(")"); 3359afd0c29SBill Fenner } else { 3369afd0c29SBill Fenner /*(*/ 337ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 3389afd0c29SBill Fenner } 3399afd0c29SBill Fenner break; 340*0a7e5f1fSJoseph Mingrone case DUID_EN: 341*0a7e5f1fSJoseph Mingrone if (optlen >= 2 + 4) { 342*0a7e5f1fSJoseph Mingrone ND_PRINT(" enterprise %u ", GET_BE_U_4(tp + 2)); 343*0a7e5f1fSJoseph Mingrone for (i = 2 + 4; i < optlen; i++) 344ee67461eSJoseph Mingrone ND_PRINT("%02x", 345ee67461eSJoseph Mingrone GET_U_1(tp + i)); 3469afd0c29SBill Fenner /*(*/ 347ee67461eSJoseph Mingrone ND_PRINT(")"); 3489afd0c29SBill Fenner } else { 3499afd0c29SBill Fenner /*(*/ 350ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 3519afd0c29SBill Fenner } 3529afd0c29SBill Fenner break; 353*0a7e5f1fSJoseph Mingrone case DUID_LL: 3549afd0c29SBill Fenner if (optlen >= 2 + 2) { 355ee67461eSJoseph Mingrone ND_PRINT(" hwaddr type %u ", 356ee67461eSJoseph Mingrone GET_BE_U_2(tp + 2)); 3579afd0c29SBill Fenner for (i = 4; i < optlen; i++) 358ee67461eSJoseph Mingrone ND_PRINT("%02x", 359ee67461eSJoseph Mingrone GET_U_1(tp + i)); 3609afd0c29SBill Fenner /*(*/ 361ee67461eSJoseph Mingrone ND_PRINT(")"); 3629afd0c29SBill Fenner } else { 3639afd0c29SBill Fenner /*(*/ 364ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 3659afd0c29SBill Fenner } 3669afd0c29SBill Fenner break; 367*0a7e5f1fSJoseph Mingrone case DUID_UUID: 368*0a7e5f1fSJoseph Mingrone ND_PRINT(" uuid "); 369*0a7e5f1fSJoseph Mingrone if (optlen == 2 + 16) { 370*0a7e5f1fSJoseph Mingrone for (i = 2; i < optlen; i++) 371*0a7e5f1fSJoseph Mingrone ND_PRINT("%02x", 372*0a7e5f1fSJoseph Mingrone GET_U_1(tp + i)); 373*0a7e5f1fSJoseph Mingrone /*(*/ 374*0a7e5f1fSJoseph Mingrone ND_PRINT(")"); 375*0a7e5f1fSJoseph Mingrone } else { 376*0a7e5f1fSJoseph Mingrone /*(*/ 377*0a7e5f1fSJoseph Mingrone ND_PRINT(" ?)"); 378*0a7e5f1fSJoseph Mingrone } 379*0a7e5f1fSJoseph Mingrone break; 3805b0fe478SBruce M Simpson default: 381ee67461eSJoseph Mingrone ND_PRINT(" type %u)", GET_BE_U_2(tp)); 3825b0fe478SBruce M Simpson break; 3835b0fe478SBruce M Simpson } 3845b0fe478SBruce M Simpson break; 385b5bfcb5dSMax Laier case DH6OPT_IA_ADDR: 38627df3f5dSRui Paulo if (optlen < 24) { 38727df3f5dSRui Paulo /*(*/ 388ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 389b5bfcb5dSMax Laier break; 390b5bfcb5dSMax Laier } 3913340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 392ee67461eSJoseph Mingrone ND_PRINT(" %s", GET_IP6ADDR_STRING(tp)); 393ee67461eSJoseph Mingrone ND_PRINT(" pltime:%u vltime:%u", 394ee67461eSJoseph Mingrone GET_BE_U_4(tp + 16), 395ee67461eSJoseph Mingrone GET_BE_U_4(tp + 20)); 39627df3f5dSRui Paulo if (optlen > 24) { 397b5bfcb5dSMax Laier /* there are sub-options */ 3983c602fabSXin LI dhcp6opt_print(ndo, tp + 24, tp + optlen); 399b5bfcb5dSMax Laier } 400ee67461eSJoseph Mingrone ND_PRINT(")"); 401b5bfcb5dSMax Laier break; 4025b0fe478SBruce M Simpson case DH6OPT_ORO: 403a5779b6eSRui Paulo case DH6OPT_ERO: 4045b0fe478SBruce M Simpson if (optlen % 2) { 405ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 4065b0fe478SBruce M Simpson break; 4075b0fe478SBruce M Simpson } 4083340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 4095b0fe478SBruce M Simpson for (i = 0; i < optlen; i += 2) { 410ee67461eSJoseph Mingrone ND_PRINT(" %s", 411ee67461eSJoseph Mingrone tok2str(dh6opt_str, "opt_%u", GET_BE_U_2(tp + i))); 4125b0fe478SBruce M Simpson } 413ee67461eSJoseph Mingrone ND_PRINT(")"); 4145b0fe478SBruce M Simpson break; 4155b0fe478SBruce M Simpson case DH6OPT_PREFERENCE: 4165b0fe478SBruce M Simpson if (optlen != 1) { 417ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 4185b0fe478SBruce M Simpson break; 4195b0fe478SBruce M Simpson } 4203340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 421ee67461eSJoseph Mingrone ND_PRINT(" %u)", GET_U_1(tp)); 4225b0fe478SBruce M Simpson break; 4235b0fe478SBruce M Simpson case DH6OPT_ELAPSED_TIME: 4245b0fe478SBruce M Simpson if (optlen != 2) { 425ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 4265b0fe478SBruce M Simpson break; 4275b0fe478SBruce M Simpson } 4283340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 429ee67461eSJoseph Mingrone ND_PRINT(" %u)", GET_BE_U_2(tp)); 4305b0fe478SBruce M Simpson break; 4315b0fe478SBruce M Simpson case DH6OPT_RELAY_MSG: 432ee67461eSJoseph Mingrone { 433ee67461eSJoseph Mingrone const u_char *snapend_save; 434ee67461eSJoseph Mingrone 435ee67461eSJoseph Mingrone ND_PRINT(" ("); 4363340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 437ee67461eSJoseph Mingrone /* 438ee67461eSJoseph Mingrone * Update the snapend to the end of the option before 439ee67461eSJoseph Mingrone * calling recursively dhcp6_print() for the nested 440ee67461eSJoseph Mingrone * packet. Other options may be present after the 441ee67461eSJoseph Mingrone * nested DHCPv6 packet. This prevents that, in 442ee67461eSJoseph Mingrone * dhcp6_print(), for the nested DHCPv6 packet, the 443ee67461eSJoseph Mingrone * remaining length < remaining caplen. 444ee67461eSJoseph Mingrone */ 445ee67461eSJoseph Mingrone snapend_save = ndo->ndo_snapend; 446ee67461eSJoseph Mingrone ndo->ndo_snapend = ND_MIN(tp + optlen, ndo->ndo_snapend); 4473c602fabSXin LI dhcp6_print(ndo, tp, optlen); 448ee67461eSJoseph Mingrone ndo->ndo_snapend = snapend_save; 449ee67461eSJoseph Mingrone ND_PRINT(")"); 4505b0fe478SBruce M Simpson break; 451ee67461eSJoseph Mingrone } 4521de50e9fSSam Leffler case DH6OPT_AUTH: 45327df3f5dSRui Paulo if (optlen < 11) { 454ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 4551de50e9fSSam Leffler break; 4561de50e9fSSam Leffler } 4573340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 458ee67461eSJoseph Mingrone auth_proto = GET_U_1(tp); 45927df3f5dSRui Paulo switch (auth_proto) { 4601de50e9fSSam Leffler case DH6OPT_AUTHPROTO_DELAYED: 461ee67461eSJoseph Mingrone ND_PRINT(" proto: delayed"); 4621de50e9fSSam Leffler break; 4631de50e9fSSam Leffler case DH6OPT_AUTHPROTO_RECONFIG: 464ee67461eSJoseph Mingrone ND_PRINT(" proto: reconfigure"); 4651de50e9fSSam Leffler break; 4661de50e9fSSam Leffler default: 467ee67461eSJoseph Mingrone ND_PRINT(" proto: %u", auth_proto); 4681de50e9fSSam Leffler break; 4691de50e9fSSam Leffler } 47027df3f5dSRui Paulo tp++; 471ee67461eSJoseph Mingrone auth_alg = GET_U_1(tp); 472ee67461eSJoseph Mingrone switch (auth_alg) { 4731de50e9fSSam Leffler case DH6OPT_AUTHALG_HMACMD5: 4741de50e9fSSam Leffler /* XXX: may depend on the protocol */ 475ee67461eSJoseph Mingrone ND_PRINT(", alg: HMAC-MD5"); 4761de50e9fSSam Leffler break; 4771de50e9fSSam Leffler default: 478ee67461eSJoseph Mingrone ND_PRINT(", alg: %u", auth_alg); 4791de50e9fSSam Leffler break; 4801de50e9fSSam Leffler } 48127df3f5dSRui Paulo tp++; 482ee67461eSJoseph Mingrone auth_rdm = GET_U_1(tp); 483ee67461eSJoseph Mingrone switch (auth_rdm) { 4841de50e9fSSam Leffler case DH6OPT_AUTHRDM_MONOCOUNTER: 485ee67461eSJoseph Mingrone ND_PRINT(", RDM: mono"); 4861de50e9fSSam Leffler break; 4871de50e9fSSam Leffler default: 488ee67461eSJoseph Mingrone ND_PRINT(", RDM: %u", auth_rdm); 4891de50e9fSSam Leffler break; 4901de50e9fSSam Leffler } 49127df3f5dSRui Paulo tp++; 492ee67461eSJoseph Mingrone ND_PRINT(", RD:"); 49327df3f5dSRui Paulo for (i = 0; i < 4; i++, tp += 2) 494ee67461eSJoseph Mingrone ND_PRINT(" %04x", GET_BE_U_2(tp)); 4951de50e9fSSam Leffler 4961de50e9fSSam Leffler /* protocol dependent part */ 49727df3f5dSRui Paulo authinfolen = optlen - 11; 49827df3f5dSRui Paulo switch (auth_proto) { 4991de50e9fSSam Leffler case DH6OPT_AUTHPROTO_DELAYED: 5001de50e9fSSam Leffler if (authinfolen == 0) 5011de50e9fSSam Leffler break; 5021de50e9fSSam Leffler if (authinfolen < 20) { 503ee67461eSJoseph Mingrone ND_PRINT(" ??"); 5041de50e9fSSam Leffler break; 5051de50e9fSSam Leffler } 5061de50e9fSSam Leffler authrealmlen = authinfolen - 20; 5071de50e9fSSam Leffler if (authrealmlen > 0) { 508ee67461eSJoseph Mingrone ND_PRINT(", realm: "); 5091de50e9fSSam Leffler } 5101de50e9fSSam Leffler for (i = 0; i < authrealmlen; i++, tp++) 511ee67461eSJoseph Mingrone ND_PRINT("%02x", GET_U_1(tp)); 512ee67461eSJoseph Mingrone ND_PRINT(", key ID: %08x", GET_BE_U_4(tp)); 5131de50e9fSSam Leffler tp += 4; 514ee67461eSJoseph Mingrone ND_PRINT(", HMAC-MD5:"); 5151de50e9fSSam Leffler for (i = 0; i < 4; i++, tp+= 4) 516ee67461eSJoseph Mingrone ND_PRINT(" %08x", GET_BE_U_4(tp)); 5171de50e9fSSam Leffler break; 5181de50e9fSSam Leffler case DH6OPT_AUTHPROTO_RECONFIG: 5191de50e9fSSam Leffler if (authinfolen != 17) { 520ee67461eSJoseph Mingrone ND_PRINT(" ??"); 5211de50e9fSSam Leffler break; 5221de50e9fSSam Leffler } 523ee67461eSJoseph Mingrone switch (GET_U_1(tp)) { 5241de50e9fSSam Leffler case DH6OPT_AUTHRECONFIG_KEY: 525ee67461eSJoseph Mingrone ND_PRINT(" reconfig-key"); 5261de50e9fSSam Leffler break; 5271de50e9fSSam Leffler case DH6OPT_AUTHRECONFIG_HMACMD5: 528ee67461eSJoseph Mingrone ND_PRINT(" type: HMAC-MD5"); 5291de50e9fSSam Leffler break; 5301de50e9fSSam Leffler default: 531ee67461eSJoseph Mingrone ND_PRINT(" type: ??"); 5321de50e9fSSam Leffler break; 5331de50e9fSSam Leffler } 534ee67461eSJoseph Mingrone tp++; 535ee67461eSJoseph Mingrone ND_PRINT(" value:"); 5361de50e9fSSam Leffler for (i = 0; i < 4; i++, tp+= 4) 537ee67461eSJoseph Mingrone ND_PRINT(" %08x", GET_BE_U_4(tp)); 5381de50e9fSSam Leffler break; 5391de50e9fSSam Leffler default: 540ee67461eSJoseph Mingrone ND_PRINT(" ??"); 5411de50e9fSSam Leffler break; 5421de50e9fSSam Leffler } 5431de50e9fSSam Leffler 544ee67461eSJoseph Mingrone ND_PRINT(")"); 5451de50e9fSSam Leffler break; 5465b0fe478SBruce M Simpson case DH6OPT_RAPID_COMMIT: /* nothing todo */ 547ee67461eSJoseph Mingrone ND_PRINT(")"); 5485b0fe478SBruce M Simpson break; 5495b0fe478SBruce M Simpson case DH6OPT_INTERFACE_ID: 550a5779b6eSRui Paulo case DH6OPT_SUBSCRIBER_ID: 5515b0fe478SBruce M Simpson /* 5525b0fe478SBruce M Simpson * Since we cannot predict the encoding, print hex dump 5535b0fe478SBruce M Simpson * at most 10 characters. 5545b0fe478SBruce M Simpson */ 5553340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 556ee67461eSJoseph Mingrone ND_PRINT(" "); 5575b0fe478SBruce M Simpson for (i = 0; i < optlen && i < 10; i++) 558ee67461eSJoseph Mingrone ND_PRINT("%02x", GET_U_1(tp + i)); 559ee67461eSJoseph Mingrone ND_PRINT("...)"); 5605b0fe478SBruce M Simpson break; 5615b0fe478SBruce M Simpson case DH6OPT_RECONF_MSG: 5620bff6a5aSEd Maste if (optlen != 1) { 563ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 5640bff6a5aSEd Maste break; 5650bff6a5aSEd Maste } 5663340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 567ee67461eSJoseph Mingrone dh6_reconf_type = GET_U_1(tp); 568ee67461eSJoseph Mingrone switch (dh6_reconf_type) { 5695b0fe478SBruce M Simpson case DH6_RENEW: 570ee67461eSJoseph Mingrone ND_PRINT(" for renew)"); 5715b0fe478SBruce M Simpson break; 5725b0fe478SBruce M Simpson case DH6_INFORM_REQ: 573ee67461eSJoseph Mingrone ND_PRINT(" for inf-req)"); 5745b0fe478SBruce M Simpson break; 5755b0fe478SBruce M Simpson default: 576ee67461eSJoseph Mingrone ND_PRINT(" for ?\?\?(%02x))", dh6_reconf_type); 5775b0fe478SBruce M Simpson break; 5785b0fe478SBruce M Simpson } 5795b0fe478SBruce M Simpson break; 5805b0fe478SBruce M Simpson case DH6OPT_RECONF_ACCEPT: /* nothing todo */ 581ee67461eSJoseph Mingrone ND_PRINT(")"); 5825b0fe478SBruce M Simpson break; 5835b0fe478SBruce M Simpson case DH6OPT_SIP_SERVER_A: 5843c602fabSXin LI case DH6OPT_DNS_SERVERS: 5853c602fabSXin LI case DH6OPT_SNTP_SERVERS: 586b5bfcb5dSMax Laier case DH6OPT_NIS_SERVERS: 587b5bfcb5dSMax Laier case DH6OPT_NISP_SERVERS: 588b5bfcb5dSMax Laier case DH6OPT_BCMCS_SERVER_A: 589a5779b6eSRui Paulo case DH6OPT_PANA_AGENT: 590a5779b6eSRui Paulo case DH6OPT_LQ_CLIENT_LINK: 5919afd0c29SBill Fenner if (optlen % 16) { 592ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 5939afd0c29SBill Fenner break; 5949afd0c29SBill Fenner } 5953340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 5969afd0c29SBill Fenner for (i = 0; i < optlen; i += 16) 597ee67461eSJoseph Mingrone ND_PRINT(" %s", GET_IP6ADDR_STRING(tp + i)); 598ee67461eSJoseph Mingrone ND_PRINT(")"); 5993c602fabSXin LI break; 6003c602fabSXin LI case DH6OPT_SIP_SERVER_D: 6013c602fabSXin LI case DH6OPT_DOMAIN_LIST: 6023340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 6033c602fabSXin LI while (tp < cp + sizeof(*dh6o) + optlen) { 604ee67461eSJoseph Mingrone ND_PRINT(" "); 605ee67461eSJoseph Mingrone if ((tp = fqdn_print(ndo, tp, cp + sizeof(*dh6o) + optlen)) == NULL) 6063c602fabSXin LI goto trunc; 6073c602fabSXin LI } 608ee67461eSJoseph Mingrone ND_PRINT(")"); 6095b0fe478SBruce M Simpson break; 6105b0fe478SBruce M Simpson case DH6OPT_STATUS_CODE: 6115b0fe478SBruce M Simpson if (optlen < 2) { 612ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 6135b0fe478SBruce M Simpson break; 6145b0fe478SBruce M Simpson } 6153340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 616ee67461eSJoseph Mingrone ND_PRINT(" %s)", dhcp6stcode(GET_BE_U_2(tp))); 6175b0fe478SBruce M Simpson break; 6185b0fe478SBruce M Simpson case DH6OPT_IA_NA: 6195b0fe478SBruce M Simpson case DH6OPT_IA_PD: 62027df3f5dSRui Paulo if (optlen < 12) { 621ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 6225b0fe478SBruce M Simpson break; 6235b0fe478SBruce M Simpson } 6243340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 625ee67461eSJoseph Mingrone ND_PRINT(" IAID:%u T1:%u T2:%u", 626ee67461eSJoseph Mingrone GET_BE_U_4(tp), 627ee67461eSJoseph Mingrone GET_BE_U_4(tp + 4), 628ee67461eSJoseph Mingrone GET_BE_U_4(tp + 8)); 62927df3f5dSRui Paulo if (optlen > 12) { 6305b0fe478SBruce M Simpson /* there are sub-options */ 6313c602fabSXin LI dhcp6opt_print(ndo, tp + 12, tp + optlen); 6325b0fe478SBruce M Simpson } 633ee67461eSJoseph Mingrone ND_PRINT(")"); 6345b0fe478SBruce M Simpson break; 635a5779b6eSRui Paulo case DH6OPT_IA_TA: 636a5779b6eSRui Paulo if (optlen < 4) { 637ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 638a5779b6eSRui Paulo break; 639a5779b6eSRui Paulo } 6403340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 641ee67461eSJoseph Mingrone ND_PRINT(" IAID:%u", GET_BE_U_4(tp)); 642a5779b6eSRui Paulo if (optlen > 4) { 643a5779b6eSRui Paulo /* there are sub-options */ 6443c602fabSXin LI dhcp6opt_print(ndo, tp + 4, tp + optlen); 645a5779b6eSRui Paulo } 646ee67461eSJoseph Mingrone ND_PRINT(")"); 647a5779b6eSRui Paulo break; 6485b0fe478SBruce M Simpson case DH6OPT_IA_PD_PREFIX: 64927df3f5dSRui Paulo if (optlen < 25) { 650ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 6515b0fe478SBruce M Simpson break; 6525b0fe478SBruce M Simpson } 6533340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 654ee67461eSJoseph Mingrone ND_PRINT(" %s/%u", GET_IP6ADDR_STRING(tp + 9), 655ee67461eSJoseph Mingrone GET_U_1(tp + 8)); 656ee67461eSJoseph Mingrone ND_PRINT(" pltime:%u vltime:%u", 657ee67461eSJoseph Mingrone GET_BE_U_4(tp), 658ee67461eSJoseph Mingrone GET_BE_U_4(tp + 4)); 65927df3f5dSRui Paulo if (optlen > 25) { 6605b0fe478SBruce M Simpson /* there are sub-options */ 6613c602fabSXin LI dhcp6opt_print(ndo, tp + 25, tp + optlen); 6625b0fe478SBruce M Simpson } 663ee67461eSJoseph Mingrone ND_PRINT(")"); 6645b0fe478SBruce M Simpson break; 6651de50e9fSSam Leffler case DH6OPT_LIFETIME: 666a5779b6eSRui Paulo case DH6OPT_CLT_TIME: 6671de50e9fSSam Leffler if (optlen != 4) { 668ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 6691de50e9fSSam Leffler break; 6701de50e9fSSam Leffler } 6713340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 672ee67461eSJoseph Mingrone ND_PRINT(" %u)", GET_BE_U_4(tp)); 6731de50e9fSSam Leffler break; 674a5779b6eSRui Paulo case DH6OPT_REMOTE_ID: 675a5779b6eSRui Paulo if (optlen < 4) { 676ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 677a5779b6eSRui Paulo break; 678a5779b6eSRui Paulo } 6793340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 680ee67461eSJoseph Mingrone ND_PRINT(" %u ", GET_BE_U_4(tp)); 681a5779b6eSRui Paulo /* 682a5779b6eSRui Paulo * Print hex dump first 10 characters. 683a5779b6eSRui Paulo */ 684a5779b6eSRui Paulo for (i = 4; i < optlen && i < 14; i++) 685ee67461eSJoseph Mingrone ND_PRINT("%02x", GET_U_1(tp + i)); 686ee67461eSJoseph Mingrone ND_PRINT("...)"); 687a5779b6eSRui Paulo break; 688a5779b6eSRui Paulo case DH6OPT_LQ_QUERY: 689a5779b6eSRui Paulo if (optlen < 17) { 690ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 691a5779b6eSRui Paulo break; 692a5779b6eSRui Paulo } 6933340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 694ee67461eSJoseph Mingrone dh6_lq_query_type = GET_U_1(tp); 695ee67461eSJoseph Mingrone switch (dh6_lq_query_type) { 696a5779b6eSRui Paulo case 1: 697ee67461eSJoseph Mingrone ND_PRINT(" by-address"); 698a5779b6eSRui Paulo break; 699a5779b6eSRui Paulo case 2: 700ee67461eSJoseph Mingrone ND_PRINT(" by-clientID"); 701a5779b6eSRui Paulo break; 702a5779b6eSRui Paulo default: 703ee67461eSJoseph Mingrone ND_PRINT(" type_%u", dh6_lq_query_type); 704a5779b6eSRui Paulo break; 705a5779b6eSRui Paulo } 706ee67461eSJoseph Mingrone ND_PRINT(" %s", GET_IP6ADDR_STRING(tp + 1)); 707a5779b6eSRui Paulo if (optlen > 17) { 708a5779b6eSRui Paulo /* there are query-options */ 7093c602fabSXin LI dhcp6opt_print(ndo, tp + 17, tp + optlen); 710a5779b6eSRui Paulo } 711ee67461eSJoseph Mingrone ND_PRINT(")"); 712a5779b6eSRui Paulo break; 713a5779b6eSRui Paulo case DH6OPT_CLIENT_DATA: 7143340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 715a5779b6eSRui Paulo if (optlen > 0) { 716a5779b6eSRui Paulo /* there are encapsulated options */ 7173c602fabSXin LI dhcp6opt_print(ndo, tp, tp + optlen); 718a5779b6eSRui Paulo } 719ee67461eSJoseph Mingrone ND_PRINT(")"); 720a5779b6eSRui Paulo break; 721a5779b6eSRui Paulo case DH6OPT_LQ_RELAY_DATA: 722a5779b6eSRui Paulo if (optlen < 16) { 723ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 724a5779b6eSRui Paulo break; 725a5779b6eSRui Paulo } 7263340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 727ee67461eSJoseph Mingrone ND_PRINT(" %s ", GET_IP6ADDR_STRING(tp)); 728a5779b6eSRui Paulo /* 729a5779b6eSRui Paulo * Print hex dump first 10 characters. 730a5779b6eSRui Paulo */ 731a5779b6eSRui Paulo for (i = 16; i < optlen && i < 26; i++) 732ee67461eSJoseph Mingrone ND_PRINT("%02x", GET_U_1(tp + i)); 733ee67461eSJoseph Mingrone ND_PRINT("...)"); 734a5779b6eSRui Paulo break; 7353c602fabSXin LI case DH6OPT_NTP_SERVER: 7363c602fabSXin LI if (optlen < 4) { 737ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 738d03c0883SXin LI break; 739d03c0883SXin LI } 7403340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 7413c602fabSXin LI while (tp < cp + sizeof(*dh6o) + optlen - 4) { 742ee67461eSJoseph Mingrone subopt_code = GET_BE_U_2(tp); 7433c602fabSXin LI tp += 2; 744ee67461eSJoseph Mingrone subopt_len = GET_BE_U_2(tp); 7453c602fabSXin LI tp += 2; 7463c602fabSXin LI if (tp + subopt_len > cp + sizeof(*dh6o) + optlen) 7473c602fabSXin LI goto trunc; 748ee67461eSJoseph Mingrone ND_PRINT(" subopt:%u", subopt_code); 7493c602fabSXin LI switch (subopt_code) { 7503c602fabSXin LI case DH6OPT_NTP_SUBOPTION_SRV_ADDR: 7513c602fabSXin LI case DH6OPT_NTP_SUBOPTION_MC_ADDR: 7523c602fabSXin LI if (subopt_len != 16) { 753ee67461eSJoseph Mingrone ND_PRINT(" ?"); 7543c602fabSXin LI break; 7553c602fabSXin LI } 756ee67461eSJoseph Mingrone ND_PRINT(" %s", GET_IP6ADDR_STRING(tp)); 7573c602fabSXin LI break; 7583c602fabSXin LI case DH6OPT_NTP_SUBOPTION_SRV_FQDN: 759ee67461eSJoseph Mingrone ND_PRINT(" "); 760ee67461eSJoseph Mingrone if (fqdn_print(ndo, tp, tp + subopt_len) == NULL) 7613c602fabSXin LI goto trunc; 7623c602fabSXin LI break; 7633c602fabSXin LI default: 764ee67461eSJoseph Mingrone ND_PRINT(" ?"); 7653c602fabSXin LI break; 7663c602fabSXin LI } 7673c602fabSXin LI tp += subopt_len; 7683c602fabSXin LI } 769ee67461eSJoseph Mingrone ND_PRINT(")"); 7703c602fabSXin LI break; 7713c602fabSXin LI case DH6OPT_AFTR_NAME: 7723c602fabSXin LI if (optlen < 3) { 773ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 7743c602fabSXin LI break; 7753c602fabSXin LI } 7763340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 7773c602fabSXin LI remain_len = optlen; 778ee67461eSJoseph Mingrone ND_PRINT(" "); 779d03c0883SXin LI /* Encoding is described in section 3.1 of RFC 1035 */ 780ee67461eSJoseph Mingrone while (remain_len && GET_U_1(tp)) { 781ee67461eSJoseph Mingrone label_len = GET_U_1(tp); 782ee67461eSJoseph Mingrone tp++; 783d03c0883SXin LI if (label_len < remain_len - 1) { 784ee67461eSJoseph Mingrone nd_printjnp(ndo, tp, label_len); 785d03c0883SXin LI tp += label_len; 786d03c0883SXin LI remain_len -= (label_len + 1); 787ee67461eSJoseph Mingrone if(GET_U_1(tp)) ND_PRINT("."); 788d03c0883SXin LI } else { 789ee67461eSJoseph Mingrone ND_PRINT(" ?"); 790d03c0883SXin LI break; 791d03c0883SXin LI } 792d03c0883SXin LI } 793ee67461eSJoseph Mingrone ND_PRINT(")"); 794d03c0883SXin LI break; 7953340d773SGleb Smirnoff case DH6OPT_NEW_POSIX_TIMEZONE: /* all three of these options */ 7963340d773SGleb Smirnoff case DH6OPT_NEW_TZDB_TIMEZONE: /* are encoded similarly */ 7973340d773SGleb Smirnoff case DH6OPT_MUDURL: /* although GMT might not work */ 7983340d773SGleb Smirnoff if (optlen < 5) { 799ee67461eSJoseph Mingrone ND_PRINT(" ?)"); 8003340d773SGleb Smirnoff break; 8013340d773SGleb Smirnoff } 8023340d773SGleb Smirnoff tp = (const u_char *)(dh6o + 1); 803ee67461eSJoseph Mingrone ND_PRINT(" "); 804ee67461eSJoseph Mingrone nd_printjnp(ndo, tp, optlen); 805ee67461eSJoseph Mingrone ND_PRINT(")"); 8063340d773SGleb Smirnoff break; 8073340d773SGleb Smirnoff 808*0a7e5f1fSJoseph Mingrone case DH6OPT_BOOTFILE_URL: 809*0a7e5f1fSJoseph Mingrone tp = (const u_char *)(dh6o + 1); 810*0a7e5f1fSJoseph Mingrone ND_PRINT(" "); 811*0a7e5f1fSJoseph Mingrone nd_printjn(ndo, tp, optlen); 812*0a7e5f1fSJoseph Mingrone ND_PRINT(")"); 813*0a7e5f1fSJoseph Mingrone break; 814*0a7e5f1fSJoseph Mingrone 815*0a7e5f1fSJoseph Mingrone case DH6OPT_SZTP_REDIRECT: 816*0a7e5f1fSJoseph Mingrone case DH6OPT_USER_CLASS: 817*0a7e5f1fSJoseph Mingrone ND_PRINT(" "); 818*0a7e5f1fSJoseph Mingrone tp = (const u_char *)(dh6o + 1); 819*0a7e5f1fSJoseph Mingrone first_list_value = TRUE; 820*0a7e5f1fSJoseph Mingrone remainder_len = optlen; 821*0a7e5f1fSJoseph Mingrone while (remainder_len >= 2) { 822*0a7e5f1fSJoseph Mingrone if (first_list_value == FALSE) { 823*0a7e5f1fSJoseph Mingrone ND_PRINT(","); 824*0a7e5f1fSJoseph Mingrone } 825*0a7e5f1fSJoseph Mingrone first_list_value = FALSE; 826*0a7e5f1fSJoseph Mingrone subopt_len = GET_BE_U_2(tp); 827*0a7e5f1fSJoseph Mingrone if (subopt_len > remainder_len-2) { 828*0a7e5f1fSJoseph Mingrone break; 829*0a7e5f1fSJoseph Mingrone } 830*0a7e5f1fSJoseph Mingrone tp += 2; 831*0a7e5f1fSJoseph Mingrone nd_printjn(ndo, tp, subopt_len); 832*0a7e5f1fSJoseph Mingrone tp += subopt_len; 833*0a7e5f1fSJoseph Mingrone remainder_len -= (subopt_len+2); 834*0a7e5f1fSJoseph Mingrone } 835*0a7e5f1fSJoseph Mingrone if (remainder_len != 0 ) { 836*0a7e5f1fSJoseph Mingrone ND_PRINT(" ?"); 837*0a7e5f1fSJoseph Mingrone } 838*0a7e5f1fSJoseph Mingrone ND_PRINT(")"); 839*0a7e5f1fSJoseph Mingrone break; 840*0a7e5f1fSJoseph Mingrone 8419afd0c29SBill Fenner default: 842ee67461eSJoseph Mingrone ND_PRINT(")"); 8439afd0c29SBill Fenner break; 8449afd0c29SBill Fenner } 8459afd0c29SBill Fenner 8469afd0c29SBill Fenner cp += sizeof(*dh6o) + optlen; 847b0453382SBill Fenner } 848b0453382SBill Fenner return; 849b0453382SBill Fenner 850b0453382SBill Fenner trunc: 851ee67461eSJoseph Mingrone nd_print_trunc(ndo); 852b0453382SBill Fenner } 853b0453382SBill Fenner 854b0453382SBill Fenner /* 8559afd0c29SBill Fenner * Print dhcp6 packets 856b0453382SBill Fenner */ 857b0453382SBill Fenner void 8583c602fabSXin LI dhcp6_print(netdissect_options *ndo, 8593c602fabSXin LI const u_char *cp, u_int length) 860b0453382SBill Fenner { 8613340d773SGleb Smirnoff const struct dhcp6 *dh6; 8623340d773SGleb Smirnoff const struct dhcp6_relay *dh6relay; 863ee67461eSJoseph Mingrone uint8_t msgtype; 8645b0fe478SBruce M Simpson const u_char *ep; 8653340d773SGleb Smirnoff const u_char *extp; 8669afd0c29SBill Fenner const char *name; 867b0453382SBill Fenner 868ee67461eSJoseph Mingrone ndo->ndo_protocol = "dhcp6"; 869ee67461eSJoseph Mingrone ND_PRINT("dhcp6"); 870b0453382SBill Fenner 871ee67461eSJoseph Mingrone ep = ndo->ndo_snapend; 8725b0fe478SBruce M Simpson if (cp + length < ep) 8735b0fe478SBruce M Simpson ep = cp + length; 874b0453382SBill Fenner 8753340d773SGleb Smirnoff dh6 = (const struct dhcp6 *)cp; 8763340d773SGleb Smirnoff dh6relay = (const struct dhcp6_relay *)cp; 877ee67461eSJoseph Mingrone ND_TCHECK_4(dh6->dh6_msgtypexid.xid); 878ee67461eSJoseph Mingrone msgtype = GET_U_1(dh6->dh6_msgtypexid.msgtype); 879ee67461eSJoseph Mingrone name = tok2str(dh6_msgtype_str, "msgtype-%u", msgtype); 8809afd0c29SBill Fenner 8813c602fabSXin LI if (!ndo->ndo_vflag) { 882ee67461eSJoseph Mingrone ND_PRINT(" %s", name); 8839afd0c29SBill Fenner return; 884b0453382SBill Fenner } 8859afd0c29SBill Fenner 8869afd0c29SBill Fenner /* XXX relay agent messages have to be handled differently */ 8879afd0c29SBill Fenner 888ee67461eSJoseph Mingrone ND_PRINT(" %s (", name); /*)*/ 889ee67461eSJoseph Mingrone if (msgtype != DH6_RELAY_FORW && msgtype != DH6_RELAY_REPLY) { 890ee67461eSJoseph Mingrone ND_PRINT("xid=%x", 891ee67461eSJoseph Mingrone GET_BE_U_4(dh6->dh6_msgtypexid.xid) & DH6_XIDMASK); 8923340d773SGleb Smirnoff extp = (const u_char *)(dh6 + 1); 8933c602fabSXin LI dhcp6opt_print(ndo, extp, ep); 8945b0fe478SBruce M Simpson } else { /* relay messages */ 895ee67461eSJoseph Mingrone ND_PRINT("linkaddr=%s", GET_IP6ADDR_STRING(dh6relay->dh6relay_linkaddr)); 8965b0fe478SBruce M Simpson 897ee67461eSJoseph Mingrone ND_PRINT(" peeraddr=%s", GET_IP6ADDR_STRING(dh6relay->dh6relay_peeraddr)); 8985b0fe478SBruce M Simpson 8993340d773SGleb Smirnoff dhcp6opt_print(ndo, (const u_char *)(dh6relay + 1), ep); 9005b0fe478SBruce M Simpson } 901685295f4SBill Fenner /*(*/ 902ee67461eSJoseph Mingrone ND_PRINT(")"); 903b0453382SBill Fenner return; 904b0453382SBill Fenner 905b0453382SBill Fenner trunc: 906ee67461eSJoseph Mingrone nd_print_trunc(ndo); 907b0453382SBill Fenner } 908