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 --- |