1 | #include <machine/rtems-bsd-user-space.h> |
---|
2 | |
---|
3 | /* |
---|
4 | * Copyright (C) 1998 and 1999 WIDE Project. |
---|
5 | * All rights reserved. |
---|
6 | * |
---|
7 | * Redistribution and use in source and binary forms, with or without |
---|
8 | * modification, are permitted provided that the following conditions |
---|
9 | * are met: |
---|
10 | * 1. Redistributions of source code must retain the above copyright |
---|
11 | * notice, this list of conditions and the following disclaimer. |
---|
12 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
13 | * notice, this list of conditions and the following disclaimer in the |
---|
14 | * documentation and/or other materials provided with the distribution. |
---|
15 | * 3. Neither the name of the project nor the names of its contributors |
---|
16 | * may be used to endorse or promote products derived from this software |
---|
17 | * without specific prior written permission. |
---|
18 | * |
---|
19 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND |
---|
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE |
---|
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
---|
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
---|
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
---|
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
---|
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
---|
29 | * SUCH DAMAGE. |
---|
30 | */ |
---|
31 | /* |
---|
32 | * RFC3315: DHCPv6 |
---|
33 | * supported DHCPv6 options: |
---|
34 | * RFC3319: Session Initiation Protocol (SIP) Servers options, |
---|
35 | * RFC3633: IPv6 Prefix options, |
---|
36 | * RFC3646: DNS Configuration options, |
---|
37 | * RFC3898: Network Information Service (NIS) Configuration options, |
---|
38 | * RFC4075: Simple Network Time Protocol (SNTP) Configuration option, |
---|
39 | * RFC4242: Information Refresh Time option, |
---|
40 | * RFC4280: Broadcast and Multicast Control Servers options, |
---|
41 | * RFC6334: Dual-Stack Lite option, |
---|
42 | */ |
---|
43 | |
---|
44 | #ifndef lint |
---|
45 | static const char rcsid[] _U_ = |
---|
46 | "@(#) $Header: /tcpdump/master/tcpdump/print-dhcp6.c,v 1.37 2008-02-06 10:26:09 guy Exp $"; |
---|
47 | #endif |
---|
48 | |
---|
49 | #ifdef HAVE_CONFIG_H |
---|
50 | #include "config.h" |
---|
51 | #endif |
---|
52 | |
---|
53 | #include <tcpdump-stdinc.h> |
---|
54 | |
---|
55 | #include <stdio.h> |
---|
56 | #include <string.h> |
---|
57 | |
---|
58 | #include "interface.h" |
---|
59 | #include "addrtoname.h" |
---|
60 | #include "extract.h" |
---|
61 | |
---|
62 | /* lease duration */ |
---|
63 | #define DHCP6_DURATITION_INFINITE 0xffffffff |
---|
64 | |
---|
65 | /* Error Values */ |
---|
66 | #define DH6ERR_FAILURE 16 |
---|
67 | #define DH6ERR_AUTHFAIL 17 |
---|
68 | #define DH6ERR_POORLYFORMED 18 |
---|
69 | #define DH6ERR_UNAVAIL 19 |
---|
70 | #define DH6ERR_OPTUNAVAIL 20 |
---|
71 | |
---|
72 | /* Message type */ |
---|
73 | #define DH6_SOLICIT 1 |
---|
74 | #define DH6_ADVERTISE 2 |
---|
75 | #define DH6_REQUEST 3 |
---|
76 | #define DH6_CONFIRM 4 |
---|
77 | #define DH6_RENEW 5 |
---|
78 | #define DH6_REBIND 6 |
---|
79 | #define DH6_REPLY 7 |
---|
80 | #define DH6_RELEASE 8 |
---|
81 | #define DH6_DECLINE 9 |
---|
82 | #define DH6_RECONFIGURE 10 |
---|
83 | #define DH6_INFORM_REQ 11 |
---|
84 | #define DH6_RELAY_FORW 12 |
---|
85 | #define DH6_RELAY_REPLY 13 |
---|
86 | #define DH6_LEASEQUERY 14 |
---|
87 | #define DH6_LQ_REPLY 15 |
---|
88 | |
---|
89 | /* DHCP6 base packet format */ |
---|
90 | struct dhcp6 { |
---|
91 | union { |
---|
92 | u_int8_t m; |
---|
93 | u_int32_t x; |
---|
94 | } dh6_msgtypexid; |
---|
95 | /* options follow */ |
---|
96 | }; |
---|
97 | #define dh6_msgtype dh6_msgtypexid.m |
---|
98 | #define dh6_xid dh6_msgtypexid.x |
---|
99 | #define DH6_XIDMASK 0x00ffffff |
---|
100 | |
---|
101 | /* DHCPv6 relay messages */ |
---|
102 | struct dhcp6_relay { |
---|
103 | u_int8_t dh6relay_msgtype; |
---|
104 | u_int8_t dh6relay_hcnt; |
---|
105 | u_int8_t dh6relay_linkaddr[16]; /* XXX: badly aligned */ |
---|
106 | u_int8_t dh6relay_peeraddr[16]; |
---|
107 | /* options follow */ |
---|
108 | }; |
---|
109 | |
---|
110 | /* options */ |
---|
111 | #define DH6OPT_CLIENTID 1 |
---|
112 | #define DH6OPT_SERVERID 2 |
---|
113 | #define DH6OPT_IA_NA 3 |
---|
114 | #define DH6OPT_IA_TA 4 |
---|
115 | #define DH6OPT_IA_ADDR 5 |
---|
116 | #define DH6OPT_ORO 6 |
---|
117 | #define DH6OPT_PREFERENCE 7 |
---|
118 | # define DH6OPT_PREF_MAX 255 |
---|
119 | #define DH6OPT_ELAPSED_TIME 8 |
---|
120 | #define DH6OPT_RELAY_MSG 9 |
---|
121 | /*#define DH6OPT_SERVER_MSG 10 deprecated */ |
---|
122 | #define DH6OPT_AUTH 11 |
---|
123 | # define DH6OPT_AUTHPROTO_DELAYED 2 |
---|
124 | # define DH6OPT_AUTHPROTO_RECONFIG 3 |
---|
125 | # define DH6OPT_AUTHALG_HMACMD5 1 |
---|
126 | # define DH6OPT_AUTHRDM_MONOCOUNTER 0 |
---|
127 | # define DH6OPT_AUTHRECONFIG_KEY 1 |
---|
128 | # define DH6OPT_AUTHRECONFIG_HMACMD5 2 |
---|
129 | #define DH6OPT_UNICAST 12 |
---|
130 | #define DH6OPT_STATUS_CODE 13 |
---|
131 | # define DH6OPT_STCODE_SUCCESS 0 |
---|
132 | # define DH6OPT_STCODE_UNSPECFAIL 1 |
---|
133 | # define DH6OPT_STCODE_NOADDRAVAIL 2 |
---|
134 | # define DH6OPT_STCODE_NOBINDING 3 |
---|
135 | # define DH6OPT_STCODE_NOTONLINK 4 |
---|
136 | # define DH6OPT_STCODE_USEMULTICAST 5 |
---|
137 | # define DH6OPT_STCODE_NOPREFIXAVAIL 6 |
---|
138 | # define DH6OPT_STCODE_UNKNOWNQUERYTYPE 7 |
---|
139 | # define DH6OPT_STCODE_MALFORMEDQUERY 8 |
---|
140 | # define DH6OPT_STCODE_NOTCONFIGURED 9 |
---|
141 | # define DH6OPT_STCODE_NOTALLOWED 10 |
---|
142 | #define DH6OPT_RAPID_COMMIT 14 |
---|
143 | #define DH6OPT_USER_CLASS 15 |
---|
144 | #define DH6OPT_VENDOR_CLASS 16 |
---|
145 | #define DH6OPT_VENDOR_OPTS 17 |
---|
146 | #define DH6OPT_INTERFACE_ID 18 |
---|
147 | #define DH6OPT_RECONF_MSG 19 |
---|
148 | #define DH6OPT_RECONF_ACCEPT 20 |
---|
149 | #define DH6OPT_SIP_SERVER_D 21 |
---|
150 | #define DH6OPT_SIP_SERVER_A 22 |
---|
151 | #define DH6OPT_DNS 23 |
---|
152 | #define DH6OPT_DNSNAME 24 |
---|
153 | #define DH6OPT_IA_PD 25 |
---|
154 | #define DH6OPT_IA_PD_PREFIX 26 |
---|
155 | #define DH6OPT_NIS_SERVERS 27 |
---|
156 | #define DH6OPT_NISP_SERVERS 28 |
---|
157 | #define DH6OPT_NIS_NAME 29 |
---|
158 | #define DH6OPT_NISP_NAME 30 |
---|
159 | #define DH6OPT_NTP_SERVERS 31 |
---|
160 | #define DH6OPT_LIFETIME 32 |
---|
161 | #define DH6OPT_BCMCS_SERVER_D 33 |
---|
162 | #define DH6OPT_BCMCS_SERVER_A 34 |
---|
163 | #define DH6OPT_GEOCONF_CIVIC 36 |
---|
164 | #define DH6OPT_REMOTE_ID 37 |
---|
165 | #define DH6OPT_SUBSCRIBER_ID 38 |
---|
166 | #define DH6OPT_CLIENT_FQDN 39 |
---|
167 | #define DH6OPT_PANA_AGENT 40 |
---|
168 | #define DH6OPT_NEW_POSIX_TIMEZONE 41 |
---|
169 | #define DH6OPT_NEW_TZDB_TIMEZONE 42 |
---|
170 | #define DH6OPT_ERO 43 |
---|
171 | #define DH6OPT_LQ_QUERY 44 |
---|
172 | #define DH6OPT_CLIENT_DATA 45 |
---|
173 | #define DH6OPT_CLT_TIME 46 |
---|
174 | #define DH6OPT_LQ_RELAY_DATA 47 |
---|
175 | #define DH6OPT_LQ_CLIENT_LINK 48 |
---|
176 | #define DH6OPT_AFTR_NAME 64 |
---|
177 | |
---|
178 | struct dhcp6opt { |
---|
179 | u_int16_t dh6opt_type; |
---|
180 | u_int16_t dh6opt_len; |
---|
181 | /* type-dependent data follows */ |
---|
182 | }; |
---|
183 | |
---|
184 | static const char * |
---|
185 | dhcp6opt_name(int type) |
---|
186 | { |
---|
187 | static char genstr[sizeof("opt_65535") + 1]; /* XXX thread unsafe */ |
---|
188 | |
---|
189 | if (type > 65535) |
---|
190 | return "INVALID-option"; |
---|
191 | |
---|
192 | switch(type) { |
---|
193 | case DH6OPT_CLIENTID: |
---|
194 | return "client-ID"; |
---|
195 | case DH6OPT_SERVERID: |
---|
196 | return "server-ID"; |
---|
197 | case DH6OPT_IA_NA: |
---|
198 | return "IA_NA"; |
---|
199 | case DH6OPT_IA_TA: |
---|
200 | return "IA_TA"; |
---|
201 | case DH6OPT_IA_ADDR: |
---|
202 | return "IA_ADDR"; |
---|
203 | case DH6OPT_ORO: |
---|
204 | return "option-request"; |
---|
205 | case DH6OPT_PREFERENCE: |
---|
206 | return "preference"; |
---|
207 | case DH6OPT_ELAPSED_TIME: |
---|
208 | return "elapsed-time"; |
---|
209 | case DH6OPT_RELAY_MSG: |
---|
210 | return "relay-message"; |
---|
211 | case DH6OPT_AUTH: |
---|
212 | return "authentication"; |
---|
213 | case DH6OPT_UNICAST: |
---|
214 | return "server-unicast"; |
---|
215 | case DH6OPT_STATUS_CODE: |
---|
216 | return "status-code"; |
---|
217 | case DH6OPT_RAPID_COMMIT: |
---|
218 | return "rapid-commit"; |
---|
219 | case DH6OPT_USER_CLASS: |
---|
220 | return "user-class"; |
---|
221 | case DH6OPT_VENDOR_CLASS: |
---|
222 | return "vendor-class"; |
---|
223 | case DH6OPT_VENDOR_OPTS: |
---|
224 | return "vendor-specific-info"; |
---|
225 | case DH6OPT_INTERFACE_ID: |
---|
226 | return "interface-ID"; |
---|
227 | case DH6OPT_RECONF_MSG: |
---|
228 | return "reconfigure-message"; |
---|
229 | case DH6OPT_RECONF_ACCEPT: |
---|
230 | return "reconfigure-accept"; |
---|
231 | case DH6OPT_SIP_SERVER_D: |
---|
232 | return "SIP-servers-domain"; |
---|
233 | case DH6OPT_SIP_SERVER_A: |
---|
234 | return "SIP-servers-address"; |
---|
235 | case DH6OPT_DNS: |
---|
236 | return "DNS-server"; |
---|
237 | case DH6OPT_DNSNAME: |
---|
238 | return "DNS-search-list"; |
---|
239 | case DH6OPT_IA_PD: |
---|
240 | return "IA_PD"; |
---|
241 | case DH6OPT_IA_PD_PREFIX: |
---|
242 | return "IA_PD-prefix"; |
---|
243 | case DH6OPT_NTP_SERVERS: |
---|
244 | return "NTP-server"; |
---|
245 | case DH6OPT_LIFETIME: |
---|
246 | return "lifetime"; |
---|
247 | case DH6OPT_NIS_SERVERS: |
---|
248 | return "NIS-server"; |
---|
249 | case DH6OPT_NISP_SERVERS: |
---|
250 | return "NIS+-server"; |
---|
251 | case DH6OPT_NIS_NAME: |
---|
252 | return "NIS-domain-name"; |
---|
253 | case DH6OPT_NISP_NAME: |
---|
254 | return "NIS+-domain-name"; |
---|
255 | case DH6OPT_BCMCS_SERVER_D: |
---|
256 | return "BCMCS-domain-name"; |
---|
257 | case DH6OPT_BCMCS_SERVER_A: |
---|
258 | return "BCMCS-server"; |
---|
259 | case DH6OPT_GEOCONF_CIVIC: |
---|
260 | return "Geoconf-Civic"; |
---|
261 | case DH6OPT_REMOTE_ID: |
---|
262 | return "Remote-ID"; |
---|
263 | case DH6OPT_SUBSCRIBER_ID: |
---|
264 | return "Subscriber-ID"; |
---|
265 | case DH6OPT_CLIENT_FQDN: |
---|
266 | return "Client-FQDN"; |
---|
267 | case DH6OPT_PANA_AGENT: |
---|
268 | return "PANA-agent"; |
---|
269 | case DH6OPT_NEW_POSIX_TIMEZONE: |
---|
270 | return "POSIX-timezone"; |
---|
271 | case DH6OPT_NEW_TZDB_TIMEZONE: |
---|
272 | return "POSIX-tz-database"; |
---|
273 | case DH6OPT_ERO: |
---|
274 | return "Echo-request-option"; |
---|
275 | case DH6OPT_LQ_QUERY: |
---|
276 | return "Lease-query"; |
---|
277 | case DH6OPT_CLIENT_DATA: |
---|
278 | return "LQ-client-data"; |
---|
279 | case DH6OPT_CLT_TIME: |
---|
280 | return "Clt-time"; |
---|
281 | case DH6OPT_LQ_RELAY_DATA: |
---|
282 | return "LQ-relay-data"; |
---|
283 | case DH6OPT_LQ_CLIENT_LINK: |
---|
284 | return "LQ-client-link"; |
---|
285 | case DH6OPT_AFTR_NAME: |
---|
286 | return "AFTR-Name"; |
---|
287 | default: |
---|
288 | snprintf(genstr, sizeof(genstr), "opt_%d", type); |
---|
289 | return(genstr); |
---|
290 | } |
---|
291 | } |
---|
292 | |
---|
293 | static const char * |
---|
294 | dhcp6stcode(int code) |
---|
295 | { |
---|
296 | static char genstr[sizeof("code255") + 1]; /* XXX thread unsafe */ |
---|
297 | |
---|
298 | if (code > 255) |
---|
299 | return "INVALID code"; |
---|
300 | |
---|
301 | switch(code) { |
---|
302 | case DH6OPT_STCODE_SUCCESS: |
---|
303 | return "success"; |
---|
304 | case DH6OPT_STCODE_UNSPECFAIL: |
---|
305 | return "unspec failure"; |
---|
306 | case DH6OPT_STCODE_NOADDRAVAIL: |
---|
307 | return "no addresses"; |
---|
308 | case DH6OPT_STCODE_NOBINDING: |
---|
309 | return "no binding"; |
---|
310 | case DH6OPT_STCODE_NOTONLINK: |
---|
311 | return "not on-link"; |
---|
312 | case DH6OPT_STCODE_USEMULTICAST: |
---|
313 | return "use multicast"; |
---|
314 | case DH6OPT_STCODE_NOPREFIXAVAIL: |
---|
315 | return "no prefixes"; |
---|
316 | case DH6OPT_STCODE_UNKNOWNQUERYTYPE: |
---|
317 | return "unknown query type"; |
---|
318 | case DH6OPT_STCODE_MALFORMEDQUERY: |
---|
319 | return "malformed query"; |
---|
320 | case DH6OPT_STCODE_NOTCONFIGURED: |
---|
321 | return "not configured"; |
---|
322 | case DH6OPT_STCODE_NOTALLOWED: |
---|
323 | return "not allowed"; |
---|
324 | default: |
---|
325 | snprintf(genstr, sizeof(genstr), "code%d", code); |
---|
326 | return(genstr); |
---|
327 | } |
---|
328 | } |
---|
329 | |
---|
330 | static void |
---|
331 | dhcp6opt_print(const u_char *cp, const u_char *ep) |
---|
332 | { |
---|
333 | struct dhcp6opt *dh6o; |
---|
334 | u_char *tp; |
---|
335 | size_t i; |
---|
336 | u_int16_t opttype; |
---|
337 | size_t optlen; |
---|
338 | u_int8_t auth_proto; |
---|
339 | u_int authinfolen, authrealmlen; |
---|
340 | |
---|
341 | if (cp == ep) |
---|
342 | return; |
---|
343 | while (cp < ep) { |
---|
344 | if (ep < cp + sizeof(*dh6o)) |
---|
345 | goto trunc; |
---|
346 | dh6o = (struct dhcp6opt *)cp; |
---|
347 | TCHECK(*dh6o); |
---|
348 | optlen = EXTRACT_16BITS(&dh6o->dh6opt_len); |
---|
349 | if (ep < cp + sizeof(*dh6o) + optlen) |
---|
350 | goto trunc; |
---|
351 | opttype = EXTRACT_16BITS(&dh6o->dh6opt_type); |
---|
352 | printf(" (%s", dhcp6opt_name(opttype)); |
---|
353 | switch (opttype) { |
---|
354 | case DH6OPT_CLIENTID: |
---|
355 | case DH6OPT_SERVERID: |
---|
356 | if (optlen < 2) { |
---|
357 | /*(*/ |
---|
358 | printf(" ?)"); |
---|
359 | break; |
---|
360 | } |
---|
361 | tp = (u_char *)(dh6o + 1); |
---|
362 | switch (EXTRACT_16BITS(tp)) { |
---|
363 | case 1: |
---|
364 | if (optlen >= 2 + 6) { |
---|
365 | printf(" hwaddr/time type %u time %u ", |
---|
366 | EXTRACT_16BITS(&tp[2]), |
---|
367 | EXTRACT_32BITS(&tp[4])); |
---|
368 | for (i = 8; i < optlen; i++) |
---|
369 | printf("%02x", tp[i]); |
---|
370 | /*(*/ |
---|
371 | printf(")"); |
---|
372 | } else { |
---|
373 | /*(*/ |
---|
374 | printf(" ?)"); |
---|
375 | } |
---|
376 | break; |
---|
377 | case 2: |
---|
378 | if (optlen >= 2 + 8) { |
---|
379 | printf(" vid "); |
---|
380 | for (i = 2; i < 2 + 8; i++) |
---|
381 | printf("%02x", tp[i]); |
---|
382 | /*(*/ |
---|
383 | printf(")"); |
---|
384 | } else { |
---|
385 | /*(*/ |
---|
386 | printf(" ?)"); |
---|
387 | } |
---|
388 | break; |
---|
389 | case 3: |
---|
390 | if (optlen >= 2 + 2) { |
---|
391 | printf(" hwaddr type %u ", |
---|
392 | EXTRACT_16BITS(&tp[2])); |
---|
393 | for (i = 4; i < optlen; i++) |
---|
394 | printf("%02x", tp[i]); |
---|
395 | /*(*/ |
---|
396 | printf(")"); |
---|
397 | } else { |
---|
398 | /*(*/ |
---|
399 | printf(" ?)"); |
---|
400 | } |
---|
401 | break; |
---|
402 | default: |
---|
403 | printf(" type %d)", EXTRACT_16BITS(tp)); |
---|
404 | break; |
---|
405 | } |
---|
406 | break; |
---|
407 | case DH6OPT_IA_ADDR: |
---|
408 | if (optlen < 24) { |
---|
409 | /*(*/ |
---|
410 | printf(" ?)"); |
---|
411 | break; |
---|
412 | } |
---|
413 | tp = (u_char *)(dh6o + 1); |
---|
414 | printf(" %s", ip6addr_string(&tp[0])); |
---|
415 | printf(" pltime:%u vltime:%u", |
---|
416 | EXTRACT_32BITS(&tp[16]), |
---|
417 | EXTRACT_32BITS(&tp[20])); |
---|
418 | if (optlen > 24) { |
---|
419 | /* there are sub-options */ |
---|
420 | dhcp6opt_print(tp + 24, tp + optlen); |
---|
421 | } |
---|
422 | printf(")"); |
---|
423 | break; |
---|
424 | case DH6OPT_ORO: |
---|
425 | case DH6OPT_ERO: |
---|
426 | if (optlen % 2) { |
---|
427 | printf(" ?)"); |
---|
428 | break; |
---|
429 | } |
---|
430 | tp = (u_char *)(dh6o + 1); |
---|
431 | for (i = 0; i < optlen; i += 2) { |
---|
432 | printf(" %s", |
---|
433 | dhcp6opt_name(EXTRACT_16BITS(&tp[i]))); |
---|
434 | } |
---|
435 | printf(")"); |
---|
436 | break; |
---|
437 | case DH6OPT_PREFERENCE: |
---|
438 | if (optlen != 1) { |
---|
439 | printf(" ?)"); |
---|
440 | break; |
---|
441 | } |
---|
442 | tp = (u_char *)(dh6o + 1); |
---|
443 | printf(" %d)", *tp); |
---|
444 | break; |
---|
445 | case DH6OPT_ELAPSED_TIME: |
---|
446 | if (optlen != 2) { |
---|
447 | printf(" ?)"); |
---|
448 | break; |
---|
449 | } |
---|
450 | tp = (u_char *)(dh6o + 1); |
---|
451 | printf(" %d)", EXTRACT_16BITS(tp)); |
---|
452 | break; |
---|
453 | case DH6OPT_RELAY_MSG: |
---|
454 | printf(" ("); |
---|
455 | tp = (u_char *)(dh6o + 1); |
---|
456 | dhcp6_print(tp, optlen); |
---|
457 | printf(")"); |
---|
458 | break; |
---|
459 | case DH6OPT_AUTH: |
---|
460 | if (optlen < 11) { |
---|
461 | printf(" ?)"); |
---|
462 | break; |
---|
463 | } |
---|
464 | tp = (u_char *)(dh6o + 1); |
---|
465 | auth_proto = *tp; |
---|
466 | switch (auth_proto) { |
---|
467 | case DH6OPT_AUTHPROTO_DELAYED: |
---|
468 | printf(" proto: delayed"); |
---|
469 | break; |
---|
470 | case DH6OPT_AUTHPROTO_RECONFIG: |
---|
471 | printf(" proto: reconfigure"); |
---|
472 | break; |
---|
473 | default: |
---|
474 | printf(" proto: %d", auth_proto); |
---|
475 | break; |
---|
476 | } |
---|
477 | tp++; |
---|
478 | switch (*tp) { |
---|
479 | case DH6OPT_AUTHALG_HMACMD5: |
---|
480 | /* XXX: may depend on the protocol */ |
---|
481 | printf(", alg: HMAC-MD5"); |
---|
482 | break; |
---|
483 | default: |
---|
484 | printf(", alg: %d", *tp); |
---|
485 | break; |
---|
486 | } |
---|
487 | tp++; |
---|
488 | switch (*tp) { |
---|
489 | case DH6OPT_AUTHRDM_MONOCOUNTER: |
---|
490 | printf(", RDM: mono"); |
---|
491 | break; |
---|
492 | default: |
---|
493 | printf(", RDM: %d", *tp); |
---|
494 | break; |
---|
495 | } |
---|
496 | tp++; |
---|
497 | printf(", RD:"); |
---|
498 | for (i = 0; i < 4; i++, tp += 2) |
---|
499 | printf(" %04x", EXTRACT_16BITS(tp)); |
---|
500 | |
---|
501 | /* protocol dependent part */ |
---|
502 | authinfolen = optlen - 11; |
---|
503 | switch (auth_proto) { |
---|
504 | case DH6OPT_AUTHPROTO_DELAYED: |
---|
505 | if (authinfolen == 0) |
---|
506 | break; |
---|
507 | if (authinfolen < 20) { |
---|
508 | printf(" ??"); |
---|
509 | break; |
---|
510 | } |
---|
511 | authrealmlen = authinfolen - 20; |
---|
512 | if (authrealmlen > 0) { |
---|
513 | printf(", realm: "); |
---|
514 | } |
---|
515 | for (i = 0; i < authrealmlen; i++, tp++) |
---|
516 | printf("%02x", *tp); |
---|
517 | printf(", key ID: %08x", EXTRACT_32BITS(tp)); |
---|
518 | tp += 4; |
---|
519 | printf(", HMAC-MD5:"); |
---|
520 | for (i = 0; i < 4; i++, tp+= 4) |
---|
521 | printf(" %08x", EXTRACT_32BITS(tp)); |
---|
522 | break; |
---|
523 | case DH6OPT_AUTHPROTO_RECONFIG: |
---|
524 | if (authinfolen != 17) { |
---|
525 | printf(" ??"); |
---|
526 | break; |
---|
527 | } |
---|
528 | switch (*tp++) { |
---|
529 | case DH6OPT_AUTHRECONFIG_KEY: |
---|
530 | printf(" reconfig-key"); |
---|
531 | break; |
---|
532 | case DH6OPT_AUTHRECONFIG_HMACMD5: |
---|
533 | printf(" type: HMAC-MD5"); |
---|
534 | break; |
---|
535 | default: |
---|
536 | printf(" type: ??"); |
---|
537 | break; |
---|
538 | } |
---|
539 | printf(" value:"); |
---|
540 | for (i = 0; i < 4; i++, tp+= 4) |
---|
541 | printf(" %08x", EXTRACT_32BITS(tp)); |
---|
542 | break; |
---|
543 | default: |
---|
544 | printf(" ??"); |
---|
545 | break; |
---|
546 | } |
---|
547 | |
---|
548 | printf(")"); |
---|
549 | break; |
---|
550 | case DH6OPT_RAPID_COMMIT: /* nothing todo */ |
---|
551 | printf(")"); |
---|
552 | break; |
---|
553 | case DH6OPT_INTERFACE_ID: |
---|
554 | case DH6OPT_SUBSCRIBER_ID: |
---|
555 | /* |
---|
556 | * Since we cannot predict the encoding, print hex dump |
---|
557 | * at most 10 characters. |
---|
558 | */ |
---|
559 | tp = (u_char *)(dh6o + 1); |
---|
560 | printf(" "); |
---|
561 | for (i = 0; i < optlen && i < 10; i++) |
---|
562 | printf("%02x", tp[i]); |
---|
563 | printf("...)"); |
---|
564 | break; |
---|
565 | case DH6OPT_RECONF_MSG: |
---|
566 | tp = (u_char *)(dh6o + 1); |
---|
567 | switch (*tp) { |
---|
568 | case DH6_RENEW: |
---|
569 | printf(" for renew)"); |
---|
570 | break; |
---|
571 | case DH6_INFORM_REQ: |
---|
572 | printf(" for inf-req)"); |
---|
573 | break; |
---|
574 | default: |
---|
575 | printf(" for ?\?\?(%02x))", *tp); |
---|
576 | break; |
---|
577 | } |
---|
578 | break; |
---|
579 | case DH6OPT_RECONF_ACCEPT: /* nothing todo */ |
---|
580 | printf(")"); |
---|
581 | break; |
---|
582 | case DH6OPT_SIP_SERVER_A: |
---|
583 | case DH6OPT_DNS: |
---|
584 | case DH6OPT_NTP_SERVERS: |
---|
585 | case DH6OPT_NIS_SERVERS: |
---|
586 | case DH6OPT_NISP_SERVERS: |
---|
587 | case DH6OPT_BCMCS_SERVER_A: |
---|
588 | case DH6OPT_PANA_AGENT: |
---|
589 | case DH6OPT_LQ_CLIENT_LINK: |
---|
590 | if (optlen % 16) { |
---|
591 | printf(" ?)"); |
---|
592 | break; |
---|
593 | } |
---|
594 | tp = (u_char *)(dh6o + 1); |
---|
595 | for (i = 0; i < optlen; i += 16) |
---|
596 | printf(" %s", ip6addr_string(&tp[i])); |
---|
597 | printf(")"); |
---|
598 | break; |
---|
599 | case DH6OPT_STATUS_CODE: |
---|
600 | if (optlen < 2) { |
---|
601 | printf(" ?)"); |
---|
602 | break; |
---|
603 | } |
---|
604 | tp = (u_char *)(dh6o + 1); |
---|
605 | printf(" %s)", dhcp6stcode(EXTRACT_16BITS(&tp[0]))); |
---|
606 | break; |
---|
607 | case DH6OPT_IA_NA: |
---|
608 | case DH6OPT_IA_PD: |
---|
609 | if (optlen < 12) { |
---|
610 | printf(" ?)"); |
---|
611 | break; |
---|
612 | } |
---|
613 | tp = (u_char *)(dh6o + 1); |
---|
614 | printf(" IAID:%u T1:%u T2:%u", |
---|
615 | EXTRACT_32BITS(&tp[0]), |
---|
616 | EXTRACT_32BITS(&tp[4]), |
---|
617 | EXTRACT_32BITS(&tp[8])); |
---|
618 | if (optlen > 12) { |
---|
619 | /* there are sub-options */ |
---|
620 | dhcp6opt_print(tp + 12, tp + optlen); |
---|
621 | } |
---|
622 | printf(")"); |
---|
623 | break; |
---|
624 | case DH6OPT_IA_TA: |
---|
625 | if (optlen < 4) { |
---|
626 | printf(" ?)"); |
---|
627 | break; |
---|
628 | } |
---|
629 | tp = (u_char *)(dh6o + 1); |
---|
630 | printf(" IAID:%u", EXTRACT_32BITS(tp)); |
---|
631 | if (optlen > 4) { |
---|
632 | /* there are sub-options */ |
---|
633 | dhcp6opt_print(tp + 4, tp + optlen); |
---|
634 | } |
---|
635 | printf(")"); |
---|
636 | break; |
---|
637 | case DH6OPT_IA_PD_PREFIX: |
---|
638 | if (optlen < 25) { |
---|
639 | printf(" ?)"); |
---|
640 | break; |
---|
641 | } |
---|
642 | tp = (u_char *)(dh6o + 1); |
---|
643 | printf(" %s/%d", ip6addr_string(&tp[9]), tp[8]); |
---|
644 | printf(" pltime:%u vltime:%u", |
---|
645 | EXTRACT_32BITS(&tp[0]), |
---|
646 | EXTRACT_32BITS(&tp[4])); |
---|
647 | if (optlen > 25) { |
---|
648 | /* there are sub-options */ |
---|
649 | dhcp6opt_print(tp + 25, tp + optlen); |
---|
650 | } |
---|
651 | printf(")"); |
---|
652 | break; |
---|
653 | case DH6OPT_LIFETIME: |
---|
654 | case DH6OPT_CLT_TIME: |
---|
655 | if (optlen != 4) { |
---|
656 | printf(" ?)"); |
---|
657 | break; |
---|
658 | } |
---|
659 | tp = (u_char *)(dh6o + 1); |
---|
660 | printf(" %d)", EXTRACT_32BITS(tp)); |
---|
661 | break; |
---|
662 | case DH6OPT_REMOTE_ID: |
---|
663 | if (optlen < 4) { |
---|
664 | printf(" ?)"); |
---|
665 | break; |
---|
666 | } |
---|
667 | tp = (u_char *)(dh6o + 1); |
---|
668 | printf(" %d ", EXTRACT_32BITS(tp)); |
---|
669 | /* |
---|
670 | * Print hex dump first 10 characters. |
---|
671 | */ |
---|
672 | for (i = 4; i < optlen && i < 14; i++) |
---|
673 | printf("%02x", tp[i]); |
---|
674 | printf("...)"); |
---|
675 | break; |
---|
676 | case DH6OPT_LQ_QUERY: |
---|
677 | if (optlen < 17) { |
---|
678 | printf(" ?)"); |
---|
679 | break; |
---|
680 | } |
---|
681 | tp = (u_char *)(dh6o + 1); |
---|
682 | switch (*tp) { |
---|
683 | case 1: |
---|
684 | printf(" by-address"); |
---|
685 | break; |
---|
686 | case 2: |
---|
687 | printf(" by-clientID"); |
---|
688 | break; |
---|
689 | default: |
---|
690 | printf(" type_%d", (int)*tp); |
---|
691 | break; |
---|
692 | } |
---|
693 | printf(" %s", ip6addr_string(&tp[1])); |
---|
694 | if (optlen > 17) { |
---|
695 | /* there are query-options */ |
---|
696 | dhcp6opt_print(tp + 17, tp + optlen); |
---|
697 | } |
---|
698 | printf(")"); |
---|
699 | break; |
---|
700 | case DH6OPT_CLIENT_DATA: |
---|
701 | tp = (u_char *)(dh6o + 1); |
---|
702 | if (optlen > 0) { |
---|
703 | /* there are encapsulated options */ |
---|
704 | dhcp6opt_print(tp, tp + optlen); |
---|
705 | } |
---|
706 | printf(")"); |
---|
707 | break; |
---|
708 | case DH6OPT_LQ_RELAY_DATA: |
---|
709 | if (optlen < 16) { |
---|
710 | printf(" ?)"); |
---|
711 | break; |
---|
712 | } |
---|
713 | tp = (u_char *)(dh6o + 1); |
---|
714 | printf(" %s ", ip6addr_string(&tp[0])); |
---|
715 | /* |
---|
716 | * Print hex dump first 10 characters. |
---|
717 | */ |
---|
718 | for (i = 16; i < optlen && i < 26; i++) |
---|
719 | printf("%02x", tp[i]); |
---|
720 | printf("...)"); |
---|
721 | break; |
---|
722 | case DH6OPT_AFTR_NAME: |
---|
723 | if (optlen < 3) { |
---|
724 | printf(" ?)"); |
---|
725 | break; |
---|
726 | } |
---|
727 | tp = (u_char *)(dh6o + 1); |
---|
728 | int remain_len = optlen; |
---|
729 | printf(" "); |
---|
730 | /* Encoding is described in section 3.1 of RFC 1035 */ |
---|
731 | int label_len; /* Label length */ |
---|
732 | while (remain_len && *tp) { |
---|
733 | label_len = *tp++; |
---|
734 | if (label_len < remain_len - 1) { |
---|
735 | printf("%.*s", label_len, tp); |
---|
736 | tp += label_len; |
---|
737 | remain_len -= (label_len + 1); |
---|
738 | if(*tp) printf("."); |
---|
739 | } else { |
---|
740 | printf(" ?"); |
---|
741 | break; |
---|
742 | } |
---|
743 | } |
---|
744 | printf(")"); |
---|
745 | break; |
---|
746 | default: |
---|
747 | printf(")"); |
---|
748 | break; |
---|
749 | } |
---|
750 | |
---|
751 | cp += sizeof(*dh6o) + optlen; |
---|
752 | } |
---|
753 | return; |
---|
754 | |
---|
755 | trunc: |
---|
756 | printf("[|dhcp6ext]"); |
---|
757 | } |
---|
758 | |
---|
759 | /* |
---|
760 | * Print dhcp6 packets |
---|
761 | */ |
---|
762 | void |
---|
763 | dhcp6_print(const u_char *cp, u_int length) |
---|
764 | { |
---|
765 | struct dhcp6 *dh6; |
---|
766 | struct dhcp6_relay *dh6relay; |
---|
767 | const u_char *ep; |
---|
768 | u_char *extp; |
---|
769 | const char *name; |
---|
770 | |
---|
771 | printf("dhcp6"); |
---|
772 | |
---|
773 | ep = (u_char *)snapend; |
---|
774 | if (cp + length < ep) |
---|
775 | ep = cp + length; |
---|
776 | |
---|
777 | dh6 = (struct dhcp6 *)cp; |
---|
778 | dh6relay = (struct dhcp6_relay *)cp; |
---|
779 | TCHECK(dh6->dh6_xid); |
---|
780 | switch (dh6->dh6_msgtype) { |
---|
781 | case DH6_SOLICIT: |
---|
782 | name = "solicit"; |
---|
783 | break; |
---|
784 | case DH6_ADVERTISE: |
---|
785 | name = "advertise"; |
---|
786 | break; |
---|
787 | case DH6_REQUEST: |
---|
788 | name = "request"; |
---|
789 | break; |
---|
790 | case DH6_CONFIRM: |
---|
791 | name = "confirm"; |
---|
792 | break; |
---|
793 | case DH6_RENEW: |
---|
794 | name = "renew"; |
---|
795 | break; |
---|
796 | case DH6_REBIND: |
---|
797 | name = "rebind"; |
---|
798 | break; |
---|
799 | case DH6_REPLY: |
---|
800 | name = "reply"; |
---|
801 | break; |
---|
802 | case DH6_RELEASE: |
---|
803 | name = "release"; |
---|
804 | break; |
---|
805 | case DH6_DECLINE: |
---|
806 | name = "decline"; |
---|
807 | break; |
---|
808 | case DH6_RECONFIGURE: |
---|
809 | name = "reconfigure"; |
---|
810 | break; |
---|
811 | case DH6_INFORM_REQ: |
---|
812 | name= "inf-req"; |
---|
813 | break; |
---|
814 | case DH6_RELAY_FORW: |
---|
815 | name= "relay-fwd"; |
---|
816 | break; |
---|
817 | case DH6_RELAY_REPLY: |
---|
818 | name= "relay-reply"; |
---|
819 | break; |
---|
820 | case DH6_LEASEQUERY: |
---|
821 | name= "leasequery"; |
---|
822 | break; |
---|
823 | case DH6_LQ_REPLY: |
---|
824 | name= "leasequery-reply"; |
---|
825 | break; |
---|
826 | default: |
---|
827 | name = NULL; |
---|
828 | break; |
---|
829 | } |
---|
830 | |
---|
831 | if (!vflag) { |
---|
832 | if (name) |
---|
833 | printf(" %s", name); |
---|
834 | else if (dh6->dh6_msgtype != DH6_RELAY_FORW && |
---|
835 | dh6->dh6_msgtype != DH6_RELAY_REPLY) { |
---|
836 | printf(" msgtype-%u", dh6->dh6_msgtype); |
---|
837 | } |
---|
838 | return; |
---|
839 | } |
---|
840 | |
---|
841 | /* XXX relay agent messages have to be handled differently */ |
---|
842 | |
---|
843 | if (name) |
---|
844 | printf(" %s (", name); /*)*/ |
---|
845 | else |
---|
846 | printf(" msgtype-%u (", dh6->dh6_msgtype); /*)*/ |
---|
847 | if (dh6->dh6_msgtype != DH6_RELAY_FORW && |
---|
848 | dh6->dh6_msgtype != DH6_RELAY_REPLY) { |
---|
849 | printf("xid=%x", EXTRACT_32BITS(&dh6->dh6_xid) & DH6_XIDMASK); |
---|
850 | extp = (u_char *)(dh6 + 1); |
---|
851 | dhcp6opt_print(extp, ep); |
---|
852 | } else { /* relay messages */ |
---|
853 | struct in6_addr addr6; |
---|
854 | |
---|
855 | TCHECK(dh6relay->dh6relay_peeraddr); |
---|
856 | |
---|
857 | memcpy(&addr6, dh6relay->dh6relay_linkaddr, sizeof (addr6)); |
---|
858 | printf("linkaddr=%s", ip6addr_string(&addr6)); |
---|
859 | |
---|
860 | memcpy(&addr6, dh6relay->dh6relay_peeraddr, sizeof (addr6)); |
---|
861 | printf(" peeraddr=%s", ip6addr_string(&addr6)); |
---|
862 | |
---|
863 | dhcp6opt_print((u_char *)(dh6relay + 1), ep); |
---|
864 | } |
---|
865 | /*(*/ |
---|
866 | printf(")"); |
---|
867 | return; |
---|
868 | |
---|
869 | trunc: |
---|
870 | printf("[|dhcp6]"); |
---|
871 | } |
---|