From 292e18d60bec079818a43e45fc60c66e1ba5a0dd Mon Sep 17 00:00:00 2001 From: florian Date: Wed, 23 Apr 2014 09:18:27 +0000 Subject: [PATCH] Prepare merge: check AF OK benno@ --- usr.sbin/traceroute/traceroute.c | 201 ++++++++++++++++------------- usr.sbin/traceroute6/traceroute6.c | 187 +++++++++++++++------------ 2 files changed, 217 insertions(+), 171 deletions(-) diff --git a/usr.sbin/traceroute/traceroute.c b/usr.sbin/traceroute/traceroute.c index 015679761d4..378c3460af5 100644 --- a/usr.sbin/traceroute/traceroute.c +++ b/usr.sbin/traceroute/traceroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: traceroute.c,v 1.123 2014/04/23 09:20:59 florian Exp $ */ +/* $OpenBSD: traceroute.c,v 1.124 2014/04/23 09:21:41 florian Exp $ */ /* $NetBSD: traceroute.c,v 1.10 1995/05/21 15:50:45 mycroft Exp $ */ /*- @@ -527,11 +527,18 @@ main(int argc, char *argv[]) if ((error = getaddrinfo(dest, NULL, &hints, &res))) errx(1, "%s", gai_strerror(error)); - if (res->ai_addrlen != sizeof(to4)) - errx(1, "size of sockaddr mismatch"); + switch(res->ai_family) { + case AF_INET: + if (res->ai_addrlen != sizeof(to4)) + errx(1, "size of sockaddr mismatch"); - to = (struct sockaddr *)&to4; - from = (struct sockaddr *)&from4; + to = (struct sockaddr *)&to4; + from = (struct sockaddr *)&from4; + break; + default: + errx(1, "unsupported AF: %d", res->ai_family); + break; + } memcpy(to, res->ai_addr, res->ai_addrlen); @@ -559,78 +566,86 @@ main(int argc, char *argv[]) datalen = (int)l; } - switch (proto) { - case IPPROTO_UDP: - headerlen = (sizeof(struct ip) + lsrrlen + - sizeof(struct udphdr) + sizeof(struct packetdata)); - break; - case IPPROTO_ICMP: - headerlen = (sizeof(struct ip) + lsrrlen + - sizeof(struct icmp) + sizeof(struct packetdata)); - break; - default: - headerlen = (sizeof(struct ip) + lsrrlen + - sizeof(struct packetdata)); - } + switch(to->sa_family) { + case AF_INET: + switch (proto) { + case IPPROTO_UDP: + headerlen = (sizeof(struct ip) + lsrrlen + + sizeof(struct udphdr) + sizeof(struct packetdata)); + break; + case IPPROTO_ICMP: + headerlen = (sizeof(struct ip) + lsrrlen + + sizeof(struct icmp) + sizeof(struct packetdata)); + break; + default: + headerlen = (sizeof(struct ip) + lsrrlen + + sizeof(struct packetdata)); + } - if (datalen < 0 || datalen > IP_MAXPACKET - headerlen) - errx(1, "packet size must be 0 to %d.", - IP_MAXPACKET - headerlen); - - datalen += headerlen; - - if ((outpacket = calloc(1, datalen)) == NULL) - err(1, "calloc"); - - rcviov[0].iov_base = (caddr_t)packet; - rcviov[0].iov_len = sizeof(packet); - rcvmhdr.msg_name = (caddr_t)&from4; - rcvmhdr.msg_namelen = sizeof(from4); - rcvmhdr.msg_iov = rcviov; - rcvmhdr.msg_iovlen = 1; - rcvmhdr.msg_control = NULL; - rcvmhdr.msg_controllen = 0; - - ip = (struct ip *)outpacket; - if (lsrr != 0) { - u_char *p = (u_char *)(ip + 1); - - *p++ = IPOPT_NOP; - *p++ = IPOPT_LSRR; - *p++ = lsrrlen - 1; - *p++ = IPOPT_MINOFF; - gateway[lsrr] = to4.sin_addr; - for (i = 1; i <= lsrr; i++) { - memcpy(p, &gateway[i], sizeof(struct in_addr)); - p += sizeof(struct in_addr); + if (datalen < 0 || datalen > IP_MAXPACKET - headerlen) + errx(1, "packet size must be 0 to %d.", + IP_MAXPACKET - headerlen); + + datalen += headerlen; + + if ((outpacket = calloc(1, datalen)) == NULL) + err(1, "calloc"); + + rcviov[0].iov_base = (caddr_t)packet; + rcviov[0].iov_len = sizeof(packet); + rcvmhdr.msg_name = (caddr_t)&from4; + rcvmhdr.msg_namelen = sizeof(from4); + rcvmhdr.msg_iov = rcviov; + rcvmhdr.msg_iovlen = 1; + rcvmhdr.msg_control = NULL; + rcvmhdr.msg_controllen = 0; + + ip = (struct ip *)outpacket; + if (lsrr != 0) { + u_char *p = (u_char *)(ip + 1); + + *p++ = IPOPT_NOP; + *p++ = IPOPT_LSRR; + *p++ = lsrrlen - 1; + *p++ = IPOPT_MINOFF; + gateway[lsrr] = to4.sin_addr; + for (i = 1; i <= lsrr; i++) { + memcpy(p, &gateway[i], sizeof(struct in_addr)); + p += sizeof(struct in_addr); + } + ip->ip_dst = gateway[0]; + } else + ip->ip_dst = to4.sin_addr; + ip->ip_off = htons(0); + ip->ip_hl = (sizeof(struct ip) + lsrrlen) >> 2; + ip->ip_p = proto; + ip->ip_v = IPVERSION; + ip->ip_tos = tos; + + if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on, + sizeof(on)) < 0) + err(6, "IP_HDRINCL"); + + if (source) { + (void) memset(&from4, 0, sizeof(from4)); + from4.sin_family = AF_INET; + if (inet_aton(source, &from4.sin_addr) == 0) + errx(1, "unknown host %s", source); + ip->ip_src = from4.sin_addr; + if (getuid() != 0 && + (ntohl(from4.sin_addr.s_addr) & 0xff000000U) == + 0x7f000000U && (ntohl(to4.sin_addr.s_addr) & + 0xff000000U) != 0x7f000000U) + errx(1, "source is on 127/8, destination is" + " not"); + if (getuid() && bind(sndsock, (struct sockaddr *)&from4, + sizeof(from4)) < 0) + err(1, "bind"); } - ip->ip_dst = gateway[0]; - } else - ip->ip_dst = to4.sin_addr; - ip->ip_off = htons(0); - ip->ip_hl = (sizeof(struct ip) + lsrrlen) >> 2; - ip->ip_p = proto; - ip->ip_v = IPVERSION; - ip->ip_tos = tos; - - if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on, - sizeof(on)) < 0) - err(6, "IP_HDRINCL"); - - if (source) { - (void) memset(&from4, 0, sizeof(from4)); - from4.sin_family = AF_INET; - if (inet_aton(source, &from4.sin_addr) == 0) - errx(1, "unknown host %s", source); - ip->ip_src = from4.sin_addr; - if (getuid() != 0 && - (ntohl(from4.sin_addr.s_addr) & 0xff000000U) == - 0x7f000000U && (ntohl(to4.sin_addr.s_addr) & 0xff000000U) - != 0x7f000000U) - errx(1, "source is on 127/8, destination is not"); - if (getuid() && - bind(sndsock, (struct sockaddr *)&from4, sizeof(from4)) < 0) - err(1, "bind"); + break; + default: + errx(1, "unsupported AF: %d", to->sa_family); + break; } if (options & SO_DEBUG) { @@ -674,27 +689,33 @@ main(int argc, char *argv[]) /* Skip short packet */ if (i == 0) continue; - ip = (struct ip *)packet; - if (from4.sin_addr.s_addr != lastaddr) { - print(from, - cc - (ip->ip_hl << 2), - inet_ntop(AF_INET, &ip->ip_dst, - hbuf, sizeof(hbuf))); - lastaddr = from4.sin_addr.s_addr; + if (to->sa_family == AF_INET) { + ip = (struct ip *)packet; + if (from4.sin_addr.s_addr != lastaddr) { + print(from, + cc - (ip->ip_hl << 2), + inet_ntop(AF_INET, + &ip->ip_dst, hbuf, + sizeof(hbuf))); + lastaddr = + from4.sin_addr.s_addr; + } } printf(" %g ms", deltaT(&t1, &t2)); if (ttl_flag) printf(" (%u)", ip->ip_ttl); - if (i == -2) { - if (ip->ip_ttl <= 1) - printf(" !"); - ++got_there; - break; + if (to->sa_family == AF_INET) { + if (i == -2) { + if (ip->ip_ttl <= 1) + printf(" !"); + ++got_there; + break; + } + + if (tflag) + check_tos(ip); } - if (tflag) - check_tos(ip); - /* time exceeded in transit */ if (i == -1) break; diff --git a/usr.sbin/traceroute6/traceroute6.c b/usr.sbin/traceroute6/traceroute6.c index a672f6a26f9..5c56647d48c 100644 --- a/usr.sbin/traceroute6/traceroute6.c +++ b/usr.sbin/traceroute6/traceroute6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: traceroute6.c,v 1.93 2014/04/23 09:17:10 florian Exp $ */ +/* $OpenBSD: traceroute6.c,v 1.94 2014/04/23 09:18:27 florian Exp $ */ /* $KAME: traceroute6.c,v 1.63 2002/10/24 12:53:25 itojun Exp $ */ /* @@ -489,11 +489,19 @@ main(int argc, char *argv[]) hints.ai_flags = AI_CANONNAME; if ((error = getaddrinfo(*argv, NULL, &hints, &res))) errx(1, "%s", gai_strerror(error)); - if (res->ai_addrlen != sizeof(to6)) - errx(1, "size of sockaddr mismatch"); - to = (struct sockaddr *)&to6; - from = (struct sockaddr *)&from6; + switch(res->ai_family) { + case AF_INET6: + if (res->ai_addrlen != sizeof(to6)) + errx(1, "size of sockaddr mismatch"); + + to = (struct sockaddr *)&to6; + from = (struct sockaddr *)&from6; + break; + default: + errx(1, "unsupported AF: %d", res->ai_family); + break; + } memcpy(to, res->ai_addr, res->ai_addrlen); @@ -516,82 +524,93 @@ main(int argc, char *argv[]) errx(1, "datalen out of range"); datalen = (int)l; } - if (useicmp) - minlen = ICMP6ECHOLEN + sizeof(struct packetdata); - else - minlen = sizeof(struct packetdata); - if (datalen < minlen) - datalen = minlen; - else if (datalen >= MAXPACKET) - errx(1, "packet size must be %d <= s < %ld.\n", minlen, - (long)MAXPACKET); - - if ((outpacket = calloc(1, datalen)) == NULL) - err(1, "calloc"); - - /* initialize msghdr for receiving packets */ - rcviov[0].iov_base = (caddr_t)packet; - rcviov[0].iov_len = sizeof(packet); - rcvmhdr.msg_name = (caddr_t)&from6; - rcvmhdr.msg_namelen = sizeof(from6); - rcvmhdr.msg_iov = rcviov; - rcvmhdr.msg_iovlen = 1; - rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + - CMSG_SPACE(sizeof(int)); + + switch(to->sa_family) { + case AF_INET6: + if (useicmp) + minlen = ICMP6ECHOLEN + sizeof(struct packetdata); + else + minlen = sizeof(struct packetdata); + if (datalen < minlen) + datalen = minlen; + else if (datalen >= MAXPACKET) + errx(1, "packet size must be %d <= s < %ld.\n", minlen, + (long)MAXPACKET); + + if ((outpacket = calloc(1, datalen)) == NULL) + err(1, "calloc"); + + /* initialize msghdr for receiving packets */ + rcviov[0].iov_base = (caddr_t)packet; + rcviov[0].iov_len = sizeof(packet); + rcvmhdr.msg_name = (caddr_t)&from6; + rcvmhdr.msg_namelen = sizeof(from6); + rcvmhdr.msg_iov = rcviov; + rcvmhdr.msg_iovlen = 1; + rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + + CMSG_SPACE(sizeof(int)); - if ((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) - errx(1, "malloc"); - rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf; - rcvmhdr.msg_controllen = rcvcmsglen; + if ((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) + errx(1, "malloc"); + rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf; + rcvmhdr.msg_controllen = rcvcmsglen; + + /* + * Send UDP or ICMP + */ + if (useicmp) { + close(sndsock); + sndsock = rcvsock; + } - /* - * Send UDP or ICMP - */ - if (useicmp) { - close(sndsock); - sndsock = rcvsock; - } + /* + * Source selection + */ + bzero(&from6, sizeof(from6)); + if (source) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_flags = AI_NUMERICHOST; + if ((error = getaddrinfo(source, "0", &hints, &res))) + errx(1, "%s: %s", source, gai_strerror(error)); + if (res->ai_addrlen != sizeof(from6)) + errx(1, "size of sockaddr mismatch"); + memcpy(&from6, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + } else { + struct sockaddr_in6 nxt; + int dummy; + + nxt = to6; + nxt.sin6_port = htons(DUMMY_PORT); + if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) + err(1, "socket"); + if (connect(dummy, (struct sockaddr *)&nxt, + nxt.sin6_len) < 0) + err(1, "connect"); + len = sizeof(from6); + if (getsockname(dummy, (struct sockaddr *)&from6, + &len) < 0) + err(1, "getsockname"); + close(dummy); + } + + from6.sin6_port = htons(0); + if (bind(sndsock, (struct sockaddr *)&from6, from6.sin6_len) < + 0) + err(1, "bind sndsock"); - /* - * Source selection - */ - bzero(&from6, sizeof(from6)); - if (source) { - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET6; - hints.ai_socktype = SOCK_DGRAM; /*dummy*/ - hints.ai_flags = AI_NUMERICHOST; - if ((error = getaddrinfo(source, "0", &hints, &res))) - errx(1, "%s: %s", source, gai_strerror(error)); - if (res->ai_addrlen != sizeof(from6)) - errx(1, "size of sockaddr mismatch"); - memcpy(&from6, res->ai_addr, res->ai_addrlen); - freeaddrinfo(res); - } else { - struct sockaddr_in6 nxt; - int dummy; - - nxt = to6; - nxt.sin6_port = htons(DUMMY_PORT); - if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) - err(1, "socket"); - if (connect(dummy, (struct sockaddr *)&nxt, nxt.sin6_len) < 0) - err(1, "connect"); len = sizeof(from6); - if (getsockname(dummy, (struct sockaddr *)&from6, &len) < 0) + if (getsockname(sndsock, (struct sockaddr *)&from6, &len) < 0) err(1, "getsockname"); - close(dummy); + srcport = ntohs(from6.sin6_port); + break; + default: + errx(1, "unsupported AF: %d", to->sa_family); + break; } - from6.sin6_port = htons(0); - if (bind(sndsock, (struct sockaddr *)&from6, from6.sin6_len) < 0) - err(1, "bind sndsock"); - - len = sizeof(from6); - if (getsockname(sndsock, (struct sockaddr *)&from6, &len) < 0) - err(1, "getsockname"); - srcport = ntohs(from6.sin6_port); - if (options & SO_DEBUG) { (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on)); @@ -642,13 +661,19 @@ main(int argc, char *argv[]) /* Skip short packet */ if (i == 0) continue; - if (!IN6_ARE_ADDR_EQUAL(&from6.sin6_addr, - &lastaddr)) { - print(from, cc, rcvpktinfo ? inet_ntop( - AF_INET6, &rcvpktinfo->ipi6_addr, - hbuf, sizeof(hbuf)) : "?"); - lastaddr = from6.sin6_addr; - } + if (to->sa_family == AF_INET6) { + if (!IN6_ARE_ADDR_EQUAL( + &from6.sin6_addr, &lastaddr)) { + print(from, cc, rcvpktinfo ? + inet_ntop( AF_INET6, + &rcvpktinfo->ipi6_addr, + hbuf, sizeof(hbuf)) : "?"); + lastaddr = from6.sin6_addr; + } + } else + errx(1, "unsupported AF: %d", + to->sa_family); + printf(" %g ms", deltaT(&t1, &t2)); if (ttl_flag) printf(" (%u)", rcvhlim); -- 2.20.1