Deleted Added
full compact
print-icmp.c (147904) print-icmp.c (172686)
1/*
2 * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996
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

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

13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
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 *
1/*
2 * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996
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

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

13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
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 * $FreeBSD: head/contrib/tcpdump/print-icmp.c 147904 2005-07-11 04:14:02Z sam $
21 * $FreeBSD: head/contrib/tcpdump/print-icmp.c 172686 2007-10-16 02:31:48Z mlaier $
22 */
23
24#ifndef lint
25static const char rcsid[] _U_ =
22 */
23
24#ifndef lint
25static const char rcsid[] _U_ =
26 "@(#) $Header: /tcpdump/master/tcpdump/print-icmp.c,v 1.81.2.2 2005/07/01 16:13:37 hannes Exp $ (LBL)";
26 "@(#) $Header: /tcpdump/master/tcpdump/print-icmp.c,v 1.81.2.6 2007/09/13 17:40:18 guy Exp $ (LBL)";
27#endif
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include <tcpdump-stdinc.h>
34

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

59 union {
60 u_int8_t ih_pptr; /* ICMP_PARAMPROB */
61 struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
62 struct ih_idseq {
63 u_int16_t icd_id;
64 u_int16_t icd_seq;
65 } ih_idseq;
66 u_int32_t ih_void;
27#endif
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include <tcpdump-stdinc.h>
34

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

59 union {
60 u_int8_t ih_pptr; /* ICMP_PARAMPROB */
61 struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
62 struct ih_idseq {
63 u_int16_t icd_id;
64 u_int16_t icd_seq;
65 } ih_idseq;
66 u_int32_t ih_void;
67
68 /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
69 struct ih_pmtu {
70 u_int16_t ipm_void;
71 u_int16_t ipm_nextmtu;
72 } ih_pmtu;
73 } icmp_hun;
74#define icmp_pptr icmp_hun.ih_pptr
75#define icmp_gwaddr icmp_hun.ih_gwaddr
76#define icmp_id icmp_hun.ih_idseq.icd_id
77#define icmp_seq icmp_hun.ih_idseq.icd_seq
78#define icmp_void icmp_hun.ih_void
67 } icmp_hun;
68#define icmp_pptr icmp_hun.ih_pptr
69#define icmp_gwaddr icmp_hun.ih_gwaddr
70#define icmp_id icmp_hun.ih_idseq.icd_id
71#define icmp_seq icmp_hun.ih_idseq.icd_seq
72#define icmp_void icmp_hun.ih_void
79#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
80#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
81 union {
82 struct id_ts {
83 u_int32_t its_otime;
84 u_int32_t its_rtime;
85 u_int32_t its_ttime;
86 } id_ts;
87 struct id_ip {
88 struct ip idi_ip;
89 /* options and then 64 bits of data */
90 } id_ip;
73 union {
74 struct id_ts {
75 u_int32_t its_otime;
76 u_int32_t its_rtime;
77 u_int32_t its_ttime;
78 } id_ts;
79 struct id_ip {
80 struct ip idi_ip;
81 /* options and then 64 bits of data */
82 } id_ip;
91 struct mpls_ext {
92 u_int8_t legacy_header[128]; /* extension header starts 128 bytes after ICMP header */
93 u_int8_t version_res[2];
94 u_int8_t checksum[2];
95 u_int8_t data[1];
96 } mpls_ext;
97 u_int32_t id_mask;
98 u_int8_t id_data[1];
99 } icmp_dun;
100#define icmp_otime icmp_dun.id_ts.its_otime
101#define icmp_rtime icmp_dun.id_ts.its_rtime
102#define icmp_ttime icmp_dun.id_ts.its_ttime
103#define icmp_ip icmp_dun.id_ip.idi_ip
104#define icmp_mask icmp_dun.id_mask
105#define icmp_data icmp_dun.id_data
83 u_int32_t id_mask;
84 u_int8_t id_data[1];
85 } icmp_dun;
86#define icmp_otime icmp_dun.id_ts.its_otime
87#define icmp_rtime icmp_dun.id_ts.its_rtime
88#define icmp_ttime icmp_dun.id_ts.its_ttime
89#define icmp_ip icmp_dun.id_ip.idi_ip
90#define icmp_mask icmp_dun.id_mask
91#define icmp_data icmp_dun.id_data
106#define icmp_mpls_ext_version icmp_dun.mpls_ext.version_res
107#define icmp_mpls_ext_checksum icmp_dun.mpls_ext.checksum
108#define icmp_mpls_ext_data icmp_dun.mpls_ext.data
109};
110
111#define ICMP_MPLS_EXT_EXTRACT_VERSION(x) (((x)&0xf0)>>4)
112#define ICMP_MPLS_EXT_VERSION 2
113
114/*
115 * Lower bounds on packet lengths for various types.
116 * For the error advice packets must first insure that the
117 * packet is large enought to contain the returned ip header.
118 * Only then can we do the check to see if 64 bits of packet
119 * data have been returned, since we need to check the returned
120 * ip header length.
121 */
122#define ICMP_MINLEN 8 /* abs minimum */
92};
93
94#define ICMP_MPLS_EXT_EXTRACT_VERSION(x) (((x)&0xf0)>>4)
95#define ICMP_MPLS_EXT_VERSION 2
96
97/*
98 * Lower bounds on packet lengths for various types.
99 * For the error advice packets must first insure that the
100 * packet is large enought to contain the returned ip header.
101 * Only then can we do the check to see if 64 bits of packet
102 * data have been returned, since we need to check the returned
103 * ip header length.
104 */
105#define ICMP_MINLEN 8 /* abs minimum */
123#define ICMP_EXTD_MINLEN (156 - sizeof (struct ip)) /* draft-bonica-icmp-mpls-02 */
106#define ICMP_EXTD_MINLEN (156 - sizeof (struct ip)) /* draft-bonica-internet-icmp-08 */
124#define ICMP_TSLEN (8 + 3 * sizeof (u_int32_t)) /* timestamp */
125#define ICMP_MASKLEN 12 /* address mask */
126#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */
127#define ICMP_ADVLEN(p) (8 + (IP_HL(&(p)->icmp_ip) << 2) + 8)
128 /* N.B.: must separately check that ip_hl >= 5 */
129
130/*
131 * Definition of type and code field values.

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

170
171#define ICMP_INFOTYPE(type) \
172 ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \
173 (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \
174 (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
175 (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
176 (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
177#define ICMP_MPLS_EXT_TYPE(type) \
107#define ICMP_TSLEN (8 + 3 * sizeof (u_int32_t)) /* timestamp */
108#define ICMP_MASKLEN 12 /* address mask */
109#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */
110#define ICMP_ADVLEN(p) (8 + (IP_HL(&(p)->icmp_ip) << 2) + 8)
111 /* N.B.: must separately check that ip_hl >= 5 */
112
113/*
114 * Definition of type and code field values.

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

153
154#define ICMP_INFOTYPE(type) \
155 ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \
156 (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \
157 (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
158 (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
159 (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
160#define ICMP_MPLS_EXT_TYPE(type) \
178 ((type) == ICMP_UNREACH || (type) == ICMP_TIMXCEED)
161 ((type) == ICMP_UNREACH || \
162 (type) == ICMP_TIMXCEED || \
163 (type) == ICMP_PARAMPROB)
179/* rfc1700 */
180#ifndef ICMP_UNREACH_NET_UNKNOWN
181#define ICMP_UNREACH_NET_UNKNOWN 6 /* destination net unknown */
182#endif
183#ifndef ICMP_UNREACH_HOST_UNKNOWN
184#define ICMP_UNREACH_HOST_UNKNOWN 7 /* destination host unknown */
185#endif
186#ifndef ICMP_UNREACH_ISOLATED

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

273 u_int16_t ird_lifetime;
274};
275
276struct id_rdiscovery {
277 u_int32_t ird_addr;
278 u_int32_t ird_pref;
279};
280
164/* rfc1700 */
165#ifndef ICMP_UNREACH_NET_UNKNOWN
166#define ICMP_UNREACH_NET_UNKNOWN 6 /* destination net unknown */
167#endif
168#ifndef ICMP_UNREACH_HOST_UNKNOWN
169#define ICMP_UNREACH_HOST_UNKNOWN 7 /* destination host unknown */
170#endif
171#ifndef ICMP_UNREACH_ISOLATED

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

258 u_int16_t ird_lifetime;
259};
260
261struct id_rdiscovery {
262 u_int32_t ird_addr;
263 u_int32_t ird_pref;
264};
265
281/* draft-bonica-icmp-mpls-02 */
266/*
267 * draft-bonica-internet-icmp-08
268 *
269 * The Destination Unreachable, Time Exceeded
270 * and Parameter Problem messages are slighly changed as per
271 * the above draft. A new Length field gets added to give
272 * the caller an idea about the length of the piggypacked
273 * IP packet before the MPLS extension header starts.
274 *
275 * The Length field represents length of the padded "original datagram"
276 * field measured in 32-bit words.
277 *
278 * 0 1 2 3
279 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
280 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
281 * | Type | Code | Checksum |
282 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
283 * | unused | Length | unused |
284 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
285 * | Internet Header + leading octets of original datagram |
286 * | |
287 * | // |
288 * | |
289 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
290 */
291
292struct icmp_ext_t {
293 u_int8_t icmp_type;
294 u_int8_t icmp_code;
295 u_int8_t icmp_checksum[2];
296 u_int8_t icmp_reserved;
297 u_int8_t icmp_length;
298 u_int8_t icmp_reserved2[2];
299 u_int8_t icmp_ext_legacy_header[128]; /* extension header starts 128 bytes after ICMP header */
300 u_int8_t icmp_ext_version_res[2];
301 u_int8_t icmp_ext_checksum[2];
302 u_int8_t icmp_ext_data[1];
303};
304
282struct icmp_mpls_ext_object_header_t {
283 u_int8_t length[2];
284 u_int8_t class_num;
285 u_int8_t ctype;
286};
287
288static const struct tok icmp_mpls_ext_obj_values[] = {
289 { 1, "MPLS Stack Entry" },

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

309 return buf;
310}
311
312void
313icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented)
314{
315 char *cp;
316 const struct icmp *dp;
305struct icmp_mpls_ext_object_header_t {
306 u_int8_t length[2];
307 u_int8_t class_num;
308 u_int8_t ctype;
309};
310
311static const struct tok icmp_mpls_ext_obj_values[] = {
312 { 1, "MPLS Stack Entry" },

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

332 return buf;
333}
334
335void
336icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented)
337{
338 char *cp;
339 const struct icmp *dp;
340 const struct icmp_ext_t *ext_dp;
317 const struct ip *ip;
318 const char *str, *fmt;
319 const struct ip *oip;
320 const struct udphdr *ouh;
321 const u_int8_t *obj_tptr;
322 u_int32_t raw_label;
341 const struct ip *ip;
342 const char *str, *fmt;
343 const struct ip *oip;
344 const struct udphdr *ouh;
345 const u_int8_t *obj_tptr;
346 u_int32_t raw_label;
347 const u_char *snapend_save;
323 const struct icmp_mpls_ext_object_header_t *icmp_mpls_ext_object_header;
324 u_int hlen, dport, mtu, obj_tlen, obj_class_num, obj_ctype;
325 char buf[MAXHOSTNAMELEN + 100];
326
327 dp = (struct icmp *)bp;
348 const struct icmp_mpls_ext_object_header_t *icmp_mpls_ext_object_header;
349 u_int hlen, dport, mtu, obj_tlen, obj_class_num, obj_ctype;
350 char buf[MAXHOSTNAMELEN + 100];
351
352 dp = (struct icmp *)bp;
353 ext_dp = (struct icmp_ext_t *)bp;
328 ip = (struct ip *)bp2;
329 str = buf;
330
331 TCHECK(dp->icmp_code);
332 switch (dp->icmp_type) {
333
334 case ICMP_ECHO:
335 case ICMP_ECHOREPLY:

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

541 if (sum != 0) {
542 icmp_sum = EXTRACT_16BITS(&dp->icmp_cksum);
543 (void)printf(" (wrong icmp cksum %x (->%x)!)",
544 icmp_sum,
545 in_cksum_shouldbe(icmp_sum, sum));
546 }
547 }
548 }
354 ip = (struct ip *)bp2;
355 str = buf;
356
357 TCHECK(dp->icmp_code);
358 switch (dp->icmp_type) {
359
360 case ICMP_ECHO:
361 case ICMP_ECHOREPLY:

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

567 if (sum != 0) {
568 icmp_sum = EXTRACT_16BITS(&dp->icmp_cksum);
569 (void)printf(" (wrong icmp cksum %x (->%x)!)",
570 icmp_sum,
571 in_cksum_shouldbe(icmp_sum, sum));
572 }
573 }
574 }
575
576 /*
577 * print the remnants of the IP packet.
578 * save the snaplength as this may get overidden in the IP printer.
579 */
549 if (vflag >= 1 && !ICMP_INFOTYPE(dp->icmp_type)) {
550 bp += 8;
551 (void)printf("\n\t");
552 ip = (struct ip *)bp;
553 snaplen = snapend - bp;
580 if (vflag >= 1 && !ICMP_INFOTYPE(dp->icmp_type)) {
581 bp += 8;
582 (void)printf("\n\t");
583 ip = (struct ip *)bp;
584 snaplen = snapend - bp;
585 snapend_save = snapend;
554 ip_print(gndo, bp, EXTRACT_16BITS(&ip->ip_len));
586 ip_print(gndo, bp, EXTRACT_16BITS(&ip->ip_len));
587 snapend = snapend_save;
555 }
556
588 }
589
590 /*
591 * Attempt to decode the MPLS extensions only for some ICMP types.
592 */
557 if (vflag >= 1 && plen > ICMP_EXTD_MINLEN && ICMP_MPLS_EXT_TYPE(dp->icmp_type)) {
558
593 if (vflag >= 1 && plen > ICMP_EXTD_MINLEN && ICMP_MPLS_EXT_TYPE(dp->icmp_type)) {
594
559 TCHECK(*(dp->icmp_mpls_ext_version));
560 printf("\n\tMPLS extension v%u",ICMP_MPLS_EXT_EXTRACT_VERSION(*(dp->icmp_mpls_ext_version)));
595 TCHECK(*ext_dp);
596
597 /*
598 * Check first if the mpls extension header shows a non-zero length.
599 * If the length field is not set then silently verify the checksum
600 * to check if an extension header is present. This is expedient,
601 * however not all implementations set the length field proper.
602 */
603 if (!ext_dp->icmp_length &&
604 in_cksum((const u_short *)&ext_dp->icmp_ext_version_res,
605 plen - ICMP_EXTD_MINLEN, 0)) {
606 return;
607 }
608
609 printf("\n\tMPLS extension v%u",
610 ICMP_MPLS_EXT_EXTRACT_VERSION(*(ext_dp->icmp_ext_version_res)));
561
562 /*
563 * Sanity checking of the header.
564 */
611
612 /*
613 * Sanity checking of the header.
614 */
565 if (ICMP_MPLS_EXT_EXTRACT_VERSION(*(dp->icmp_mpls_ext_version)) != ICMP_MPLS_EXT_VERSION) {
615 if (ICMP_MPLS_EXT_EXTRACT_VERSION(*(ext_dp->icmp_ext_version_res)) !=
616 ICMP_MPLS_EXT_VERSION) {
566 printf(" packet not supported");
567 return;
568 }
569
570 hlen = plen - ICMP_EXTD_MINLEN;
617 printf(" packet not supported");
618 return;
619 }
620
621 hlen = plen - ICMP_EXTD_MINLEN;
571 TCHECK2(*(dp->icmp_mpls_ext_checksum), 2);
572 printf(", checksum 0x%04x (unverified), length %u", /* FIXME */
573 EXTRACT_16BITS(dp->icmp_mpls_ext_checksum),
622 printf(", checksum 0x%04x (%scorrect), length %u",
623 EXTRACT_16BITS(ext_dp->icmp_ext_checksum),
624 in_cksum((const u_short *)&ext_dp->icmp_ext_version_res,
625 plen - ICMP_EXTD_MINLEN, 0) ? "in" : "",
574 hlen);
575
576 hlen -= 4; /* subtract common header size */
626 hlen);
627
628 hlen -= 4; /* subtract common header size */
577 obj_tptr = (u_int8_t *)dp->icmp_mpls_ext_data;
629 obj_tptr = (u_int8_t *)ext_dp->icmp_ext_data;
578
579 while (hlen > sizeof(struct icmp_mpls_ext_object_header_t)) {
580
581 icmp_mpls_ext_object_header = (struct icmp_mpls_ext_object_header_t *)obj_tptr;
582 TCHECK(*icmp_mpls_ext_object_header);
583 obj_tlen = EXTRACT_16BITS(icmp_mpls_ext_object_header->length);
584 obj_class_num = icmp_mpls_ext_object_header->class_num;
585 obj_ctype = icmp_mpls_ext_object_header->ctype;
586 obj_tptr += sizeof(struct icmp_mpls_ext_object_header_t);
587
588 printf("\n\t %s Object (%u), Class-Type: %u, length %u",
589 tok2str(icmp_mpls_ext_obj_values,"unknown",obj_class_num),
590 obj_class_num,
591 obj_ctype,
592 obj_tlen);
593
594 hlen-=sizeof(struct icmp_mpls_ext_object_header_t); /* length field includes tlv header */
630
631 while (hlen > sizeof(struct icmp_mpls_ext_object_header_t)) {
632
633 icmp_mpls_ext_object_header = (struct icmp_mpls_ext_object_header_t *)obj_tptr;
634 TCHECK(*icmp_mpls_ext_object_header);
635 obj_tlen = EXTRACT_16BITS(icmp_mpls_ext_object_header->length);
636 obj_class_num = icmp_mpls_ext_object_header->class_num;
637 obj_ctype = icmp_mpls_ext_object_header->ctype;
638 obj_tptr += sizeof(struct icmp_mpls_ext_object_header_t);
639
640 printf("\n\t %s Object (%u), Class-Type: %u, length %u",
641 tok2str(icmp_mpls_ext_obj_values,"unknown",obj_class_num),
642 obj_class_num,
643 obj_ctype,
644 obj_tlen);
645
646 hlen-=sizeof(struct icmp_mpls_ext_object_header_t); /* length field includes tlv header */
595 if (obj_tlen < sizeof(struct icmp_mpls_ext_object_header_t))
596 break;
647
648 /* infinite loop protection */
649 if ((obj_class_num == 0) ||
650 (obj_tlen < sizeof(struct icmp_mpls_ext_object_header_t))) {
651 return;
652 }
597 obj_tlen-=sizeof(struct icmp_mpls_ext_object_header_t);
598
599 switch (obj_class_num) {
600 case 1:
601 switch(obj_ctype) {
602 case 1:
603 TCHECK2(*obj_tptr, 4);
604 raw_label = EXTRACT_32BITS(obj_tptr);

--- 30 unchanged lines hidden ---
653 obj_tlen-=sizeof(struct icmp_mpls_ext_object_header_t);
654
655 switch (obj_class_num) {
656 case 1:
657 switch(obj_ctype) {
658 case 1:
659 TCHECK2(*obj_tptr, 4);
660 raw_label = EXTRACT_32BITS(obj_tptr);

--- 30 unchanged lines hidden ---