Deleted Added
full compact
print-icmp6.c (127668) print-icmp6.c (146773)
1/*
2 * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and

--- 7 unchanged lines hidden (view full) ---

16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 */
21
22#ifndef lint
23static const char rcsid[] _U_ =
1/*
2 * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and

--- 7 unchanged lines hidden (view full) ---

16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 */
21
22#ifndef lint
23static const char rcsid[] _U_ =
24 "@(#) $Header: /tcpdump/master/tcpdump/print-icmp6.c,v 1.72.2.4 2004/03/24 00:14:09 guy Exp $";
24 "@(#) $Header: /tcpdump/master/tcpdump/print-icmp6.c,v 1.79 2005/01/14 10:41:50 hannes Exp $";
25#endif
26
27#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#ifdef INET6
32

--- 13 unchanged lines hidden (view full) ---

46#include "udp.h"
47#include "ah.h"
48
49static const char *get_rtpref(u_int);
50static const char *get_lifetime(u_int32_t);
51static void print_lladdr(const u_char *, size_t);
52static void icmp6_opt_print(const u_char *, int);
53static void mld6_print(const u_char *);
25#endif
26
27#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#ifdef INET6
32

--- 13 unchanged lines hidden (view full) ---

46#include "udp.h"
47#include "ah.h"
48
49static const char *get_rtpref(u_int);
50static const char *get_lifetime(u_int32_t);
51static void print_lladdr(const u_char *, size_t);
52static void icmp6_opt_print(const u_char *, int);
53static void mld6_print(const u_char *);
54static void mldv2_report_print(const u_char *, u_int);
55static void mldv2_query_print(const u_char *, u_int);
54static struct udphdr *get_upperlayer(u_char *, u_int *);
55static void dnsname_print(const u_char *, const u_char *);
56static void icmp6_nodeinfo_print(u_int, const u_char *, const u_char *);
57static void icmp6_rrenum_print(const u_char *, const u_char *);
58
59#ifndef abs
60#define abs(a) ((0 < (a)) ? (a) : -(a))
61#endif
62
56static struct udphdr *get_upperlayer(u_char *, u_int *);
57static void dnsname_print(const u_char *, const u_char *);
58static void icmp6_nodeinfo_print(u_int, const u_char *, const u_char *);
59static void icmp6_rrenum_print(const u_char *, const u_char *);
60
61#ifndef abs
62#define abs(a) ((0 < (a)) ? (a) : -(a))
63#endif
64
65static struct tok icmp6_type_values[] = {
66 { ICMP6_DST_UNREACH, "destination unreachable"},
67 { ICMP6_PACKET_TOO_BIG, "packet too big"},
68 { ICMP6_TIME_EXCEEDED, "time exceeded in-transit"},
69 { ICMP6_PARAM_PROB, "parameter problem"},
70 { ICMP6_ECHO_REQUEST, "echo request"},
71 { ICMP6_ECHO_REPLY, "echo reply"},
72 { MLD6_LISTENER_QUERY, "multicast listener query "},
73 { MLD6_LISTENER_REPORT, "multicast listener report "},
74 { MLD6_LISTENER_DONE, "multicast listener done "},
75 { ND_ROUTER_SOLICIT, "router solicitation "},
76 { ND_ROUTER_ADVERT, "router advertisement"},
77 { ND_NEIGHBOR_SOLICIT, "neighbor solicitation"},
78 { ND_NEIGHBOR_ADVERT, "neighbor advertisment"},
79 { ND_REDIRECT, "redirect"},
80 { ICMP6_ROUTER_RENUMBERING, "router renumbering"},
81 { IND_SOLICIT, "inverse neighbor solicitation"},
82 { IND_ADVERT, "inverse neighbor advertisement"},
83 { MLDV2_LISTENER_REPORT, "multicast listener report v2 "},
84 { ICMP6_HADISCOV_REQUEST, "ha discovery request"},
85 { ICMP6_HADISCOV_REPLY, "ha discovery reply"},
86 { ICMP6_MOBILEPREFIX_SOLICIT, "mobile router solicitation"},
87 { ICMP6_MOBILEPREFIX_ADVERT, "mobile router advertisement"},
88 { ICMP6_WRUREQUEST, "who-are-you request"},
89 { ICMP6_WRUREPLY, "who-are-you reply"},
90 { ICMP6_NI_QUERY, "node information query"},
91 { ICMP6_NI_REPLY, "node information reply"},
92 { MLD6_MTRACE, "mtrace message"},
93 { MLD6_MTRACE_RESP, "mtrace response"},
94 { 0, NULL }
95};
96
97static struct tok icmp6_dst_unreach_code_values[] = {
98 { ICMP6_DST_UNREACH_NOROUTE, "unreachable route" },
99 { ICMP6_DST_UNREACH_ADMIN, " unreachable prohibited"},
100 { ICMP6_DST_UNREACH_BEYONDSCOPE, "beyond scope"},
101 { ICMP6_DST_UNREACH_ADDR, "unreachable address"},
102 { ICMP6_DST_UNREACH_NOPORT, "unreachable port"},
103 { 0, NULL }
104};
105
106static struct tok icmp6_opt_pi_flag_values[] = {
107 { ND_OPT_PI_FLAG_ONLINK, "onlink" },
108 { ND_OPT_PI_FLAG_AUTO, "auto" },
109 { ND_OPT_PI_FLAG_ROUTER, "router" },
110 { 0, NULL }
111};
112
113static struct tok icmp6_opt_ra_flag_values[] = {
114 { ND_RA_FLAG_MANAGED, "managed" },
115 { ND_RA_FLAG_OTHER, "other stateful"},
116 { ND_RA_FLAG_HOME_AGENT, "home agent"},
117 { 0, NULL }
118};
119
120static struct tok icmp6_nd_na_flag_values[] = {
121 { ND_NA_FLAG_ROUTER, "router" },
122 { ND_NA_FLAG_SOLICITED, "solicited" },
123 { ND_NA_FLAG_OVERRIDE, "override" },
124 { 0, NULL }
125};
126
127
128static struct tok icmp6_opt_values[] = {
129 { ND_OPT_SOURCE_LINKADDR, "source link-address"},
130 { ND_OPT_TARGET_LINKADDR, "destination link-address"},
131 { ND_OPT_PREFIX_INFORMATION, "prefix info"},
132 { ND_OPT_REDIRECTED_HEADER, "redirected header"},
133 { ND_OPT_MTU, "mtu"},
134 { ND_OPT_ADVINTERVAL, "advertisment interval"},
135 { ND_OPT_HOMEAGENT_INFO, "homeagent information"},
136 { ND_OPT_ROUTE_INFO, "route info"},
137 { 0, NULL }
138};
139
140/* mldv2 report types */
141static struct tok mldv2report2str[] = {
142 { 1, "is_in" },
143 { 2, "is_ex" },
144 { 3, "to_in" },
145 { 4, "to_ex" },
146 { 5, "allow" },
147 { 6, "block" },
148 { 0, NULL }
149};
150
63static const char *
64get_rtpref(u_int v)
65{
66 static const char *rtpref_str[] = {
67 "medium", /* 00 */
68 "high", /* 01 */
69 "rsv", /* 10 */
70 "low" /* 11 */

--- 102 unchanged lines hidden (view full) ---

173 sum = icmp6_cksum(ip, dp, length);
174 if (sum != 0)
175 (void)printf("[bad icmp6 cksum %x!] ", sum);
176 else
177 (void)printf("[icmp6 sum ok] ");
178 }
179 }
180
151static const char *
152get_rtpref(u_int v)
153{
154 static const char *rtpref_str[] = {
155 "medium", /* 00 */
156 "high", /* 01 */
157 "rsv", /* 10 */
158 "low" /* 11 */

--- 102 unchanged lines hidden (view full) ---

261 sum = icmp6_cksum(ip, dp, length);
262 if (sum != 0)
263 (void)printf("[bad icmp6 cksum %x!] ", sum);
264 else
265 (void)printf("[icmp6 sum ok] ");
266 }
267 }
268
269 printf("ICMP6, %s", tok2str(icmp6_type_values,"unknown icmp6 type (%u)",dp->icmp6_type));
270
271 /* display cosmetics: print the packet length for printer that use the vflag now */
272 if (vflag && (dp->icmp6_type ==
273 ND_ROUTER_SOLICIT ||
274 ND_ROUTER_ADVERT ||
275 ND_NEIGHBOR_ADVERT ||
276 ND_NEIGHBOR_SOLICIT ||
277 ND_REDIRECT ||
278 ICMP6_HADISCOV_REPLY ||
279 ICMP6_MOBILEPREFIX_ADVERT ))
280 printf(", length %u", length);
281
181 switch (dp->icmp6_type) {
182 case ICMP6_DST_UNREACH:
183 TCHECK(oip->ip6_dst);
282 switch (dp->icmp6_type) {
283 case ICMP6_DST_UNREACH:
284 TCHECK(oip->ip6_dst);
285 printf(", %s", tok2str(icmp6_dst_unreach_code_values,"unknown unreach code (%u)",dp->icmp6_code));
184 switch (dp->icmp6_code) {
286 switch (dp->icmp6_code) {
185 case ICMP6_DST_UNREACH_NOROUTE:
186 printf("icmp6: %s unreachable route",
187 ip6addr_string(&oip->ip6_dst));
188 break;
287
288 case ICMP6_DST_UNREACH_NOROUTE: /* fall through */
189 case ICMP6_DST_UNREACH_ADMIN:
289 case ICMP6_DST_UNREACH_ADMIN:
190 printf("icmp6: %s unreachable prohibited",
191 ip6addr_string(&oip->ip6_dst));
192 break;
290 case ICMP6_DST_UNREACH_ADDR:
291 printf(" %s",ip6addr_string(&oip->ip6_dst));
292 break;
193 case ICMP6_DST_UNREACH_BEYONDSCOPE:
293 case ICMP6_DST_UNREACH_BEYONDSCOPE:
194 printf("icmp6: %s beyond scope of source address %s",
294 printf(" %s, source address %s",
195 ip6addr_string(&oip->ip6_dst),
196 ip6addr_string(&oip->ip6_src));
197 break;
295 ip6addr_string(&oip->ip6_dst),
296 ip6addr_string(&oip->ip6_src));
297 break;
198 case ICMP6_DST_UNREACH_ADDR:
199 printf("icmp6: %s unreachable address",
200 ip6addr_string(&oip->ip6_dst));
201 break;
202 case ICMP6_DST_UNREACH_NOPORT:
203 if ((ouh = get_upperlayer((u_char *)oip, &prot))
204 == NULL)
205 goto trunc;
206
207 dport = EXTRACT_16BITS(&ouh->uh_dport);
208 switch (prot) {
209 case IPPROTO_TCP:
298 case ICMP6_DST_UNREACH_NOPORT:
299 if ((ouh = get_upperlayer((u_char *)oip, &prot))
300 == NULL)
301 goto trunc;
302
303 dport = EXTRACT_16BITS(&ouh->uh_dport);
304 switch (prot) {
305 case IPPROTO_TCP:
210 printf("icmp6: %s tcp port %s unreachable",
306 printf(", %s tcp port %s",
211 ip6addr_string(&oip->ip6_dst),
212 tcpport_string(dport));
213 break;
214 case IPPROTO_UDP:
307 ip6addr_string(&oip->ip6_dst),
308 tcpport_string(dport));
309 break;
310 case IPPROTO_UDP:
215 printf("icmp6: %s udp port %s unreachable",
311 printf(", %s udp port %s",
216 ip6addr_string(&oip->ip6_dst),
217 udpport_string(dport));
218 break;
219 default:
312 ip6addr_string(&oip->ip6_dst),
313 udpport_string(dport));
314 break;
315 default:
220 printf("icmp6: %s protocol %d port %d unreachable",
316 printf(", %s protocol %d port %d unreachable",
221 ip6addr_string(&oip->ip6_dst),
222 oip->ip6_nxt, dport);
223 break;
224 }
225 break;
226 default:
317 ip6addr_string(&oip->ip6_dst),
318 oip->ip6_nxt, dport);
319 break;
320 }
321 break;
322 default:
227 printf("icmp6: %s unreachable code-#%d",
228 ip6addr_string(&oip->ip6_dst),
229 dp->icmp6_code);
230 break;
323 if (vflag <= 1) {
324 print_unknown_data(bp,"\n\t",length);
325 return;
326 }
327 break;
231 }
232 break;
233 case ICMP6_PACKET_TOO_BIG:
234 TCHECK(dp->icmp6_mtu);
328 }
329 break;
330 case ICMP6_PACKET_TOO_BIG:
331 TCHECK(dp->icmp6_mtu);
235 printf("icmp6: too big %u", EXTRACT_32BITS(&dp->icmp6_mtu));
332 printf(", mtu %u", EXTRACT_32BITS(&dp->icmp6_mtu));
236 break;
237 case ICMP6_TIME_EXCEEDED:
238 TCHECK(oip->ip6_dst);
239 switch (dp->icmp6_code) {
240 case ICMP6_TIME_EXCEED_TRANSIT:
333 break;
334 case ICMP6_TIME_EXCEEDED:
335 TCHECK(oip->ip6_dst);
336 switch (dp->icmp6_code) {
337 case ICMP6_TIME_EXCEED_TRANSIT:
241 printf("icmp6: time exceeded in-transit for %s",
338 printf(" for %s",
242 ip6addr_string(&oip->ip6_dst));
243 break;
244 case ICMP6_TIME_EXCEED_REASSEMBLY:
339 ip6addr_string(&oip->ip6_dst));
340 break;
341 case ICMP6_TIME_EXCEED_REASSEMBLY:
245 printf("icmp6: ip6 reassembly time exceeded");
342 printf(" (reassembly)");
246 break;
247 default:
343 break;
344 default:
248 printf("icmp6: time exceeded code-#%d",
249 dp->icmp6_code);
345 printf(", unknown code (%u)", dp->icmp6_code);
250 break;
251 }
252 break;
253 case ICMP6_PARAM_PROB:
254 TCHECK(oip->ip6_dst);
255 switch (dp->icmp6_code) {
256 case ICMP6_PARAMPROB_HEADER:
346 break;
347 }
348 break;
349 case ICMP6_PARAM_PROB:
350 TCHECK(oip->ip6_dst);
351 switch (dp->icmp6_code) {
352 case ICMP6_PARAMPROB_HEADER:
257 printf("icmp6: parameter problem errorneous - octet %u",
258 EXTRACT_32BITS(&dp->icmp6_pptr));
353 printf(", errorneous - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr));
259 break;
260 case ICMP6_PARAMPROB_NEXTHEADER:
354 break;
355 case ICMP6_PARAMPROB_NEXTHEADER:
261 printf("icmp6: parameter problem next header - octet %u",
262 EXTRACT_32BITS(&dp->icmp6_pptr));
356 printf(", next header - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr));
263 break;
264 case ICMP6_PARAMPROB_OPTION:
357 break;
358 case ICMP6_PARAMPROB_OPTION:
265 printf("icmp6: parameter problem option - octet %u",
266 EXTRACT_32BITS(&dp->icmp6_pptr));
359 printf(", option - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr));
267 break;
268 default:
360 break;
361 default:
269 printf("icmp6: parameter problem code-#%d",
362 printf(", code-#%d",
270 dp->icmp6_code);
271 break;
272 }
273 break;
274 case ICMP6_ECHO_REQUEST:
275 case ICMP6_ECHO_REPLY:
276 TCHECK(dp->icmp6_seq);
363 dp->icmp6_code);
364 break;
365 }
366 break;
367 case ICMP6_ECHO_REQUEST:
368 case ICMP6_ECHO_REPLY:
369 TCHECK(dp->icmp6_seq);
277 printf("icmp6: echo %s seq %u",
278 dp->icmp6_type == ICMP6_ECHO_REQUEST ?
279 "request" : "reply",
280 EXTRACT_16BITS(&dp->icmp6_seq));
370 printf(", seq %u", EXTRACT_16BITS(&dp->icmp6_seq));
281 break;
282 case ICMP6_MEMBERSHIP_QUERY:
371 break;
372 case ICMP6_MEMBERSHIP_QUERY:
283 printf("icmp6: multicast listener query ");
284 mld6_print((const u_char *)dp);
373 if (length == MLD_MINLEN) {
374 mld6_print((const u_char *)dp);
375 } else if (length >= MLDV2_MINLEN) {
376 printf("v2 ");
377 mldv2_query_print((const u_char *)dp, length);
378 } else {
379 printf(" unknown-version (len %u) ", length);
380 }
285 break;
286 case ICMP6_MEMBERSHIP_REPORT:
381 break;
382 case ICMP6_MEMBERSHIP_REPORT:
287 printf("icmp6: multicast listener report ");
288 mld6_print((const u_char *)dp);
289 break;
290 case ICMP6_MEMBERSHIP_REDUCTION:
383 mld6_print((const u_char *)dp);
384 break;
385 case ICMP6_MEMBERSHIP_REDUCTION:
291 printf("icmp6: multicast listener done ");
292 mld6_print((const u_char *)dp);
293 break;
294 case ND_ROUTER_SOLICIT:
386 mld6_print((const u_char *)dp);
387 break;
388 case ND_ROUTER_SOLICIT:
295 printf("icmp6: router solicitation ");
296 if (vflag) {
297#define RTSOLLEN 8
389#define RTSOLLEN 8
390 if (vflag) {
298 icmp6_opt_print((const u_char *)dp + RTSOLLEN,
299 length - RTSOLLEN);
300 }
301 break;
302 case ND_ROUTER_ADVERT:
391 icmp6_opt_print((const u_char *)dp + RTSOLLEN,
392 length - RTSOLLEN);
393 }
394 break;
395 case ND_ROUTER_ADVERT:
303 printf("icmp6: router advertisement");
396#define RTADVLEN 16
304 if (vflag) {
305 struct nd_router_advert *p;
306
307 p = (struct nd_router_advert *)dp;
308 TCHECK(p->nd_ra_retransmit);
397 if (vflag) {
398 struct nd_router_advert *p;
399
400 p = (struct nd_router_advert *)dp;
401 TCHECK(p->nd_ra_retransmit);
309 printf("(chlim=%d, ", (int)p->nd_ra_curhoplimit);
310 if (p->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED)
311 printf("M");
312 if (p->nd_ra_flags_reserved & ND_RA_FLAG_OTHER)
313 printf("O");
314 if (p->nd_ra_flags_reserved & ND_RA_FLAG_HOME_AGENT)
315 printf("H");
402 printf("\n\thop limit %u, Flags [%s]" \
403 ", pref %s, router lifetime %us, reachable time %us, retrans time %us",
404 (u_int)p->nd_ra_curhoplimit,
405 bittok2str(icmp6_opt_ra_flag_values,"none",(p->nd_ra_flags_reserved)),
406 get_rtpref(p->nd_ra_flags_reserved),
407 EXTRACT_16BITS(&p->nd_ra_router_lifetime),
408 EXTRACT_32BITS(&p->nd_ra_reachable),
409 EXTRACT_32BITS(&p->nd_ra_retransmit));
316
410
317 if ((p->nd_ra_flags_reserved & ~ND_RA_FLAG_RTPREF_MASK)
318 != 0)
319 printf(" ");
320
321 printf("pref=%s, ",
322 get_rtpref(p->nd_ra_flags_reserved));
323
324 printf("router_ltime=%d, ", EXTRACT_16BITS(&p->nd_ra_router_lifetime));
325 printf("reachable_time=%u, ",
326 EXTRACT_32BITS(&p->nd_ra_reachable));
327 printf("retrans_time=%u)",
328 EXTRACT_32BITS(&p->nd_ra_retransmit));
329#define RTADVLEN 16
330 icmp6_opt_print((const u_char *)dp + RTADVLEN,
331 length - RTADVLEN);
332 }
333 break;
334 case ND_NEIGHBOR_SOLICIT:
335 {
336 struct nd_neighbor_solicit *p;
337 p = (struct nd_neighbor_solicit *)dp;
338 TCHECK(p->nd_ns_target);
411 icmp6_opt_print((const u_char *)dp + RTADVLEN,
412 length - RTADVLEN);
413 }
414 break;
415 case ND_NEIGHBOR_SOLICIT:
416 {
417 struct nd_neighbor_solicit *p;
418 p = (struct nd_neighbor_solicit *)dp;
419 TCHECK(p->nd_ns_target);
339 printf("icmp6: neighbor sol: who has %s",
340 ip6addr_string(&p->nd_ns_target));
420 printf(", who has %s", ip6addr_string(&p->nd_ns_target));
341 if (vflag) {
342#define NDSOLLEN 24
343 icmp6_opt_print((const u_char *)dp + NDSOLLEN,
344 length - NDSOLLEN);
345 }
346 }
347 break;
348 case ND_NEIGHBOR_ADVERT:
349 {
350 struct nd_neighbor_advert *p;
351
352 p = (struct nd_neighbor_advert *)dp;
353 TCHECK(p->nd_na_target);
421 if (vflag) {
422#define NDSOLLEN 24
423 icmp6_opt_print((const u_char *)dp + NDSOLLEN,
424 length - NDSOLLEN);
425 }
426 }
427 break;
428 case ND_NEIGHBOR_ADVERT:
429 {
430 struct nd_neighbor_advert *p;
431
432 p = (struct nd_neighbor_advert *)dp;
433 TCHECK(p->nd_na_target);
354 printf("icmp6: neighbor adv: tgt is %s",
434 printf(", tgt is %s",
355 ip6addr_string(&p->nd_na_target));
356 if (vflag) {
435 ip6addr_string(&p->nd_na_target));
436 if (vflag) {
357#define ND_NA_FLAG_ALL \
358 (ND_NA_FLAG_ROUTER|ND_NA_FLAG_SOLICITED|ND_NA_FLAG_OVERRIDE)
359 /* we don't need ntohl() here. see advanced-api-04. */
360 if (p->nd_na_flags_reserved & ND_NA_FLAG_ALL) {
361#undef ND_NA_FLAG_ALL
362 u_int32_t flags;
363
364 flags = p->nd_na_flags_reserved;
365 printf("(");
366 if (flags & ND_NA_FLAG_ROUTER)
367 printf("R");
368 if (flags & ND_NA_FLAG_SOLICITED)
369 printf("S");
370 if (flags & ND_NA_FLAG_OVERRIDE)
371 printf("O");
372 printf(")");
373 }
437 printf(", Flags [%s]",
438 bittok2str(icmp6_nd_na_flag_values,
439 "none",
440 EXTRACT_32BITS(&p->nd_na_flags_reserved)));
374#define NDADVLEN 24
375 icmp6_opt_print((const u_char *)dp + NDADVLEN,
376 length - NDADVLEN);
377#undef NDADVLEN
378 }
379 }
380 break;
381 case ND_REDIRECT:
382#define RDR(i) ((struct nd_redirect *)(i))
383 TCHECK(RDR(dp)->nd_rd_dst);
441#define NDADVLEN 24
442 icmp6_opt_print((const u_char *)dp + NDADVLEN,
443 length - NDADVLEN);
444#undef NDADVLEN
445 }
446 }
447 break;
448 case ND_REDIRECT:
449#define RDR(i) ((struct nd_redirect *)(i))
450 TCHECK(RDR(dp)->nd_rd_dst);
384 printf("icmp6: redirect %s",
385 getname6((const u_char *)&RDR(dp)->nd_rd_dst));
451 printf(", %s", getname6((const u_char *)&RDR(dp)->nd_rd_dst));
386 TCHECK(RDR(dp)->nd_rd_target);
387 printf(" to %s",
388 getname6((const u_char*)&RDR(dp)->nd_rd_target));
389#define REDIRECTLEN 40
390 if (vflag) {
391 icmp6_opt_print((const u_char *)dp + REDIRECTLEN,
392 length - REDIRECTLEN);
393 }
394 break;
395#undef REDIRECTLEN
396#undef RDR
397 case ICMP6_ROUTER_RENUMBERING:
398 icmp6_rrenum_print(bp, ep);
399 break;
400 case ICMP6_NI_QUERY:
401 case ICMP6_NI_REPLY:
402 icmp6_nodeinfo_print(length, bp, ep);
403 break;
452 TCHECK(RDR(dp)->nd_rd_target);
453 printf(" to %s",
454 getname6((const u_char*)&RDR(dp)->nd_rd_target));
455#define REDIRECTLEN 40
456 if (vflag) {
457 icmp6_opt_print((const u_char *)dp + REDIRECTLEN,
458 length - REDIRECTLEN);
459 }
460 break;
461#undef REDIRECTLEN
462#undef RDR
463 case ICMP6_ROUTER_RENUMBERING:
464 icmp6_rrenum_print(bp, ep);
465 break;
466 case ICMP6_NI_QUERY:
467 case ICMP6_NI_REPLY:
468 icmp6_nodeinfo_print(length, bp, ep);
469 break;
404 case ICMP6_HADISCOV_REQUEST:
405 printf("icmp6: ha discovery request");
406 if (vflag) {
407 TCHECK(dp->icmp6_data16[0]);
408 printf("(id=%d)", EXTRACT_16BITS(&dp->icmp6_data16[0]));
409 }
470 case IND_SOLICIT:
471 case IND_ADVERT:
410 break;
472 break;
473 case ICMP6_V2_MEMBERSHIP_REPORT:
474 mldv2_report_print((const u_char *) dp, length);
475 break;
476 case ICMP6_MOBILEPREFIX_SOLICIT: /* fall through */
477 case ICMP6_HADISCOV_REQUEST:
478 TCHECK(dp->icmp6_data16[0]);
479 printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0]));
480 break;
411 case ICMP6_HADISCOV_REPLY:
481 case ICMP6_HADISCOV_REPLY:
412 printf("icmp6: ha discovery reply");
413 if (vflag) {
414 struct in6_addr *in6;
415 u_char *cp;
416
417 TCHECK(dp->icmp6_data16[0]);
482 if (vflag) {
483 struct in6_addr *in6;
484 u_char *cp;
485
486 TCHECK(dp->icmp6_data16[0]);
418 printf("(id=%d", EXTRACT_16BITS(&dp->icmp6_data16[0]));
487 printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0]));
419 cp = (u_char *)dp + length;
420 in6 = (struct in6_addr *)(dp + 1);
421 for (; (u_char *)in6 < cp; in6++) {
422 TCHECK(*in6);
423 printf(", %s", ip6addr_string(in6));
424 }
488 cp = (u_char *)dp + length;
489 in6 = (struct in6_addr *)(dp + 1);
490 for (; (u_char *)in6 < cp; in6++) {
491 TCHECK(*in6);
492 printf(", %s", ip6addr_string(in6));
493 }
425 printf(")");
426 }
427 break;
494 }
495 break;
428 case ICMP6_MOBILEPREFIX_SOLICIT:
429 printf("icmp6: mobile router solicitation");
430 if (vflag) {
431 TCHECK(dp->icmp6_data16[0]);
432 printf("(id=%d)", EXTRACT_16BITS(&dp->icmp6_data16[0]));
433 }
434 break;
435 case ICMP6_MOBILEPREFIX_ADVERT:
496 case ICMP6_MOBILEPREFIX_ADVERT:
436 printf("icmp6: mobile router advertisement");
437 if (vflag) {
438 TCHECK(dp->icmp6_data16[0]);
497 if (vflag) {
498 TCHECK(dp->icmp6_data16[0]);
439 printf("(id=%d", EXTRACT_16BITS(&dp->icmp6_data16[0]));
499 printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0]));
440 if (dp->icmp6_data16[1] & 0xc0)
441 printf(" ");
442 if (dp->icmp6_data16[1] & 0x80)
443 printf("M");
444 if (dp->icmp6_data16[1] & 0x40)
445 printf("O");
500 if (dp->icmp6_data16[1] & 0xc0)
501 printf(" ");
502 if (dp->icmp6_data16[1] & 0x80)
503 printf("M");
504 if (dp->icmp6_data16[1] & 0x40)
505 printf("O");
446 printf(")");
447#define MPADVLEN 8
448 icmp6_opt_print((const u_char *)dp + MPADVLEN,
449 length - MPADVLEN);
450 }
451 break;
452 default:
506#define MPADVLEN 8
507 icmp6_opt_print((const u_char *)dp + MPADVLEN,
508 length - MPADVLEN);
509 }
510 break;
511 default:
453 printf("icmp6: type-#%d", dp->icmp6_type);
454 break;
455 }
512 printf(", length %u", length);
513 if (vflag <= 1)
514 print_unknown_data(bp,"\n\t", length);
515 return;
516 }
517 if (!vflag)
518 printf(", length %u", length);
456 return;
457trunc:
458 fputs("[|icmp6]", stdout);
459}
460
461static struct udphdr *
462get_upperlayer(u_char *bp, u_int *prot)
463{

--- 95 unchanged lines hidden (view full) ---

559 ECHECK(op->nd_opt_len);
560 if (resid <= 0)
561 return;
562 if (op->nd_opt_len == 0)
563 goto trunc;
564 if (cp + (op->nd_opt_len << 3) > ep)
565 goto trunc;
566
519 return;
520trunc:
521 fputs("[|icmp6]", stdout);
522}
523
524static struct udphdr *
525get_upperlayer(u_char *bp, u_int *prot)
526{

--- 95 unchanged lines hidden (view full) ---

622 ECHECK(op->nd_opt_len);
623 if (resid <= 0)
624 return;
625 if (op->nd_opt_len == 0)
626 goto trunc;
627 if (cp + (op->nd_opt_len << 3) > ep)
628 goto trunc;
629
630 printf("\n\t %s option (%u), length %u (%u): ",
631 tok2str(icmp6_opt_values, "unknown", op->nd_opt_type),
632 op->nd_opt_type,
633 op->nd_opt_len << 3,
634 op->nd_opt_len);
635
567 switch (op->nd_opt_type) {
568 case ND_OPT_SOURCE_LINKADDR:
569 opl = (struct nd_opt_hdr *)op;
636 switch (op->nd_opt_type) {
637 case ND_OPT_SOURCE_LINKADDR:
638 opl = (struct nd_opt_hdr *)op;
570 printf("(src lladdr: ");
571 l = (op->nd_opt_len << 3) - 2;
572 print_lladdr(cp + 2, l);
639 l = (op->nd_opt_len << 3) - 2;
640 print_lladdr(cp + 2, l);
573 /*(*/
574 printf(")");
575 break;
576 case ND_OPT_TARGET_LINKADDR:
577 opl = (struct nd_opt_hdr *)op;
641 break;
642 case ND_OPT_TARGET_LINKADDR:
643 opl = (struct nd_opt_hdr *)op;
578 printf("(tgt lladdr: ");
579 l = (op->nd_opt_len << 3) - 2;
580 print_lladdr(cp + 2, l);
644 l = (op->nd_opt_len << 3) - 2;
645 print_lladdr(cp + 2, l);
581 /*(*/
582 printf(")");
583 break;
584 case ND_OPT_PREFIX_INFORMATION:
585 opp = (struct nd_opt_prefix_info *)op;
586 TCHECK(opp->nd_opt_pi_prefix);
646 break;
647 case ND_OPT_PREFIX_INFORMATION:
648 opp = (struct nd_opt_prefix_info *)op;
649 TCHECK(opp->nd_opt_pi_prefix);
587 printf("(prefix info: "); /*)*/
588 if (op->nd_opt_len != 4) {
589 printf("badlen");
590 /*(*/
591 printf(")");
592 break;
593 }
594 if (opp->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_ONLINK)
595 printf("L");
596 if (opp->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_AUTO)
597 printf("A");
598 if (opp->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_ROUTER)
599 printf("R");
600 if (opp->nd_opt_pi_flags_reserved)
601 printf(" ");
602 printf("valid_ltime=%s,",
603 get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_valid_time)));
604 printf("preferred_ltime=%s,",
605 get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_preferred_time)));
606 printf("prefix=%s/%d",
607 ip6addr_string(&opp->nd_opt_pi_prefix),
608 opp->nd_opt_pi_prefix_len);
609 if (opp->nd_opt_pi_len != 4)
610 printf("!");
611 /*(*/
612 printf(")");
650 printf("%s/%u%s, Flags [%s], valid time %ss",
651 ip6addr_string(&opp->nd_opt_pi_prefix),
652 opp->nd_opt_pi_prefix_len,
653 (op->nd_opt_len != 4) ? "badlen" : "",
654 bittok2str(icmp6_opt_pi_flag_values, "none", opp->nd_opt_pi_flags_reserved),
655 get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_valid_time)));
656 printf(", pref. time %ss", get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_preferred_time)));
613 break;
614 case ND_OPT_REDIRECTED_HEADER:
615 opr = (struct icmp6_opts_redirect *)op;
657 break;
658 case ND_OPT_REDIRECTED_HEADER:
659 opr = (struct icmp6_opts_redirect *)op;
616 printf("(redirect)");
660 print_unknown_data(bp,"\n\t ",op->nd_opt_len<<3);
617 /* xxx */
618 break;
619 case ND_OPT_MTU:
620 opm = (struct nd_opt_mtu *)op;
621 TCHECK(opm->nd_opt_mtu_mtu);
661 /* xxx */
662 break;
663 case ND_OPT_MTU:
664 opm = (struct nd_opt_mtu *)op;
665 TCHECK(opm->nd_opt_mtu_mtu);
622 printf("(mtu:"); /*)*/
623 if (op->nd_opt_len != 1) {
624 printf("badlen");
625 /*(*/
626 printf(")");
627 break;
628 }
629 printf(" mtu=%u", EXTRACT_32BITS(&opm->nd_opt_mtu_mtu));
630 if (opm->nd_opt_mtu_len != 1)
631 printf("!");
632 printf(")");
633 break;
666 printf(" %u%s",
667 EXTRACT_32BITS(&opm->nd_opt_mtu_mtu),
668 (op->nd_opt_len != 1) ? "bad option length" : "" );
669 break;
634 case ND_OPT_ADVINTERVAL:
635 opa = (struct nd_opt_advinterval *)op;
636 TCHECK(opa->nd_opt_adv_interval);
670 case ND_OPT_ADVINTERVAL:
671 opa = (struct nd_opt_advinterval *)op;
672 TCHECK(opa->nd_opt_adv_interval);
637 printf("(advint:"); /*)*/
638 printf(" advint=%u",
639 EXTRACT_32BITS(&opa->nd_opt_adv_interval));
640 /*(*/
641 printf(")");
673 printf(" %us", EXTRACT_32BITS(&opa->nd_opt_adv_interval));
642 break;
643 case ND_OPT_HOMEAGENT_INFO:
644 oph = (struct nd_opt_homeagent_info *)op;
645 TCHECK(oph->nd_opt_hai_lifetime);
674 break;
675 case ND_OPT_HOMEAGENT_INFO:
676 oph = (struct nd_opt_homeagent_info *)op;
677 TCHECK(oph->nd_opt_hai_lifetime);
646 printf("(ha info:"); /*)*/
647 printf(" pref=%d", EXTRACT_16BITS(&oph->nd_opt_hai_preference));
648 printf(", lifetime=%u", EXTRACT_16BITS(&oph->nd_opt_hai_lifetime));
649 printf(")");
678 printf(" preference %u, lifetime %u",
679 EXTRACT_16BITS(&oph->nd_opt_hai_preference),
680 EXTRACT_16BITS(&oph->nd_opt_hai_lifetime));
650 break;
651 case ND_OPT_ROUTE_INFO:
652 opri = (struct nd_opt_route_info *)op;
653 TCHECK(opri->nd_opt_rti_lifetime);
654 memset(&in6, 0, sizeof(in6));
655 in6p = (struct in6_addr *)(opri + 1);
656 switch (op->nd_opt_len) {
657 case 1:

--- 4 unchanged lines hidden (view full) ---

662 break;
663 case 3:
664 TCHECK(*in6p);
665 memcpy(&in6, opri + 1, sizeof(in6));
666 break;
667 default:
668 goto trunc;
669 }
681 break;
682 case ND_OPT_ROUTE_INFO:
683 opri = (struct nd_opt_route_info *)op;
684 TCHECK(opri->nd_opt_rti_lifetime);
685 memset(&in6, 0, sizeof(in6));
686 in6p = (struct in6_addr *)(opri + 1);
687 switch (op->nd_opt_len) {
688 case 1:

--- 4 unchanged lines hidden (view full) ---

693 break;
694 case 3:
695 TCHECK(*in6p);
696 memcpy(&in6, opri + 1, sizeof(in6));
697 break;
698 default:
699 goto trunc;
700 }
670 printf("(rtinfo:"); /*)*/
671 printf(" %s/%u", ip6addr_string(&in6),
672 opri->nd_opt_rti_prefixlen);
673 printf(", pref=%s", get_rtpref(opri->nd_opt_rti_flags));
674 printf(", lifetime=%s",
675 get_lifetime(EXTRACT_32BITS(&opri->nd_opt_rti_lifetime)));
701 printf(" %s/%u", ip6addr_string(&in6),
702 opri->nd_opt_rti_prefixlen);
703 printf(", pref=%s", get_rtpref(opri->nd_opt_rti_flags));
704 printf(", lifetime=%s",
705 get_lifetime(EXTRACT_32BITS(&opri->nd_opt_rti_lifetime)));
676 /*(*/
677 printf(")");
678 break;
679 default:
706 break;
707 default:
680 printf("(unknown opt_type=%d, opt_len=%d)",
681 op->nd_opt_type, op->nd_opt_len);
682 break;
708 if (vflag <= 1) {
709 print_unknown_data(cp+2,"\n\t ", (op->nd_opt_len << 3) - 2); /* skip option header */
710 return;
711 }
712 break;
683 }
713 }
714 /* do we want to see an additional hexdump ? */
715 if (vflag> 1)
716 print_unknown_data(cp+2,"\n\t ", (op->nd_opt_len << 3) - 2); /* skip option header */
684
685 cp += op->nd_opt_len << 3;
686 resid -= op->nd_opt_len << 3;
687 }
688 return;
689
690 trunc:
691 fputs("[ndp opt]", stdout);

--- 13 unchanged lines hidden (view full) ---

705 if ((u_char *)mp + sizeof(*mp) > ep)
706 return;
707
708 printf("max resp delay: %d ", EXTRACT_16BITS(&mp->mld6_maxdelay));
709 printf("addr: %s", ip6addr_string(&mp->mld6_addr));
710}
711
712static void
717
718 cp += op->nd_opt_len << 3;
719 resid -= op->nd_opt_len << 3;
720 }
721 return;
722
723 trunc:
724 fputs("[ndp opt]", stdout);

--- 13 unchanged lines hidden (view full) ---

738 if ((u_char *)mp + sizeof(*mp) > ep)
739 return;
740
741 printf("max resp delay: %d ", EXTRACT_16BITS(&mp->mld6_maxdelay));
742 printf("addr: %s", ip6addr_string(&mp->mld6_addr));
743}
744
745static void
746mldv2_report_print(const u_char *bp, u_int len)
747{
748 struct icmp6_hdr *icp = (struct icmp6_hdr *) bp;
749 u_int group, nsrcs, ngroups;
750 u_int i, j;
751
752 /* Minimum len is 8 */
753 if (len < 8) {
754 printf(" [invalid len %d]", len);
755 return;
756 }
757
758 TCHECK(icp->icmp6_data16[1]);
759 ngroups = ntohs(icp->icmp6_data16[1]);
760 printf(", %d group record(s)", ngroups);
761 if (vflag > 0) {
762 /* Print the group records */
763 group = 8;
764 for (i = 0; i < ngroups; i++) {
765 /* type(1) + auxlen(1) + numsrc(2) + grp(16) */
766 if (len < group + 20) {
767 printf(" [invalid number of groups]");
768 return;
769 }
770 TCHECK2(bp[group + 4], 16);
771 printf(" [gaddr %s", ip6addr_string(&bp[group + 4]));
772 printf(" %s", tok2str(mldv2report2str, " [v2-report-#%d]",
773 bp[group]));
774 nsrcs = (bp[group + 2] << 8) + bp[group + 3];
775 /* Check the number of sources and print them */
776 if (len < group + 20 + (nsrcs * 16)) {
777 printf(" [invalid number of sources %d]", nsrcs);
778 return;
779 }
780 if (vflag == 1)
781 printf(", %d source(s)", nsrcs);
782 else {
783 /* Print the sources */
784 (void)printf(" {");
785 for (j = 0; j < nsrcs; j++) {
786 TCHECK2(bp[group + 20 + j * 16], 16);
787 printf(" %s", ip6addr_string(&bp[group + 20 + j * 16]));
788 }
789 (void)printf(" }");
790 }
791 /* Next group record */
792 group += 20 + nsrcs * 16;
793 printf("]");
794 }
795 }
796 return;
797trunc:
798 (void)printf("[|icmp6]");
799 return;
800}
801
802static void
803mldv2_query_print(const u_char *bp, u_int len)
804{
805 struct icmp6_hdr *icp = (struct icmp6_hdr *) bp;
806 u_int mrc;
807 int mrt, qqi;
808 u_int nsrcs;
809 register u_int i;
810
811 /* Minimum len is 28 */
812 if (len < 28) {
813 printf(" [invalid len %d]", len);
814 return;
815 }
816 TCHECK(icp->icmp6_data16[0]);
817 mrc = ntohs(icp->icmp6_data16[0]);
818 if (mrc < 32768) {
819 mrt = mrc;
820 } else {
821 mrt = ((mrc & 0x0fff) | 0x1000) << (((mrc & 0x7000) >> 12) + 3);
822 }
823 if (vflag) {
824 (void)printf(" [max resp delay=%d]", mrt);
825 }
826 TCHECK2(bp[8], 16);
827 printf(" [gaddr %s", ip6addr_string(&bp[8]));
828
829 if (vflag) {
830 TCHECK(bp[25]);
831 if (bp[24] & 0x08) {
832 printf(" sflag");
833 }
834 if (bp[24] & 0x07) {
835 printf(" robustness=%d", bp[24] & 0x07);
836 }
837 if (bp[25] < 128) {
838 qqi = bp[25];
839 } else {
840 qqi = ((bp[25] & 0x0f) | 0x10) << (((bp[25] & 0x70) >> 4) + 3);
841 }
842 printf(" qqi=%d", qqi);
843 }
844
845 TCHECK2(bp[26], 2);
846 nsrcs = ntohs(*(u_short *)&bp[26]);
847 if (nsrcs > 0) {
848 if (len < 28 + nsrcs * 16)
849 printf(" [invalid number of sources]");
850 else if (vflag > 1) {
851 printf(" {");
852 for (i = 0; i < nsrcs; i++) {
853 TCHECK2(bp[28 + i * 16], 16);
854 printf(" %s", ip6addr_string(&bp[28 + i * 16]));
855 }
856 printf(" }");
857 } else
858 printf(", %d source(s)", nsrcs);
859 }
860 printf("]");
861 return;
862trunc:
863 (void)printf("[|icmp6]");
864 return;
865}
866
867void
713dnsname_print(const u_char *cp, const u_char *ep)
714{
715 int i;
716
717 /* DNS name decoding - no decompression */
718 printf(", \"");
719 while (cp < ep) {
720 i = *cp++;

--- 38 unchanged lines hidden (view full) ---

759 dp = (struct icmp6_hdr *)bp;
760 ni6 = (struct icmp6_nodeinfo *)bp;
761 siz = ep - bp;
762
763 switch (ni6->ni_type) {
764 case ICMP6_NI_QUERY:
765 if (siz == sizeof(*dp) + 4) {
766 /* KAME who-are-you */
868dnsname_print(const u_char *cp, const u_char *ep)
869{
870 int i;
871
872 /* DNS name decoding - no decompression */
873 printf(", \"");
874 while (cp < ep) {
875 i = *cp++;

--- 38 unchanged lines hidden (view full) ---

914 dp = (struct icmp6_hdr *)bp;
915 ni6 = (struct icmp6_nodeinfo *)bp;
916 siz = ep - bp;
917
918 switch (ni6->ni_type) {
919 case ICMP6_NI_QUERY:
920 if (siz == sizeof(*dp) + 4) {
921 /* KAME who-are-you */
767 printf("icmp6: who-are-you request");
922 printf(" who-are-you request");
768 break;
769 }
923 break;
924 }
770 printf("icmp6: node information query");
925 printf(" node information query");
771
772 TCHECK2(*dp, sizeof(*ni6));
773 ni6 = (struct icmp6_nodeinfo *)dp;
774 printf(" ("); /*)*/
775 switch (EXTRACT_16BITS(&ni6->ni_qtype)) {
776 case NI_QTYPE_NOOP:
777 printf("noop");
778 break;

--- 99 unchanged lines hidden (view full) ---

878 if (icmp6len > siz) {
879 printf("[|icmp6: node information reply]");
880 break;
881 }
882
883 needcomma = 0;
884
885 ni6 = (struct icmp6_nodeinfo *)dp;
926
927 TCHECK2(*dp, sizeof(*ni6));
928 ni6 = (struct icmp6_nodeinfo *)dp;
929 printf(" ("); /*)*/
930 switch (EXTRACT_16BITS(&ni6->ni_qtype)) {
931 case NI_QTYPE_NOOP:
932 printf("noop");
933 break;

--- 99 unchanged lines hidden (view full) ---

1033 if (icmp6len > siz) {
1034 printf("[|icmp6: node information reply]");
1035 break;
1036 }
1037
1038 needcomma = 0;
1039
1040 ni6 = (struct icmp6_nodeinfo *)dp;
886 printf("icmp6: node information reply");
1041 printf(" node information reply");
887 printf(" ("); /*)*/
888 switch (ni6->ni_code) {
889 case ICMP6_NI_SUCCESS:
890 if (vflag) {
891 printf("success");
892 needcomma++;
893 }
894 break;

--- 243 unchanged lines hidden ---
1042 printf(" ("); /*)*/
1043 switch (ni6->ni_code) {
1044 case ICMP6_NI_SUCCESS:
1045 if (vflag) {
1046 printf("success");
1047 needcomma++;
1048 }
1049 break;

--- 243 unchanged lines hidden ---