X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/05913a0700412705944c90926f28034f18020fec..9bdbb51f4122817ca8bdba9fb9917969809ff451:/print-icmp.c diff --git a/print-icmp.c b/print-icmp.c index 09b94618..bd6470d4 100644 --- a/print-icmp.c +++ b/print-icmp.c @@ -21,7 +21,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-icmp.c,v 1.77 2004-06-14 15:08:08 hannes Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-icmp.c,v 1.83 2005-07-01 16:10:02 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -107,6 +107,7 @@ struct icmp { }; #define ICMP_MPLS_EXT_EXTRACT_VERSION(x) (((x)&0xf0)>>4) +#define ICMP_MPLS_EXT_VERSION 2 /* * Lower bounds on packet lengths for various types. @@ -171,6 +172,8 @@ struct icmp { (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \ (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) +#define ICMP_MPLS_EXT_TYPE(type) \ + ((type) == ICMP_UNREACH || (type) == ICMP_TIMXCEED) /* rfc1700 */ #ifndef ICMP_UNREACH_NET_UNKNOWN #define ICMP_UNREACH_NET_UNKNOWN 6 /* destination net unknown */ @@ -286,6 +289,24 @@ static const struct tok icmp_mpls_ext_obj_values[] = { { 0, NULL} }; +/* prototypes */ +const char *icmp_tstamp_print(u_int); + +/* print the milliseconds since midnight UTC */ +const char * +icmp_tstamp_print(u_int tstamp) { + u_int msec,sec,min,hrs; + + static char buf[64]; + + msec = tstamp % 1000; + sec = tstamp / 1000; + min = sec / 60; sec -= min * 60; + hrs = min / 60; min -= hrs * 60; + snprintf(buf, sizeof(buf), "%02u:%02u:%02u.%03u",hrs,min,sec,msec); + return buf; +} + void icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented) { @@ -311,10 +332,11 @@ icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented) case ICMP_ECHO: case ICMP_ECHOREPLY: TCHECK(dp->icmp_seq); - (void)snprintf(buf, sizeof(buf), "echo %s seq %u", - dp->icmp_type == ICMP_ECHO ? - "request" : "reply", - EXTRACT_16BITS(&dp->icmp_seq)); + (void)snprintf(buf, sizeof(buf), "echo %s, id %u, seq %u", + dp->icmp_type == ICMP_ECHO ? + "request" : "reply", + EXTRACT_16BITS(&dp->icmp_id), + EXTRACT_16BITS(&dp->icmp_seq)); break; case ICMP_UNREACH: @@ -494,13 +516,16 @@ icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented) case ICMP_TSTAMPREPLY: TCHECK(dp->icmp_ttime); (void)snprintf(buf, sizeof(buf), - "time stamp reply id %u seq %u : org 0x%x recv 0x%x xmit 0x%x", - EXTRACT_16BITS(&dp->icmp_id), - EXTRACT_16BITS(&dp->icmp_seq), - EXTRACT_32BITS(&dp->icmp_otime), - EXTRACT_32BITS(&dp->icmp_rtime), - EXTRACT_32BITS(&dp->icmp_ttime)); - break; + "time stamp reply id %u seq %u: org %s", + EXTRACT_16BITS(&dp->icmp_id), + EXTRACT_16BITS(&dp->icmp_seq), + icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_otime))); + + (void)snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),", recv %s", + icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_rtime))); + (void)snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),", xmit %s", + icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_ttime))); + break; default: str = tok2str(icmp2str, "type-#%d", dp->icmp_type); @@ -524,22 +549,35 @@ icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented) (void)printf("\n\t"); ip = (struct ip *)bp; snaplen = snapend - bp; - ip_print(bp, EXTRACT_16BITS(&ip->ip_len)); + ip_print(gndo, bp, EXTRACT_16BITS(&ip->ip_len)); } - if (vflag >= 1 && plen > ICMP_EXTD_MINLEN) { + if (vflag >= 1 && plen > ICMP_EXTD_MINLEN && ICMP_MPLS_EXT_TYPE(dp->icmp_type)) { + + TCHECK(*(dp->icmp_mpls_ext_version)); + printf("\n\tMPLS extension v%u",ICMP_MPLS_EXT_EXTRACT_VERSION(*(dp->icmp_mpls_ext_version))); + + /* + * Sanity checking of the header. + */ + if (ICMP_MPLS_EXT_EXTRACT_VERSION(*(dp->icmp_mpls_ext_version)) != ICMP_MPLS_EXT_VERSION) { + printf(" packet not supported"); + return; + } + hlen = plen - ICMP_EXTD_MINLEN; - printf("\n\tMPLS extension v%u, checksum 0x%04x (unverified), length %u", /* FIXME */ - ICMP_MPLS_EXT_EXTRACT_VERSION(*(dp->icmp_mpls_ext_version)), + TCHECK2(*(dp->icmp_mpls_ext_checksum), 2); + printf(", checksum 0x%04x (unverified), length %u", /* FIXME */ EXTRACT_16BITS(dp->icmp_mpls_ext_checksum), hlen); - hlen -= 4; /* subtract common header size */ + hlen -= 4; /* subtract common header size */ obj_tptr = (u_int8_t *)dp->icmp_mpls_ext_data; while (hlen > sizeof(struct icmp_mpls_ext_object_header_t)) { icmp_mpls_ext_object_header = (struct icmp_mpls_ext_object_header_t *)obj_tptr; + TCHECK(*icmp_mpls_ext_object_header); obj_tlen = EXTRACT_16BITS(icmp_mpls_ext_object_header->length); obj_class_num = icmp_mpls_ext_object_header->class_num; obj_ctype = icmp_mpls_ext_object_header->ctype; @@ -552,12 +590,15 @@ icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented) obj_tlen); hlen-=sizeof(struct icmp_mpls_ext_object_header_t); /* length field includes tlv header */ - obj_tlen-=sizeof(struct icmp_mpls_ext_object_header_t); + if (obj_tlen < sizeof(struct icmp_mpls_ext_object_header_t)) + break; + obj_tlen-=sizeof(struct icmp_mpls_ext_object_header_t); switch (obj_class_num) { case 1: switch(obj_ctype) { case 1: + TCHECK2(*obj_tptr, 4); raw_label = EXTRACT_32BITS(obj_tptr); printf("\n\t label %u, exp %u", MPLS_LABEL(raw_label), MPLS_EXP(raw_label)); if (MPLS_STACK(raw_label)) @@ -578,6 +619,8 @@ icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented) print_unknown_data(obj_tptr, "\n\t ", obj_tlen); break; } + if (hlen < obj_tlen) + break; hlen -= obj_tlen; obj_tptr += obj_tlen; }