2 * Copyright (C) 1998 and 1999 WIDE Project.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
30 * draft-ietf-dhc-dhcpv6-26.txt
34 static const char rcsid
[] =
35 "@(#) $Header: /tcpdump/master/tcpdump/print-dhcp6.c,v 1.24 2002-12-11 22:29:21 guy Exp $";
42 #include <tcpdump-stdinc.h>
47 #include "interface.h"
48 #include "addrtoname.h"
52 #define DHCP6_DURATITION_INFINITE 0xffffffff
55 #define DH6ERR_FAILURE 16
56 #define DH6ERR_AUTHFAIL 17
57 #define DH6ERR_POORLYFORMED 18
58 #define DH6ERR_UNAVAIL 19
59 #define DH6ERR_OPTUNAVAIL 20
63 #define DH6_ADVERTISE 2
69 #define DH6_INFORM_REQ 11
71 /* DHCP6 base packet format */
79 #define dh6_msgtype dh6_msgtypexid.m
80 #define dh6_xid dh6_msgtypexid.x
81 #define DH6_XIDMASK 0x00ffffff
84 #define DH6OPT_CLIENTID 1
85 #define DH6OPT_SERVERID 2
87 #define DH6OPT_IA_TMP 4
88 #define DH6OPT_IADDR 5
90 #define DH6OPT_PREFERENCE 7
91 # define DH6OPT_PREF_UNDEF -1
92 # define DH6OPT_PREF_MAX 255
93 #define DH6OPT_ELAPSED_TIME 8
94 #define DH6OPT_CLIENT_MSG 9
95 #define DH6OPT_SERVER_MSG 10
96 #define DH6OPT_AUTH 11
97 #define DH6OPT_UNICAST 12
98 #define DH6OPT_STATUS_CODE 13
99 # define DH6OPT_STCODE_SUCCESS 0
100 # define DH6OPT_STCODE_UNSPECFAIL 1
101 # define DH6OPT_STCODE_AUTHFAILED 2
102 # define DH6OPT_STCODE_ADDRUNAVAIL 3
103 # define DH6OPT_STCODE_NOADDRAVAIL 4
104 # define DH6OPT_STCODE_NOBINDING 5
105 # define DH6OPT_STCODE_CONFNOMATCH 6
106 # define DH6OPT_STCODE_NOTONLINK 7
107 # define DH6OPT_STCODE_USEMULTICAST 8
108 #define DH6OPT_RAPID_COMMIT 14
109 #define DH6OPT_USER_CLASS 15
110 #define DH6OPT_VENDOR_CLASS 16
111 #define DH6OPT_VENDOR_OPTS 17
112 #define DH6OPT_INTERFACE_ID 18
113 #define DH6OPT_RECONF_MSG 19
116 * The option type has not been assigned for the following options.
117 * We temporarily adopt values used in the service specification document
118 * (200206xx version) by NTT Communications.
119 * Note that we'll change the following definitions if different type values
120 * are officially assigned.
122 #define DH6OPT_DNS 25
123 #define DH6OPT_PREFIX_DELEGATION 30
124 #define DH6OPT_PREFIX_INFORMATION 31
125 #define DH6OPT_PREFIX_REQUEST 32
128 u_int16_t dh6opt_type
;
129 u_int16_t dh6opt_len
;
130 /* type-dependent data follows */
134 dhcp6opt_name(int type
)
136 static char genstr
[sizeof("opt_65535") + 1]; /* XXX thread unsafe */
139 return "INVALID option";
142 case DH6OPT_CLIENTID
:
144 case DH6OPT_SERVERID
:
147 return "option request";
148 case DH6OPT_PREFERENCE
:
150 case DH6OPT_STATUS_CODE
:
151 return "status code";
152 case DH6OPT_RAPID_COMMIT
:
153 return "rapid commit";
156 case DH6OPT_PREFIX_DELEGATION
:
157 return "prefix delegation";
158 case DH6OPT_PREFIX_INFORMATION
:
159 return "prefix information";
161 sprintf(genstr
, "opt_%d", type
);
167 dhcp6stcode(int code
)
169 static char genstr
[sizeof("code255") + 1]; /* XXX thread unsafe */
172 return "INVALID code";
175 case DH6OPT_STCODE_SUCCESS
:
177 case DH6OPT_STCODE_UNSPECFAIL
:
178 return "unspec failure";
179 case DH6OPT_STCODE_AUTHFAILED
:
181 case DH6OPT_STCODE_ADDRUNAVAIL
:
182 return "address unavailable";
183 case DH6OPT_STCODE_NOADDRAVAIL
:
184 return "no addresses";
185 case DH6OPT_STCODE_NOBINDING
:
187 case DH6OPT_STCODE_CONFNOMATCH
:
188 return "confirm no match";
189 case DH6OPT_STCODE_NOTONLINK
:
190 return "not on-link";
191 case DH6OPT_STCODE_USEMULTICAST
:
192 return "use multicast";
194 sprintf(genstr
, "code%d", code
);
200 dhcp6opt_print(u_char
*cp
, u_char
*ep
)
202 struct dhcp6opt
*dh6o
;
209 struct in6_addr addr6
;
214 if (ep
< cp
+ sizeof(*dh6o
))
216 dh6o
= (struct dhcp6opt
*)cp
;
217 optlen
= EXTRACT_16BITS(&dh6o
->dh6opt_len
);
218 if (ep
< cp
+ sizeof(*dh6o
) + optlen
)
220 opttype
= EXTRACT_16BITS(&dh6o
->dh6opt_type
);
221 printf(" (%s", dhcp6opt_name(opttype
));
223 case DH6OPT_CLIENTID
:
224 case DH6OPT_SERVERID
:
230 tp
= (u_char
*)(dh6o
+ 1);
231 switch (EXTRACT_16BITS(tp
)) {
233 if (optlen
>= 2 + 6) {
234 printf(" hwaddr/time type %u time %u ",
235 EXTRACT_16BITS(&tp
[2]),
236 EXTRACT_32BITS(&tp
[4]));
237 for (i
= 8; i
< optlen
; i
++)
238 printf("%02x", tp
[i
]);
247 if (optlen
>= 2 + 8) {
249 for (i
= 2; i
< 2 + 8; i
++)
250 printf("%02x", tp
[i
]);
259 if (optlen
>= 2 + 2) {
260 printf(" hwaddr type %u ",
261 EXTRACT_16BITS(&tp
[2]));
262 for (i
= 4; i
< optlen
; i
++)
263 printf("%02x", tp
[i
]);
272 printf(" type %d)", EXTRACT_16BITS(tp
));
281 tp
= (u_char
*)(dh6o
+ 1);
282 for (i
= 0; i
< optlen
; i
+= 2) {
285 memcpy(&opt
, &tp
[i
], sizeof(opt
));
286 printf(" %s", dhcp6opt_name(ntohs(opt
)));
290 case DH6OPT_PREFERENCE
:
295 printf(" %d)", *((u_char
*)(dh6o
+ 1) + 1));
297 case DH6OPT_RAPID_COMMIT
: /* nothing todo */
305 tp
= (u_char
*)(dh6o
+ 1);
306 for (i
= 0; i
< optlen
; i
+= 16)
307 printf(" %s", ip6addr_string(&tp
[i
]));
310 case DH6OPT_PREFIX_DELEGATION
:
311 dhcp6opt_print((u_char
*)(dh6o
+ 1),
312 (u_char
*)(dh6o
+ 1) + optlen
);
315 case DH6OPT_PREFIX_INFORMATION
:
318 memcpy(&addr6
, (u_char
*)(dh6o
+ 1) + 5,
320 printf(" %s/%d", ip6addr_string(&addr6
),
321 (int)*((u_char
*)(dh6o
+ 1) + 4));
322 memcpy(&val32
, dh6o
+ 1, sizeof(val32
));
323 val32
= ntohl(val32
);
324 if (val32
== DHCP6_DURATITION_INFINITE
)
325 printf(" lease-duration: infinite)");
327 printf(" lease-duration: %u)", val32
);
329 case DH6OPT_STATUS_CODE
:
332 memcpy(&val16
, (u_char
*)(dh6o
+ 1), sizeof(val16
));
333 val16
= ntohs(val16
);
334 printf(" %s)", dhcp6stcode(val16
));
341 cp
+= sizeof(*dh6o
) + optlen
;
346 printf("[|dhcp6ext]");
350 * Print dhcp6 packets
353 dhcp6_print(register const u_char
*cp
, u_int length
,
354 u_int16_t sport
, u_int16_t dport
)
363 ep
= (u_char
*)snapend
;
365 dh6
= (struct dhcp6
*)cp
;
366 TCHECK(dh6
->dh6_xid
);
367 switch (dh6
->dh6_msgtype
) {
401 printf(" msgtype-%u", dh6
->dh6_msgtype
);
405 /* XXX relay agent messages have to be handled differently */
408 printf(" %s (", name
); /*)*/
410 printf(" msgtype-%u (", dh6
->dh6_msgtype
); /*)*/
411 printf("xid=%x", EXTRACT_32BITS(&dh6
->dh6_xid
) & DH6_XIDMASK
);
412 extp
= (u_char
*)(dh6
+ 1);
413 dhcp6opt_print(extp
, ep
);