From 087b61e2cc33bf96aaf4db9f60a0e21d93c079a6 Mon Sep 17 00:00:00 2001 From: tuexen Date: Tue, 16 Jul 2019 12:38:17 +0000 Subject: [PATCH] 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 after: 2 weeks --- usr.sbin/traceroute6/traceroute6.c | 90 +++++++++++++++--------------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/usr.sbin/traceroute6/traceroute6.c b/usr.sbin/traceroute6/traceroute6.c index e7de974ae79..f8de981cec0 100644 --- a/usr.sbin/traceroute6/traceroute6.c +++ b/usr.sbin/traceroute6/traceroute6.c @@ -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); @@ -367,6 +367,7 @@ main(int argc, char *argv[]) struct hostent *hp; size_t size, minlen; uid_t uid; + u_char type, code; /* * Receive ICMP @@ -937,7 +938,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) @@ -946,29 +947,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) { @@ -1265,11 +1273,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; @@ -1334,10 +1341,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; @@ -1357,15 +1365,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; @@ -1381,20 +1387,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; @@ -1404,19 +1407,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]; @@ -1429,8 +1431,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++) { -- 2.45.0