Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 May 2020 22:13:09 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r360709 - stable/11/usr.sbin/traceroute6
Message-ID:  <202005062213.046MD9Un035373@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Wed May  6 22:13:08 2020
New Revision: 360709
URL: https://svnweb.freebsd.org/changeset/base/360709

Log:
  MFC r350027, r350028: Let traceroute6 not ignore some ICMPv6 packets
  
  MFC rr350027:
  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.
  
  MFC r350028:
  Add support for ICMPv6 messages indicating a parameter problem related
  to an unrecognized next header.

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

Modified: stable/11/usr.sbin/traceroute6/traceroute6.8
==============================================================================
--- stable/11/usr.sbin/traceroute6/traceroute6.8	Wed May  6 22:07:48 2020	(r360708)
+++ stable/11/usr.sbin/traceroute6/traceroute6.8	Wed May  6 22:13:08 2020	(r360709)
@@ -29,7 +29,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd May 2, 2018
+.Dd July 16, 2019
 .Dt TRACEROUTE6 8
 .Os
 .\"
@@ -172,6 +172,8 @@ Destination Unreachable - Administratively Prohibited.
 Destination Unreachable - Not a Neighbour.
 .It !A
 Destination Unreachable - Address Unreachable.
+.It !H
+Parameter Problem - Unrecognized Next Header Type.
 .It !\&
 This is printed if the hop limit is <= 1 on a port unreachable message.
 This means that the packet got to the destination,

Modified: stable/11/usr.sbin/traceroute6/traceroute6.c
==============================================================================
--- stable/11/usr.sbin/traceroute6/traceroute6.c	Wed May  6 22:07:48 2020	(r360708)
+++ stable/11/usr.sbin/traceroute6/traceroute6.c	Wed May  6 22:13:08 2020	(r360709)
@@ -307,7 +307,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
@@ -935,7 +936,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)
@@ -944,29 +945,40 @@ 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_PARAM_PROB &&
+					    code == ICMP6_PARAMPROB_NEXTHEADER) {
+						printf(" !H");
+						++got_there;
+					} else if (type == ICMP6_ECHO_REPLY) {
 						if (rcvhlim >= 0 &&
 						    rcvhlim <= 1)
 							printf(" !");
 						++got_there;
-						break;
 					}
 					break;
 				} else if (deltaT(&t1, &t2) > waittime * 1000) {
@@ -1263,11 +1275,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;
@@ -1332,10 +1343,13 @@ 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) ||
+	    (*type == ICMP6_PARAM_PROB &&
+	    *code == ICMP6_PARAMPROB_NEXTHEADER)) {
 		struct ip6_hdr *hip;
 		struct icmp6_hdr *icmp;
 		struct sctp_init_chunk *init;
@@ -1355,15 +1369,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;
@@ -1379,20 +1391,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;
@@ -1402,19 +1411,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];
@@ -1427,8 +1435,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++) {



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