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.20 2002-06-15 02:49:54 itojun Exp $";
42 #include <sys/param.h>
44 #include <sys/socket.h>
46 #include <netinet/in.h>
51 #include <arpa/inet.h>
53 #include "interface.h"
54 #include "addrtoname.h"
57 #define DHCP6_DURATITION_INFINITE 0xffffffff
60 #define DH6ERR_FAILURE 16
61 #define DH6ERR_AUTHFAIL 17
62 #define DH6ERR_POORLYFORMED 18
63 #define DH6ERR_UNAVAIL 19
64 #define DH6ERR_OPTUNAVAIL 20
68 #define DH6_ADVERTISE 2
74 #define DH6_INFORM_REQ 11
76 /* DHCP6 base packet format */
83 } __attribute__ ((__packed__
));
84 #define dh6_msgtype dh6_msgtypexid.m
85 #define dh6_xid dh6_msgtypexid.x
86 #define DH6_XIDMASK 0x00ffffff
89 #define DH6OPT_CLIENTID 1
90 #define DH6OPT_SERVERID 2
92 #define DH6OPT_IA_TMP 4
93 #define DH6OPT_IADDR 5
95 #define DH6OPT_PREFERENCE 7
96 # define DH6OPT_PREF_UNDEF -1
97 # define DH6OPT_PREF_MAX 255
98 #define DH6OPT_ELAPSED_TIME 8
99 #define DH6OPT_CLIENT_MSG 9
100 #define DH6OPT_SERVER_MSG 10
101 #define DH6OPT_AUTH 11
102 #define DH6OPT_UNICAST 12
103 #define DH6OPT_STATUS_CODE 13
104 # define DH6OPT_STCODE_SUCCESS 0
105 # define DH6OPT_STCODE_UNSPECFAIL 1
106 # define DH6OPT_STCODE_AUTHFAILED 2
107 # define DH6OPT_STCODE_ADDRUNAVAIL 3
108 # define DH6OPT_STCODE_NOADDRAVAIL 4
109 # define DH6OPT_STCODE_NOBINDING 5
110 # define DH6OPT_STCODE_CONFNOMATCH 6
111 # define DH6OPT_STCODE_NOTONLINK 7
112 # define DH6OPT_STCODE_USEMULTICAST 8
113 #define DH6OPT_RAPID_COMMIT 14
114 #define DH6OPT_USER_CLASS 15
115 #define DH6OPT_VENDOR_CLASS 16
116 #define DH6OPT_VENDOR_OPTS 17
117 #define DH6OPT_INTERFACE_ID 18
118 #define DH6OPT_RECONF_MSG 19
121 * The option type has not been assigned for the following options.
122 * We temporarily adopt values used in the service specification document
123 * (200206xx version) by NTT Communications.
124 * Note that we'll change the following definitions if different type values
125 * are officially assigned.
127 #define DH6OPT_DNS 25
128 #define DH6OPT_PREFIX_DELEGATION 30
129 #define DH6OPT_PREFIX_INFORMATION 31
130 #define DH6OPT_PREFIX_REQUEST 32
133 u_int16_t dh6opt_type
;
134 u_int16_t dh6opt_len
;
135 /* type-dependent data follows */
136 } __attribute__ ((__packed__
));
139 dhcp6opt_name(int type
)
141 static char genstr
[sizeof("opt_65535") + 1]; /* XXX thread unsafe */
144 return "INVALID option";
147 case DH6OPT_CLIENTID
:
149 case DH6OPT_SERVERID
:
152 return "option request";
153 case DH6OPT_PREFERENCE
:
155 case DH6OPT_STATUS_CODE
:
156 return "status code";
157 case DH6OPT_RAPID_COMMIT
:
158 return "rapid commit";
161 case DH6OPT_PREFIX_DELEGATION
:
162 return "prefix delegation";
163 case DH6OPT_PREFIX_INFORMATION
:
164 return "prefix information";
166 sprintf(genstr
, "opt_%d", type
);
172 dhcp6stcode(int code
)
174 static char genstr
[sizeof("code255") + 1]; /* XXX thread unsafe */
177 return "INVALID code";
180 case DH6OPT_STCODE_SUCCESS
:
182 case DH6OPT_STCODE_UNSPECFAIL
:
183 return "unspec failure";
184 case DH6OPT_STCODE_AUTHFAILED
:
186 case DH6OPT_STCODE_ADDRUNAVAIL
:
187 return "address unavailable";
188 case DH6OPT_STCODE_NOADDRAVAIL
:
189 return "no addresses";
190 case DH6OPT_STCODE_NOBINDING
:
192 case DH6OPT_STCODE_CONFNOMATCH
:
193 return "confirm no match";
194 case DH6OPT_STCODE_NOTONLINK
:
195 return "not on-link";
196 case DH6OPT_STCODE_USEMULTICAST
:
197 return "use multicast";
199 sprintf(genstr
, "code%d", code
);
205 dhcp6opt_print(u_char
*cp
, u_char
*ep
)
207 struct dhcp6opt
*dh6o
;
213 struct in6_addr addr6
;
218 if (ep
- cp
< sizeof(*dh6o
))
220 dh6o
= (struct dhcp6opt
*)cp
;
221 optlen
= ntohs(dh6o
->dh6opt_len
);
222 if (ep
- cp
< sizeof(*dh6o
) + optlen
)
224 opttype
= ntohs(dh6o
->dh6opt_type
);
225 printf(" (%s", dhcp6opt_name(opttype
));
227 case DH6OPT_CLIENTID
:
228 case DH6OPT_SERVERID
:
234 tp
= (u_char
*)(dh6o
+ 1);
235 switch (ntohs(*(u_int16_t
*)tp
)) {
237 if (optlen
>= 2 + 6) {
238 printf(" hwaddr/time type %u time %u ",
239 ntohs(*(u_int16_t
*)&tp
[2]),
240 ntohl(*(u_int32_t
*)&tp
[4]));
241 for (i
= 8; i
< optlen
; i
++)
242 printf("%02x", tp
[i
]);
251 if (optlen
>= 2 + 8) {
253 for (i
= 2; i
< 2 + 8; i
++)
254 printf("%02x", tp
[i
]);
263 if (optlen
>= 2 + 2) {
264 printf(" hwaddr type %u ",
265 ntohs(*(u_int16_t
*)&tp
[2]));
266 for (i
= 4; i
< optlen
; i
++)
267 printf("%02x", tp
[i
]);
276 printf(" type %d)", ntohs(*(u_int16_t
*)tp
));
285 tp
= (u_char
*)(dh6o
+ 1);
286 for (i
= 0; i
< optlen
; i
+= 2) {
289 memcpy(&opt
, &tp
[i
], sizeof(opt
));
290 printf(" %s", dhcp6opt_name(ntohs(opt
)));
294 case DH6OPT_PREFERENCE
:
299 printf(" %d)", *((u_char
*)(dh6o
+ 1) + 1));
301 case DH6OPT_RAPID_COMMIT
: /* nothing todo */
309 tp
= (u_char
*)(dh6o
+ 1);
310 for (i
= 0; i
< optlen
; i
+= 16)
311 printf(" %s", ip6addr_string(&tp
[i
]));
314 case DH6OPT_PREFIX_DELEGATION
:
315 dhcp6opt_print((u_char
*)(dh6o
+ 1),
316 (u_char
*)(dh6o
+ 1) + optlen
);
319 case DH6OPT_PREFIX_INFORMATION
:
322 memcpy(&addr6
, (u_char
*)(dh6o
+ 1) + 5,
324 printf(" %s/%d", ip6addr_string(&addr6
),
325 (int)*((u_char
*)(dh6o
+ 1) + 4));
326 memcpy(&val32
, dh6o
+ 1, sizeof(val32
));
327 val32
= ntohl(val32
);
328 if (val32
== DHCP6_DURATITION_INFINITE
)
329 printf(" lease-duration: infinite)");
331 printf(" lease-duration: %u)", val32
);
333 case DH6OPT_STATUS_CODE
:
336 memcpy(&val16
, (u_char
*)(dh6o
+ 1), sizeof(val16
));
337 val16
= ntohs(val16
);
338 printf(" %s)", dhcp6stcode(val16
));
341 printf(")", ntohs(dh6o
->dh6opt_type
));
345 cp
+= sizeof(*dh6o
) + optlen
;
350 printf("[|dhcp6ext]");
354 * Print dhcp6 packets
357 dhcp6_print(register const u_char
*cp
, u_int length
,
358 u_int16_t sport
, u_int16_t dport
)
367 ep
= (u_char
*)snapend
;
369 dh6
= (struct dhcp6
*)cp
;
370 TCHECK(dh6
->dh6_xid
);
371 switch (dh6
->dh6_msgtype
) {
405 printf(" msgtype-%u", dh6
->dh6_msgtype
);
409 /* XXX relay agent messages have to be handled differently */
412 printf(" %s (", name
); /*)*/
414 printf(" msgtype-%u (", dh6
->dh6_msgtype
); /*)*/
415 printf("xid=%x", ntohl(dh6
->dh6_xid
) & DH6_XIDMASK
);
416 extp
= (u_char
*)(dh6
+ 1);
417 dhcp6opt_print(extp
, ep
);