-/* $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 $ */
/*-
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);
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) {
/* 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;
-/* $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 $ */
/*
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);
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));
/* 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);