Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 Sep 2019 00:56:33 +0000 (UTC)
From:      Alan Somers <asomers@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r352371 - in stable/12: etc/mtree sbin/ping sbin/ping/tests
Message-ID:  <201909160056.x8G0uXTI006195@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: asomers
Date: Mon Sep 16 00:56:33 2019
New Revision: 352371
URL: https://svnweb.freebsd.org/changeset/base/352371

Log:
  MFC r351318, r351330, r351393, r351398, r351440, r351461, r351548, r352226, r352229
  
  r351318:
  ping: Add tests of the Internet checksum function
  
  Submitted by:	Ján Sučan <sucanjan@gmail.com>
  Sponsored by:	Google LLC (Google Summer of Code 2019)
  Differential Revision:	https://reviews.freebsd.org/D21340
  
  r351330:
  ping: do reverse DNS lookup of the target address
  
  When printing replies, ping will now attempt a reverse DNS lookup of the
  target.  That can be suppressed by using the "-n" option.  Curiously, ping
  has always done reverse lookups in certain error paths, but never in the
  success path.
  
  Submitted by:	Ján Sučan <sucanjan@gmail.com>
  Sponsored by:	Google LLC (Google Summer of Code 2019)
  Differential Revision:	https://reviews.freebsd.org/D21351
  
  r351393:
  ping: add a basic functional test
  
  Submitted by:	Ján Sučan <sucanjan@gmail.com>
  Sponsored by:	Google, inc. (Google Summer of Code 2019)
  Differential Revision:	https://reviews.freebsd.org/D21289
  
  r351398:
  ping: By default, don't reverse lookup IP addresses
  
  ping's default is now not to attempt reverse DNS lookups.  The -H flag will
  enable them.  This change is not quite a reversion of r351330.  That change
  made the happy path and error path do reverse lookups consistently; this
  change changes the default for both paths.
  
  Submitted by:	Ján Sučan <sucanjan@gmail.com>
  Discussed with:	cem
  MFC-With:	351330
  Sponsored by:	Google LLC (Google Summer of Code 2019)
  Differential Revision:	https://reviews.freebsd.org/D21364
  
  r351440:
  ping: Fix alignment errors
  
  This fixes -Wcast-align errors when compiled with WARNS=6.
  
  Submitted by:	Ján Sučan <sucanjan@gmail.com>
  Sponsored by:	Google LLC (Google Summer of Code 2019)
  Differential Revision:	https://reviews.freebsd.org/D21327
  
  r351461:
  ping: fix unaligned access to ancillary data
  
  Use CMSG_FIRSTHDR rather than assume that an array is correctly aligned.
  Fixes warnings on sparc64 and powerpcspe.
  
  Submitted by:	Ján Sučan <sucanjan@gmail.com>
  MFH:		2 weeks
  Sponsored by:	Google LLC (Google Summer of Code 2019)
  Differential Revision:	https://reviews.freebsd.org/D21406
  
  r351548:
  ping: raise WARNS level to 6
  
  Submitted by:	Ján Sučan <sucanjan@gmail.com>
  Sponsored by:	Google LLC (Google Summer of Code 2019)
  Differential Revision:	https://reviews.freebsd.org/D21405
  
  r352226:
  ping: fix a string in an error message
  
  r352229:
  ping: Verify whether a datagram timestamp was actually received.
  
  ping(8) uses SO_TIMESTAMP, which attaches a timestamp to each IP datagram at
  the time it's received by the kernel.  Except that occasionally it doesn't.
  Add a check to see whether such a timestamp was actually set before trying
  to read it.  This fixes segfaults that can happen when the kernel doesn't
  attach a timestamp.
  
  The bug has always existed, but prior to r351461 it manifested as an
  implausible round-trip-time, not a segfault.
  
  Reported by:	pho
  MFC-With:	351461

Added:
  stable/12/sbin/ping/tests/
     - copied from r351318, head/sbin/ping/tests/
  stable/12/sbin/ping/tests/ping_c1_s56_t1.out
     - copied, changed from r351393, head/sbin/ping/tests/ping_c1_s56_t1.out
  stable/12/sbin/ping/tests/ping_test.sh
     - copied unchanged from r351393, head/sbin/ping/tests/ping_test.sh
Modified:
  stable/12/etc/mtree/BSD.tests.dist
  stable/12/sbin/ping/Makefile
  stable/12/sbin/ping/ping.8
  stable/12/sbin/ping/ping.c
  stable/12/sbin/ping/tests/Makefile
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/etc/mtree/BSD.tests.dist
==============================================================================
--- stable/12/etc/mtree/BSD.tests.dist	Mon Sep 16 00:32:23 2019	(r352370)
+++ stable/12/etc/mtree/BSD.tests.dist	Mon Sep 16 00:56:33 2019	(r352371)
@@ -428,6 +428,8 @@
             files
             ..
         ..
+        ping
+        ..
     ..
     secure
         lib

Modified: stable/12/sbin/ping/Makefile
==============================================================================
--- stable/12/sbin/ping/Makefile	Mon Sep 16 00:32:23 2019	(r352370)
+++ stable/12/sbin/ping/Makefile	Mon Sep 16 00:56:33 2019	(r352371)
@@ -9,7 +9,6 @@ SRCS=	ping.c utils.c
 MAN=	ping.8
 BINOWN=	root
 BINMODE=4555
-WARNS?=	3
 LIBADD=	m
 
 .if ${MK_DYNAMICROOT} == "no"
@@ -24,5 +23,8 @@ CFLAGS+=-DWITH_CASPER
 CFLAGS+=-DIPSEC
 LIBADD+=	ipsec
 .endif
+
+HAS_TESTS=
+SUBDIR.${MK_TESTS}+= tests
 
 .include <bsd.prog.mk>

Modified: stable/12/sbin/ping/ping.8
==============================================================================
--- stable/12/sbin/ping/ping.8	Mon Sep 16 00:32:23 2019	(r352370)
+++ stable/12/sbin/ping/ping.8	Mon Sep 16 00:56:33 2019	(r352371)
@@ -28,7 +28,7 @@
 .\"     @(#)ping.8	8.2 (Berkeley) 12/11/93
 .\" $FreeBSD$
 .\"
-.Dd March 11, 2016
+.Dd August 22, 2019
 .Dt PING 8
 .Os
 .Sh NAME
@@ -157,6 +157,12 @@ Specify the size of
 .Tn ICMP
 payload to start with when sending sweeping pings.
 The default value is 0.
+.It Fl H
+Hostname output.
+Try to do a reverse DNS lookup when displaying addresses.
+This is the opposite of the
+.Fl n
+option.
 .It Fl h Ar sweepincrsize
 Specify the number of bytes to increment the size of
 .Tn ICMP
@@ -220,6 +226,9 @@ MIB variable.
 .It Fl n
 Numeric output only.
 No attempt will be made to lookup symbolic names for host addresses.
+This is the opposite of
+.Fl H ,
+and it is the default behavior.
 .It Fl o
 Exit successfully after receiving one reply packet.
 .It Fl P Ar policy

Modified: stable/12/sbin/ping/ping.c
==============================================================================
--- stable/12/sbin/ping/ping.c	Mon Sep 16 00:32:23 2019	(r352370)
+++ stable/12/sbin/ping/ping.c	Mon Sep 16 00:56:33 2019	(r352371)
@@ -90,6 +90,7 @@ __FBSDID("$FreeBSD$");
 #include <errno.h>
 #include <math.h>
 #include <netdb.h>
+#include <stddef.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -216,10 +217,10 @@ static void finish(void) __dead2;
 static void pinger(void);
 static char *pr_addr(struct in_addr);
 static char *pr_ntime(n_time);
-static void pr_icmph(struct icmp *);
+static void pr_icmph(struct icmp *, struct ip *, const u_char *const);
 static void pr_iph(struct ip *);
-static void pr_pack(char *, int, struct sockaddr_in *, struct timespec *);
-static void pr_retip(struct ip *);
+static void pr_pack(char *, ssize_t, struct sockaddr_in *, struct timespec *);
+static void pr_retip(struct ip *, const u_char *);
 static void status(int);
 static void stopit(int);
 static void usage(void) __dead2;
@@ -231,7 +232,6 @@ main(int argc, char *const *argv)
 	struct in_addr ifaddr;
 	struct timespec last, intvl;
 	struct iovec iov;
-	struct ip *ip;
 	struct msghdr msg;
 	struct sigaction si_sa;
 	size_t sz;
@@ -261,6 +261,8 @@ main(int argc, char *const *argv)
 	cap_rights_t rights;
 	bool cansandbox;
 
+	options |= F_NUMERIC;
+
 	/*
 	 * Do the stuff that we need root priv's for *first*, and
 	 * then drop our setuid bit.  Save error reporting for
@@ -689,7 +691,9 @@ main(int argc, char *const *argv)
 #endif /*IPSEC*/
 
 	if (options & F_HDRINCL) {
-		ip = (struct ip*)outpackhdr;
+		struct ip ip;
+
+		memcpy(&ip, outpackhdr, sizeof(ip));
 		if (!(options & (F_TTL | F_MTTL))) {
 			mib[0] = CTL_NET;
 			mib[1] = PF_INET;
@@ -700,15 +704,16 @@ main(int argc, char *const *argv)
 				err(1, "sysctl(net.inet.ip.ttl)");
 		}
 		setsockopt(ssend, IPPROTO_IP, IP_HDRINCL, &hold, sizeof(hold));
-		ip->ip_v = IPVERSION;
-		ip->ip_hl = sizeof(struct ip) >> 2;
-		ip->ip_tos = tos;
-		ip->ip_id = 0;
-		ip->ip_off = htons(df ? IP_DF : 0);
-		ip->ip_ttl = ttl;
-		ip->ip_p = IPPROTO_ICMP;
-		ip->ip_src.s_addr = source ? sock_in.sin_addr.s_addr : INADDR_ANY;
-		ip->ip_dst = to->sin_addr;
+		ip.ip_v = IPVERSION;
+		ip.ip_hl = sizeof(struct ip) >> 2;
+		ip.ip_tos = tos;
+		ip.ip_id = 0;
+		ip.ip_off = htons(df ? IP_DF : 0);
+		ip.ip_ttl = ttl;
+		ip.ip_p = IPPROTO_ICMP;
+		ip.ip_src.s_addr = source ? sock_in.sin_addr.s_addr : INADDR_ANY;
+		ip.ip_dst = to->sin_addr;
+		memcpy(outpackhdr, &ip, sizeof(ip));
         }
 
 	if (options & F_NUMERIC)
@@ -724,7 +729,7 @@ main(int argc, char *const *argv)
 	 * We must connect(2) our socket before this point.
 	 */
 	if (cansandbox && cap_enter() < 0 && errno != ENOSYS)
-		err(1, "cap_enter");
+		err(1, "caph_enter_casper");
 
 	cap_rights_init(&rights, CAP_RECV, CAP_EVENT, CAP_SETSOCKOPT);
 	if (cap_rights_limit(srecv, &rights) < 0 && errno != ENOSYS)
@@ -881,6 +886,7 @@ main(int argc, char *const *argv)
 	msg.msg_iovlen = 1;
 #ifdef SO_TIMESTAMP
 	msg.msg_control = (caddr_t)ctrl;
+	msg.msg_controllen = sizeof(ctrl);
 #endif
 	iov.iov_base = packet;
 	iov.iov_len = IP_MAXPACKET;
@@ -907,7 +913,8 @@ main(int argc, char *const *argv)
 	while (!finish_up) {
 		struct timespec now, timeout;
 		fd_set rfds;
-		int cc, n;
+		int n;
+		ssize_t cc;
 
 		check_status();
 		if ((unsigned)srecv >= FD_SETSIZE)
@@ -925,9 +932,7 @@ main(int argc, char *const *argv)
 		if (n == 1) {
 			struct timespec *tv = NULL;
 #ifdef SO_TIMESTAMP
-			struct cmsghdr *cmsg = (struct cmsghdr *)&ctrl;
-
-			msg.msg_controllen = sizeof(ctrl);
+			struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
 #endif
 			msg.msg_namelen = sizeof(from);
 			if ((cc = recvmsg(srecv, &msg, 0)) < 0) {
@@ -937,7 +942,8 @@ main(int argc, char *const *argv)
 				continue;
 			}
 #ifdef SO_TIMESTAMP
-			if (cmsg->cmsg_level == SOL_SOCKET &&
+			if (cmsg != NULL &&
+			    cmsg->cmsg_level == SOL_SOCKET &&
 			    cmsg->cmsg_type == SCM_TIMESTAMP &&
 			    cmsg->cmsg_len == CMSG_LEN(sizeof *tv)) {
 				/* Copy to avoid alignment problems: */
@@ -1025,18 +1031,17 @@ pinger(void)
 {
 	struct timespec now;
 	struct tv32 tv32;
-	struct ip *ip;
-	struct icmp *icp;
+	struct icmp icp;
 	int cc, i;
 	u_char *packet;
 
 	packet = outpack;
-	icp = (struct icmp *)outpack;
-	icp->icmp_type = icmp_type;
-	icp->icmp_code = 0;
-	icp->icmp_cksum = 0;
-	icp->icmp_seq = htons(ntransmitted);
-	icp->icmp_id = ident;			/* ID */
+	memcpy(&icp, outpack, ICMP_MINLEN + phdr_len);
+	icp.icmp_type = icmp_type;
+	icp.icmp_code = 0;
+	icp.icmp_cksum = 0;
+	icp.icmp_seq = htons(ntransmitted);
+	icp.icmp_id = ident;			/* ID */
 
 	CLR(ntransmitted % mx_dup_ck);
 
@@ -1051,7 +1056,7 @@ pinger(void)
 		tv32.tv32_sec = (uint32_t)htonl(now.tv_sec);
 		tv32.tv32_nsec = (uint32_t)htonl(now.tv_nsec);
 		if (options & F_TIME)
-			icp->icmp_otime = htonl((now.tv_sec % (24*60*60))
+			icp.icmp_otime = htonl((now.tv_sec % (24*60*60))
 				* 1000 + now.tv_nsec / 1000000);
 		if (timing)
 			bcopy((void *)&tv32,
@@ -1059,16 +1064,28 @@ pinger(void)
 			    sizeof(tv32));
 	}
 
+	memcpy(outpack, &icp, ICMP_MINLEN + phdr_len);
+
 	cc = ICMP_MINLEN + phdr_len + datalen;
 
 	/* compute ICMP checksum here */
-	icp->icmp_cksum = in_cksum((u_char *)icp, cc);
+	icp.icmp_cksum = in_cksum(outpack, cc);
+	/* Update icmp_cksum in the raw packet data buffer. */
+	memcpy(outpack + offsetof(struct icmp, icmp_cksum), &icp.icmp_cksum,
+	    sizeof(icp.icmp_cksum));
 
 	if (options & F_HDRINCL) {
+		struct ip ip;
+
 		cc += sizeof(struct ip);
-		ip = (struct ip *)outpackhdr;
-		ip->ip_len = htons(cc);
-		ip->ip_sum = in_cksum(outpackhdr, cc);
+		ip.ip_len = htons(cc);
+		/* Update ip_len in the raw packet data buffer. */
+		memcpy(outpackhdr + offsetof(struct ip, ip_len), &ip.ip_len,
+		    sizeof(ip.ip_len));
+		ip.ip_sum = in_cksum(outpackhdr, cc);
+		/* Update ip_sum in the raw packet data buffer. */
+		memcpy(outpackhdr + offsetof(struct ip, ip_sum), &ip.ip_sum,
+		    sizeof(ip.ip_sum));
 		packet = outpackhdr;
 	}
 	i = send(ssend, (char *)packet, cc, 0);
@@ -1098,48 +1115,62 @@ pinger(void)
  * program to be run without having intermingled output (or statistics!).
  */
 static void
-pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timespec *tv)
+pr_pack(char *buf, ssize_t cc, struct sockaddr_in *from, struct timespec *tv)
 {
 	struct in_addr ina;
-	u_char *cp, *dp;
-	struct icmp *icp;
-	struct ip *ip;
-	const void *tp;
+	u_char *cp, *dp, l;
+	struct icmp icp;
+	struct ip ip;
+	const u_char *icmp_data_raw;
 	double triptime;
 	int dupflag, hlen, i, j, recv_len;
 	uint16_t seq;
 	static int old_rrlen;
 	static char old_rr[MAX_IPOPTLEN];
+	struct ip oip;
+	u_char oip_header_len;
+	struct icmp oicmp;
+	const u_char *oicmp_raw;
 
+	/*
+	 * Get size of IP header of the received packet. The
+	 * information is contained in the lower four bits of the
+	 * first byte.
+	 */
+	memcpy(&l, buf, sizeof(l));
+	hlen = (l & 0x0f) << 2;
+	memcpy(&ip, buf, hlen);
+
 	/* Check the IP header */
-	ip = (struct ip *)buf;
-	hlen = ip->ip_hl << 2;
 	recv_len = cc;
 	if (cc < hlen + ICMP_MINLEN) {
 		if (options & F_VERBOSE)
-			warn("packet too short (%d bytes) from %s", cc,
+			warn("packet too short (%zd bytes) from %s", cc,
 			     inet_ntoa(from->sin_addr));
 		return;
 	}
 
+#ifndef icmp_data
+	icmp_data_raw = buf + hlen + offsetof(struct icmp, icmp_ip);
+#else
+	icmp_data_raw = buf + hlen + offsetof(struct icmp, icmp_data);
+#endif
+
 	/* Now the ICMP part */
 	cc -= hlen;
-	icp = (struct icmp *)(buf + hlen);
-	if (icp->icmp_type == icmp_type_rsp) {
-		if (icp->icmp_id != ident)
+	memcpy(&icp, buf + hlen, MIN((ssize_t)sizeof(icp), cc));
+	if (icp.icmp_type == icmp_type_rsp) {
+		if (icp.icmp_id != ident)
 			return;			/* 'Twas not our ECHO */
 		++nreceived;
 		triptime = 0.0;
 		if (timing) {
 			struct timespec tv1;
 			struct tv32 tv32;
-#ifndef icmp_data
-			tp = &icp->icmp_ip;
-#else
-			tp = icp->icmp_data;
-#endif
-			tp = (const char *)tp + phdr_len;
+			const u_char *tp;
 
+			tp = icmp_data_raw + phdr_len;
+
 			if ((size_t)(cc - ICMP_MINLEN - phdr_len) >=
 			    sizeof(tv1)) {
 				/* Copy to avoid alignment problems: */
@@ -1159,7 +1190,7 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, s
 				timing = 0;
 		}
 
-		seq = ntohs(icp->icmp_seq);
+		seq = ntohs(icp.icmp_seq);
 
 		if (TST(seq % mx_dup_ck)) {
 			++nrepeats;
@@ -1181,10 +1212,9 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, s
 		if (options & F_FLOOD)
 			(void)write(STDOUT_FILENO, &BSPACE, 1);
 		else {
-			(void)printf("%d bytes from %s: icmp_seq=%u", cc,
-			   inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr),
-			   seq);
-			(void)printf(" ttl=%d", ip->ip_ttl);
+			(void)printf("%zd bytes from %s: icmp_seq=%u", cc,
+			    pr_addr(from->sin_addr), seq);
+			(void)printf(" ttl=%d", ip.ip_ttl);
 			if (timing)
 				(void)printf(" time=%.3f ms", triptime);
 			if (dupflag)
@@ -1194,12 +1224,12 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, s
 			if (options & F_MASK) {
 				/* Just prentend this cast isn't ugly */
 				(void)printf(" mask=%s",
-					inet_ntoa(*(struct in_addr *)&(icp->icmp_mask)));
+					inet_ntoa(*(struct in_addr *)&(icp.icmp_mask)));
 			}
 			if (options & F_TIME) {
-				(void)printf(" tso=%s", pr_ntime(icp->icmp_otime));
-				(void)printf(" tsr=%s", pr_ntime(icp->icmp_rtime));
-				(void)printf(" tst=%s", pr_ntime(icp->icmp_ttime));
+				(void)printf(" tso=%s", pr_ntime(icp.icmp_otime));
+				(void)printf(" tsr=%s", pr_ntime(icp.icmp_rtime));
+				(void)printf(" tst=%s", pr_ntime(icp.icmp_ttime));
 			}
 			if (recv_len != send_len) {
                         	(void)printf(
@@ -1207,7 +1237,8 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, s
 				     recv_len, send_len);
 			}
 			/* check the data */
-			cp = (u_char*)&icp->icmp_data[phdr_len];
+			cp = (u_char*)(buf + hlen + offsetof(struct icmp,
+				icmp_data) + phdr_len);
 			dp = &outpack[ICMP_MINLEN + phdr_len];
 			cc -= ICMP_MINLEN + phdr_len;
 			i = 0;
@@ -1222,7 +1253,8 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, s
 	(void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x",
 	    i, *dp, *cp);
 					(void)printf("\ncp:");
-					cp = (u_char*)&icp->icmp_data[0];
+					cp = (u_char*)(buf + hlen +
+					    offsetof(struct icmp, icmp_data));
 					for (i = 0; i < datalen; ++i, ++cp) {
 						if ((i % 16) == 8)
 							(void)printf("\n\t");
@@ -1250,22 +1282,22 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, s
 		 * as root to avoid leaking information not normally
 		 * available to those not running as root.
 		 */
-#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);
+		memcpy(&oip_header_len, icmp_data_raw, sizeof(oip_header_len));
+		oip_header_len = (oip_header_len & 0x0f) << 2;
+		memcpy(&oip, icmp_data_raw, oip_header_len);
+		oicmp_raw = icmp_data_raw + oip_header_len;
+		memcpy(&oicmp, oicmp_raw, offsetof(struct icmp, icmp_id) +
+		    sizeof(oicmp.icmp_id));
 
 		if (((options & F_VERBOSE) && uid == 0) ||
 		    (!(options & F_QUIET2) &&
-		     (oip->ip_dst.s_addr == 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,
+		     (oip.ip_dst.s_addr == whereto.sin_addr.s_addr) &&
+		     (oip.ip_p == IPPROTO_ICMP) &&
+		     (oicmp.icmp_type == ICMP_ECHO) &&
+		     (oicmp.icmp_id == ident))) {
+		    (void)printf("%zd bytes from %s: ", cc,
 			pr_addr(from->sin_addr));
-		    pr_icmph(icp);
+		    pr_icmph(&icp, &oip, oicmp_raw);
 		} else
 		    return;
 	}
@@ -1451,7 +1483,7 @@ static char *ttab[] = {
  *	Print a descriptive string about an ICMP header.
  */
 static void
-pr_icmph(struct icmp *icp)
+pr_icmph(struct icmp *icp, struct ip *oip, const u_char *const oicmp_raw)
 {
 
 	switch(icp->icmp_type) {
@@ -1489,19 +1521,11 @@ pr_icmph(struct icmp *icp)
 			break;
 		}
 		/* Print returned IP header information */
-#ifndef icmp_data
-		pr_retip(&icp->icmp_ip);
-#else
-		pr_retip((struct ip *)icp->icmp_data);
-#endif
+		pr_retip(oip, oicmp_raw);
 		break;
 	case ICMP_SOURCEQUENCH:
 		(void)printf("Source Quench\n");
-#ifndef icmp_data
-		pr_retip(&icp->icmp_ip);
-#else
-		pr_retip((struct ip *)icp->icmp_data);
-#endif
+		pr_retip(oip, oicmp_raw);
 		break;
 	case ICMP_REDIRECT:
 		switch(icp->icmp_code) {
@@ -1522,11 +1546,7 @@ pr_icmph(struct icmp *icp)
 			break;
 		}
 		(void)printf("(New addr: %s)\n", inet_ntoa(icp->icmp_gwaddr));
-#ifndef icmp_data
-		pr_retip(&icp->icmp_ip);
-#else
-		pr_retip((struct ip *)icp->icmp_data);
-#endif
+		pr_retip(oip, oicmp_raw);
 		break;
 	case ICMP_ECHO:
 		(void)printf("Echo Request\n");
@@ -1545,20 +1565,12 @@ pr_icmph(struct icmp *icp)
 			    icp->icmp_code);
 			break;
 		}
-#ifndef icmp_data
-		pr_retip(&icp->icmp_ip);
-#else
-		pr_retip((struct ip *)icp->icmp_data);
-#endif
+		pr_retip(oip, oicmp_raw);
 		break;
 	case ICMP_PARAMPROB:
 		(void)printf("Parameter problem: pointer = 0x%02x\n",
 		    icp->icmp_hun.ih_pptr);
-#ifndef icmp_data
-		pr_retip(&icp->icmp_ip);
-#else
-		pr_retip((struct ip *)icp->icmp_data);
-#endif
+		pr_retip(oip, oicmp_raw);
 		break;
 	case ICMP_TSTAMP:
 		(void)printf("Timestamp\n");
@@ -1659,14 +1671,9 @@ pr_addr(struct in_addr ina)
  *	Dump some info on a returned (via ICMP) IP packet.
  */
 static void
-pr_retip(struct ip *ip)
+pr_retip(struct ip *ip, const u_char *cp)
 {
-	u_char *cp;
-	int hlen;
-
 	pr_iph(ip);
-	hlen = ip->ip_hl << 2;
-	cp = (u_char *)ip + hlen;
 
 	if (ip->ip_p == 6)
 		(void)printf("TCP: from port %u, to port %u (decimal)\n",

Modified: stable/12/sbin/ping/tests/Makefile
==============================================================================
--- head/sbin/ping/tests/Makefile	Tue Aug 20 21:59:48 2019	(r351318)
+++ stable/12/sbin/ping/tests/Makefile	Mon Sep 16 00:56:33 2019	(r352371)
@@ -5,4 +5,9 @@ WARNS?=	6
 ATF_TESTS_C+=	in_cksum_test
 SRCS.in_cksum_test= in_cksum_test.c ../utils.c
 
+PACKAGE= tests
+
+ATF_TESTS_SH+=	ping_test
+${PACKAGE}FILES+= ping_c1_s56_t1.out
+
 .include <bsd.test.mk>

Copied and modified: stable/12/sbin/ping/tests/ping_c1_s56_t1.out (from r351393, head/sbin/ping/tests/ping_c1_s56_t1.out)
==============================================================================
--- head/sbin/ping/tests/ping_c1_s56_t1.out	Thu Aug 22 15:00:36 2019	(r351393, copy source)
+++ stable/12/sbin/ping/tests/ping_c1_s56_t1.out	Mon Sep 16 00:56:33 2019	(r352371)
@@ -1,5 +1,5 @@
 PING localhost: 56 data bytes
-64 bytes from localhost: icmp_seq=0 ttl= time= ms
+64 bytes from: icmp_seq=0 ttl= time= ms
 
 --- localhost ping statistics ---
 1 packets transmitted, 1 packets received, 0.0% packet loss

Copied: stable/12/sbin/ping/tests/ping_test.sh (from r351393, head/sbin/ping/tests/ping_test.sh)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/12/sbin/ping/tests/ping_test.sh	Mon Sep 16 00:56:33 2019	(r352371, copy of r351393, head/sbin/ping/tests/ping_test.sh)
@@ -0,0 +1,55 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+#
+# Copyright (C) 2019 Jan Sucan <jansucan@FreeBSD.org>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+atf_test_case ping_c1_s56_t1
+ping_c1_s56_t1_head() {
+    atf_set "descr" "Stop after receiving 1 ECHO_RESPONSE packet"
+}
+ping_c1_s56_t1_body() {
+    if ! getaddrinfo -f inet localhost 1>/dev/null 2>&1; then
+	atf_skip "IPv4 is not configured"
+    fi
+    atf_check -s exit:0 -o save:std.out -e empty \
+	      ping -c 1 -s 56 -t 1 localhost
+    check_ping_statistics std.out $(atf_get_srcdir)/ping_c1_s56_t1.out
+}
+
+atf_init_test_cases() {
+    atf_add_test_case ping_c1_s56_t1
+}
+
+check_ping_statistics() {
+    sed -e 's/0.[0-9]\{3\}//g' \
+	-e 's/[1-9][0-9]*.[0-9]\{3\}//g' \
+	-e 's/localhost ([0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{1,3\})/localhost/' \
+	-e 's/from [0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{1,3\}/from/' \
+	-e 's/ttl=[0-9][0-9]*/ttl=/' \
+	"$1" >"$1".filtered
+    atf_check -s exit:0 diff -u "$1".filtered "$2"
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201909160056.x8G0uXTI006195>