svn commit: r352232 - stable/12/sbin/ping6

Alan Somers asomers at FreeBSD.org
Wed Sep 11 20:13:39 UTC 2019


Author: asomers
Date: Wed Sep 11 20:13:38 2019
New Revision: 352232
URL: https://svnweb.freebsd.org/changeset/base/352232

Log:
  MFC r350993, r350997, r351079-r351080, r351082, r351090, r351101-r351102
  
  r350993:
  Consistently use the byteorder functions in the correct direction
  
  Though ntohs and htons are functionally identical, they have different meanings.Using the correct one helps to document the code.
  
  Submitted by:	Ján Sučan <sucanjan at gmail.com>
  Sponsored by:	Google, inc. (Google Summer of Code 2019)
  Differential Revision:	https://reviews.freebsd.org/D21219
  
  r350997:
  ping6: use the monotonic clock to measure durations
  
  Submitted by:	Ján Sučan <sucanjan at gmail.com>
  Sponsored by:	Google, inc. (Google Summer of Code 2019)
  Differential Revision:	https://reviews.freebsd.org/D21226
  
  r351079:
  ping6: quiet warning about unused copyright variable
  
  Submitted by:	Ján Sučan <sucanjan at gmail.com>
  Sponsored by:	Google, inc. (Google Summer of Code 2019)
  Differential Revision:	https://reviews.freebsd.org/D21270
  
  r351080:
  ping6: quiet an undefined variable warning
  
  GCC 4.2 isn't smart enough to know that this variable is already defined by
  the time it's used.
  
  Submitted by:	Ján Sučan <sucanjan at gmail.com>
  Sponsored by:	Google, inc. (Google Summer of Code 2019)
  Differential Revision:	https://reviews.freebsd.org/D21269
  
  r351082:
  ping6: fix uninitialized variable warning for intvl
  
  GCC isn't smart enough to realize that this variable was always initialized.
  
  Submitted by:	Ján Sučan <sucanjan at gmail.com>
  Sponsored by:	Google, inc. (Google Summer of Code 2019)
  Differential Revision:	https://reviews.freebsd.org/D21271
  
  r351090:
  ping6: Fix data type of the buffer for ancillary data of a received message
  
  The old code worked, but wasted some stack space.
  
  Submitted by:	Ján Sučan <sucanjan at gmail.com>
  Sponsored by:	Google, inc. (Google Summer of Code 2019)
  Differential Revision:	https://reviews.freebsd.org/D21275
  
  r351101:
  ping6: fix uninitialized variable warnings when MK_CASPER=no
  
  Submitted by:	Ján Sučan <sucanjan at gmail.com>
  Sponsored by:	Google, inc. (Google Summer of Code 2019)
  Differential Revision:	https://reviews.freebsd.org/D21273
  
  r351102:
  ping6: Fix alignment errors
  
  This fixes -Wcast-align errors when compiled with WARNS=6.
  
  Submitted by:	Ján Sučan <sucanjan at gmail.com>
  Sponsored by:	Google, inc. (Google Summer of Code 2019)
  Differential Revision:	https://reviews.freebsd.org/D21217

Modified:
  stable/12/sbin/ping6/ping6.c

Modified: stable/12/sbin/ping6/ping6.c
==============================================================================
--- stable/12/sbin/ping6/ping6.c	Wed Sep 11 19:48:32 2019	(r352231)
+++ stable/12/sbin/ping6/ping6.c	Wed Sep 11 20:13:38 2019	(r352232)
@@ -65,6 +65,7 @@
  * SUCH DAMAGE.
  */
 
+#if 0
 #ifndef lint
 static const char copyright[] =
 "@(#) Copyright (c) 1989, 1993\n\
@@ -72,10 +73,9 @@ static const char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
-#if 0
 static char sccsid[] = "@(#)ping.c	8.1 (Berkeley) 6/5/93";
-#endif
 #endif /* not lint */
+#endif
 
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
@@ -107,7 +107,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/capsicum.h>
 #include <sys/uio.h>
 #include <sys/socket.h>
-#include <sys/time.h>
 
 #include <net/if.h>
 #include <net/route.h>
@@ -133,6 +132,7 @@ __FBSDID("$FreeBSD$");
 #include <stdlib.h>
 #include <string.h>
 #include <sysexits.h>
+#include <time.h>
 #include <unistd.h>
 
 #ifdef IPSEC
@@ -144,7 +144,7 @@ __FBSDID("$FreeBSD$");
 
 struct tv32 {
 	u_int32_t tv32_sec;
-	u_int32_t tv32_usec;
+	u_int32_t tv32_nsec;
 };
 
 #define MAXPACKETLEN	131072
@@ -288,7 +288,6 @@ static void	 pr_rthdr(void *, size_t);
 static int	 pr_bitrange(u_int32_t, int, int);
 static void	 pr_retip(struct ip6_hdr *, u_char *);
 static void	 summary(void);
-static void	 tvsub(struct timeval *, struct timeval *);
 static int	 setpolicy(int, char *);
 static char	*nigroup(char *, int);
 static void	 usage(void);
@@ -296,7 +295,7 @@ static void	 usage(void);
 int
 main(int argc, char *argv[])
 {
-	struct timeval last, intvl;
+	struct timespec last, intvl;
 	struct sockaddr_in6 from, *sin6;
 	struct addrinfo hints, *res;
 	struct sigaction si_sa;
@@ -308,13 +307,14 @@ main(int argc, char *argv[])
 	int ip6optlen = 0;
 	struct cmsghdr *scmsgp = NULL;
 	/* For control (ancillary) data received from recvmsg() */
-	struct cmsghdr cm[CONTROLLEN];
+	u_char cm[CONTROLLEN];
 #if defined(SO_SNDBUF) && defined(SO_RCVBUF)
 	u_long lsockbufsize;
 	int sockbufsize = 0;
 #endif
 	int usepktinfo = 0;
-	struct in6_pktinfo *pktinfo = NULL;
+	struct in6_pktinfo pktinfo;
+	char *cmsg_pktinfo = NULL;
 	struct ip6_rthdr *rthdr = NULL;
 #ifdef IPSEC_POLICY_IPSEC
 	char *policy_in = NULL;
@@ -333,7 +333,11 @@ main(int argc, char *argv[])
 	/* just to be sure */
 	memset(&smsghdr, 0, sizeof(smsghdr));
 	memset(&smsgiov, 0, sizeof(smsgiov));
+	memset(&pktinfo, 0, sizeof(pktinfo));
 
+	intvl.tv_sec = interval / 1000;
+	intvl.tv_nsec = interval % 1000 * 1000000;
+
 	alarmtimeout = preload = 0;
 	datap = &outpack[ICMP6ECHOLEN + ICMP6ECHOTMLEN];
 	capdns = capdns_setup();
@@ -456,15 +460,15 @@ main(int argc, char *argv[])
 				errx(1, "%s: only root may use interval < 1s",
 				    strerror(EPERM));
 			}
-			intvl.tv_sec = (long)t;
-			intvl.tv_usec =
-			    (long)((t - intvl.tv_sec) * 1000000);
+			intvl.tv_sec = (time_t)t;
+			intvl.tv_nsec =
+			    (long)((t - intvl.tv_sec) * 1000000000);
 			if (intvl.tv_sec < 0)
 				errx(1, "illegal timing interval %s", optarg);
 			/* less than 1/hz does not make sense */
-			if (intvl.tv_sec == 0 && intvl.tv_usec < 1) {
+			if (intvl.tv_sec == 0 && intvl.tv_nsec < 1000) {
 				warnx("too small interval, raised to .000001");
-				intvl.tv_usec = 1;
+				intvl.tv_nsec = 1000;
 			}
 			options |= F_INTERVAL;
 			break;
@@ -894,11 +898,10 @@ main(int argc, char *argv[])
 			errx(1, "can't allocate enough memory");
 		smsghdr.msg_control = (caddr_t)scmsg;
 		smsghdr.msg_controllen = ip6optlen;
-		scmsgp = (struct cmsghdr *)scmsg;
+		scmsgp = CMSG_FIRSTHDR(&smsghdr);
 	}
 	if (usepktinfo) {
-		pktinfo = (struct in6_pktinfo *)(CMSG_DATA(scmsgp));
-		memset(pktinfo, 0, sizeof(*pktinfo));
+		cmsg_pktinfo = CMSG_DATA(scmsgp);
 		scmsgp->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
 		scmsgp->cmsg_level = IPPROTO_IPV6;
 		scmsgp->cmsg_type = IPV6_PKTINFO;
@@ -909,7 +912,7 @@ main(int argc, char *argv[])
 	if (ifname) {
 #ifndef USE_SIN6_SCOPE_ID
 		/* pktinfo must have already been allocated */
-		if ((pktinfo->ipi6_ifindex = if_nametoindex(ifname)) == 0)
+		if ((pktinfo.ipi6_ifindex = if_nametoindex(ifname)) == 0)
 			errx(1, "%s: invalid interface name", ifname);
 #else
 		if ((dst.sin6_scope_id = if_nametoindex(ifname)) == 0)
@@ -920,7 +923,7 @@ main(int argc, char *argv[])
 		scmsgp->cmsg_len = CMSG_LEN(sizeof(int));
 		scmsgp->cmsg_level = IPPROTO_IPV6;
 		scmsgp->cmsg_type = IPV6_HOPLIMIT;
-		*(int *)(CMSG_DATA(scmsgp)) = hoplimit;
+		memcpy(CMSG_DATA(scmsgp), &hoplimit, sizeof(hoplimit));
 
 		scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp);
 	}
@@ -959,6 +962,7 @@ main(int argc, char *argv[])
 	}
 
 	/* From now on we will use only reverse DNS lookups. */
+#ifdef WITH_CASPER
 	if (capdns != NULL) {
 		const char *types[1];
 
@@ -966,7 +970,7 @@ main(int argc, char *argv[])
 		if (cap_dns_type_limit(capdns, types, nitems(types)) < 0)
 			err(1, "unable to limit access to system.dns service");
 	}
-
+#endif
 	if (!(options & F_SRCADDR)) {
 		/*
 		 * get the source address. XXX since we revoked the root
@@ -983,9 +987,9 @@ main(int argc, char *argv[])
 		src.sin6_port = ntohs(DUMMY_PORT);
 		src.sin6_scope_id = dst.sin6_scope_id;
 
-		if (pktinfo &&
+		if (usepktinfo &&
 		    setsockopt(dummy, IPPROTO_IPV6, IPV6_PKTINFO,
-		    (void *)pktinfo, sizeof(*pktinfo)))
+		    (void *)&pktinfo, sizeof(pktinfo)))
 			err(1, "UDP setsockopt(IPV6_PKTINFO)");
 
 		if (hoplimit != -1 &&
@@ -1012,6 +1016,10 @@ main(int argc, char *argv[])
 		close(dummy);
 	}
 
+	/* Save pktinfo in the ancillary data. */
+	if (usepktinfo)
+		memcpy(cmsg_pktinfo, &pktinfo, sizeof(pktinfo));
+
 	if (connect(ssend, (struct sockaddr *)&dst, sizeof(dst)) != 0)
 		err(1, "connect() ssend");
 
@@ -1102,7 +1110,7 @@ main(int argc, char *argv[])
 		while (preload--)
 			pinger();
 	}
-	gettimeofday(&last, NULL);
+	clock_gettime(CLOCK_MONOTONIC, &last);
 
 	sigemptyset(&si_sa.sa_mask);
 	si_sa.sa_flags = 0;
@@ -1121,15 +1129,12 @@ main(int argc, char *argv[])
 	}
 	if (options & F_FLOOD) {
 		intvl.tv_sec = 0;
-		intvl.tv_usec = 10000;
-	} else if ((options & F_INTERVAL) == 0) {
-		intvl.tv_sec = interval / 1000;
-		intvl.tv_usec = interval % 1000 * 1000;
+		intvl.tv_nsec = 10000000;
 	}
 
 	almost_done = 0;
 	while (seenint == 0) {
-		struct timeval now, timeout;
+		struct timespec now, timeout;
 		struct msghdr m;
 		struct iovec iov[2];
 		fd_set rfds;
@@ -1147,21 +1152,13 @@ main(int argc, char *argv[])
 #endif
 		FD_ZERO(&rfds);
 		FD_SET(srecv, &rfds);
-		gettimeofday(&now, NULL);
-		timeout.tv_sec = last.tv_sec + intvl.tv_sec - now.tv_sec;
-		timeout.tv_usec = last.tv_usec + intvl.tv_usec - now.tv_usec;
-		while (timeout.tv_usec < 0) {
-			timeout.tv_usec += 1000000;
-			timeout.tv_sec--;
-		}
-		while (timeout.tv_usec > 1000000) {
-			timeout.tv_usec -= 1000000;
-			timeout.tv_sec++;
-		}
+		clock_gettime(CLOCK_MONOTONIC, &now);
+		timespecadd(&last, &intvl, &timeout);
+		timespecsub(&timeout, &now, &timeout);
 		if (timeout.tv_sec < 0)
-			timeout.tv_sec = timeout.tv_usec = 0;
+			timespecclear(&timeout);
 
-		n = select(srecv + 1, &rfds, NULL, NULL, &timeout);
+		n = pselect(srecv + 1, &rfds, NULL, NULL, &timeout, NULL);
 		if (n < 0)
 			continue;	/* EINTR */
 		if (n == 1) {
@@ -1222,17 +1219,18 @@ main(int argc, char *argv[])
 			 * if we've received any packets or (waittime)
 			 * milliseconds if we haven't.
 			 */
-				intvl.tv_usec = 0;
+				intvl.tv_nsec = 0;
 				if (nreceived) {
 					intvl.tv_sec = 2 * tmax / 1000;
 					if (intvl.tv_sec == 0)
 						intvl.tv_sec = 1;
 				} else {
 					intvl.tv_sec = waittime / 1000;
-					intvl.tv_usec = waittime % 1000 * 1000;
+					intvl.tv_nsec =
+						waittime % 1000 * 1000000;
 				}
 			}
-			gettimeofday(&last, NULL);
+			clock_gettime(CLOCK_MONOTONIC, &last);
 			if (ntransmitted - nreceived - 1 > nmissedmax) {
 				nmissedmax = ntransmitted - nreceived - 1;
 				if (options & F_MISSED)
@@ -1275,7 +1273,7 @@ onsignal(int sig)
  *	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 "timespec" struct in VAX
  * byte-order, to compute the round-trip time.
  */
 static size_t
@@ -1317,6 +1315,8 @@ pinger(void)
 	CLR(seq % mx_dup_ck);
 
 	if (options & F_FQDN) {
+		uint16_t s;
+
 		icp->icmp6_type = ICMP6_NI_QUERY;
 		icp->icmp6_code = ICMP6_NI_SUBJ_IPV6;
 		nip->ni_qtype = htons(NI_QTYPE_FQDN);
@@ -1324,13 +1324,15 @@ pinger(void)
 
 		memcpy(nip->icmp6_ni_nonce, nonce,
 		    sizeof(nip->icmp6_ni_nonce));
-		*(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq);
+		s = htons(seq);
+		memcpy(nip->icmp6_ni_nonce, &s, sizeof(s));
 
 		memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr,
 		    sizeof(dst.sin6_addr));
 		cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr);
 		datalen = 0;
 	} else if (options & F_FQDNOLD) {
+		uint16_t s;
 		/* packet format in 03 draft - no Subject data on queries */
 		icp->icmp6_type = ICMP6_NI_QUERY;
 		icp->icmp6_code = 0;	/* code field is always 0 */
@@ -1339,11 +1341,14 @@ pinger(void)
 
 		memcpy(nip->icmp6_ni_nonce, nonce,
 		    sizeof(nip->icmp6_ni_nonce));
-		*(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq);
+		s = htons(seq);
+		memcpy(nip->icmp6_ni_nonce, &s, sizeof(s));
 
 		cc = ICMP6_NIQLEN;
 		datalen = 0;
 	} else if (options & F_NODEADDR) {
+		uint16_t s;
+
 		icp->icmp6_type = ICMP6_NI_QUERY;
 		icp->icmp6_code = ICMP6_NI_SUBJ_IPV6;
 		nip->ni_qtype = htons(NI_QTYPE_NODEADDR);
@@ -1351,13 +1356,16 @@ pinger(void)
 
 		memcpy(nip->icmp6_ni_nonce, nonce,
 		    sizeof(nip->icmp6_ni_nonce));
-		*(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq);
+		s = htons(seq);
+		memcpy(nip->icmp6_ni_nonce, &s, sizeof(s));
 
 		memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr,
 		    sizeof(dst.sin6_addr));
 		cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr);
 		datalen = 0;
 	} else if (options & F_SUPTYPES) {
+		uint16_t s;
+
 		icp->icmp6_type = ICMP6_NI_QUERY;
 		icp->icmp6_code = ICMP6_NI_SUBJ_FQDN;	/*empty*/
 		nip->ni_qtype = htons(NI_QTYPE_SUPTYPES);
@@ -1366,21 +1374,29 @@ pinger(void)
 
 		memcpy(nip->icmp6_ni_nonce, nonce,
 		    sizeof(nip->icmp6_ni_nonce));
-		*(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq);
+		s = htons(seq);
+		memcpy(nip->icmp6_ni_nonce, &s, sizeof(s));
+
 		cc = ICMP6_NIQLEN;
 		datalen = 0;
 	} else {
 		icp->icmp6_type = ICMP6_ECHO_REQUEST;
 		icp->icmp6_code = 0;
 		icp->icmp6_id = htons(ident);
-		icp->icmp6_seq = ntohs(seq);
+		icp->icmp6_seq = htons(seq);
 		if (timing) {
-			struct timeval tv;
-			struct tv32 *tv32;
-			(void)gettimeofday(&tv, NULL);
-			tv32 = (struct tv32 *)&outpack[ICMP6ECHOLEN];
-			tv32->tv32_sec = htonl(tv.tv_sec);
-			tv32->tv32_usec = htonl(tv.tv_usec);
+			struct timespec tv;
+			struct tv32 tv32;
+			(void)clock_gettime(CLOCK_MONOTONIC, &tv);
+			/*
+			 * Truncate seconds down to 32 bits in order
+			 * to fit the timestamp within 8 bytes of the
+			 * packet. We're only concerned with
+			 * durations, not absolute times.
+			 */
+			tv32.tv32_sec = (uint32_t)htonl(tv.tv_sec);
+			tv32.tv32_nsec = (uint32_t)htonl(tv.tv_nsec);
+			memcpy(&outpack[ICMP6ECHOLEN], &tv32, sizeof(tv32));
 		}
 		cc = ICMP6ECHOLEN + datalen;
 	}
@@ -1525,8 +1541,8 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
 	const u_char *cp = NULL;
 	u_char *dp, *end = buf + cc;
 	struct in6_pktinfo *pktinfo = NULL;
-	struct timeval tv, tp;
-	struct tv32 *tpp;
+	struct timespec tv, tp;
+	struct tv32 tpp;
 	double triptime = 0;
 	int dupflag;
 	size_t off;
@@ -1534,7 +1550,7 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
 	u_int16_t seq;
 	char dnsname[MAXDNAME + 1];
 
-	(void)gettimeofday(&tv, NULL);
+	(void)clock_gettime(CLOCK_MONOTONIC, &tv);
 
 	if (!mhdr || !mhdr->msg_name ||
 	    mhdr->msg_namelen != sizeof(struct sockaddr_in6) ||
@@ -1571,12 +1587,12 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
 		seq = ntohs(icp->icmp6_seq);
 		++nreceived;
 		if (timing) {
-			tpp = (struct tv32 *)(icp + 1);
-			tp.tv_sec = ntohl(tpp->tv32_sec);
-			tp.tv_usec = ntohl(tpp->tv32_usec);
-			tvsub(&tv, &tp);
+			memcpy(&tpp, icp + 1, sizeof(tpp));
+			tp.tv_sec = ntohl(tpp.tv32_sec);
+			tp.tv_nsec = ntohl(tpp.tv32_nsec);
+			timespecsub(&tv, &tp, &tv);
 			triptime = ((double)tv.tv_sec) * 1000.0 +
-			    ((double)tv.tv_usec) / 1000.0;
+			    ((double)tv.tv_nsec) / 1000000.0;
 			tsum += triptime;
 			tsumsq += triptime * triptime;
 			if (triptime < tmin)
@@ -1637,7 +1653,8 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
 			}
 		}
 	} else if (icp->icmp6_type == ICMP6_NI_REPLY && mynireply(ni)) {
-		seq = ntohs(*(u_int16_t *)ni->icmp6_ni_nonce);
+		memcpy(&seq, ni->icmp6_ni_nonce, sizeof(seq));
+		seq = ntohs(seq);
 		++nreceived;
 		if (TST(seq % mx_dup_ck)) {
 			++nrepeats;
@@ -1716,6 +1733,7 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
 				}
 			}
 			if (options & F_VERBOSE) {
+				u_long t;
 				int32_t ttl;
 				int comma = 0;
 
@@ -1738,7 +1756,8 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
 					putchar(')');
 					goto fqdnend;
 				}
-				ttl = (int32_t)ntohl(*(u_long *)&buf[off+ICMP6ECHOLEN+8]);
+				memcpy(&t, &buf[off+ICMP6ECHOLEN+8], sizeof(t));
+				ttl = (int32_t)ntohl(t);
 				if (comma)
 					printf(",");
 				if (!(ni->ni_flags & NI_FQDN_FLAG_VALIDTTL)) {
@@ -2101,11 +2120,13 @@ pr_nodeaddr(struct icmp6_nodeinfo *ni, int nilen)
 	if (nilen % (sizeof(u_int32_t) + sizeof(struct in6_addr)) == 0)
 		withttl = 1;
 	while (nilen > 0) {
-		u_int32_t ttl;
+		u_int32_t ttl = 0;
 
 		if (withttl) {
-			/* XXX: alignment? */
-			ttl = (u_int32_t)ntohl(*(u_int32_t *)cp);
+			uint32_t t;
+
+			memcpy(&t, cp, sizeof(t));
+			ttl = (u_int32_t)ntohl(t);
 			cp += sizeof(u_int32_t);
 			nilen -= sizeof(u_int32_t);
 		}
@@ -2144,8 +2165,12 @@ get_hoplim(struct msghdr *mhdr)
 
 		if (cm->cmsg_level == IPPROTO_IPV6 &&
 		    cm->cmsg_type == IPV6_HOPLIMIT &&
-		    cm->cmsg_len == CMSG_LEN(sizeof(int)))
-			return(*(int *)CMSG_DATA(cm));
+		    cm->cmsg_len == CMSG_LEN(sizeof(int))) {
+			int r;
+
+			memcpy(&r, CMSG_DATA(cm), sizeof(r));
+			return(r);
+		}
 	}
 
 	return(-1);
@@ -2154,6 +2179,7 @@ get_hoplim(struct msghdr *mhdr)
 static struct in6_pktinfo *
 get_rcvpktinfo(struct msghdr *mhdr)
 {
+	static struct in6_pktinfo pi;
 	struct cmsghdr *cm;
 
 	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
@@ -2163,8 +2189,10 @@ get_rcvpktinfo(struct msghdr *mhdr)
 
 		if (cm->cmsg_level == IPPROTO_IPV6 &&
 		    cm->cmsg_type == IPV6_PKTINFO &&
-		    cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo)))
-			return((struct in6_pktinfo *)CMSG_DATA(cm));
+		    cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) {
+			memcpy(&pi, CMSG_DATA(cm), sizeof(pi));
+			return(&pi);
+		}
 	}
 
 	return(NULL);
@@ -2175,7 +2203,7 @@ get_pathmtu(struct msghdr *mhdr)
 {
 #ifdef IPV6_RECVPATHMTU
 	struct cmsghdr *cm;
-	struct ip6_mtuinfo *mtuctl = NULL;
+	struct ip6_mtuinfo mtuctl;
 
 	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
 	     cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
@@ -2185,7 +2213,7 @@ get_pathmtu(struct msghdr *mhdr)
 		if (cm->cmsg_level == IPPROTO_IPV6 &&
 		    cm->cmsg_type == IPV6_PATHMTU &&
 		    cm->cmsg_len == CMSG_LEN(sizeof(struct ip6_mtuinfo))) {
-			mtuctl = (struct ip6_mtuinfo *)CMSG_DATA(cm);
+			memcpy(&mtuctl, CMSG_DATA(cm), sizeof(mtuctl));
 
 			/*
 			 * If the notified destination is different from
@@ -2195,17 +2223,17 @@ get_pathmtu(struct msghdr *mhdr)
 			 * have used the default scope zone ID for sending,
 			 * in which case the scope ID value is 0.
 			 */
-			if (!IN6_ARE_ADDR_EQUAL(&mtuctl->ip6m_addr.sin6_addr,
+			if (!IN6_ARE_ADDR_EQUAL(&mtuctl.ip6m_addr.sin6_addr,
 						&dst.sin6_addr) ||
-			    (mtuctl->ip6m_addr.sin6_scope_id &&
+			    (mtuctl.ip6m_addr.sin6_scope_id &&
 			     dst.sin6_scope_id &&
-			     mtuctl->ip6m_addr.sin6_scope_id !=
+			     mtuctl.ip6m_addr.sin6_scope_id !=
 			     dst.sin6_scope_id)) {
 				if ((options & F_VERBOSE) != 0) {
 					printf("path MTU for %s is notified. "
 					       "(ignored)\n",
-					   pr_addr((struct sockaddr *)&mtuctl->ip6m_addr,
-					   sizeof(mtuctl->ip6m_addr)));
+					   pr_addr((struct sockaddr *)&mtuctl.ip6m_addr,
+					   sizeof(mtuctl.ip6m_addr)));
 				}
 				return(0);
 			}
@@ -2214,11 +2242,11 @@ get_pathmtu(struct msghdr *mhdr)
 			 * Ignore an invalid MTU. XXX: can we just believe
 			 * the kernel check?
 			 */
-			if (mtuctl->ip6m_mtu < IPV6_MMTU)
+			if (mtuctl.ip6m_mtu < IPV6_MMTU)
 				return(0);
 
 			/* notification for our destination. return the MTU. */
-			return((int)mtuctl->ip6m_mtu);
+			return((int)mtuctl.ip6m_mtu);
 		}
 	}
 #endif
@@ -2226,21 +2254,6 @@ get_pathmtu(struct msghdr *mhdr)
 }
 
 /*
- * tvsub --
- *	Subtract 2 timeval structs:  out = out - in.  Out is assumed to
- * be >= in.
- */
-static void
-tvsub(struct timeval *out, struct timeval *in)
-{
-	if ((out->tv_usec -= in->tv_usec) < 0) {
-		--out->tv_sec;
-		out->tv_usec += 1000000;
-	}
-	out->tv_sec -= in->tv_sec;
-}
-
-/*
  * onint --
  *	SIGINT handler.
  */
@@ -2605,6 +2618,8 @@ pr_retip(struct ip6_hdr *ip6, u_char *end)
 	nh = ip6->ip6_nxt;
 	cp += hlen;
 	while (end - cp >= 8) {
+		struct ah ah;
+
 		switch (nh) {
 		case IPPROTO_HOPOPTS:
 			printf("HBH ");
@@ -2629,8 +2644,9 @@ pr_retip(struct ip6_hdr *ip6, u_char *end)
 #ifdef IPSEC
 		case IPPROTO_AH:
 			printf("AH ");
-			hlen = (((struct ah *)cp)->ah_len+2) << 2;
-			nh = ((struct ah *)cp)->ah_nxt;
+			memcpy(&ah, cp, sizeof(ah));
+			hlen = (ah.ah_len+2) << 2;
+			nh = ah.ah_nxt;
 			break;
 #endif
 		case IPPROTO_ICMPV6:
@@ -2815,9 +2831,10 @@ static cap_channel_t *
 capdns_setup(void)
 {
 	cap_channel_t *capcas, *capdnsloc;
+#ifdef WITH_CASPER
 	const char *types[2];
 	int families[1];
-
+#endif
 	capcas = cap_init();
 	if (capcas == NULL)
 		err(1, "unable to create casper process");
@@ -2826,6 +2843,7 @@ capdns_setup(void)
 	cap_close(capcas);
 	if (capdnsloc == NULL)
 		err(1, "unable to open system.dns service");
+#ifdef WITH_CASPER
 	types[0] = "NAME2ADDR";
 	types[1] = "ADDR2NAME";
 	if (cap_dns_type_limit(capdnsloc, types, nitems(types)) < 0)
@@ -2833,6 +2851,6 @@ capdns_setup(void)
 	families[0] = AF_INET6;
 	if (cap_dns_family_limit(capdnsloc, families, nitems(families)) < 0)
 		err(1, "unable to limit access to system.dns service");
-
+#endif
 	return (capdnsloc);
 }


More information about the svn-src-stable-12 mailing list