blob: cbb6d84a0588b8204f1c930a089136925e46197f [file] [log] [blame]
The Android Open Source Project2949f582009-03-03 19:30:46 -08001/*
2 * Copyright (C) 1998 and 1999 WIDE Project.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
Elliott Hughese2e3bd12017-05-15 10:59:29 -070029
30/* \summary: IPv6 DHCP printer */
31
The Android Open Source Project2949f582009-03-03 19:30:46 -080032/*
33 * RFC3315: DHCPv6
Elliott Hughes892a68b2015-10-19 14:43:53 -070034 * supported DHCPv6 options:
JP Abgrall53f17a92014-02-12 14:02:41 -080035 * RFC3319: Session Initiation Protocol (SIP) Servers options,
36 * RFC3633: IPv6 Prefix options,
37 * RFC3646: DNS Configuration options,
38 * RFC3898: Network Information Service (NIS) Configuration options,
39 * RFC4075: Simple Network Time Protocol (SNTP) Configuration option,
40 * RFC4242: Information Refresh Time option,
41 * RFC4280: Broadcast and Multicast Control Servers options,
42 * RFC5908: Network Time Protocol (NTP) Server Option for DHCPv6
43 * RFC6334: Dual-Stack Lite option,
The Android Open Source Project2949f582009-03-03 19:30:46 -080044 */
45
The Android Open Source Project2949f582009-03-03 19:30:46 -080046#ifdef HAVE_CONFIG_H
47#include "config.h"
48#endif
49
Elliott Hughese2e3bd12017-05-15 10:59:29 -070050#include <netdissect-stdinc.h>
The Android Open Source Project2949f582009-03-03 19:30:46 -080051
52#include <stdio.h>
53#include <string.h>
54
Elliott Hughese2e3bd12017-05-15 10:59:29 -070055#include "netdissect.h"
The Android Open Source Project2949f582009-03-03 19:30:46 -080056#include "addrtoname.h"
57#include "extract.h"
58
59/* lease duration */
Elliott Hughes892a68b2015-10-19 14:43:53 -070060#define DHCP6_DURATION_INFINITE 0xffffffff
The Android Open Source Project2949f582009-03-03 19:30:46 -080061
62/* Error Values */
63#define DH6ERR_FAILURE 16
64#define DH6ERR_AUTHFAIL 17
65#define DH6ERR_POORLYFORMED 18
66#define DH6ERR_UNAVAIL 19
67#define DH6ERR_OPTUNAVAIL 20
68
69/* Message type */
70#define DH6_SOLICIT 1
71#define DH6_ADVERTISE 2
72#define DH6_REQUEST 3
73#define DH6_CONFIRM 4
74#define DH6_RENEW 5
75#define DH6_REBIND 6
76#define DH6_REPLY 7
77#define DH6_RELEASE 8
78#define DH6_DECLINE 9
79#define DH6_RECONFIGURE 10
80#define DH6_INFORM_REQ 11
81#define DH6_RELAY_FORW 12
82#define DH6_RELAY_REPLY 13
JP Abgrall53f17a92014-02-12 14:02:41 -080083#define DH6_LEASEQUERY 14
84#define DH6_LQ_REPLY 15
The Android Open Source Project2949f582009-03-03 19:30:46 -080085
Elliott Hughes892a68b2015-10-19 14:43:53 -070086static const struct tok dh6_msgtype_str[] = {
87 { DH6_SOLICIT, "solicit" },
88 { DH6_ADVERTISE, "advertise" },
89 { DH6_REQUEST, "request" },
90 { DH6_CONFIRM, "confirm" },
91 { DH6_RENEW, "renew" },
92 { DH6_REBIND, "rebind" },
93 { DH6_REPLY, "reply" },
94 { DH6_RELEASE, "release" },
95 { DH6_DECLINE, "decline" },
96 { DH6_RECONFIGURE, "reconfigure" },
97 { DH6_INFORM_REQ, "inf-req" },
98 { DH6_RELAY_FORW, "relay-fwd" },
99 { DH6_RELAY_REPLY, "relay-reply" },
100 { DH6_LEASEQUERY, "leasequery" },
101 { DH6_LQ_REPLY, "leasequery-reply" },
102 { 0, NULL }
103};
104
The Android Open Source Project2949f582009-03-03 19:30:46 -0800105/* DHCP6 base packet format */
106struct dhcp6 {
107 union {
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700108 nd_uint8_t m;
109 nd_uint32_t x;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800110 } dh6_msgtypexid;
111 /* options follow */
112};
113#define dh6_msgtype dh6_msgtypexid.m
114#define dh6_xid dh6_msgtypexid.x
115#define DH6_XIDMASK 0x00ffffff
116
117/* DHCPv6 relay messages */
118struct dhcp6_relay {
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700119 nd_uint8_t dh6relay_msgtype;
120 nd_uint8_t dh6relay_hcnt;
121 nd_uint8_t dh6relay_linkaddr[16]; /* XXX: badly aligned */
122 nd_uint8_t dh6relay_peeraddr[16];
The Android Open Source Project2949f582009-03-03 19:30:46 -0800123 /* options follow */
124};
125
126/* options */
127#define DH6OPT_CLIENTID 1
128#define DH6OPT_SERVERID 2
129#define DH6OPT_IA_NA 3
130#define DH6OPT_IA_TA 4
131#define DH6OPT_IA_ADDR 5
132#define DH6OPT_ORO 6
133#define DH6OPT_PREFERENCE 7
134# define DH6OPT_PREF_MAX 255
135#define DH6OPT_ELAPSED_TIME 8
136#define DH6OPT_RELAY_MSG 9
137/*#define DH6OPT_SERVER_MSG 10 deprecated */
138#define DH6OPT_AUTH 11
139# define DH6OPT_AUTHPROTO_DELAYED 2
140# define DH6OPT_AUTHPROTO_RECONFIG 3
141# define DH6OPT_AUTHALG_HMACMD5 1
142# define DH6OPT_AUTHRDM_MONOCOUNTER 0
143# define DH6OPT_AUTHRECONFIG_KEY 1
144# define DH6OPT_AUTHRECONFIG_HMACMD5 2
145#define DH6OPT_UNICAST 12
146#define DH6OPT_STATUS_CODE 13
147# define DH6OPT_STCODE_SUCCESS 0
148# define DH6OPT_STCODE_UNSPECFAIL 1
149# define DH6OPT_STCODE_NOADDRAVAIL 2
150# define DH6OPT_STCODE_NOBINDING 3
151# define DH6OPT_STCODE_NOTONLINK 4
152# define DH6OPT_STCODE_USEMULTICAST 5
153# define DH6OPT_STCODE_NOPREFIXAVAIL 6
JP Abgrall53f17a92014-02-12 14:02:41 -0800154# define DH6OPT_STCODE_UNKNOWNQUERYTYPE 7
155# define DH6OPT_STCODE_MALFORMEDQUERY 8
156# define DH6OPT_STCODE_NOTCONFIGURED 9
157# define DH6OPT_STCODE_NOTALLOWED 10
The Android Open Source Project2949f582009-03-03 19:30:46 -0800158#define DH6OPT_RAPID_COMMIT 14
159#define DH6OPT_USER_CLASS 15
160#define DH6OPT_VENDOR_CLASS 16
161#define DH6OPT_VENDOR_OPTS 17
162#define DH6OPT_INTERFACE_ID 18
163#define DH6OPT_RECONF_MSG 19
164#define DH6OPT_RECONF_ACCEPT 20
165#define DH6OPT_SIP_SERVER_D 21
166#define DH6OPT_SIP_SERVER_A 22
JP Abgrall53f17a92014-02-12 14:02:41 -0800167#define DH6OPT_DNS_SERVERS 23
168#define DH6OPT_DOMAIN_LIST 24
The Android Open Source Project2949f582009-03-03 19:30:46 -0800169#define DH6OPT_IA_PD 25
170#define DH6OPT_IA_PD_PREFIX 26
171#define DH6OPT_NIS_SERVERS 27
172#define DH6OPT_NISP_SERVERS 28
173#define DH6OPT_NIS_NAME 29
174#define DH6OPT_NISP_NAME 30
JP Abgrall53f17a92014-02-12 14:02:41 -0800175#define DH6OPT_SNTP_SERVERS 31
The Android Open Source Project2949f582009-03-03 19:30:46 -0800176#define DH6OPT_LIFETIME 32
177#define DH6OPT_BCMCS_SERVER_D 33
178#define DH6OPT_BCMCS_SERVER_A 34
179#define DH6OPT_GEOCONF_CIVIC 36
180#define DH6OPT_REMOTE_ID 37
181#define DH6OPT_SUBSCRIBER_ID 38
182#define DH6OPT_CLIENT_FQDN 39
JP Abgrall53f17a92014-02-12 14:02:41 -0800183#define DH6OPT_PANA_AGENT 40
184#define DH6OPT_NEW_POSIX_TIMEZONE 41
185#define DH6OPT_NEW_TZDB_TIMEZONE 42
186#define DH6OPT_ERO 43
187#define DH6OPT_LQ_QUERY 44
188#define DH6OPT_CLIENT_DATA 45
189#define DH6OPT_CLT_TIME 46
190#define DH6OPT_LQ_RELAY_DATA 47
191#define DH6OPT_LQ_CLIENT_LINK 48
192#define DH6OPT_NTP_SERVER 56
193# define DH6OPT_NTP_SUBOPTION_SRV_ADDR 1
194# define DH6OPT_NTP_SUBOPTION_MC_ADDR 2
195# define DH6OPT_NTP_SUBOPTION_SRV_FQDN 3
196#define DH6OPT_AFTR_NAME 64
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700197#define DH6OPT_MUDURL 112
The Android Open Source Project2949f582009-03-03 19:30:46 -0800198
Elliott Hughes892a68b2015-10-19 14:43:53 -0700199static const struct tok dh6opt_str[] = {
200 { DH6OPT_CLIENTID, "client-ID" },
201 { DH6OPT_SERVERID, "server-ID" },
202 { DH6OPT_IA_NA, "IA_NA" },
203 { DH6OPT_IA_TA, "IA_TA" },
204 { DH6OPT_IA_ADDR, "IA_ADDR" },
205 { DH6OPT_ORO, "option-request" },
206 { DH6OPT_PREFERENCE, "preference" },
207 { DH6OPT_ELAPSED_TIME, "elapsed-time" },
208 { DH6OPT_RELAY_MSG, "relay-message" },
209 { DH6OPT_AUTH, "authentication" },
210 { DH6OPT_UNICAST, "server-unicast" },
211 { DH6OPT_STATUS_CODE, "status-code" },
212 { DH6OPT_RAPID_COMMIT, "rapid-commit" },
213 { DH6OPT_USER_CLASS, "user-class" },
214 { DH6OPT_VENDOR_CLASS, "vendor-class" },
215 { DH6OPT_VENDOR_OPTS, "vendor-specific-info" },
216 { DH6OPT_INTERFACE_ID, "interface-ID" },
217 { DH6OPT_RECONF_MSG, "reconfigure-message" },
218 { DH6OPT_RECONF_ACCEPT, "reconfigure-accept" },
219 { DH6OPT_SIP_SERVER_D, "SIP-servers-domain" },
220 { DH6OPT_SIP_SERVER_A, "SIP-servers-address" },
221 { DH6OPT_DNS_SERVERS, "DNS-server" },
222 { DH6OPT_DOMAIN_LIST, "DNS-search-list" },
223 { DH6OPT_IA_PD, "IA_PD" },
224 { DH6OPT_IA_PD_PREFIX, "IA_PD-prefix" },
225 { DH6OPT_SNTP_SERVERS, "SNTP-servers" },
226 { DH6OPT_LIFETIME, "lifetime" },
227 { DH6OPT_NIS_SERVERS, "NIS-server" },
228 { DH6OPT_NISP_SERVERS, "NIS+-server" },
229 { DH6OPT_NIS_NAME, "NIS-domain-name" },
230 { DH6OPT_NISP_NAME, "NIS+-domain-name" },
231 { DH6OPT_BCMCS_SERVER_D, "BCMCS-domain-name" },
232 { DH6OPT_BCMCS_SERVER_A, "BCMCS-server" },
233 { DH6OPT_GEOCONF_CIVIC, "Geoconf-Civic" },
234 { DH6OPT_REMOTE_ID, "Remote-ID" },
235 { DH6OPT_SUBSCRIBER_ID, "Subscriber-ID" },
236 { DH6OPT_CLIENT_FQDN, "Client-FQDN" },
237 { DH6OPT_PANA_AGENT, "PANA-agent" },
238 { DH6OPT_NEW_POSIX_TIMEZONE, "POSIX-timezone" },
239 { DH6OPT_NEW_TZDB_TIMEZONE, "POSIX-tz-database" },
240 { DH6OPT_ERO, "Echo-request-option" },
241 { DH6OPT_LQ_QUERY, "Lease-query" },
242 { DH6OPT_CLIENT_DATA, "LQ-client-data" },
243 { DH6OPT_CLT_TIME, "Clt-time" },
244 { DH6OPT_LQ_RELAY_DATA, "LQ-relay-data" },
245 { DH6OPT_LQ_CLIENT_LINK, "LQ-client-link" },
246 { DH6OPT_NTP_SERVER, "NTP-server" },
247 { DH6OPT_AFTR_NAME, "AFTR-Name" },
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700248 { DH6OPT_MUDURL, "MUD-URL" },
Elliott Hughes892a68b2015-10-19 14:43:53 -0700249 { 0, NULL }
250};
251
252static const struct tok dh6opt_stcode_str[] = {
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700253 { DH6OPT_STCODE_SUCCESS, "Success" }, /* RFC3315 */
254 { DH6OPT_STCODE_UNSPECFAIL, "UnspecFail" }, /* RFC3315 */
255 { DH6OPT_STCODE_NOADDRAVAIL, "NoAddrsAvail" }, /* RFC3315 */
256 { DH6OPT_STCODE_NOBINDING, "NoBinding" }, /* RFC3315 */
257 { DH6OPT_STCODE_NOTONLINK, "NotOnLink" }, /* RFC3315 */
258 { DH6OPT_STCODE_USEMULTICAST, "UseMulticast" }, /* RFC3315 */
259 { DH6OPT_STCODE_NOPREFIXAVAIL, "NoPrefixAvail" }, /* RFC3633 */
260 { DH6OPT_STCODE_UNKNOWNQUERYTYPE, "UnknownQueryType" }, /* RFC5007 */
261 { DH6OPT_STCODE_MALFORMEDQUERY, "MalformedQuery" }, /* RFC5007 */
262 { DH6OPT_STCODE_NOTCONFIGURED, "NotConfigured" }, /* RFC5007 */
263 { DH6OPT_STCODE_NOTALLOWED, "NotAllowed" }, /* RFC5007 */
Elliott Hughes892a68b2015-10-19 14:43:53 -0700264 { 0, NULL }
265};
266
The Android Open Source Project2949f582009-03-03 19:30:46 -0800267struct dhcp6opt {
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700268 nd_uint16_t dh6opt_type;
269 nd_uint16_t dh6opt_len;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800270 /* type-dependent data follows */
271};
272
The Android Open Source Project2949f582009-03-03 19:30:46 -0800273static const char *
Elliott Hughes892a68b2015-10-19 14:43:53 -0700274dhcp6stcode(const uint16_t code)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800275{
Elliott Hughes892a68b2015-10-19 14:43:53 -0700276 return code > 255 ? "INVALID code" : tok2str(dh6opt_stcode_str, "code%u", code);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800277}
278
279static void
Elliott Hughes892a68b2015-10-19 14:43:53 -0700280dhcp6opt_print(netdissect_options *ndo,
281 const u_char *cp, const u_char *ep)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800282{
JP Abgrall53f17a92014-02-12 14:02:41 -0800283 const struct dhcp6opt *dh6o;
284 const u_char *tp;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800285 size_t i;
Elliott Hughes892a68b2015-10-19 14:43:53 -0700286 uint16_t opttype;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800287 size_t optlen;
Elliott Hughes892a68b2015-10-19 14:43:53 -0700288 uint8_t auth_proto;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800289 u_int authinfolen, authrealmlen;
JP Abgrall53f17a92014-02-12 14:02:41 -0800290 int remain_len; /* Length of remaining options */
291 int label_len; /* Label length */
Elliott Hughes892a68b2015-10-19 14:43:53 -0700292 uint16_t subopt_code;
293 uint16_t subopt_len;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800294
295 if (cp == ep)
296 return;
297 while (cp < ep) {
298 if (ep < cp + sizeof(*dh6o))
299 goto trunc;
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700300 dh6o = (const struct dhcp6opt *)cp;
Elliott Hughes892a68b2015-10-19 14:43:53 -0700301 ND_TCHECK(*dh6o);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800302 optlen = EXTRACT_16BITS(&dh6o->dh6opt_len);
303 if (ep < cp + sizeof(*dh6o) + optlen)
304 goto trunc;
305 opttype = EXTRACT_16BITS(&dh6o->dh6opt_type);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700306 ND_PRINT((ndo, " (%s", tok2str(dh6opt_str, "opt_%u", opttype)));
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700307 ND_TCHECK2(*(cp + sizeof(*dh6o)), optlen);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800308 switch (opttype) {
309 case DH6OPT_CLIENTID:
310 case DH6OPT_SERVERID:
311 if (optlen < 2) {
312 /*(*/
Elliott Hughes892a68b2015-10-19 14:43:53 -0700313 ND_PRINT((ndo, " ?)"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800314 break;
315 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700316 tp = (const u_char *)(dh6o + 1);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800317 switch (EXTRACT_16BITS(tp)) {
318 case 1:
319 if (optlen >= 2 + 6) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700320 ND_PRINT((ndo, " hwaddr/time type %u time %u ",
The Android Open Source Project2949f582009-03-03 19:30:46 -0800321 EXTRACT_16BITS(&tp[2]),
Elliott Hughes892a68b2015-10-19 14:43:53 -0700322 EXTRACT_32BITS(&tp[4])));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800323 for (i = 8; i < optlen; i++)
Elliott Hughes892a68b2015-10-19 14:43:53 -0700324 ND_PRINT((ndo, "%02x", tp[i]));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800325 /*(*/
Elliott Hughes892a68b2015-10-19 14:43:53 -0700326 ND_PRINT((ndo, ")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800327 } else {
328 /*(*/
Elliott Hughes892a68b2015-10-19 14:43:53 -0700329 ND_PRINT((ndo, " ?)"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800330 }
331 break;
332 case 2:
333 if (optlen >= 2 + 8) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700334 ND_PRINT((ndo, " vid "));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800335 for (i = 2; i < 2 + 8; i++)
Elliott Hughes892a68b2015-10-19 14:43:53 -0700336 ND_PRINT((ndo, "%02x", tp[i]));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800337 /*(*/
Elliott Hughes892a68b2015-10-19 14:43:53 -0700338 ND_PRINT((ndo, ")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800339 } else {
340 /*(*/
Elliott Hughes892a68b2015-10-19 14:43:53 -0700341 ND_PRINT((ndo, " ?)"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800342 }
343 break;
344 case 3:
345 if (optlen >= 2 + 2) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700346 ND_PRINT((ndo, " hwaddr type %u ",
347 EXTRACT_16BITS(&tp[2])));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800348 for (i = 4; i < optlen; i++)
Elliott Hughes892a68b2015-10-19 14:43:53 -0700349 ND_PRINT((ndo, "%02x", tp[i]));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800350 /*(*/
Elliott Hughes892a68b2015-10-19 14:43:53 -0700351 ND_PRINT((ndo, ")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800352 } else {
353 /*(*/
Elliott Hughes892a68b2015-10-19 14:43:53 -0700354 ND_PRINT((ndo, " ?)"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800355 }
356 break;
357 default:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700358 ND_PRINT((ndo, " type %d)", EXTRACT_16BITS(tp)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800359 break;
360 }
361 break;
362 case DH6OPT_IA_ADDR:
JP Abgrall53f17a92014-02-12 14:02:41 -0800363 if (optlen < 24) {
364 /*(*/
Elliott Hughes892a68b2015-10-19 14:43:53 -0700365 ND_PRINT((ndo, " ?)"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800366 break;
367 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700368 tp = (const u_char *)(dh6o + 1);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700369 ND_PRINT((ndo, " %s", ip6addr_string(ndo, &tp[0])));
370 ND_PRINT((ndo, " pltime:%u vltime:%u",
JP Abgrall53f17a92014-02-12 14:02:41 -0800371 EXTRACT_32BITS(&tp[16]),
Elliott Hughes892a68b2015-10-19 14:43:53 -0700372 EXTRACT_32BITS(&tp[20])));
JP Abgrall53f17a92014-02-12 14:02:41 -0800373 if (optlen > 24) {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800374 /* there are sub-options */
Elliott Hughes892a68b2015-10-19 14:43:53 -0700375 dhcp6opt_print(ndo, tp + 24, tp + optlen);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800376 }
Elliott Hughes892a68b2015-10-19 14:43:53 -0700377 ND_PRINT((ndo, ")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800378 break;
379 case DH6OPT_ORO:
JP Abgrall53f17a92014-02-12 14:02:41 -0800380 case DH6OPT_ERO:
The Android Open Source Project2949f582009-03-03 19:30:46 -0800381 if (optlen % 2) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700382 ND_PRINT((ndo, " ?)"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800383 break;
384 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700385 tp = (const u_char *)(dh6o + 1);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800386 for (i = 0; i < optlen; i += 2) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700387 ND_PRINT((ndo, " %s",
388 tok2str(dh6opt_str, "opt_%u", EXTRACT_16BITS(&tp[i]))));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800389 }
Elliott Hughes892a68b2015-10-19 14:43:53 -0700390 ND_PRINT((ndo, ")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800391 break;
392 case DH6OPT_PREFERENCE:
393 if (optlen != 1) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700394 ND_PRINT((ndo, " ?)"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800395 break;
396 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700397 tp = (const u_char *)(dh6o + 1);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700398 ND_PRINT((ndo, " %d)", *tp));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800399 break;
400 case DH6OPT_ELAPSED_TIME:
401 if (optlen != 2) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700402 ND_PRINT((ndo, " ?)"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800403 break;
404 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700405 tp = (const u_char *)(dh6o + 1);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700406 ND_PRINT((ndo, " %d)", EXTRACT_16BITS(tp)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800407 break;
408 case DH6OPT_RELAY_MSG:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700409 ND_PRINT((ndo, " ("));
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700410 tp = (const u_char *)(dh6o + 1);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700411 dhcp6_print(ndo, tp, optlen);
412 ND_PRINT((ndo, ")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800413 break;
414 case DH6OPT_AUTH:
JP Abgrall53f17a92014-02-12 14:02:41 -0800415 if (optlen < 11) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700416 ND_PRINT((ndo, " ?)"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800417 break;
418 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700419 tp = (const u_char *)(dh6o + 1);
JP Abgrall53f17a92014-02-12 14:02:41 -0800420 auth_proto = *tp;
421 switch (auth_proto) {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800422 case DH6OPT_AUTHPROTO_DELAYED:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700423 ND_PRINT((ndo, " proto: delayed"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800424 break;
425 case DH6OPT_AUTHPROTO_RECONFIG:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700426 ND_PRINT((ndo, " proto: reconfigure"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800427 break;
428 default:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700429 ND_PRINT((ndo, " proto: %d", auth_proto));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800430 break;
431 }
JP Abgrall53f17a92014-02-12 14:02:41 -0800432 tp++;
433 switch (*tp) {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800434 case DH6OPT_AUTHALG_HMACMD5:
435 /* XXX: may depend on the protocol */
Elliott Hughes892a68b2015-10-19 14:43:53 -0700436 ND_PRINT((ndo, ", alg: HMAC-MD5"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800437 break;
438 default:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700439 ND_PRINT((ndo, ", alg: %d", *tp));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800440 break;
441 }
JP Abgrall53f17a92014-02-12 14:02:41 -0800442 tp++;
443 switch (*tp) {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800444 case DH6OPT_AUTHRDM_MONOCOUNTER:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700445 ND_PRINT((ndo, ", RDM: mono"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800446 break;
447 default:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700448 ND_PRINT((ndo, ", RDM: %d", *tp));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800449 break;
450 }
JP Abgrall53f17a92014-02-12 14:02:41 -0800451 tp++;
Elliott Hughes892a68b2015-10-19 14:43:53 -0700452 ND_PRINT((ndo, ", RD:"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800453 for (i = 0; i < 4; i++, tp += 2)
Elliott Hughes892a68b2015-10-19 14:43:53 -0700454 ND_PRINT((ndo, " %04x", EXTRACT_16BITS(tp)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800455
456 /* protocol dependent part */
JP Abgrall53f17a92014-02-12 14:02:41 -0800457 authinfolen = optlen - 11;
458 switch (auth_proto) {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800459 case DH6OPT_AUTHPROTO_DELAYED:
460 if (authinfolen == 0)
461 break;
462 if (authinfolen < 20) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700463 ND_PRINT((ndo, " ??"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800464 break;
465 }
466 authrealmlen = authinfolen - 20;
467 if (authrealmlen > 0) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700468 ND_PRINT((ndo, ", realm: "));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800469 }
470 for (i = 0; i < authrealmlen; i++, tp++)
Elliott Hughes892a68b2015-10-19 14:43:53 -0700471 ND_PRINT((ndo, "%02x", *tp));
472 ND_PRINT((ndo, ", key ID: %08x", EXTRACT_32BITS(tp)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800473 tp += 4;
Elliott Hughes892a68b2015-10-19 14:43:53 -0700474 ND_PRINT((ndo, ", HMAC-MD5:"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800475 for (i = 0; i < 4; i++, tp+= 4)
Elliott Hughes892a68b2015-10-19 14:43:53 -0700476 ND_PRINT((ndo, " %08x", EXTRACT_32BITS(tp)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800477 break;
478 case DH6OPT_AUTHPROTO_RECONFIG:
479 if (authinfolen != 17) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700480 ND_PRINT((ndo, " ??"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800481 break;
482 }
483 switch (*tp++) {
484 case DH6OPT_AUTHRECONFIG_KEY:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700485 ND_PRINT((ndo, " reconfig-key"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800486 break;
487 case DH6OPT_AUTHRECONFIG_HMACMD5:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700488 ND_PRINT((ndo, " type: HMAC-MD5"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800489 break;
490 default:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700491 ND_PRINT((ndo, " type: ??"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800492 break;
493 }
Elliott Hughes892a68b2015-10-19 14:43:53 -0700494 ND_PRINT((ndo, " value:"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800495 for (i = 0; i < 4; i++, tp+= 4)
Elliott Hughes892a68b2015-10-19 14:43:53 -0700496 ND_PRINT((ndo, " %08x", EXTRACT_32BITS(tp)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800497 break;
498 default:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700499 ND_PRINT((ndo, " ??"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800500 break;
501 }
502
Elliott Hughes892a68b2015-10-19 14:43:53 -0700503 ND_PRINT((ndo, ")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800504 break;
505 case DH6OPT_RAPID_COMMIT: /* nothing todo */
Elliott Hughes892a68b2015-10-19 14:43:53 -0700506 ND_PRINT((ndo, ")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800507 break;
508 case DH6OPT_INTERFACE_ID:
JP Abgrall53f17a92014-02-12 14:02:41 -0800509 case DH6OPT_SUBSCRIBER_ID:
The Android Open Source Project2949f582009-03-03 19:30:46 -0800510 /*
511 * Since we cannot predict the encoding, print hex dump
512 * at most 10 characters.
513 */
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700514 tp = (const u_char *)(dh6o + 1);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700515 ND_PRINT((ndo, " "));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800516 for (i = 0; i < optlen && i < 10; i++)
Elliott Hughes892a68b2015-10-19 14:43:53 -0700517 ND_PRINT((ndo, "%02x", tp[i]));
518 ND_PRINT((ndo, "...)"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800519 break;
520 case DH6OPT_RECONF_MSG:
Elliott Hughescec480a2017-12-19 16:54:57 -0800521 if (optlen != 1) {
522 ND_PRINT((ndo, " ?)"));
523 break;
524 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700525 tp = (const u_char *)(dh6o + 1);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800526 switch (*tp) {
527 case DH6_RENEW:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700528 ND_PRINT((ndo, " for renew)"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800529 break;
530 case DH6_INFORM_REQ:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700531 ND_PRINT((ndo, " for inf-req)"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800532 break;
533 default:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700534 ND_PRINT((ndo, " for ?\?\?(%02x))", *tp));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800535 break;
536 }
537 break;
538 case DH6OPT_RECONF_ACCEPT: /* nothing todo */
Elliott Hughes892a68b2015-10-19 14:43:53 -0700539 ND_PRINT((ndo, ")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800540 break;
541 case DH6OPT_SIP_SERVER_A:
JP Abgrall53f17a92014-02-12 14:02:41 -0800542 case DH6OPT_DNS_SERVERS:
543 case DH6OPT_SNTP_SERVERS:
The Android Open Source Project2949f582009-03-03 19:30:46 -0800544 case DH6OPT_NIS_SERVERS:
545 case DH6OPT_NISP_SERVERS:
546 case DH6OPT_BCMCS_SERVER_A:
JP Abgrall53f17a92014-02-12 14:02:41 -0800547 case DH6OPT_PANA_AGENT:
548 case DH6OPT_LQ_CLIENT_LINK:
The Android Open Source Project2949f582009-03-03 19:30:46 -0800549 if (optlen % 16) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700550 ND_PRINT((ndo, " ?)"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800551 break;
552 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700553 tp = (const u_char *)(dh6o + 1);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800554 for (i = 0; i < optlen; i += 16)
Elliott Hughes892a68b2015-10-19 14:43:53 -0700555 ND_PRINT((ndo, " %s", ip6addr_string(ndo, &tp[i])));
556 ND_PRINT((ndo, ")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800557 break;
JP Abgrall53f17a92014-02-12 14:02:41 -0800558 case DH6OPT_SIP_SERVER_D:
559 case DH6OPT_DOMAIN_LIST:
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700560 tp = (const u_char *)(dh6o + 1);
JP Abgrall53f17a92014-02-12 14:02:41 -0800561 while (tp < cp + sizeof(*dh6o) + optlen) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700562 ND_PRINT((ndo, " "));
563 if ((tp = ns_nprint(ndo, tp, cp + sizeof(*dh6o) + optlen)) == NULL)
JP Abgrall53f17a92014-02-12 14:02:41 -0800564 goto trunc;
565 }
Elliott Hughes892a68b2015-10-19 14:43:53 -0700566 ND_PRINT((ndo, ")"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800567 break;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800568 case DH6OPT_STATUS_CODE:
569 if (optlen < 2) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700570 ND_PRINT((ndo, " ?)"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800571 break;
572 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700573 tp = (const u_char *)(dh6o + 1);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700574 ND_PRINT((ndo, " %s)", dhcp6stcode(EXTRACT_16BITS(&tp[0]))));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800575 break;
576 case DH6OPT_IA_NA:
577 case DH6OPT_IA_PD:
JP Abgrall53f17a92014-02-12 14:02:41 -0800578 if (optlen < 12) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700579 ND_PRINT((ndo, " ?)"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800580 break;
581 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700582 tp = (const u_char *)(dh6o + 1);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700583 ND_PRINT((ndo, " IAID:%u T1:%u T2:%u",
JP Abgrall53f17a92014-02-12 14:02:41 -0800584 EXTRACT_32BITS(&tp[0]),
585 EXTRACT_32BITS(&tp[4]),
Elliott Hughes892a68b2015-10-19 14:43:53 -0700586 EXTRACT_32BITS(&tp[8])));
JP Abgrall53f17a92014-02-12 14:02:41 -0800587 if (optlen > 12) {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800588 /* there are sub-options */
Elliott Hughes892a68b2015-10-19 14:43:53 -0700589 dhcp6opt_print(ndo, tp + 12, tp + optlen);
JP Abgrall53f17a92014-02-12 14:02:41 -0800590 }
Elliott Hughes892a68b2015-10-19 14:43:53 -0700591 ND_PRINT((ndo, ")"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800592 break;
593 case DH6OPT_IA_TA:
594 if (optlen < 4) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700595 ND_PRINT((ndo, " ?)"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800596 break;
597 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700598 tp = (const u_char *)(dh6o + 1);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700599 ND_PRINT((ndo, " IAID:%u", EXTRACT_32BITS(tp)));
JP Abgrall53f17a92014-02-12 14:02:41 -0800600 if (optlen > 4) {
601 /* there are sub-options */
Elliott Hughes892a68b2015-10-19 14:43:53 -0700602 dhcp6opt_print(ndo, tp + 4, tp + optlen);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800603 }
Elliott Hughes892a68b2015-10-19 14:43:53 -0700604 ND_PRINT((ndo, ")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800605 break;
606 case DH6OPT_IA_PD_PREFIX:
JP Abgrall53f17a92014-02-12 14:02:41 -0800607 if (optlen < 25) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700608 ND_PRINT((ndo, " ?)"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800609 break;
610 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700611 tp = (const u_char *)(dh6o + 1);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700612 ND_PRINT((ndo, " %s/%d", ip6addr_string(ndo, &tp[9]), tp[8]));
613 ND_PRINT((ndo, " pltime:%u vltime:%u",
JP Abgrall53f17a92014-02-12 14:02:41 -0800614 EXTRACT_32BITS(&tp[0]),
Elliott Hughes892a68b2015-10-19 14:43:53 -0700615 EXTRACT_32BITS(&tp[4])));
JP Abgrall53f17a92014-02-12 14:02:41 -0800616 if (optlen > 25) {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800617 /* there are sub-options */
Elliott Hughes892a68b2015-10-19 14:43:53 -0700618 dhcp6opt_print(ndo, tp + 25, tp + optlen);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800619 }
Elliott Hughes892a68b2015-10-19 14:43:53 -0700620 ND_PRINT((ndo, ")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800621 break;
622 case DH6OPT_LIFETIME:
JP Abgrall53f17a92014-02-12 14:02:41 -0800623 case DH6OPT_CLT_TIME:
The Android Open Source Project2949f582009-03-03 19:30:46 -0800624 if (optlen != 4) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700625 ND_PRINT((ndo, " ?)"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800626 break;
627 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700628 tp = (const u_char *)(dh6o + 1);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700629 ND_PRINT((ndo, " %d)", EXTRACT_32BITS(tp)));
JP Abgrall53f17a92014-02-12 14:02:41 -0800630 break;
631 case DH6OPT_REMOTE_ID:
632 if (optlen < 4) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700633 ND_PRINT((ndo, " ?)"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800634 break;
635 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700636 tp = (const u_char *)(dh6o + 1);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700637 ND_PRINT((ndo, " %d ", EXTRACT_32BITS(tp)));
JP Abgrall53f17a92014-02-12 14:02:41 -0800638 /*
639 * Print hex dump first 10 characters.
640 */
641 for (i = 4; i < optlen && i < 14; i++)
Elliott Hughes892a68b2015-10-19 14:43:53 -0700642 ND_PRINT((ndo, "%02x", tp[i]));
643 ND_PRINT((ndo, "...)"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800644 break;
645 case DH6OPT_LQ_QUERY:
646 if (optlen < 17) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700647 ND_PRINT((ndo, " ?)"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800648 break;
649 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700650 tp = (const u_char *)(dh6o + 1);
JP Abgrall53f17a92014-02-12 14:02:41 -0800651 switch (*tp) {
652 case 1:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700653 ND_PRINT((ndo, " by-address"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800654 break;
655 case 2:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700656 ND_PRINT((ndo, " by-clientID"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800657 break;
658 default:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700659 ND_PRINT((ndo, " type_%d", (int)*tp));
JP Abgrall53f17a92014-02-12 14:02:41 -0800660 break;
661 }
Elliott Hughes892a68b2015-10-19 14:43:53 -0700662 ND_PRINT((ndo, " %s", ip6addr_string(ndo, &tp[1])));
JP Abgrall53f17a92014-02-12 14:02:41 -0800663 if (optlen > 17) {
664 /* there are query-options */
Elliott Hughes892a68b2015-10-19 14:43:53 -0700665 dhcp6opt_print(ndo, tp + 17, tp + optlen);
JP Abgrall53f17a92014-02-12 14:02:41 -0800666 }
Elliott Hughes892a68b2015-10-19 14:43:53 -0700667 ND_PRINT((ndo, ")"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800668 break;
669 case DH6OPT_CLIENT_DATA:
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700670 tp = (const u_char *)(dh6o + 1);
JP Abgrall53f17a92014-02-12 14:02:41 -0800671 if (optlen > 0) {
672 /* there are encapsulated options */
Elliott Hughes892a68b2015-10-19 14:43:53 -0700673 dhcp6opt_print(ndo, tp, tp + optlen);
JP Abgrall53f17a92014-02-12 14:02:41 -0800674 }
Elliott Hughes892a68b2015-10-19 14:43:53 -0700675 ND_PRINT((ndo, ")"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800676 break;
677 case DH6OPT_LQ_RELAY_DATA:
678 if (optlen < 16) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700679 ND_PRINT((ndo, " ?)"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800680 break;
681 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700682 tp = (const u_char *)(dh6o + 1);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700683 ND_PRINT((ndo, " %s ", ip6addr_string(ndo, &tp[0])));
JP Abgrall53f17a92014-02-12 14:02:41 -0800684 /*
685 * Print hex dump first 10 characters.
686 */
687 for (i = 16; i < optlen && i < 26; i++)
Elliott Hughes892a68b2015-10-19 14:43:53 -0700688 ND_PRINT((ndo, "%02x", tp[i]));
689 ND_PRINT((ndo, "...)"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800690 break;
691 case DH6OPT_NTP_SERVER:
692 if (optlen < 4) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700693 ND_PRINT((ndo, " ?)"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800694 break;
695 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700696 tp = (const u_char *)(dh6o + 1);
JP Abgrall53f17a92014-02-12 14:02:41 -0800697 while (tp < cp + sizeof(*dh6o) + optlen - 4) {
698 subopt_code = EXTRACT_16BITS(tp);
699 tp += 2;
700 subopt_len = EXTRACT_16BITS(tp);
701 tp += 2;
702 if (tp + subopt_len > cp + sizeof(*dh6o) + optlen)
703 goto trunc;
Elliott Hughes892a68b2015-10-19 14:43:53 -0700704 ND_PRINT((ndo, " subopt:%d", subopt_code));
JP Abgrall53f17a92014-02-12 14:02:41 -0800705 switch (subopt_code) {
706 case DH6OPT_NTP_SUBOPTION_SRV_ADDR:
707 case DH6OPT_NTP_SUBOPTION_MC_ADDR:
708 if (subopt_len != 16) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700709 ND_PRINT((ndo, " ?"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800710 break;
711 }
Elliott Hughes892a68b2015-10-19 14:43:53 -0700712 ND_PRINT((ndo, " %s", ip6addr_string(ndo, &tp[0])));
JP Abgrall53f17a92014-02-12 14:02:41 -0800713 break;
714 case DH6OPT_NTP_SUBOPTION_SRV_FQDN:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700715 ND_PRINT((ndo, " "));
716 if (ns_nprint(ndo, tp, tp + subopt_len) == NULL)
JP Abgrall53f17a92014-02-12 14:02:41 -0800717 goto trunc;
718 break;
719 default:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700720 ND_PRINT((ndo, " ?"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800721 break;
722 }
723 tp += subopt_len;
724 }
Elliott Hughes892a68b2015-10-19 14:43:53 -0700725 ND_PRINT((ndo, ")"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800726 break;
727 case DH6OPT_AFTR_NAME:
728 if (optlen < 3) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700729 ND_PRINT((ndo, " ?)"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800730 break;
731 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700732 tp = (const u_char *)(dh6o + 1);
JP Abgrall53f17a92014-02-12 14:02:41 -0800733 remain_len = optlen;
Elliott Hughes892a68b2015-10-19 14:43:53 -0700734 ND_PRINT((ndo, " "));
JP Abgrall53f17a92014-02-12 14:02:41 -0800735 /* Encoding is described in section 3.1 of RFC 1035 */
736 while (remain_len && *tp) {
737 label_len = *tp++;
738 if (label_len < remain_len - 1) {
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700739 (void)fn_printn(ndo, tp, label_len, NULL);
JP Abgrall53f17a92014-02-12 14:02:41 -0800740 tp += label_len;
741 remain_len -= (label_len + 1);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700742 if(*tp) ND_PRINT((ndo, "."));
JP Abgrall53f17a92014-02-12 14:02:41 -0800743 } else {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700744 ND_PRINT((ndo, " ?"));
JP Abgrall53f17a92014-02-12 14:02:41 -0800745 break;
746 }
747 }
Elliott Hughes892a68b2015-10-19 14:43:53 -0700748 ND_PRINT((ndo, ")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800749 break;
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700750 case DH6OPT_NEW_POSIX_TIMEZONE: /* all three of these options */
751 case DH6OPT_NEW_TZDB_TIMEZONE: /* are encoded similarly */
752 case DH6OPT_MUDURL: /* although GMT might not work */
753 if (optlen < 5) {
754 ND_PRINT((ndo, " ?)"));
755 break;
756 }
757 tp = (const u_char *)(dh6o + 1);
758 ND_PRINT((ndo, "="));
759 (void)fn_printn(ndo, tp, (u_int)optlen, NULL);
760 ND_PRINT((ndo, ")"));
761 break;
762
The Android Open Source Project2949f582009-03-03 19:30:46 -0800763 default:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700764 ND_PRINT((ndo, ")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800765 break;
766 }
767
768 cp += sizeof(*dh6o) + optlen;
769 }
770 return;
771
772trunc:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700773 ND_PRINT((ndo, "[|dhcp6ext]"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800774}
775
776/*
777 * Print dhcp6 packets
778 */
779void
Elliott Hughes892a68b2015-10-19 14:43:53 -0700780dhcp6_print(netdissect_options *ndo,
781 const u_char *cp, u_int length)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800782{
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700783 const struct dhcp6 *dh6;
784 const struct dhcp6_relay *dh6relay;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800785 const u_char *ep;
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700786 const u_char *extp;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800787 const char *name;
788
Elliott Hughes892a68b2015-10-19 14:43:53 -0700789 ND_PRINT((ndo, "dhcp6"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800790
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700791 ep = (const u_char *)ndo->ndo_snapend;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800792 if (cp + length < ep)
793 ep = cp + length;
794
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700795 dh6 = (const struct dhcp6 *)cp;
796 dh6relay = (const struct dhcp6_relay *)cp;
Elliott Hughes892a68b2015-10-19 14:43:53 -0700797 ND_TCHECK(dh6->dh6_xid);
798 name = tok2str(dh6_msgtype_str, "msgtype-%u", dh6->dh6_msgtype);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800799
Elliott Hughes892a68b2015-10-19 14:43:53 -0700800 if (!ndo->ndo_vflag) {
801 ND_PRINT((ndo, " %s", name));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800802 return;
803 }
804
805 /* XXX relay agent messages have to be handled differently */
806
Elliott Hughes892a68b2015-10-19 14:43:53 -0700807 ND_PRINT((ndo, " %s (", name)); /*)*/
The Android Open Source Project2949f582009-03-03 19:30:46 -0800808 if (dh6->dh6_msgtype != DH6_RELAY_FORW &&
809 dh6->dh6_msgtype != DH6_RELAY_REPLY) {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700810 ND_PRINT((ndo, "xid=%x", EXTRACT_32BITS(&dh6->dh6_xid) & DH6_XIDMASK));
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700811 extp = (const u_char *)(dh6 + 1);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700812 dhcp6opt_print(ndo, extp, ep);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800813 } else { /* relay messages */
814 struct in6_addr addr6;
815
Elliott Hughes892a68b2015-10-19 14:43:53 -0700816 ND_TCHECK(dh6relay->dh6relay_peeraddr);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800817
818 memcpy(&addr6, dh6relay->dh6relay_linkaddr, sizeof (addr6));
Elliott Hughes892a68b2015-10-19 14:43:53 -0700819 ND_PRINT((ndo, "linkaddr=%s", ip6addr_string(ndo, &addr6)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800820
821 memcpy(&addr6, dh6relay->dh6relay_peeraddr, sizeof (addr6));
Elliott Hughes892a68b2015-10-19 14:43:53 -0700822 ND_PRINT((ndo, " peeraddr=%s", ip6addr_string(ndo, &addr6)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800823
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700824 dhcp6opt_print(ndo, (const u_char *)(dh6relay + 1), ep);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800825 }
826 /*(*/
Elliott Hughes892a68b2015-10-19 14:43:53 -0700827 ND_PRINT((ndo, ")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800828 return;
829
830trunc:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700831 ND_PRINT((ndo, "[|dhcp6]"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800832}