X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/afdea7aeac56fe8debf5b62a56abaf478e05cc83..refs/heads/tcpdump-3.8:/print-icmp.c diff --git a/print-icmp.c b/print-icmp.c index fc835133..a8e21b0a 100644 --- a/print-icmp.c +++ b/print-icmp.c @@ -20,26 +20,18 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-icmp.c,v 1.57 2000-10-10 05:03:32 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-icmp.c,v 1.73.2.3 2004-03-24 00:56:34 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include -#include -#include - -struct mbuf; -struct rtentry; - -#include +#include #include #include -#include /* for MAXHOSTNAMELEN on some platforms */ #include "interface.h" #include "addrtoname.h" @@ -47,6 +39,7 @@ struct rtentry; #include "ip.h" #include "udp.h" +#include "ipproto.h" /* * Interface Control Message Protocol Definitions. @@ -71,7 +64,7 @@ struct icmp { /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ struct ih_pmtu { - u_int16_t ipm_void; + u_int16_t ipm_void; u_int16_t ipm_nextmtu; } ih_pmtu; } icmp_hun; @@ -245,7 +238,7 @@ static struct tok type2str[] = { { ICMP_REDIRECT_NET, "redirect %s to net %s" }, { ICMP_REDIRECT_HOST, "redirect %s to host %s" }, { ICMP_REDIRECT_TOSNET, "redirect-tos %s to net %s" }, - { ICMP_REDIRECT_TOSHOST, "redirect-tos %s to net %s" }, + { ICMP_REDIRECT_TOSHOST, "redirect-tos %s to host %s" }, { 0, NULL } }; @@ -268,30 +261,33 @@ struct id_rdiscovery { }; void -icmp_print(register const u_char *bp, u_int plen, register const u_char *bp2) +icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented) { - register char *cp; - register const struct icmp *dp; - register const struct ip *ip; - register const char *str, *fmt; - register const struct ip *oip; - register const struct udphdr *ouh; - register u_int hlen, dport, mtu; + char *cp; + const struct icmp *dp; + const struct ip *ip; + const char *str, *fmt; + const struct ip *oip; + const struct udphdr *ouh; + u_int hlen, dport, mtu; char buf[MAXHOSTNAMELEN + 100]; dp = (struct icmp *)bp; ip = (struct ip *)bp2; str = buf; -#if 0 - (void)printf("%s > %s: ", - ipaddr_string(&ip->ip_src), - ipaddr_string(&ip->ip_dst)); -#endif - TCHECK(dp->icmp_code); switch (dp->icmp_type) { + 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)); + break; + case ICMP_UNREACH: TCHECK(dp->icmp_ip.ip_dst); switch (dp->icmp_code) { @@ -309,7 +305,8 @@ icmp_print(register const u_char *bp, u_int plen, register const u_char *bp2) oip = &dp->icmp_ip; hlen = IP_HL(oip) * 4; ouh = (struct udphdr *)(((u_char *)oip) + hlen); - dport = ntohs(ouh->uh_dport); + TCHECK(ouh->uh_dport); + dport = EXTRACT_16BITS(&ouh->uh_dport); switch (oip->ip_p) { case IPPROTO_TCP: @@ -339,12 +336,12 @@ icmp_print(register const u_char *bp, u_int plen, register const u_char *bp2) { register const struct mtu_discovery *mp; mp = (struct mtu_discovery *)&dp->icmp_void; - mtu = EXTRACT_16BITS(&mp->nexthopmtu); - if (mtu) { + mtu = EXTRACT_16BITS(&mp->nexthopmtu); + if (mtu) { (void)snprintf(buf, sizeof(buf), "%s unreachable - need to frag (mtu %d)", ipaddr_string(&dp->icmp_ip.ip_dst), mtu); - } else { + } else { (void)snprintf(buf, sizeof(buf), "%s unreachable - need to frag", ipaddr_string(&dp->icmp_ip.ip_dst)); @@ -454,46 +451,52 @@ icmp_print(register const u_char *bp, u_int plen, register const u_char *bp2) case ICMP_MASKREPLY: TCHECK(dp->icmp_mask); (void)snprintf(buf, sizeof(buf), "address mask is 0x%08x", - (unsigned)ntohl(dp->icmp_mask)); + EXTRACT_32BITS(&dp->icmp_mask)); break; case ICMP_TSTAMP: TCHECK(dp->icmp_seq); (void)snprintf(buf, sizeof(buf), "time stamp query id %u seq %u", - (unsigned)ntohs(dp->icmp_id), - (unsigned)ntohs(dp->icmp_seq)); + EXTRACT_16BITS(&dp->icmp_id), + EXTRACT_16BITS(&dp->icmp_seq)); break; case ICMP_TSTAMPREPLY: TCHECK(dp->icmp_ttime); (void)snprintf(buf, sizeof(buf), - "time stamp reply id %u seq %u : org 0x%lx recv 0x%lx xmit 0x%lx", - (unsigned)ntohs(dp->icmp_id), - (unsigned)ntohs(dp->icmp_seq), - (unsigned long)ntohl(dp->icmp_otime), - (unsigned long)ntohl(dp->icmp_rtime), - (unsigned long)ntohl(dp->icmp_ttime)); + "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; default: str = tok2str(icmp2str, "type-#%d", dp->icmp_type); break; } - (void)printf("icmp: %s", str); - if (vflag) { + (void)printf("icmp %d: %s", plen, str); + if (vflag && !fragmented) { /* don't attempt checksumming if this is a frag */ + u_int16_t sum, icmp_sum; if (TTEST2(*bp, plen)) { - if (in_cksum((u_short*)dp, plen, 0)) - printf(" (wrong icmp csum)"); + sum = in_cksum((u_short*)dp, plen, 0); + if (sum != 0) { + icmp_sum = EXTRACT_16BITS(&dp->icmp_cksum); + (void)printf(" (wrong icmp cksum %x (->%x)!)", + icmp_sum, + in_cksum_shouldbe(icmp_sum, sum)); + } } } - if (vflag > 1 && !ICMP_INFOTYPE(dp->icmp_type)) { - bp += 8; - (void)printf(" for "); - ip = (struct ip *)bp; - snaplen = snapend - bp; - ip_print(bp, ntohs(ip->ip_len)); - } + if (vflag > 1 && !ICMP_INFOTYPE(dp->icmp_type)) { + bp += 8; + (void)printf(" for "); + ip = (struct ip *)bp; + snaplen = snapend - bp; + ip_print(bp, EXTRACT_16BITS(&ip->ip_len)); + } return; trunc: fputs("[|icmp]", stdout);