diff options
-rw-r--r-- | contrib/traceroute/as.c | 242 | ||||
-rw-r--r-- | contrib/traceroute/as.h | 42 | ||||
-rw-r--r-- | contrib/traceroute/traceroute.8 | 18 | ||||
-rw-r--r-- | contrib/traceroute/traceroute.c | 35 | ||||
-rw-r--r-- | usr.sbin/traceroute/Makefile | 2 |
5 files changed, 332 insertions, 7 deletions
diff --git a/contrib/traceroute/as.c b/contrib/traceroute/as.c new file mode 100644 index 0000000..abb6c71 --- /dev/null +++ b/contrib/traceroute/as.c @@ -0,0 +1,242 @@ +/* $FreeBSD$ */ +/* $NetBSD: as.c,v 1.1 2001/11/04 23:14:36 atatat Exp $ */ + +/* + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andrew Brown. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <err.h> +#include <stdio.h> + +#include "as.h" + +#define DEFAULT_AS_SERVER "whois.radb.net" +#undef AS_DEBUG_FILE + +struct aslookup { + FILE *as_f; +#ifdef AS_DEBUG_FILE + FILE *as_debug; +#endif /* AS_DEBUG_FILE */ +}; + +void * +as_setup(server) + char *server; +{ + struct aslookup *asn; + struct hostent *he = NULL; + struct servent *se; + struct sockaddr_in in; + FILE *f; + int s; + + if (server == NULL) + server = DEFAULT_AS_SERVER; + + (void)memset(&in, 0, sizeof(in)); + in.sin_family = AF_INET; + in.sin_len = sizeof(in); + if ((se = getservbyname("whois", "tcp")) == NULL) { + warnx("warning: whois/tcp service not found"); + in.sin_port = ntohs(43); + } else + in.sin_port = se->s_port; + + if (inet_aton(server, &in.sin_addr) == 0 && + ((he = gethostbyname(server)) == NULL || + he->h_addr == NULL)) { + warnx("%s: %s", server, hstrerror(h_errno)); + return (NULL); + } + + if ((s = socket(PF_INET, SOCK_STREAM, 0)) == -1) { + warn("socket"); + return (NULL); + } + + do { + if (he != NULL) { + memcpy(&in.sin_addr, he->h_addr, he->h_length); + he->h_addr_list++; + } + if (connect(s, (struct sockaddr *)&in, sizeof(in)) == 0) + break; + if (he == NULL || he->h_addr == NULL) { + close(s); + s = -1; + break; + } + } while (1); + + if (s == -1) { + warn("connect"); + return (NULL); + } + + f = fdopen(s, "r+"); + (void)fprintf(f, "!!\n"); + (void)fflush(f); + + asn = malloc(sizeof(struct aslookup)); + if (asn == NULL) + (void)fclose(f); + else + asn->as_f = f; + +#ifdef AS_DEBUG_FILE + asn->as_debug = fopen(AS_DEBUG_FILE, "w"); + if (asn->as_debug) { + (void)fprintf(asn->as_debug, ">> !!\n"); + (void)fflush(asn->as_debug); + } +#endif /* AS_DEBUG_FILE */ + + return (asn); +} + +int +as_lookup(_asn, addr) + void *_asn; + struct in_addr *addr; +{ + struct aslookup *asn = _asn; + char buf[1024]; + int as, rc, dlen; + + as = rc = dlen = 0; + (void)fprintf(asn->as_f, "!r%s/32,l\n", inet_ntoa(*addr)); + (void)fflush(asn->as_f); + +#ifdef AS_DEBUG_FILE + if (asn->as_debug) { + (void)fprintf(asn->as_debug, ">> !r%s/32,l\n", + inet_ntoa(*addr)); + (void)fflush(asn->as_debug); + } +#endif /* AS_DEBUG_FILE */ + + while (fgets(buf, sizeof(buf), asn->as_f) != NULL) { + buf[sizeof(buf) - 1] = '\0'; + +#ifdef AS_DEBUG_FILE + if (asn->as_debug) { + (void)fprintf(asn->as_debug, "<< %s", buf); + (void)fflush(asn->as_debug); + } +#endif /* AS_DEBUG_FILE */ + + if (rc == 0) { + rc = buf[0]; + switch (rc) { + case 'A': + /* A - followed by # bytes of answer */ + sscanf(buf, "A%d\n", &dlen); +#ifdef AS_DEBUG_FILE + if (asn->as_debug) { + (void)fprintf(asn->as_debug, + "dlen: %d\n", dlen); + (void)fflush(asn->as_debug); + } +#endif /* AS_DEBUG_FILE */ + break; + case 'C': + case 'D': + case 'E': + case 'F': + /* C - no data returned */ + /* D - key not found */ + /* E - multiple copies of key */ + /* F - some other error */ + break; + } + if (rc == 'A') + /* skip to next input line */ + continue; + } + + if (dlen == 0) + /* out of data, next char read is end code */ + rc = buf[0]; + if (rc != 'A') + /* either an error off the bat, or a done code */ + break; + + /* data received, thank you */ + dlen -= strlen(buf); + + /* origin line is the interesting bit */ + if (as == 0 && strncasecmp(buf, "origin:", 7) == 0) { + sscanf(buf + 7, " AS%d", &as); +#ifdef AS_DEBUG_FILE + if (asn->as_debug) { + (void)fprintf(asn->as_debug, "as: %d\n", as); + (void)fflush(asn->as_debug); + } +#endif /* AS_DEBUG_FILE */ + } + } + + return (as); +} + +void +as_shutdown(_asn) + void *_asn; +{ + struct aslookup *asn = _asn; + + (void)fprintf(asn->as_f, "!q\n"); + (void)fclose(asn->as_f); + +#ifdef AS_DEBUG_FILE + if (asn->as_debug) { + (void)fprintf(asn->as_debug, ">> !q\n"); + (void)fclose(asn->as_debug); + } +#endif /* AS_DEBUG_FILE */ + + free(asn); +} diff --git a/contrib/traceroute/as.h b/contrib/traceroute/as.h new file mode 100644 index 0000000..5ed563d --- /dev/null +++ b/contrib/traceroute/as.h @@ -0,0 +1,42 @@ +/* $FreeBSD$ */ +/* $NetBSD: as.h,v 1.1 2001/11/04 23:14:36 atatat Exp $ */ + +/* + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andrew Brown. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +void *as_setup __P((char *)); +int as_lookup __P((void *, struct in_addr *)); +void as_shutdown __P((void *)); diff --git a/contrib/traceroute/traceroute.8 b/contrib/traceroute/traceroute.8 index de3b7de..9d54bc6 100644 --- a/contrib/traceroute/traceroute.8 +++ b/contrib/traceroute/traceroute.8 @@ -16,7 +16,7 @@ .\" $Id: traceroute.8,v 1.19 2000/09/21 08:44:19 leres Exp $ .\" $FreeBSD$ .\" -.TH TRACEROUTE 8 "21 September 2000" +.TH TRACEROUTE 8 "19 February 2008" .UC 6 .SH NAME traceroute \- print the route packets take to network host @@ -24,7 +24,7 @@ traceroute \- print the route packets take to network host .na .B traceroute [ -.B \-dDeFISnrvx +.B \-adDeFISnrvx ] [ .B \-f .I first_ttl @@ -71,6 +71,9 @@ traceroute \- print the route packets take to network host .B \-w .I waittime ] [ +.B \-A +.I as_server +] [ .B \-z .I pausemsecs ] @@ -98,6 +101,13 @@ name. .PP Other options are: .TP +.B \-a +Turn on AS# lookups for each hop encountered. +.TP +.B -A +Turn on AS# lookups and use the given server instead of the +default. +.TP .B \-e Firewall evasion mode. Use fixed destination ports for UDP and TCP probes. @@ -443,3 +453,7 @@ should listen for a RST from the destination host (or an intermediate router that's filtering packets), but this is not implemented yet. .PP Please send bug reports to traceroute@ee.lbl.gov. +.PP +The AS number capability reports information that may sometimes be +inaccurate due to discrepancies between the contents of the +routing database server and the current state of the Internet. diff --git a/contrib/traceroute/traceroute.c b/contrib/traceroute/traceroute.c index 5a9e8d2..a4bce61 100644 --- a/contrib/traceroute/traceroute.c +++ b/contrib/traceroute/traceroute.c @@ -263,6 +263,7 @@ static const char rcsid[] = #include "findsaddr.h" #include "ifaddrlist.h" +#include "as.h" #include "traceroute.h" /* Maximum number of gateways (include room for one noop) */ @@ -350,6 +351,9 @@ int options; /* socket options */ int verbose; int waittime = 5; /* time to wait for response (in seconds) */ int nflag; /* print addresses numerically */ +int as_path; /* print as numbers for each hop */ +char *as_server = NULL; +void *asn; #ifdef CANT_HACK_IPCKSUM int doipcksum = 0; /* don't calculate ip checksums by default */ #else @@ -535,9 +539,17 @@ main(int argc, char **argv) prog = argv[0]; opterr = 0; - while ((op = getopt(argc, argv, "edDFInrSvxf:g:i:M:m:P:p:q:s:t:w:z:")) != EOF) + while ((op = getopt(argc, argv, "aA:edDFInrSvxf:g:i:M:m:P:p:q:s:t:w:z:")) != EOF) switch (op) { - + case 'a': + as_path = 1; + break; + + case 'A': + as_path = 1; + as_server = optarg; + break; + case 'd': options |= SO_DEBUG; break; @@ -913,6 +925,16 @@ main(int argc, char **argv) exit (1); } + if (as_path) { + asn = as_setup(as_server); + if (asn == NULL) { + Fprintf(stderr, "%s: as_setup failed, AS# lookups" + " disabled\n", prog); + (void)fflush(stderr); + as_path = 0; + } + } + #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) if (setpolicy(sndsock, "in bypass") < 0) errx(1, "%s", ipsec_strerror()); @@ -1118,6 +1140,8 @@ main(int argc, char **argv) (unreachable > 0 && unreachable >= nprobes - 1)) break; } + if (as_path) + as_shutdown(asn); exit(0); } @@ -1458,6 +1482,9 @@ print(register u_char *buf, register int cc, register struct sockaddr_in *from) hlen = ip->ip_hl << 2; cc -= hlen; + if (as_path) + Printf(" [AS%d]", as_lookup(asn, &from->sin_addr)); + if (nflag) Printf(" %s", inet_ntoa(from->sin_addr)); else @@ -1764,8 +1791,8 @@ usage(void) Fprintf(stderr, "Version %s\n", version); Fprintf(stderr, - "Usage: %s [-dDeFInrSvx] [-f first_ttl] [-g gateway] [-i iface]\n" + "Usage: %s [-adDeFInrSvx] [-f first_ttl] [-g gateway] [-i iface]\n" "\t[-m max_ttl] [-p port] [-P proto] [-q nqueries] [-s src_addr]\n" - "\t[-t tos] [-w waittime] [-z pausemsecs] host [packetlen]\n", prog); + "\t[-t tos] [-w waittime] [-A as_server] [-z pausemsecs] host [packetlen]\n", prog); exit(1); } diff --git a/usr.sbin/traceroute/Makefile b/usr.sbin/traceroute/Makefile index 8b941e5..489c862 100644 --- a/usr.sbin/traceroute/Makefile +++ b/usr.sbin/traceroute/Makefile @@ -5,7 +5,7 @@ TRACEROUTE_DISTDIR?= ${.CURDIR}/../../contrib/traceroute PROG= traceroute MAN= traceroute.8 -SRCS= version.c traceroute.c ifaddrlist.c findsaddr-socket.c +SRCS= as.c version.c traceroute.c ifaddrlist.c findsaddr-socket.c BINOWN= root BINMODE=4555 CLEANFILES= version.c |