svn commit: r351977 - stable/12/usr.sbin/traceroute6

Michael Tuexen tuexen at FreeBSD.org
Sat Sep 7 10:56:39 UTC 2019


Author: tuexen
Date: Sat Sep  7 10:56:38 2019
New Revision: 351977
URL: https://svnweb.freebsd.org/changeset/base/351977

Log:
  MFC 350027:
  
  Let packet_op() explicitly return the type and code instead of doing
  this implicitly by encoding it in a number space.
  
  No functional change intended.
  
  This is done as a preparation to add support for ICMPv6 mesages
  indicating a parameter problem related to the next header.

Modified:
  stable/12/usr.sbin/traceroute6/traceroute6.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/usr.sbin/traceroute6/traceroute6.c
==============================================================================
--- stable/12/usr.sbin/traceroute6/traceroute6.c	Sat Sep  7 10:55:12 2019	(r351976)
+++ stable/12/usr.sbin/traceroute6/traceroute6.c	Sat Sep  7 10:56:38 2019	(r351977)
@@ -309,7 +309,7 @@ void	*get_uphdr(struct ip6_hdr *, u_char *);
 int	get_hoplim(struct msghdr *);
 double	deltaT(struct timeval *, struct timeval *);
 const char *pr_type(int);
-int	packet_ok(struct msghdr *, int, int);
+int	packet_ok(struct msghdr *, int, int, u_char *, u_char *);
 void	print(struct msghdr *, int);
 const char *inetname(struct sockaddr *);
 u_int32_t sctp_crc32c(void *, u_int32_t);
@@ -365,6 +365,7 @@ main(int argc, char *argv[])
 	struct hostent *hp;
 	size_t size, minlen;
 	uid_t uid;
+	u_char type, code;
 
 	/*
 	 * Receive ICMP
@@ -916,7 +917,7 @@ main(int argc, char *argv[])
 			send_probe(++seq, hops);
 			while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) {
 				(void) gettimeofday(&t2, NULL);
-				if ((i = packet_ok(&rcvmhdr, cc, seq))) {
+				if (packet_ok(&rcvmhdr, cc, seq, &type, &code)) {
 					if (!IN6_ARE_ADDR_EQUAL(&Rcv.sin6_addr,
 					    &lastaddr)) {
 						if (probe > 0)
@@ -925,29 +926,36 @@ main(int argc, char *argv[])
 						lastaddr = Rcv.sin6_addr;
 					}
 					printf("  %.3f ms", deltaT(&t1, &t2));
-					switch (i - 1) {
-					case ICMP6_DST_UNREACH_NOROUTE:
-						++unreachable;
-						printf(" !N");
-						break;
-					case ICMP6_DST_UNREACH_ADMIN:
-						++unreachable;
-						printf(" !P");
-						break;
-					case ICMP6_DST_UNREACH_NOTNEIGHBOR:
-						++unreachable;
-						printf(" !S");
-						break;
-					case ICMP6_DST_UNREACH_ADDR:
-						++unreachable;
-						printf(" !A");
-						break;
-					case ICMP6_DST_UNREACH_NOPORT:
+					if (type == ICMP6_DST_UNREACH) {
+						switch (code) {
+						case ICMP6_DST_UNREACH_NOROUTE:
+							++unreachable;
+							printf(" !N");
+							break;
+						case ICMP6_DST_UNREACH_ADMIN:
+							++unreachable;
+							printf(" !P");
+							break;
+						case ICMP6_DST_UNREACH_NOTNEIGHBOR:
+							++unreachable;
+							printf(" !S");
+							break;
+						case ICMP6_DST_UNREACH_ADDR:
+							++unreachable;
+							printf(" !A");
+							break;
+						case ICMP6_DST_UNREACH_NOPORT:
+							if (rcvhlim >= 0 &&
+							    rcvhlim <= 1)
+								printf(" !");
+							++got_there;
+							break;
+						}
+					} else if (type == ICMP6_ECHO_REPLY) {
 						if (rcvhlim >= 0 &&
 						    rcvhlim <= 1)
 							printf(" !");
 						++got_there;
-						break;
 					}
 					break;
 				} else if (deltaT(&t1, &t2) > waittime * 1000) {
@@ -1244,11 +1252,10 @@ pr_type(int t0)
 }
 
 int
-packet_ok(struct msghdr *mhdr, int cc, int seq)
+packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code)
 {
 	struct icmp6_hdr *icp;
 	struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
-	u_char type, code;
 	char *buf = (char *)mhdr->msg_iov[0].iov_base;
 	struct cmsghdr *cm;
 	int *hlimp;
@@ -1313,10 +1320,11 @@ packet_ok(struct msghdr *mhdr, int cc, int seq)
 	else
 		rcvhlim = *hlimp;
 
-	type = icp->icmp6_type;
-	code = icp->icmp6_code;
-	if ((type == ICMP6_TIME_EXCEEDED && code == ICMP6_TIME_EXCEED_TRANSIT)
-	    || type == ICMP6_DST_UNREACH) {
+	*type = icp->icmp6_type;
+	*code = icp->icmp6_code;
+	if ((*type == ICMP6_TIME_EXCEEDED &&
+	    *code == ICMP6_TIME_EXCEED_TRANSIT) ||
+	    (*type == ICMP6_DST_UNREACH)) {
 		struct ip6_hdr *hip;
 		struct icmp6_hdr *icmp;
 		struct sctp_init_chunk *init;
@@ -1336,15 +1344,13 @@ packet_ok(struct msghdr *mhdr, int cc, int seq)
 			icmp = (struct icmp6_hdr *)up;
 			if (icmp->icmp6_id == ident &&
 			    icmp->icmp6_seq == htons(seq))
-				return (type == ICMP6_TIME_EXCEEDED ?
-				    -1 : code + 1);
+				return (1);
 			break;
 		case IPPROTO_UDP:
 			udp = (struct udphdr *)up;
 			if (udp->uh_sport == htons(srcport) &&
 			    udp->uh_dport == htons(port + seq))
-				return (type == ICMP6_TIME_EXCEEDED ?
-				    -1 : code + 1);
+				return (1);
 			break;
 		case IPPROTO_SCTP:
 			sctp = (struct sctphdr *)up;
@@ -1360,20 +1366,17 @@ packet_ok(struct msghdr *mhdr, int cc, int seq)
 				init = (struct sctp_init_chunk *)(sctp + 1);
 				/* Check the initiate tag, if available. */
 				if ((char *)&init->init.a_rwnd > buf + cc) {
-					return (type == ICMP6_TIME_EXCEEDED ?
-					    -1 : code + 1);
+					return (1);
 				}
 				if (init->init.initiate_tag == (u_int32_t)
 				    ((sctp->src_port << 16) | sctp->dest_port)) {
-					return (type == ICMP6_TIME_EXCEEDED ?
-					    -1 : code + 1);
+					return (1);
 				}
 			} else {
 				if (sctp->v_tag ==
 				    (u_int32_t)((sctp->src_port << 16) |
 				    sctp->dest_port)) {
-					return (type == ICMP6_TIME_EXCEEDED ?
-					    -1 : code + 1);
+					return (1);
 				}
 			}
 			break;
@@ -1383,19 +1386,18 @@ packet_ok(struct msghdr *mhdr, int cc, int seq)
 			    tcp->th_dport == htons(port + seq) &&
 			    tcp->th_seq ==
 			    (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport))
-				return (type == ICMP6_TIME_EXCEEDED ?
-				    -1 : code + 1);
+				return (1);
 			break;
 		case IPPROTO_NONE:
-			return (type == ICMP6_TIME_EXCEEDED ?  -1 : code + 1);
+			return (1);
 		default:
 			fprintf(stderr, "Unknown probe proto %d.\n", useproto);
 			break;
 		}
-	} else if (useproto == IPPROTO_ICMPV6 && type == ICMP6_ECHO_REPLY) {
+	} else if (useproto == IPPROTO_ICMPV6 && *type == ICMP6_ECHO_REPLY) {
 		if (icp->icmp6_id == ident &&
 		    icp->icmp6_seq == htons(seq))
-			return (ICMP6_DST_UNREACH_NOPORT + 1);
+			return (1);
 	}
 	if (verbose) {
 		char sbuf[NI_MAXHOST+1], dbuf[INET6_ADDRSTRLEN];
@@ -1408,8 +1410,8 @@ packet_ok(struct msghdr *mhdr, int cc, int seq)
 		printf("\n%d bytes from %s to %s", cc, sbuf,
 		    rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
 		    dbuf, sizeof(dbuf)) : "?");
-		printf(": icmp type %d (%s) code %d\n", type, pr_type(type),
-		    icp->icmp6_code);
+		printf(": icmp type %d (%s) code %d\n", *type, pr_type(*type),
+		    *code);
 		p = (u_int8_t *)(icp + 1);
 #define WIDTH	16
 		for (i = 0; i < cc; i++) {


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