xref: /freebsd/contrib/tcpdump/print-dhcp6.c (revision d03c0883ad6dcda67e9281df01f1940292dee669)
1b0453382SBill Fenner /*
2b0453382SBill Fenner  * Copyright (C) 1998 and 1999 WIDE Project.
3b0453382SBill Fenner  * All rights reserved.
4b0453382SBill Fenner  *
5b0453382SBill Fenner  * Redistribution and use in source and binary forms, with or without
6b0453382SBill Fenner  * modification, are permitted provided that the following conditions
7b0453382SBill Fenner  * are met:
8b0453382SBill Fenner  * 1. Redistributions of source code must retain the above copyright
9b0453382SBill Fenner  *    notice, this list of conditions and the following disclaimer.
10b0453382SBill Fenner  * 2. Redistributions in binary form must reproduce the above copyright
11b0453382SBill Fenner  *    notice, this list of conditions and the following disclaimer in the
12b0453382SBill Fenner  *    documentation and/or other materials provided with the distribution.
13b0453382SBill Fenner  * 3. Neither the name of the project nor the names of its contributors
14b0453382SBill Fenner  *    may be used to endorse or promote products derived from this software
15b0453382SBill Fenner  *    without specific prior written permission.
16b0453382SBill Fenner  *
17b0453382SBill Fenner  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18b0453382SBill Fenner  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19b0453382SBill Fenner  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20b0453382SBill Fenner  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21b0453382SBill Fenner  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22b0453382SBill Fenner  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23b0453382SBill Fenner  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24b0453382SBill Fenner  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25b0453382SBill Fenner  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26b0453382SBill Fenner  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27b0453382SBill Fenner  * SUCH DAMAGE.
28b0453382SBill Fenner  */
299afd0c29SBill Fenner /*
305b0fe478SBruce M Simpson  * RFC3315: DHCPv6
315b0fe478SBruce M Simpson  * supported DHCPv6 options:
32*d03c0883SXin LI  *  RFC3319: Session Initiation Protocol (SIP) Servers options,
33*d03c0883SXin LI  *  RFC3633: IPv6 Prefix options,
34*d03c0883SXin LI  *  RFC3646: DNS Configuration options,
35*d03c0883SXin LI  *  RFC3898: Network Information Service (NIS) Configuration options,
36*d03c0883SXin LI  *  RFC4075: Simple Network Time Protocol (SNTP) Configuration option,
37*d03c0883SXin LI  *  RFC4242: Information Refresh Time option,
38*d03c0883SXin LI  *  RFC4280: Broadcast and Multicast Control Servers options,
39*d03c0883SXin LI  *  RFC6334: Dual-Stack Lite option,
409afd0c29SBill Fenner  */
41b0453382SBill Fenner 
42b0453382SBill Fenner #ifndef lint
435b0fe478SBruce M Simpson static const char rcsid[] _U_ =
4427df3f5dSRui Paulo     "@(#) $Header: /tcpdump/master/tcpdump/print-dhcp6.c,v 1.37 2008-02-06 10:26:09 guy Exp $";
45b0453382SBill Fenner #endif
46b0453382SBill Fenner 
47b0453382SBill Fenner #ifdef HAVE_CONFIG_H
48b0453382SBill Fenner #include "config.h"
49b0453382SBill Fenner #endif
50b0453382SBill Fenner 
515b0fe478SBruce M Simpson #include <tcpdump-stdinc.h>
52b0453382SBill Fenner 
53b0453382SBill Fenner #include <stdio.h>
54b0453382SBill Fenner #include <string.h>
55b0453382SBill Fenner 
56b0453382SBill Fenner #include "interface.h"
57b0453382SBill Fenner #include "addrtoname.h"
585b0fe478SBruce M Simpson #include "extract.h"
595b0fe478SBruce M Simpson 
605b0fe478SBruce M Simpson /* lease duration */
615b0fe478SBruce M Simpson #define DHCP6_DURATITION_INFINITE 0xffffffff
62b0453382SBill Fenner 
639afd0c29SBill Fenner /* Error Values */
649afd0c29SBill Fenner #define DH6ERR_FAILURE		16
659afd0c29SBill Fenner #define DH6ERR_AUTHFAIL		17
669afd0c29SBill Fenner #define DH6ERR_POORLYFORMED	18
679afd0c29SBill Fenner #define DH6ERR_UNAVAIL		19
689afd0c29SBill Fenner #define DH6ERR_OPTUNAVAIL	20
69b0453382SBill Fenner 
709afd0c29SBill Fenner /* Message type */
715b0fe478SBruce M Simpson #define DH6_SOLICIT	1
725b0fe478SBruce M Simpson #define DH6_ADVERTISE	2
735b0fe478SBruce M Simpson #define DH6_REQUEST	3
745b0fe478SBruce M Simpson #define DH6_CONFIRM	4
755b0fe478SBruce M Simpson #define DH6_RENEW	5
765b0fe478SBruce M Simpson #define DH6_REBIND	6
779afd0c29SBill Fenner #define DH6_REPLY	7
785b0fe478SBruce M Simpson #define DH6_RELEASE	8
795b0fe478SBruce M Simpson #define DH6_DECLINE	9
805b0fe478SBruce M Simpson #define DH6_RECONFIGURE	10
819afd0c29SBill Fenner #define DH6_INFORM_REQ	11
825b0fe478SBruce M Simpson #define DH6_RELAY_FORW	12
835b0fe478SBruce M Simpson #define DH6_RELAY_REPLY	13
84a5779b6eSRui Paulo #define DH6_LEASEQUERY	14
85a5779b6eSRui Paulo #define DH6_LQ_REPLY	15
86b0453382SBill Fenner 
879afd0c29SBill Fenner /* DHCP6 base packet format */
889afd0c29SBill Fenner struct dhcp6 {
899afd0c29SBill Fenner 	union {
909afd0c29SBill Fenner 		u_int8_t m;
919afd0c29SBill Fenner 		u_int32_t x;
929afd0c29SBill Fenner 	} dh6_msgtypexid;
939afd0c29SBill Fenner 	/* options follow */
945b0fe478SBruce M Simpson };
959afd0c29SBill Fenner #define dh6_msgtype	dh6_msgtypexid.m
969afd0c29SBill Fenner #define dh6_xid		dh6_msgtypexid.x
979afd0c29SBill Fenner #define DH6_XIDMASK	0x00ffffff
98b0453382SBill Fenner 
995b0fe478SBruce M Simpson /* DHCPv6 relay messages */
1005b0fe478SBruce M Simpson struct dhcp6_relay {
1015b0fe478SBruce M Simpson 	u_int8_t dh6relay_msgtype;
1025b0fe478SBruce M Simpson 	u_int8_t dh6relay_hcnt;
1035b0fe478SBruce M Simpson 	u_int8_t dh6relay_linkaddr[16];	/* XXX: badly aligned */
1045b0fe478SBruce M Simpson 	u_int8_t dh6relay_peeraddr[16];
1055b0fe478SBruce M Simpson 	/* options follow */
1065b0fe478SBruce M Simpson };
1075b0fe478SBruce M Simpson 
1085b0fe478SBruce M Simpson /* options */
1095b0fe478SBruce M Simpson #define DH6OPT_CLIENTID	1
1105b0fe478SBruce M Simpson #define DH6OPT_SERVERID	2
1115b0fe478SBruce M Simpson #define DH6OPT_IA_NA 3
112b5bfcb5dSMax Laier #define DH6OPT_IA_TA 4
113b5bfcb5dSMax Laier #define DH6OPT_IA_ADDR 5
1145b0fe478SBruce M Simpson #define DH6OPT_ORO 6
1155b0fe478SBruce M Simpson #define DH6OPT_PREFERENCE 7
1165b0fe478SBruce M Simpson #  define DH6OPT_PREF_MAX 255
1175b0fe478SBruce M Simpson #define DH6OPT_ELAPSED_TIME 8
1185b0fe478SBruce M Simpson #define DH6OPT_RELAY_MSG 9
1195b0fe478SBruce M Simpson /*#define DH6OPT_SERVER_MSG 10 deprecated */
1205b0fe478SBruce M Simpson #define DH6OPT_AUTH 11
1211de50e9fSSam Leffler #  define DH6OPT_AUTHPROTO_DELAYED 2
1221de50e9fSSam Leffler #  define DH6OPT_AUTHPROTO_RECONFIG 3
1231de50e9fSSam Leffler #  define DH6OPT_AUTHALG_HMACMD5 1
1241de50e9fSSam Leffler #  define DH6OPT_AUTHRDM_MONOCOUNTER 0
1251de50e9fSSam Leffler #  define DH6OPT_AUTHRECONFIG_KEY 1
1261de50e9fSSam Leffler #  define DH6OPT_AUTHRECONFIG_HMACMD5 2
1275b0fe478SBruce M Simpson #define DH6OPT_UNICAST 12
1285b0fe478SBruce M Simpson #define DH6OPT_STATUS_CODE 13
1295b0fe478SBruce M Simpson #  define DH6OPT_STCODE_SUCCESS 0
1305b0fe478SBruce M Simpson #  define DH6OPT_STCODE_UNSPECFAIL 1
1315b0fe478SBruce M Simpson #  define DH6OPT_STCODE_NOADDRAVAIL 2
1325b0fe478SBruce M Simpson #  define DH6OPT_STCODE_NOBINDING 3
1335b0fe478SBruce M Simpson #  define DH6OPT_STCODE_NOTONLINK 4
1345b0fe478SBruce M Simpson #  define DH6OPT_STCODE_USEMULTICAST 5
1355b0fe478SBruce M Simpson #  define DH6OPT_STCODE_NOPREFIXAVAIL 6
136a5779b6eSRui Paulo #  define DH6OPT_STCODE_UNKNOWNQUERYTYPE 7
137a5779b6eSRui Paulo #  define DH6OPT_STCODE_MALFORMEDQUERY 8
138a5779b6eSRui Paulo #  define DH6OPT_STCODE_NOTCONFIGURED 9
139a5779b6eSRui Paulo #  define DH6OPT_STCODE_NOTALLOWED 10
1405b0fe478SBruce M Simpson #define DH6OPT_RAPID_COMMIT 14
1415b0fe478SBruce M Simpson #define DH6OPT_USER_CLASS 15
1425b0fe478SBruce M Simpson #define DH6OPT_VENDOR_CLASS 16
1435b0fe478SBruce M Simpson #define DH6OPT_VENDOR_OPTS 17
1445b0fe478SBruce M Simpson #define DH6OPT_INTERFACE_ID 18
1455b0fe478SBruce M Simpson #define DH6OPT_RECONF_MSG 19
1465b0fe478SBruce M Simpson #define DH6OPT_RECONF_ACCEPT 20
1475b0fe478SBruce M Simpson #define DH6OPT_SIP_SERVER_D 21
1485b0fe478SBruce M Simpson #define DH6OPT_SIP_SERVER_A 22
1495b0fe478SBruce M Simpson #define DH6OPT_DNS 23
1505b0fe478SBruce M Simpson #define DH6OPT_DNSNAME 24
1511de50e9fSSam Leffler #define DH6OPT_IA_PD 25
1521de50e9fSSam Leffler #define DH6OPT_IA_PD_PREFIX 26
153b5bfcb5dSMax Laier #define DH6OPT_NIS_SERVERS 27
154b5bfcb5dSMax Laier #define DH6OPT_NISP_SERVERS 28
155b5bfcb5dSMax Laier #define DH6OPT_NIS_NAME 29
156b5bfcb5dSMax Laier #define DH6OPT_NISP_NAME 30
157b5bfcb5dSMax Laier #define DH6OPT_NTP_SERVERS 31
158b5bfcb5dSMax Laier #define DH6OPT_LIFETIME 32
159b5bfcb5dSMax Laier #define DH6OPT_BCMCS_SERVER_D 33
160b5bfcb5dSMax Laier #define DH6OPT_BCMCS_SERVER_A 34
161b5bfcb5dSMax Laier #define DH6OPT_GEOCONF_CIVIC 36
162b5bfcb5dSMax Laier #define DH6OPT_REMOTE_ID 37
163b5bfcb5dSMax Laier #define DH6OPT_SUBSCRIBER_ID 38
164b5bfcb5dSMax Laier #define DH6OPT_CLIENT_FQDN 39
165a5779b6eSRui Paulo #define DH6OPT_PANA_AGENT 40
166a5779b6eSRui Paulo #define DH6OPT_NEW_POSIX_TIMEZONE 41
167a5779b6eSRui Paulo #define DH6OPT_NEW_TZDB_TIMEZONE 42
168a5779b6eSRui Paulo #define DH6OPT_ERO 43
169a5779b6eSRui Paulo #define DH6OPT_LQ_QUERY 44
170a5779b6eSRui Paulo #define DH6OPT_CLIENT_DATA 45
171a5779b6eSRui Paulo #define DH6OPT_CLT_TIME 46
172a5779b6eSRui Paulo #define DH6OPT_LQ_RELAY_DATA 47
173a5779b6eSRui Paulo #define DH6OPT_LQ_CLIENT_LINK 48
174*d03c0883SXin LI #define DH6OPT_AFTR_NAME 64
1755b0fe478SBruce M Simpson 
1769afd0c29SBill Fenner struct dhcp6opt {
1779afd0c29SBill Fenner 	u_int16_t dh6opt_type;
1789afd0c29SBill Fenner 	u_int16_t dh6opt_len;
1799afd0c29SBill Fenner 	/* type-dependent data follows */
1805b0fe478SBruce M Simpson };
1815b0fe478SBruce M Simpson 
1825b0fe478SBruce M Simpson static const char *
1835b0fe478SBruce M Simpson dhcp6opt_name(int type)
1845b0fe478SBruce M Simpson {
1855b0fe478SBruce M Simpson 	static char genstr[sizeof("opt_65535") + 1]; /* XXX thread unsafe */
1865b0fe478SBruce M Simpson 
1875b0fe478SBruce M Simpson 	if (type > 65535)
18827df3f5dSRui Paulo 		return "INVALID-option";
1895b0fe478SBruce M Simpson 
1905b0fe478SBruce M Simpson 	switch(type) {
1915b0fe478SBruce M Simpson 	case DH6OPT_CLIENTID:
19227df3f5dSRui Paulo 		return "client-ID";
1935b0fe478SBruce M Simpson 	case DH6OPT_SERVERID:
19427df3f5dSRui Paulo 		return "server-ID";
1955b0fe478SBruce M Simpson 	case DH6OPT_IA_NA:
1965b0fe478SBruce M Simpson 		return "IA_NA";
197b5bfcb5dSMax Laier 	case DH6OPT_IA_TA:
198b5bfcb5dSMax Laier 		return "IA_TA";
199b5bfcb5dSMax Laier 	case DH6OPT_IA_ADDR:
200b5bfcb5dSMax Laier 		return "IA_ADDR";
2015b0fe478SBruce M Simpson 	case DH6OPT_ORO:
20227df3f5dSRui Paulo 		return "option-request";
2035b0fe478SBruce M Simpson 	case DH6OPT_PREFERENCE:
2045b0fe478SBruce M Simpson 		return "preference";
2055b0fe478SBruce M Simpson 	case DH6OPT_ELAPSED_TIME:
20627df3f5dSRui Paulo 		return "elapsed-time";
2075b0fe478SBruce M Simpson 	case DH6OPT_RELAY_MSG:
20827df3f5dSRui Paulo 		return "relay-message";
2091de50e9fSSam Leffler 	case DH6OPT_AUTH:
2101de50e9fSSam Leffler 		return "authentication";
2111de50e9fSSam Leffler 	case DH6OPT_UNICAST:
21227df3f5dSRui Paulo 		return "server-unicast";
2135b0fe478SBruce M Simpson 	case DH6OPT_STATUS_CODE:
21427df3f5dSRui Paulo 		return "status-code";
2155b0fe478SBruce M Simpson 	case DH6OPT_RAPID_COMMIT:
21627df3f5dSRui Paulo 		return "rapid-commit";
2171de50e9fSSam Leffler 	case DH6OPT_USER_CLASS:
21827df3f5dSRui Paulo 		return "user-class";
2191de50e9fSSam Leffler 	case DH6OPT_VENDOR_CLASS:
22027df3f5dSRui Paulo 		return "vendor-class";
2211de50e9fSSam Leffler 	case DH6OPT_VENDOR_OPTS:
22227df3f5dSRui Paulo 		return "vendor-specific-info";
2235b0fe478SBruce M Simpson 	case DH6OPT_INTERFACE_ID:
22427df3f5dSRui Paulo 		return "interface-ID";
2255b0fe478SBruce M Simpson 	case DH6OPT_RECONF_MSG:
22627df3f5dSRui Paulo 		return "reconfigure-message";
2275b0fe478SBruce M Simpson 	case DH6OPT_RECONF_ACCEPT:
22827df3f5dSRui Paulo 		return "reconfigure-accept";
2295b0fe478SBruce M Simpson 	case DH6OPT_SIP_SERVER_D:
23027df3f5dSRui Paulo 		return "SIP-servers-domain";
2315b0fe478SBruce M Simpson 	case DH6OPT_SIP_SERVER_A:
23227df3f5dSRui Paulo 		return "SIP-servers-address";
2335b0fe478SBruce M Simpson 	case DH6OPT_DNS:
234cac3dcd5SXin LI 		return "DNS-server";
2351de50e9fSSam Leffler 	case DH6OPT_DNSNAME:
236cac3dcd5SXin LI 		return "DNS-search-list";
2375b0fe478SBruce M Simpson 	case DH6OPT_IA_PD:
2385b0fe478SBruce M Simpson 		return "IA_PD";
2395b0fe478SBruce M Simpson 	case DH6OPT_IA_PD_PREFIX:
24027df3f5dSRui Paulo 		return "IA_PD-prefix";
2415b0fe478SBruce M Simpson 	case DH6OPT_NTP_SERVERS:
242cac3dcd5SXin LI 		return "NTP-server";
2431de50e9fSSam Leffler 	case DH6OPT_LIFETIME:
2441de50e9fSSam Leffler 		return "lifetime";
245b5bfcb5dSMax Laier 	case DH6OPT_NIS_SERVERS:
24627df3f5dSRui Paulo 		return "NIS-server";
247b5bfcb5dSMax Laier 	case DH6OPT_NISP_SERVERS:
24827df3f5dSRui Paulo 		return "NIS+-server";
249b5bfcb5dSMax Laier 	case DH6OPT_NIS_NAME:
25027df3f5dSRui Paulo 		return "NIS-domain-name";
251b5bfcb5dSMax Laier 	case DH6OPT_NISP_NAME:
25227df3f5dSRui Paulo 		return "NIS+-domain-name";
253b5bfcb5dSMax Laier 	case DH6OPT_BCMCS_SERVER_D:
25427df3f5dSRui Paulo 		return "BCMCS-domain-name";
255b5bfcb5dSMax Laier 	case DH6OPT_BCMCS_SERVER_A:
25627df3f5dSRui Paulo 		return "BCMCS-server";
257b5bfcb5dSMax Laier 	case DH6OPT_GEOCONF_CIVIC:
25827df3f5dSRui Paulo 		return "Geoconf-Civic";
259b5bfcb5dSMax Laier 	case DH6OPT_REMOTE_ID:
26027df3f5dSRui Paulo 		return "Remote-ID";
261b5bfcb5dSMax Laier 	case DH6OPT_SUBSCRIBER_ID:
26227df3f5dSRui Paulo 		return "Subscriber-ID";
263b5bfcb5dSMax Laier 	case DH6OPT_CLIENT_FQDN:
26427df3f5dSRui Paulo 		return "Client-FQDN";
265a5779b6eSRui Paulo 	case DH6OPT_PANA_AGENT:
26627df3f5dSRui Paulo 		return "PANA-agent";
267a5779b6eSRui Paulo 	case DH6OPT_NEW_POSIX_TIMEZONE:
26827df3f5dSRui Paulo 		return "POSIX-timezone";
269a5779b6eSRui Paulo 	case DH6OPT_NEW_TZDB_TIMEZONE:
27027df3f5dSRui Paulo 		return "POSIX-tz-database";
271a5779b6eSRui Paulo 	case DH6OPT_ERO:
27227df3f5dSRui Paulo 		return "Echo-request-option";
273a5779b6eSRui Paulo 	case DH6OPT_LQ_QUERY:
27427df3f5dSRui Paulo 		return "Lease-query";
275a5779b6eSRui Paulo 	case DH6OPT_CLIENT_DATA:
27627df3f5dSRui Paulo 		return "LQ-client-data";
277a5779b6eSRui Paulo 	case DH6OPT_CLT_TIME:
27827df3f5dSRui Paulo 		return "Clt-time";
279a5779b6eSRui Paulo 	case DH6OPT_LQ_RELAY_DATA:
28027df3f5dSRui Paulo 		return "LQ-relay-data";
281a5779b6eSRui Paulo 	case DH6OPT_LQ_CLIENT_LINK:
28227df3f5dSRui Paulo 		return "LQ-client-link";
283*d03c0883SXin LI 	case DH6OPT_AFTR_NAME:
284*d03c0883SXin LI 		return "AFTR-Name";
2855b0fe478SBruce M Simpson 	default:
2865b0fe478SBruce M Simpson 		snprintf(genstr, sizeof(genstr), "opt_%d", type);
2875b0fe478SBruce M Simpson 		return(genstr);
2885b0fe478SBruce M Simpson 	}
2895b0fe478SBruce M Simpson }
2905b0fe478SBruce M Simpson 
2915b0fe478SBruce M Simpson static const char *
2925b0fe478SBruce M Simpson dhcp6stcode(int code)
2935b0fe478SBruce M Simpson {
2945b0fe478SBruce M Simpson 	static char genstr[sizeof("code255") + 1]; /* XXX thread unsafe */
2955b0fe478SBruce M Simpson 
2965b0fe478SBruce M Simpson 	if (code > 255)
2975b0fe478SBruce M Simpson 		return "INVALID code";
2985b0fe478SBruce M Simpson 
2995b0fe478SBruce M Simpson 	switch(code) {
3005b0fe478SBruce M Simpson 	case DH6OPT_STCODE_SUCCESS:
3015b0fe478SBruce M Simpson 		return "success";
3025b0fe478SBruce M Simpson 	case DH6OPT_STCODE_UNSPECFAIL:
3035b0fe478SBruce M Simpson 		return "unspec failure";
3045b0fe478SBruce M Simpson 	case DH6OPT_STCODE_NOADDRAVAIL:
3055b0fe478SBruce M Simpson 		return "no addresses";
3065b0fe478SBruce M Simpson 	case DH6OPT_STCODE_NOBINDING:
3075b0fe478SBruce M Simpson 		return "no binding";
3085b0fe478SBruce M Simpson 	case DH6OPT_STCODE_NOTONLINK:
3095b0fe478SBruce M Simpson 		return "not on-link";
3105b0fe478SBruce M Simpson 	case DH6OPT_STCODE_USEMULTICAST:
3115b0fe478SBruce M Simpson 		return "use multicast";
3125b0fe478SBruce M Simpson 	case DH6OPT_STCODE_NOPREFIXAVAIL:
3135b0fe478SBruce M Simpson 		return "no prefixes";
314a5779b6eSRui Paulo 	case DH6OPT_STCODE_UNKNOWNQUERYTYPE:
315a5779b6eSRui Paulo 		return "unknown query type";
316a5779b6eSRui Paulo 	case DH6OPT_STCODE_MALFORMEDQUERY:
317a5779b6eSRui Paulo 		return "malformed query";
318a5779b6eSRui Paulo 	case DH6OPT_STCODE_NOTCONFIGURED:
319a5779b6eSRui Paulo 		return "not configured";
320a5779b6eSRui Paulo 	case DH6OPT_STCODE_NOTALLOWED:
321a5779b6eSRui Paulo 		return "not allowed";
3225b0fe478SBruce M Simpson 	default:
3235b0fe478SBruce M Simpson 		snprintf(genstr, sizeof(genstr), "code%d", code);
3245b0fe478SBruce M Simpson 		return(genstr);
3255b0fe478SBruce M Simpson 	}
3265b0fe478SBruce M Simpson }
3275b0fe478SBruce M Simpson 
328b0453382SBill Fenner static void
3295b0fe478SBruce M Simpson dhcp6opt_print(const u_char *cp, const u_char *ep)
330b0453382SBill Fenner {
3319afd0c29SBill Fenner 	struct dhcp6opt *dh6o;
3329afd0c29SBill Fenner 	u_char *tp;
3335b0fe478SBruce M Simpson 	size_t i;
3345b0fe478SBruce M Simpson 	u_int16_t opttype;
3359afd0c29SBill Fenner 	size_t optlen;
33627df3f5dSRui Paulo 	u_int8_t auth_proto;
3371de50e9fSSam Leffler 	u_int authinfolen, authrealmlen;
338b0453382SBill Fenner 
339b0453382SBill Fenner 	if (cp == ep)
340b0453382SBill Fenner 		return;
341b0453382SBill Fenner 	while (cp < ep) {
3425b0fe478SBruce M Simpson 		if (ep < cp + sizeof(*dh6o))
343b0453382SBill Fenner 			goto trunc;
3449afd0c29SBill Fenner 		dh6o = (struct dhcp6opt *)cp;
345*d03c0883SXin LI 		TCHECK(*dh6o);
3465b0fe478SBruce M Simpson 		optlen = EXTRACT_16BITS(&dh6o->dh6opt_len);
3475b0fe478SBruce M Simpson 		if (ep < cp + sizeof(*dh6o) + optlen)
348b0453382SBill Fenner 			goto trunc;
3495b0fe478SBruce M Simpson 		opttype = EXTRACT_16BITS(&dh6o->dh6opt_type);
3505b0fe478SBruce M Simpson 		printf(" (%s", dhcp6opt_name(opttype));
3515b0fe478SBruce M Simpson 		switch (opttype) {
3525b0fe478SBruce M Simpson 		case DH6OPT_CLIENTID:
3535b0fe478SBruce M Simpson 		case DH6OPT_SERVERID:
3549afd0c29SBill Fenner 			if (optlen < 2) {
3559afd0c29SBill Fenner 				/*(*/
3565b0fe478SBruce M Simpson 				printf(" ?)");
357b0453382SBill Fenner 				break;
358b0453382SBill Fenner 			}
3599afd0c29SBill Fenner 			tp = (u_char *)(dh6o + 1);
3605b0fe478SBruce M Simpson 			switch (EXTRACT_16BITS(tp)) {
3619afd0c29SBill Fenner 			case 1:
3629afd0c29SBill Fenner 				if (optlen >= 2 + 6) {
3635b0fe478SBruce M Simpson 					printf(" hwaddr/time type %u time %u ",
3645b0fe478SBruce M Simpson 					    EXTRACT_16BITS(&tp[2]),
3655b0fe478SBruce M Simpson 					    EXTRACT_32BITS(&tp[4]));
3669afd0c29SBill Fenner 					for (i = 8; i < optlen; i++)
3679afd0c29SBill Fenner 						printf("%02x", tp[i]);
3689afd0c29SBill Fenner 					/*(*/
369b0453382SBill Fenner 					printf(")");
3709afd0c29SBill Fenner 				} else {
3719afd0c29SBill Fenner 					/*(*/
3725b0fe478SBruce M Simpson 					printf(" ?)");
3739afd0c29SBill Fenner 				}
3749afd0c29SBill Fenner 				break;
3759afd0c29SBill Fenner 			case 2:
3769afd0c29SBill Fenner 				if (optlen >= 2 + 8) {
3779afd0c29SBill Fenner 					printf(" vid ");
3789afd0c29SBill Fenner 					for (i = 2; i < 2 + 8; i++)
3799afd0c29SBill Fenner 						printf("%02x", tp[i]);
3809afd0c29SBill Fenner 					/*(*/
3819afd0c29SBill Fenner 					printf(")");
3829afd0c29SBill Fenner 				} else {
3839afd0c29SBill Fenner 					/*(*/
3845b0fe478SBruce M Simpson 					printf(" ?)");
3859afd0c29SBill Fenner 				}
3869afd0c29SBill Fenner 				break;
3879afd0c29SBill Fenner 			case 3:
3889afd0c29SBill Fenner 				if (optlen >= 2 + 2) {
3899afd0c29SBill Fenner 					printf(" hwaddr type %u ",
3905b0fe478SBruce M Simpson 					    EXTRACT_16BITS(&tp[2]));
3919afd0c29SBill Fenner 					for (i = 4; i < optlen; i++)
3929afd0c29SBill Fenner 						printf("%02x", tp[i]);
3939afd0c29SBill Fenner 					/*(*/
3949afd0c29SBill Fenner 					printf(")");
3959afd0c29SBill Fenner 				} else {
3969afd0c29SBill Fenner 					/*(*/
3975b0fe478SBruce M Simpson 					printf(" ?)");
3989afd0c29SBill Fenner 				}
3999afd0c29SBill Fenner 				break;
4005b0fe478SBruce M Simpson 			default:
4015b0fe478SBruce M Simpson 				printf(" type %d)", EXTRACT_16BITS(tp));
4025b0fe478SBruce M Simpson 				break;
4035b0fe478SBruce M Simpson 			}
4045b0fe478SBruce M Simpson 			break;
405b5bfcb5dSMax Laier 		case DH6OPT_IA_ADDR:
40627df3f5dSRui Paulo 			if (optlen < 24) {
40727df3f5dSRui Paulo 				/*(*/
408b5bfcb5dSMax Laier 				printf(" ?)");
409b5bfcb5dSMax Laier 				break;
410b5bfcb5dSMax Laier 			}
41127df3f5dSRui Paulo 			tp = (u_char *)(dh6o + 1);
41227df3f5dSRui Paulo 			printf(" %s", ip6addr_string(&tp[0]));
41327df3f5dSRui Paulo 			printf(" pltime:%u vltime:%u",
41427df3f5dSRui Paulo 			    EXTRACT_32BITS(&tp[16]),
41527df3f5dSRui Paulo 			    EXTRACT_32BITS(&tp[20]));
41627df3f5dSRui Paulo 			if (optlen > 24) {
417b5bfcb5dSMax Laier 				/* there are sub-options */
418*d03c0883SXin LI 				dhcp6opt_print(tp + 24, tp + optlen);
419b5bfcb5dSMax Laier 			}
420b5bfcb5dSMax Laier 			printf(")");
421b5bfcb5dSMax Laier 			break;
4225b0fe478SBruce M Simpson 		case DH6OPT_ORO:
423a5779b6eSRui Paulo 		case DH6OPT_ERO:
4245b0fe478SBruce M Simpson 			if (optlen % 2) {
4255b0fe478SBruce M Simpson 				printf(" ?)");
4265b0fe478SBruce M Simpson 				break;
4275b0fe478SBruce M Simpson 			}
4285b0fe478SBruce M Simpson 			tp = (u_char *)(dh6o + 1);
4295b0fe478SBruce M Simpson 			for (i = 0; i < optlen; i += 2) {
43027df3f5dSRui Paulo 				printf(" %s",
43127df3f5dSRui Paulo 				    dhcp6opt_name(EXTRACT_16BITS(&tp[i])));
4325b0fe478SBruce M Simpson 			}
4335b0fe478SBruce M Simpson 			printf(")");
4345b0fe478SBruce M Simpson 			break;
4355b0fe478SBruce M Simpson 		case DH6OPT_PREFERENCE:
4365b0fe478SBruce M Simpson 			if (optlen != 1) {
4375b0fe478SBruce M Simpson 				printf(" ?)");
4385b0fe478SBruce M Simpson 				break;
4395b0fe478SBruce M Simpson 			}
44027df3f5dSRui Paulo 			tp = (u_char *)(dh6o + 1);
44127df3f5dSRui Paulo 			printf(" %d)", *tp);
4425b0fe478SBruce M Simpson 			break;
4435b0fe478SBruce M Simpson 		case DH6OPT_ELAPSED_TIME:
4445b0fe478SBruce M Simpson 			if (optlen != 2) {
4455b0fe478SBruce M Simpson 				printf(" ?)");
4465b0fe478SBruce M Simpson 				break;
4475b0fe478SBruce M Simpson 			}
44827df3f5dSRui Paulo 			tp = (u_char *)(dh6o + 1);
44927df3f5dSRui Paulo 			printf(" %d)", EXTRACT_16BITS(tp));
4505b0fe478SBruce M Simpson 			break;
4515b0fe478SBruce M Simpson 		case DH6OPT_RELAY_MSG:
4525b0fe478SBruce M Simpson 			printf(" (");
45327df3f5dSRui Paulo 			tp = (u_char *)(dh6o + 1);
45427df3f5dSRui Paulo 			dhcp6_print(tp, optlen);
4555b0fe478SBruce M Simpson 			printf(")");
4565b0fe478SBruce M Simpson 			break;
4571de50e9fSSam Leffler 		case DH6OPT_AUTH:
45827df3f5dSRui Paulo 			if (optlen < 11) {
4591de50e9fSSam Leffler 				printf(" ?)");
4601de50e9fSSam Leffler 				break;
4611de50e9fSSam Leffler 			}
46227df3f5dSRui Paulo 			tp = (u_char *)(dh6o + 1);
46327df3f5dSRui Paulo 			auth_proto = *tp;
46427df3f5dSRui Paulo 			switch (auth_proto) {
4651de50e9fSSam Leffler 			case DH6OPT_AUTHPROTO_DELAYED:
4661de50e9fSSam Leffler 				printf(" proto: delayed");
4671de50e9fSSam Leffler 				break;
4681de50e9fSSam Leffler 			case DH6OPT_AUTHPROTO_RECONFIG:
4691de50e9fSSam Leffler 				printf(" proto: reconfigure");
4701de50e9fSSam Leffler 				break;
4711de50e9fSSam Leffler 			default:
47227df3f5dSRui Paulo 				printf(" proto: %d", auth_proto);
4731de50e9fSSam Leffler 				break;
4741de50e9fSSam Leffler 			}
47527df3f5dSRui Paulo 			tp++;
47627df3f5dSRui Paulo 			switch (*tp) {
4771de50e9fSSam Leffler 			case DH6OPT_AUTHALG_HMACMD5:
4781de50e9fSSam Leffler 				/* XXX: may depend on the protocol */
4791de50e9fSSam Leffler 				printf(", alg: HMAC-MD5");
4801de50e9fSSam Leffler 				break;
4811de50e9fSSam Leffler 			default:
48227df3f5dSRui Paulo 				printf(", alg: %d", *tp);
4831de50e9fSSam Leffler 				break;
4841de50e9fSSam Leffler 			}
48527df3f5dSRui Paulo 			tp++;
48627df3f5dSRui Paulo 			switch (*tp) {
4871de50e9fSSam Leffler 			case DH6OPT_AUTHRDM_MONOCOUNTER:
4881de50e9fSSam Leffler 				printf(", RDM: mono");
4891de50e9fSSam Leffler 				break;
4901de50e9fSSam Leffler 			default:
49127df3f5dSRui Paulo 				printf(", RDM: %d", *tp);
4921de50e9fSSam Leffler 				break;
4931de50e9fSSam Leffler 			}
49427df3f5dSRui Paulo 			tp++;
4951de50e9fSSam Leffler 			printf(", RD:");
49627df3f5dSRui Paulo 			for (i = 0; i < 4; i++, tp += 2)
4971de50e9fSSam Leffler 				printf(" %04x", EXTRACT_16BITS(tp));
4981de50e9fSSam Leffler 
4991de50e9fSSam Leffler 			/* protocol dependent part */
50027df3f5dSRui Paulo 			authinfolen = optlen - 11;
50127df3f5dSRui Paulo 			switch (auth_proto) {
5021de50e9fSSam Leffler 			case DH6OPT_AUTHPROTO_DELAYED:
5031de50e9fSSam Leffler 				if (authinfolen == 0)
5041de50e9fSSam Leffler 					break;
5051de50e9fSSam Leffler 				if (authinfolen < 20) {
5061de50e9fSSam Leffler 					printf(" ??");
5071de50e9fSSam Leffler 					break;
5081de50e9fSSam Leffler 				}
5091de50e9fSSam Leffler 				authrealmlen = authinfolen - 20;
5101de50e9fSSam Leffler 				if (authrealmlen > 0) {
5111de50e9fSSam Leffler 					printf(", realm: ");
5121de50e9fSSam Leffler 				}
5131de50e9fSSam Leffler 				for (i = 0; i < authrealmlen; i++, tp++)
5141de50e9fSSam Leffler 					printf("%02x", *tp);
5151de50e9fSSam Leffler 				printf(", key ID: %08x", EXTRACT_32BITS(tp));
5161de50e9fSSam Leffler 				tp += 4;
5171de50e9fSSam Leffler 				printf(", HMAC-MD5:");
5181de50e9fSSam Leffler 				for (i = 0; i < 4; i++, tp+= 4)
5191de50e9fSSam Leffler 					printf(" %08x", EXTRACT_32BITS(tp));
5201de50e9fSSam Leffler 				break;
5211de50e9fSSam Leffler 			case DH6OPT_AUTHPROTO_RECONFIG:
5221de50e9fSSam Leffler 				if (authinfolen != 17) {
5231de50e9fSSam Leffler 					printf(" ??");
5241de50e9fSSam Leffler 					break;
5251de50e9fSSam Leffler 				}
5261de50e9fSSam Leffler 				switch (*tp++) {
5271de50e9fSSam Leffler 				case DH6OPT_AUTHRECONFIG_KEY:
5281de50e9fSSam Leffler 					printf(" reconfig-key");
5291de50e9fSSam Leffler 					break;
5301de50e9fSSam Leffler 				case DH6OPT_AUTHRECONFIG_HMACMD5:
5311de50e9fSSam Leffler 					printf(" type: HMAC-MD5");
5321de50e9fSSam Leffler 					break;
5331de50e9fSSam Leffler 				default:
5341de50e9fSSam Leffler 					printf(" type: ??");
5351de50e9fSSam Leffler 					break;
5361de50e9fSSam Leffler 				}
5371de50e9fSSam Leffler 				printf(" value:");
5381de50e9fSSam Leffler 				for (i = 0; i < 4; i++, tp+= 4)
5391de50e9fSSam Leffler 					printf(" %08x", EXTRACT_32BITS(tp));
5401de50e9fSSam Leffler 				break;
5411de50e9fSSam Leffler 			default:
5421de50e9fSSam Leffler 				printf(" ??");
5431de50e9fSSam Leffler 				break;
5441de50e9fSSam Leffler 			}
5451de50e9fSSam Leffler 
5461de50e9fSSam Leffler 			printf(")");
5471de50e9fSSam Leffler 			break;
5485b0fe478SBruce M Simpson 		case DH6OPT_RAPID_COMMIT: /* nothing todo */
5495b0fe478SBruce M Simpson 			printf(")");
5505b0fe478SBruce M Simpson 			break;
5515b0fe478SBruce M Simpson 		case DH6OPT_INTERFACE_ID:
552a5779b6eSRui Paulo 		case DH6OPT_SUBSCRIBER_ID:
5535b0fe478SBruce M Simpson 			/*
5545b0fe478SBruce M Simpson 			 * Since we cannot predict the encoding, print hex dump
5555b0fe478SBruce M Simpson 			 * at most 10 characters.
5565b0fe478SBruce M Simpson 			 */
55727df3f5dSRui Paulo 			tp = (u_char *)(dh6o + 1);
558a5779b6eSRui Paulo 			printf(" ");
5595b0fe478SBruce M Simpson 			for (i = 0; i < optlen && i < 10; i++)
56027df3f5dSRui Paulo 				printf("%02x", tp[i]);
561a5779b6eSRui Paulo 			printf("...)");
5625b0fe478SBruce M Simpson 			break;
5635b0fe478SBruce M Simpson 		case DH6OPT_RECONF_MSG:
5645b0fe478SBruce M Simpson 			tp = (u_char *)(dh6o + 1);
5655b0fe478SBruce M Simpson 			switch (*tp) {
5665b0fe478SBruce M Simpson 			case DH6_RENEW:
5675b0fe478SBruce M Simpson 				printf(" for renew)");
5685b0fe478SBruce M Simpson 				break;
5695b0fe478SBruce M Simpson 			case DH6_INFORM_REQ:
5705b0fe478SBruce M Simpson 				printf(" for inf-req)");
5715b0fe478SBruce M Simpson 				break;
5725b0fe478SBruce M Simpson 			default:
5735b0fe478SBruce M Simpson 				printf(" for ?\?\?(%02x))", *tp);
5745b0fe478SBruce M Simpson 				break;
5755b0fe478SBruce M Simpson 			}
5765b0fe478SBruce M Simpson 			break;
5775b0fe478SBruce M Simpson 		case DH6OPT_RECONF_ACCEPT: /* nothing todo */
5785b0fe478SBruce M Simpson 			printf(")");
5795b0fe478SBruce M Simpson 			break;
5805b0fe478SBruce M Simpson 		case DH6OPT_SIP_SERVER_A:
5819afd0c29SBill Fenner 		case DH6OPT_DNS:
5825b0fe478SBruce M Simpson 		case DH6OPT_NTP_SERVERS:
583b5bfcb5dSMax Laier 		case DH6OPT_NIS_SERVERS:
584b5bfcb5dSMax Laier 		case DH6OPT_NISP_SERVERS:
585b5bfcb5dSMax Laier 		case DH6OPT_BCMCS_SERVER_A:
586a5779b6eSRui Paulo 		case DH6OPT_PANA_AGENT:
587a5779b6eSRui Paulo 		case DH6OPT_LQ_CLIENT_LINK:
5889afd0c29SBill Fenner 			if (optlen % 16) {
5895b0fe478SBruce M Simpson 				printf(" ?)");
5909afd0c29SBill Fenner 				break;
5919afd0c29SBill Fenner 			}
5929afd0c29SBill Fenner 			tp = (u_char *)(dh6o + 1);
5939afd0c29SBill Fenner 			for (i = 0; i < optlen; i += 16)
5949afd0c29SBill Fenner 				printf(" %s", ip6addr_string(&tp[i]));
5959afd0c29SBill Fenner 			printf(")");
5965b0fe478SBruce M Simpson 			break;
5975b0fe478SBruce M Simpson 		case DH6OPT_STATUS_CODE:
5985b0fe478SBruce M Simpson 			if (optlen < 2) {
5995b0fe478SBruce M Simpson 				printf(" ?)");
6005b0fe478SBruce M Simpson 				break;
6015b0fe478SBruce M Simpson 			}
60227df3f5dSRui Paulo 			tp = (u_char *)(dh6o + 1);
60327df3f5dSRui Paulo 			printf(" %s)", dhcp6stcode(EXTRACT_16BITS(&tp[0])));
6045b0fe478SBruce M Simpson 			break;
6055b0fe478SBruce M Simpson 		case DH6OPT_IA_NA:
6065b0fe478SBruce M Simpson 		case DH6OPT_IA_PD:
60727df3f5dSRui Paulo 			if (optlen < 12) {
6085b0fe478SBruce M Simpson 				printf(" ?)");
6095b0fe478SBruce M Simpson 				break;
6105b0fe478SBruce M Simpson 			}
61127df3f5dSRui Paulo 			tp = (u_char *)(dh6o + 1);
61227df3f5dSRui Paulo 			printf(" IAID:%u T1:%u T2:%u",
61327df3f5dSRui Paulo 			    EXTRACT_32BITS(&tp[0]),
61427df3f5dSRui Paulo 			    EXTRACT_32BITS(&tp[4]),
61527df3f5dSRui Paulo 			    EXTRACT_32BITS(&tp[8]));
61627df3f5dSRui Paulo 			if (optlen > 12) {
6175b0fe478SBruce M Simpson 				/* there are sub-options */
618*d03c0883SXin LI 				dhcp6opt_print(tp + 12, tp + optlen);
6195b0fe478SBruce M Simpson 			}
6205b0fe478SBruce M Simpson 			printf(")");
6215b0fe478SBruce M Simpson 			break;
622a5779b6eSRui Paulo 		case DH6OPT_IA_TA:
623a5779b6eSRui Paulo 			if (optlen < 4) {
624a5779b6eSRui Paulo 				printf(" ?)");
625a5779b6eSRui Paulo 				break;
626a5779b6eSRui Paulo 			}
62727df3f5dSRui Paulo 			tp = (u_char *)(dh6o + 1);
62827df3f5dSRui Paulo 			printf(" IAID:%u", EXTRACT_32BITS(tp));
629a5779b6eSRui Paulo 			if (optlen > 4) {
630a5779b6eSRui Paulo 				/* there are sub-options */
631*d03c0883SXin LI 				dhcp6opt_print(tp + 4, tp + optlen);
632a5779b6eSRui Paulo 			}
633a5779b6eSRui Paulo 			printf(")");
634a5779b6eSRui Paulo 			break;
6355b0fe478SBruce M Simpson 		case DH6OPT_IA_PD_PREFIX:
63627df3f5dSRui Paulo 			if (optlen < 25) {
6375b0fe478SBruce M Simpson 				printf(" ?)");
6385b0fe478SBruce M Simpson 				break;
6395b0fe478SBruce M Simpson 			}
64027df3f5dSRui Paulo 			tp = (u_char *)(dh6o + 1);
64127df3f5dSRui Paulo 			printf(" %s/%d", ip6addr_string(&tp[9]), tp[8]);
64227df3f5dSRui Paulo 			printf(" pltime:%u vltime:%u",
64327df3f5dSRui Paulo 			    EXTRACT_32BITS(&tp[0]),
64427df3f5dSRui Paulo 			    EXTRACT_32BITS(&tp[4]));
64527df3f5dSRui Paulo 			if (optlen > 25) {
6465b0fe478SBruce M Simpson 				/* there are sub-options */
647*d03c0883SXin LI 				dhcp6opt_print(tp + 25, tp + optlen);
6485b0fe478SBruce M Simpson 			}
6495b0fe478SBruce M Simpson 			printf(")");
6505b0fe478SBruce M Simpson 			break;
6511de50e9fSSam Leffler 		case DH6OPT_LIFETIME:
652a5779b6eSRui Paulo 		case DH6OPT_CLT_TIME:
6531de50e9fSSam Leffler 			if (optlen != 4) {
6541de50e9fSSam Leffler 				printf(" ?)");
6551de50e9fSSam Leffler 				break;
6561de50e9fSSam Leffler 			}
65727df3f5dSRui Paulo 			tp = (u_char *)(dh6o + 1);
65827df3f5dSRui Paulo 			printf(" %d)", EXTRACT_32BITS(tp));
6591de50e9fSSam Leffler 			break;
660a5779b6eSRui Paulo 		case DH6OPT_REMOTE_ID:
661a5779b6eSRui Paulo 			if (optlen < 4) {
662a5779b6eSRui Paulo 				printf(" ?)");
663a5779b6eSRui Paulo 				break;
664a5779b6eSRui Paulo 			}
665a5779b6eSRui Paulo 			tp = (u_char *)(dh6o + 1);
66627df3f5dSRui Paulo 			printf(" %d ", EXTRACT_32BITS(tp));
667a5779b6eSRui Paulo 			/*
668a5779b6eSRui Paulo 			 * Print hex dump first 10 characters.
669a5779b6eSRui Paulo 			 */
670a5779b6eSRui Paulo 			for (i = 4; i < optlen && i < 14; i++)
671a5779b6eSRui Paulo 				printf("%02x", tp[i]);
672a5779b6eSRui Paulo 			printf("...)");
673a5779b6eSRui Paulo 			break;
674a5779b6eSRui Paulo 		case DH6OPT_LQ_QUERY:
675a5779b6eSRui Paulo 			if (optlen < 17) {
676a5779b6eSRui Paulo 				printf(" ?)");
677a5779b6eSRui Paulo 				break;
678a5779b6eSRui Paulo 			}
679a5779b6eSRui Paulo 			tp = (u_char *)(dh6o + 1);
680a5779b6eSRui Paulo 			switch (*tp) {
681a5779b6eSRui Paulo 			case 1:
682a5779b6eSRui Paulo 				printf(" by-address");
683a5779b6eSRui Paulo 				break;
684a5779b6eSRui Paulo 			case 2:
685a5779b6eSRui Paulo 				printf(" by-clientID");
686a5779b6eSRui Paulo 				break;
687a5779b6eSRui Paulo 			default:
688a5779b6eSRui Paulo 				printf(" type_%d", (int)*tp);
689a5779b6eSRui Paulo 				break;
690a5779b6eSRui Paulo 			}
691a5779b6eSRui Paulo 			printf(" %s", ip6addr_string(&tp[1]));
692a5779b6eSRui Paulo 			if (optlen > 17) {
693a5779b6eSRui Paulo 				/* there are query-options */
694a5779b6eSRui Paulo 				dhcp6opt_print(tp + 17, tp + optlen);
695a5779b6eSRui Paulo 			}
696a5779b6eSRui Paulo 			printf(")");
697a5779b6eSRui Paulo 			break;
698a5779b6eSRui Paulo 		case DH6OPT_CLIENT_DATA:
69927df3f5dSRui Paulo 			tp = (u_char *)(dh6o + 1);
700a5779b6eSRui Paulo 			if (optlen > 0) {
701a5779b6eSRui Paulo 				/* there are encapsulated options */
70227df3f5dSRui Paulo 				dhcp6opt_print(tp, tp + optlen);
703a5779b6eSRui Paulo 			}
704a5779b6eSRui Paulo 			printf(")");
705a5779b6eSRui Paulo 			break;
706a5779b6eSRui Paulo 		case DH6OPT_LQ_RELAY_DATA:
707a5779b6eSRui Paulo 			if (optlen < 16) {
708a5779b6eSRui Paulo 				printf(" ?)");
709a5779b6eSRui Paulo 				break;
710a5779b6eSRui Paulo 			}
711a5779b6eSRui Paulo 			tp = (u_char *)(dh6o + 1);
712a5779b6eSRui Paulo 			printf(" %s ", ip6addr_string(&tp[0]));
713a5779b6eSRui Paulo 			/*
714a5779b6eSRui Paulo 			 * Print hex dump first 10 characters.
715a5779b6eSRui Paulo 			 */
716a5779b6eSRui Paulo 			for (i = 16; i < optlen && i < 26; i++)
717a5779b6eSRui Paulo 				printf("%02x", tp[i]);
718a5779b6eSRui Paulo 			printf("...)");
719a5779b6eSRui Paulo 			break;
720*d03c0883SXin LI 		case DH6OPT_AFTR_NAME:
721*d03c0883SXin LI 			if (optlen < 3) {
722*d03c0883SXin LI 				printf(" ?)");
723*d03c0883SXin LI 				break;
724*d03c0883SXin LI 			}
725*d03c0883SXin LI 			tp = (u_char *)(dh6o + 1);
726*d03c0883SXin LI 			int remain_len = optlen;
727*d03c0883SXin LI 			printf(" ");
728*d03c0883SXin LI 			/* Encoding is described in section 3.1 of RFC 1035 */
729*d03c0883SXin LI 			int label_len; /* Label length */
730*d03c0883SXin LI 			while (remain_len && *tp) {
731*d03c0883SXin LI 				label_len =  *tp++;
732*d03c0883SXin LI 				if (label_len < remain_len - 1) {
733*d03c0883SXin LI 					printf("%.*s", label_len, tp);
734*d03c0883SXin LI 					tp += label_len;
735*d03c0883SXin LI 					remain_len -= (label_len + 1);
736*d03c0883SXin LI 					if(*tp) printf(".");
737*d03c0883SXin LI 				} else {
738*d03c0883SXin LI 					printf(" ?");
739*d03c0883SXin LI 					break;
740*d03c0883SXin LI 				}
741*d03c0883SXin LI 			}
742*d03c0883SXin LI 			printf(")");
743*d03c0883SXin LI 			break;
7449afd0c29SBill Fenner 		default:
7455b0fe478SBruce M Simpson 			printf(")");
7469afd0c29SBill Fenner 			break;
7479afd0c29SBill Fenner 		}
7489afd0c29SBill Fenner 
7499afd0c29SBill Fenner 		cp += sizeof(*dh6o) + optlen;
750b0453382SBill Fenner 	}
751b0453382SBill Fenner 	return;
752b0453382SBill Fenner 
753b0453382SBill Fenner trunc:
754b0453382SBill Fenner 	printf("[|dhcp6ext]");
755b0453382SBill Fenner }
756b0453382SBill Fenner 
757b0453382SBill Fenner /*
7589afd0c29SBill Fenner  * Print dhcp6 packets
759b0453382SBill Fenner  */
760b0453382SBill Fenner void
7615b0fe478SBruce M Simpson dhcp6_print(const u_char *cp, u_int length)
762b0453382SBill Fenner {
7639afd0c29SBill Fenner 	struct dhcp6 *dh6;
7645b0fe478SBruce M Simpson 	struct dhcp6_relay *dh6relay;
7655b0fe478SBruce M Simpson 	const u_char *ep;
766b0453382SBill Fenner 	u_char *extp;
7679afd0c29SBill Fenner 	const char *name;
768b0453382SBill Fenner 
769b0453382SBill Fenner 	printf("dhcp6");
770b0453382SBill Fenner 
771b0453382SBill Fenner 	ep = (u_char *)snapend;
7725b0fe478SBruce M Simpson 	if (cp + length < ep)
7735b0fe478SBruce M Simpson 		ep = cp + length;
774b0453382SBill Fenner 
7759afd0c29SBill Fenner 	dh6 = (struct dhcp6 *)cp;
7765b0fe478SBruce M Simpson 	dh6relay = (struct dhcp6_relay *)cp;
7775b0fe478SBruce M Simpson 	TCHECK(dh6->dh6_xid);
778b0453382SBill Fenner 	switch (dh6->dh6_msgtype) {
7795b0fe478SBruce M Simpson 	case DH6_SOLICIT:
7805b0fe478SBruce M Simpson 		name = "solicit";
7815b0fe478SBruce M Simpson 		break;
7825b0fe478SBruce M Simpson 	case DH6_ADVERTISE:
7835b0fe478SBruce M Simpson 		name = "advertise";
7845b0fe478SBruce M Simpson 		break;
7855b0fe478SBruce M Simpson 	case DH6_REQUEST:
7865b0fe478SBruce M Simpson 		name = "request";
7875b0fe478SBruce M Simpson 		break;
7885b0fe478SBruce M Simpson 	case DH6_CONFIRM:
7895b0fe478SBruce M Simpson 		name = "confirm";
7905b0fe478SBruce M Simpson 		break;
7915b0fe478SBruce M Simpson 	case DH6_RENEW:
7925b0fe478SBruce M Simpson 		name = "renew";
7935b0fe478SBruce M Simpson 		break;
7945b0fe478SBruce M Simpson 	case DH6_REBIND:
7955b0fe478SBruce M Simpson 		name = "rebind";
7965b0fe478SBruce M Simpson 		break;
797b0453382SBill Fenner 	case DH6_REPLY:
7989afd0c29SBill Fenner 		name = "reply";
7999afd0c29SBill Fenner 		break;
8005b0fe478SBruce M Simpson 	case DH6_RELEASE:
8015b0fe478SBruce M Simpson 		name = "release";
8025b0fe478SBruce M Simpson 		break;
8035b0fe478SBruce M Simpson 	case DH6_DECLINE:
8045b0fe478SBruce M Simpson 		name = "decline";
8055b0fe478SBruce M Simpson 		break;
8065b0fe478SBruce M Simpson 	case DH6_RECONFIGURE:
8075b0fe478SBruce M Simpson 		name = "reconfigure";
8085b0fe478SBruce M Simpson 		break;
8099afd0c29SBill Fenner 	case DH6_INFORM_REQ:
8109afd0c29SBill Fenner 		name= "inf-req";
8119afd0c29SBill Fenner 		break;
8125b0fe478SBruce M Simpson 	case DH6_RELAY_FORW:
8135b0fe478SBruce M Simpson 		name= "relay-fwd";
8145b0fe478SBruce M Simpson 		break;
8155b0fe478SBruce M Simpson 	case DH6_RELAY_REPLY:
8165b0fe478SBruce M Simpson 		name= "relay-reply";
8175b0fe478SBruce M Simpson 		break;
818a5779b6eSRui Paulo 	case DH6_LEASEQUERY:
819a5779b6eSRui Paulo 		name= "leasequery";
820a5779b6eSRui Paulo 		break;
821a5779b6eSRui Paulo 	case DH6_LQ_REPLY:
822a5779b6eSRui Paulo 		name= "leasequery-reply";
823a5779b6eSRui Paulo 		break;
8249afd0c29SBill Fenner 	default:
8259afd0c29SBill Fenner 		name = NULL;
826b0453382SBill Fenner 		break;
827b0453382SBill Fenner 	}
8289afd0c29SBill Fenner 
8299afd0c29SBill Fenner 	if (!vflag) {
8309afd0c29SBill Fenner 		if (name)
8319afd0c29SBill Fenner 			printf(" %s", name);
8325b0fe478SBruce M Simpson 		else if (dh6->dh6_msgtype != DH6_RELAY_FORW &&
8335b0fe478SBruce M Simpson 		    dh6->dh6_msgtype != DH6_RELAY_REPLY) {
8349afd0c29SBill Fenner 			printf(" msgtype-%u", dh6->dh6_msgtype);
8355b0fe478SBruce M Simpson 		}
8369afd0c29SBill Fenner 		return;
837b0453382SBill Fenner 	}
8389afd0c29SBill Fenner 
8399afd0c29SBill Fenner 	/* XXX relay agent messages have to be handled differently */
8409afd0c29SBill Fenner 
8419afd0c29SBill Fenner 	if (name)
8429afd0c29SBill Fenner 		printf(" %s (", name);	/*)*/
8439afd0c29SBill Fenner 	else
8449afd0c29SBill Fenner 		printf(" msgtype-%u (", dh6->dh6_msgtype);	/*)*/
8455b0fe478SBruce M Simpson 	if (dh6->dh6_msgtype != DH6_RELAY_FORW &&
8465b0fe478SBruce M Simpson 	    dh6->dh6_msgtype != DH6_RELAY_REPLY) {
8475b0fe478SBruce M Simpson 		printf("xid=%x", EXTRACT_32BITS(&dh6->dh6_xid) & DH6_XIDMASK);
8489afd0c29SBill Fenner 		extp = (u_char *)(dh6 + 1);
8499afd0c29SBill Fenner 		dhcp6opt_print(extp, ep);
8505b0fe478SBruce M Simpson 	} else {		/* relay messages */
8515b0fe478SBruce M Simpson 		struct in6_addr addr6;
8525b0fe478SBruce M Simpson 
8535b0fe478SBruce M Simpson 		TCHECK(dh6relay->dh6relay_peeraddr);
8545b0fe478SBruce M Simpson 
8555b0fe478SBruce M Simpson 		memcpy(&addr6, dh6relay->dh6relay_linkaddr, sizeof (addr6));
8565b0fe478SBruce M Simpson 		printf("linkaddr=%s", ip6addr_string(&addr6));
8575b0fe478SBruce M Simpson 
8585b0fe478SBruce M Simpson 		memcpy(&addr6, dh6relay->dh6relay_peeraddr, sizeof (addr6));
8595b0fe478SBruce M Simpson 		printf(" peeraddr=%s", ip6addr_string(&addr6));
8605b0fe478SBruce M Simpson 
8615b0fe478SBruce M Simpson 		dhcp6opt_print((u_char *)(dh6relay + 1), ep);
8625b0fe478SBruce M Simpson 	}
863685295f4SBill Fenner 	/*(*/
864b0453382SBill Fenner 	printf(")");
865b0453382SBill Fenner 	return;
866b0453382SBill Fenner 
867b0453382SBill Fenner trunc:
8689afd0c29SBill Fenner 	printf("[|dhcp6]");
869b0453382SBill Fenner }
870