From 14a5500ac5c72141c158f0b8a6d0baf666709697 Mon Sep 17 00:00:00 2001 From: fenner Date: Tue, 20 Aug 1996 23:50:16 +0000 Subject: [PATCH] Print out ICMP errors that are responses to our own packets by default. Turn this behavior off using '-Q'. This makes '-v' useless other than as an ICMP-sniffer, which tcpdump is better at anyway. Print out another couple of ICMP messages, and fix the printing of the original packet (mostly byte order problems). --- sbin/ping/ping.8 | 20 +++++++++++++- sbin/ping/ping.c | 69 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/sbin/ping/ping.8 b/sbin/ping/ping.8 index e3de68ad266..b2a6bf749d3 100644 --- a/sbin/ping/ping.8 +++ b/sbin/ping/ping.8 @@ -41,7 +41,7 @@ packets to network hosts .Sh SYNOPSIS .Nm ping -.Op Fl dfnqrvR +.Op Fl dfnqrvRQ .Op Fl c Ar count .Op Fl i Ar wait .Op Fl l Ar preload @@ -115,6 +115,20 @@ For example, .Dq Li \-p ff will cause the sent packet to be filled with all ones. +.It Fl Q +Somewhat quiet output. +Don't display ICMP error messages that are in response to our query messages. +Originally, the +.Fl v +flag was required to display such errors, but +.Fl v +displays all ICMP error messages. On a busy machine, this output can +be overbearing. Without the +.Fl Q +flag, +.Nm +prints out any ICMP error messages caused by its own ECHO_REQUEST +messages. .It Fl q Quiet output. Nothing is displayed except the summary lines at startup time and @@ -316,6 +330,10 @@ There's not much that that can be done about this, however. .Pp Flood pinging is not recommended in general, and flood pinging the broadcast address should only be done under very controlled conditions. +.Pp +The +.Fl v +option is not worth much on busy hosts. .Sh SEE ALSO .Xr netstat 1 , .Xr ifconfig 8 , diff --git a/sbin/ping/ping.c b/sbin/ping/ping.c index dfd1c2a35ff..c9c2fb33ef2 100644 --- a/sbin/ping/ping.c +++ b/sbin/ping/ping.c @@ -105,6 +105,7 @@ int options; #define F_SO_DEBUG 0x040 #define F_SO_DONTROUTE 0x080 #define F_VERBOSE 0x100 +#define F_QUIET2 0x200 /* * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum @@ -182,7 +183,7 @@ main(argc, argv) } datap = &outpack[8 + sizeof(struct timeval)]; - while ((ch = getopt(argc, argv, "Rc:dfh:i:l:np:qrs:v")) != EOF) + while ((ch = getopt(argc, argv, "QRc:dfh:i:l:np:qrs:v")) != EOF) switch(ch) { case 'c': npackets = atoi(optarg); @@ -228,6 +229,9 @@ main(argc, argv) options |= F_PINGFILLED; fill((char *)datap, optarg); break; + case 'Q': + options |= F_QUIET2; + break; case 'q': options |= F_QUIET; break; @@ -429,7 +433,7 @@ catcher() * Compose and transmit an ICMP ECHO REQUEST packet. The IP packet * will be added on by the kernel. The ID field is our UNIX process ID, * and the sequence number is an ascending integer. The first 8 bytes - * of the data portion are used to hold a UNIX "timeval" struct in VAX + * of the data portion are used to hold a UNIX "timeval" struct in host * byte-order, to compute the round-trip time. */ pinger() @@ -569,12 +573,31 @@ pr_pack(buf, cc, from) } } } else { - /* We've got something other than an ECHOREPLY */ - if (!(options & F_VERBOSE)) - return; - (void)printf("%d bytes from %s: ", cc, - pr_addr(from->sin_addr.s_addr)); - pr_icmph(icp); + /* + * We've got something other than an ECHOREPLY. + * See if it's a reply to something that we sent. + * We can compare IP destination, protocol, + * and ICMP type and ID. + */ +#ifndef icmp_data + struct ip *oip = &icp->icmp_ip; +#else + struct ip *oip = (struct ip *)icp->icmp_data; +#endif + struct icmp *oicmp = (struct icmp *)(oip + 1); + + if ((options & F_VERBOSE) || + (!(options & F_QUIET2) && + (oip->ip_dst.s_addr == + ((struct sockaddr_in *)&whereto)->sin_addr.s_addr) && + (oip->ip_p == IPPROTO_ICMP) && + (oicmp->icmp_type == ICMP_ECHO) && + (oicmp->icmp_id == ident))) { + (void)printf("%d bytes from %s: ", cc, + pr_addr(from->sin_addr.s_addr)); + pr_icmph(icp); + } else + return; } /* Display any IP options */ @@ -818,11 +841,15 @@ pr_icmph(icp) (void)printf("Destination Port Unreachable\n"); break; case ICMP_UNREACH_NEEDFRAG: - (void)printf("frag needed and DF set\n"); + (void)printf("frag needed and DF set (MTU %d)\n", + icp->icmp_nextmtu); break; case ICMP_UNREACH_SRCFAIL: (void)printf("Source Route Failed\n"); break; + case ICMP_UNREACH_FILTER_PROHIB: + (void)printf("Communication prohibited by filter\n"); + break; default: (void)printf("Dest Unreachable, Bad Code: %d\n", icp->icmp_code); @@ -916,16 +943,18 @@ pr_icmph(icp) (void)printf("Information Reply\n"); /* XXX ID + Seq */ break; -#ifdef ICMP_MASKREQ case ICMP_MASKREQ: (void)printf("Address Mask Request\n"); break; -#endif -#ifdef ICMP_MASKREPLY case ICMP_MASKREPLY: (void)printf("Address Mask Reply\n"); break; -#endif + case ICMP_ROUTERADVERT: + (void)printf("Router Advertisement\n"); + break; + case ICMP_ROUTERSOLICIT: + (void)printf("Router Solicitation\n"); + break; default: (void)printf("Bad ICMP type: %d\n", icp->icmp_type); } @@ -944,15 +973,17 @@ pr_iph(ip) hlen = ip->ip_hl << 2; cp = (u_char *)ip + 20; /* point to options */ - (void)printf("Vr HL TOS Len ID Flg off TTL Pro cks Src Dst Data\n"); + (void)printf("Vr HL TOS Len ID Flg off TTL Pro cks Src Dst\n"); (void)printf(" %1x %1x %02x %04x %04x", - ip->ip_v, ip->ip_hl, ip->ip_tos, ip->ip_len, ip->ip_id); - (void)printf(" %1x %04x", ((ip->ip_off) & 0xe000) >> 13, - (ip->ip_off) & 0x1fff); - (void)printf(" %02x %02x %04x", ip->ip_ttl, ip->ip_p, ip->ip_sum); + ip->ip_v, ip->ip_hl, ip->ip_tos, ntohs(ip->ip_len), + ntohs(ip->ip_id)); + (void)printf(" %1x %04x", (ntohl(ip->ip_off) & 0xe000) >> 13, + ntohl(ip->ip_off) & 0x1fff); + (void)printf(" %02x %02x %04x", ip->ip_ttl, ip->ip_p, + ntohs(ip->ip_sum)); (void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_src.s_addr)); (void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_dst.s_addr)); - /* dump and option bytes */ + /* dump any option bytes */ while (hlen-- > 20) { (void)printf("%02x", *cp++); } -- 2.45.2