From 7830eb4db6081a631f0740b7c9bd27a0b709af14 Mon Sep 17 00:00:00 2001 From: david Date: Sat, 6 Oct 2012 21:26:31 +0000 Subject: [PATCH] Support IPv6 UDP traceroute. --- traceroute.cc | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/traceroute.cc b/traceroute.cc index d0351c248..0d4778e11 100644 --- a/traceroute.cc +++ b/traceroute.cc @@ -559,7 +559,7 @@ struct probespec HostState::get_probe(const Target *target) { (probe.type == PS_TCP || probe.type == PS_UDP || probe.type == PS_SCTP || probe.type == PS_ICMP)) { /* Nothing needed. */ } else if (target->af() == AF_INET6 && - (probe.type == PS_TCP || probe.type == PS_ICMPV6)) { + (probe.type == PS_TCP || probe.type == PS_UDP || probe.type == PS_ICMPV6)) { /* Nothing needed. */ } else if (target->af() == AF_INET && probe.type == PS_PROTO) { /* If this is an IP protocol probe, fill in some fields for some common @@ -744,18 +744,25 @@ public: unsigned char *build_packet(const struct sockaddr_storage *source, u32 *len) const { const char *payload; size_t payload_length; - const struct sockaddr_in *sin; - - assert(source->ss_family == AF_INET); - sin = (struct sockaddr_in *) source; payload = get_udp_payload(pspec.pd.udp.dport, &payload_length); /* For UDP we encode the token in the source port. */ - return build_udp_raw(&sin->sin_addr, host->target->v4hostip(), ttl, - get_random_u16(), get_random_u8(), false, NULL, 0, - token ^ global_id, pspec.pd.udp.dport, - payload, payload_length, len); + if (source->ss_family == AF_INET) { + const struct sockaddr_in *sin = (struct sockaddr_in *) source; + return build_udp_raw(&sin->sin_addr, host->target->v4hostip(), ttl, + get_random_u16(), get_random_u8(), false, NULL, 0, + token ^ global_id, pspec.pd.udp.dport, + payload, payload_length, len); + } else if (source->ss_family == AF_INET6) { + const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) source; + return build_udp_raw_ipv6(&sin6->sin6_addr, host->target->v6hostip(), + 0, 0, ttl, + token ^ global_id, pspec.pd.udp.dport, + payload, payload_length, len); + } else { + fatal("Unknown address family %u in %s.", source->ss_family, __func__); + } } };