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.21 2002-08-01 08:53:04 risso Exp $";
42 #include <tcpdump-stdinc.h>
47 #include "interface.h"
48 #include "addrtoname.h"
51 #define DHCP6_DURATITION_INFINITE 0xffffffff
54 #define DH6ERR_FAILURE 16
55 #define DH6ERR_AUTHFAIL 17
56 #define DH6ERR_POORLYFORMED 18
57 #define DH6ERR_UNAVAIL 19
58 #define DH6ERR_OPTUNAVAIL 20
62 #define DH6_ADVERTISE 2
68 #define DH6_INFORM_REQ 11
70 /* DHCP6 base packet format */
77 } __attribute__ ((__packed__
));
78 #define dh6_msgtype dh6_msgtypexid.m
79 #define dh6_xid dh6_msgtypexid.x
80 #define DH6_XIDMASK 0x00ffffff
83 #define DH6OPT_CLIENTID 1
84 #define DH6OPT_SERVERID 2
86 #define DH6OPT_IA_TMP 4
87 #define DH6OPT_IADDR 5
89 #define DH6OPT_PREFERENCE 7
90 # define DH6OPT_PREF_UNDEF -1
91 # define DH6OPT_PREF_MAX 255
92 #define DH6OPT_ELAPSED_TIME 8
93 #define DH6OPT_CLIENT_MSG 9
94 #define DH6OPT_SERVER_MSG 10
95 #define DH6OPT_AUTH 11
96 #define DH6OPT_UNICAST 12
97 #define DH6OPT_STATUS_CODE 13
98 # define DH6OPT_STCODE_SUCCESS 0
99 # define DH6OPT_STCODE_UNSPECFAIL 1
100 # define DH6OPT_STCODE_AUTHFAILED 2
101 # define DH6OPT_STCODE_ADDRUNAVAIL 3
102 # define DH6OPT_STCODE_NOADDRAVAIL 4
103 # define DH6OPT_STCODE_NOBINDING 5
104 # define DH6OPT_STCODE_CONFNOMATCH 6
105 # define DH6OPT_STCODE_NOTONLINK 7
106 # define DH6OPT_STCODE_USEMULTICAST 8
107 #define DH6OPT_RAPID_COMMIT 14
108 #define DH6OPT_USER_CLASS 15
109 #define DH6OPT_VENDOR_CLASS 16
110 #define DH6OPT_VENDOR_OPTS 17
111 #define DH6OPT_INTERFACE_ID 18
112 #define DH6OPT_RECONF_MSG 19
115 * The option type has not been assigned for the following options.
116 * We temporarily adopt values used in the service specification document
117 * (200206xx version) by NTT Communications.
118 * Note that we'll change the following definitions if different type values
119 * are officially assigned.
121 #define DH6OPT_DNS 25
122 #define DH6OPT_PREFIX_DELEGATION 30
123 #define DH6OPT_PREFIX_INFORMATION 31
124 #define DH6OPT_PREFIX_REQUEST 32
127 u_int16_t dh6opt_type
;
128 u_int16_t dh6opt_len
;
129 /* type-dependent data follows */
130 } __attribute__ ((__packed__
));
133 dhcp6opt_name(int type
)
135 static char genstr
[sizeof("opt_65535") + 1]; /* XXX thread unsafe */
138 return "INVALID option";
141 case DH6OPT_CLIENTID
:
143 case DH6OPT_SERVERID
:
146 return "option request";
147 case DH6OPT_PREFERENCE
:
149 case DH6OPT_STATUS_CODE
:
150 return "status code";
151 case DH6OPT_RAPID_COMMIT
:
152 return "rapid commit";
155 case DH6OPT_PREFIX_DELEGATION
:
156 return "prefix delegation";
157 case DH6OPT_PREFIX_INFORMATION
:
158 return "prefix information";
160 sprintf(genstr
, "opt_%d", type
);
166 dhcp6stcode(int code
)
168 static char genstr
[sizeof("code255") + 1]; /* XXX thread unsafe */
171 return "INVALID code";
174 case DH6OPT_STCODE_SUCCESS
:
176 case DH6OPT_STCODE_UNSPECFAIL
:
177 return "unspec failure";
178 case DH6OPT_STCODE_AUTHFAILED
:
180 case DH6OPT_STCODE_ADDRUNAVAIL
:
181 return "address unavailable";
182 case DH6OPT_STCODE_NOADDRAVAIL
:
183 return "no addresses";
184 case DH6OPT_STCODE_NOBINDING
:
186 case DH6OPT_STCODE_CONFNOMATCH
:
187 return "confirm no match";
188 case DH6OPT_STCODE_NOTONLINK
:
189 return "not on-link";
190 case DH6OPT_STCODE_USEMULTICAST
:
191 return "use multicast";
193 sprintf(genstr
, "code%d", code
);
199 dhcp6opt_print(u_char
*cp
, u_char
*ep
)
201 struct dhcp6opt
*dh6o
;
207 struct in6_addr addr6
;
212 if (ep
- cp
< sizeof(*dh6o
))
214 dh6o
= (struct dhcp6opt
*)cp
;
215 optlen
= ntohs(dh6o
->dh6opt_len
);
216 if (ep
- cp
< sizeof(*dh6o
) + optlen
)
218 opttype
= ntohs(dh6o
->dh6opt_type
);
219 printf(" (%s", dhcp6opt_name(opttype
));
221 case DH6OPT_CLIENTID
:
222 case DH6OPT_SERVERID
:
228 tp
= (u_char
*)(dh6o
+ 1);
229 switch (ntohs(*(u_int16_t
*)tp
)) {
231 if (optlen
>= 2 + 6) {
232 printf(" hwaddr/time type %u time %u ",
233 ntohs(*(u_int16_t
*)&tp
[2]),
234 ntohl(*(u_int32_t
*)&tp
[4]));
235 for (i
= 8; i
< optlen
; i
++)
236 printf("%02x", tp
[i
]);
245 if (optlen
>= 2 + 8) {
247 for (i
= 2; i
< 2 + 8; i
++)
248 printf("%02x", tp
[i
]);
257 if (optlen
>= 2 + 2) {
258 printf(" hwaddr type %u ",
259 ntohs(*(u_int16_t
*)&tp
[2]));
260 for (i
= 4; i
< optlen
; i
++)
261 printf("%02x", tp
[i
]);
270 printf(" type %d)", ntohs(*(u_int16_t
*)tp
));
279 tp
= (u_char
*)(dh6o
+ 1);
280 for (i
= 0; i
< optlen
; i
+= 2) {
283 memcpy(&opt
, &tp
[i
], sizeof(opt
));
284 printf(" %s", dhcp6opt_name(ntohs(opt
)));
288 case DH6OPT_PREFERENCE
:
293 printf(" %d)", *((u_char
*)(dh6o
+ 1) + 1));
295 case DH6OPT_RAPID_COMMIT
: /* nothing todo */
303 tp
= (u_char
*)(dh6o
+ 1);
304 for (i
= 0; i
< optlen
; i
+= 16)
305 printf(" %s", ip6addr_string(&tp
[i
]));
308 case DH6OPT_PREFIX_DELEGATION
:
309 dhcp6opt_print((u_char
*)(dh6o
+ 1),
310 (u_char
*)(dh6o
+ 1) + optlen
);
313 case DH6OPT_PREFIX_INFORMATION
:
316 memcpy(&addr6
, (u_char
*)(dh6o
+ 1) + 5,
318 printf(" %s/%d", ip6addr_string(&addr6
),
319 (int)*((u_char
*)(dh6o
+ 1) + 4));
320 memcpy(&val32
, dh6o
+ 1, sizeof(val32
));
321 val32
= ntohl(val32
);
322 if (val32
== DHCP6_DURATITION_INFINITE
)
323 printf(" lease-duration: infinite)");
325 printf(" lease-duration: %u)", val32
);
327 case DH6OPT_STATUS_CODE
:
330 memcpy(&val16
, (u_char
*)(dh6o
+ 1), sizeof(val16
));
331 val16
= ntohs(val16
);
332 printf(" %s)", dhcp6stcode(val16
));
335 printf(")", ntohs(dh6o
->dh6opt_type
));
339 cp
+= sizeof(*dh6o
) + optlen
;
344 printf("[|dhcp6ext]");
348 * Print dhcp6 packets
351 dhcp6_print(register const u_char
*cp
, u_int length
,
352 u_int16_t sport
, u_int16_t dport
)
361 ep
= (u_char
*)snapend
;
363 dh6
= (struct dhcp6
*)cp
;
364 TCHECK(dh6
->dh6_xid
);
365 switch (dh6
->dh6_msgtype
) {
399 printf(" msgtype-%u", dh6
->dh6_msgtype
);
403 /* XXX relay agent messages have to be handled differently */
406 printf(" %s (", name
); /*)*/
408 printf(" msgtype-%u (", dh6
->dh6_msgtype
); /*)*/
409 printf("xid=%x", ntohl(dh6
->dh6_xid
) & DH6_XIDMASK
);
410 extp
= (u_char
*)(dh6
+ 1);
411 dhcp6opt_print(extp
, ep
);