summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2009-08-23 17:00:16 +0000
committerume <ume@FreeBSD.org>2009-08-23 17:00:16 +0000
commite9fb7bf28d0712b4366f9f39010c865c03853ac6 (patch)
treeed9630d75b8bf64e28c5ab5abefdd3666898f3d8
parent5868b7c961bb6a513bde2e133aaeae679b9cb648 (diff)
downloadFreeBSD-src-e9fb7bf28d0712b4366f9f39010c865c03853ac6.zip
FreeBSD-src-e9fb7bf28d0712b4366f9f39010c865c03853ac6.tar.gz
- Add AS lookup functionality to traceroute6(8) as well.
- Support for IPv6 transport for AS lookup. - Introduce $RA_SERVER to set whois server. - Support for 4 byte ASN. - ANSIfy function declaration in as.c. Tested by: IHANet folks.
-rw-r--r--contrib/traceroute/as.c84
-rw-r--r--contrib/traceroute/as.h6
-rw-r--r--contrib/traceroute/traceroute.c10
-rw-r--r--usr.sbin/traceroute6/Makefile5
-rw-r--r--usr.sbin/traceroute6/traceroute6.811
-rw-r--r--usr.sbin/traceroute6/traceroute6.c29
6 files changed, 86 insertions, 59 deletions
diff --git a/contrib/traceroute/as.c b/contrib/traceroute/as.c
index abb6c71..689848a 100644
--- a/contrib/traceroute/as.c
+++ b/contrib/traceroute/as.c
@@ -63,55 +63,42 @@ struct aslookup {
};
void *
-as_setup(server)
- char *server;
+as_setup(char *server)
{
struct aslookup *asn;
- struct hostent *he = NULL;
- struct servent *se;
- struct sockaddr_in in;
+ struct addrinfo hints, *res0, *res;
FILE *f;
- int s;
+ int s, error;
if (server == NULL)
+ server = getenv("RA_SERVER");
+ 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) {
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ error = getaddrinfo(server, "whois", &hints, &res0);
+ if (error == EAI_SERVICE) {
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);
+ error = getaddrinfo(server, "43", &hints, &res0);
}
-
- if ((s = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
- warn("socket");
+ if (error != 0) {
+ warnx("%s: %s", server, gai_strerror(error));
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)
+ for (res = res0; res; res = res->ai_next) {
+ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (s < 0)
+ continue;
+ if (connect(s, res->ai_addr, res->ai_addrlen) >= 0)
break;
- if (he == NULL || he->h_addr == NULL) {
- close(s);
- s = -1;
- break;
- }
- } while (1);
-
- if (s == -1) {
+ close(s);
+ s = -1;
+ }
+ freeaddrinfo(res0);
+ if (s < 0) {
warn("connect");
return (NULL);
}
@@ -137,23 +124,23 @@ as_setup(server)
return (asn);
}
-int
-as_lookup(_asn, addr)
- void *_asn;
- struct in_addr *addr;
+unsigned int
+as_lookup(void *_asn, char *addr, sa_family_t family)
{
struct aslookup *asn = _asn;
char buf[1024];
- int as, rc, dlen;
+ unsigned int as;
+ int rc, dlen, plen;
- as = rc = dlen = 0;
- (void)fprintf(asn->as_f, "!r%s/32,l\n", inet_ntoa(*addr));
+ as = 0;
+ rc = dlen = 0;
+ plen = (family == AF_INET6) ? 128 : 32;
+ (void)fprintf(asn->as_f, "!r%s/%d,l\n", addr, plen);
(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)fprintf(asn->as_debug, ">> !r%s/%d,l\n", addr, plen);
(void)fflush(asn->as_debug);
}
#endif /* AS_DEBUG_FILE */
@@ -182,7 +169,7 @@ as_lookup(_asn, addr)
}
#endif /* AS_DEBUG_FILE */
break;
- case 'C':
+ case 'C':
case 'D':
case 'E':
case 'F':
@@ -209,7 +196,7 @@ as_lookup(_asn, addr)
/* origin line is the interesting bit */
if (as == 0 && strncasecmp(buf, "origin:", 7) == 0) {
- sscanf(buf + 7, " AS%d", &as);
+ sscanf(buf + 7, " AS%u", &as);
#ifdef AS_DEBUG_FILE
if (asn->as_debug) {
(void)fprintf(asn->as_debug, "as: %d\n", as);
@@ -223,8 +210,7 @@ as_lookup(_asn, addr)
}
void
-as_shutdown(_asn)
- void *_asn;
+as_shutdown(void *_asn)
{
struct aslookup *asn = _asn;
diff --git a/contrib/traceroute/as.h b/contrib/traceroute/as.h
index 5ed563d..3b7d3a6 100644
--- a/contrib/traceroute/as.h
+++ b/contrib/traceroute/as.h
@@ -37,6 +37,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-void *as_setup __P((char *));
-int as_lookup __P((void *, struct in_addr *));
-void as_shutdown __P((void *));
+void *as_setup(char *);
+unsigned int as_lookup(void *, char *, sa_family_t);
+void as_shutdown(void *);
diff --git a/contrib/traceroute/traceroute.c b/contrib/traceroute/traceroute.c
index a4bce61..120d1cd 100644
--- a/contrib/traceroute/traceroute.c
+++ b/contrib/traceroute/traceroute.c
@@ -1477,19 +1477,21 @@ print(register u_char *buf, register int cc, register struct sockaddr_in *from)
{
register struct ip *ip;
register int hlen;
+ char addr[INET_ADDRSTRLEN];
ip = (struct ip *) buf;
hlen = ip->ip_hl << 2;
cc -= hlen;
+ strlcpy(addr, inet_ntoa(from->sin_addr), sizeof(addr));
+
if (as_path)
- Printf(" [AS%d]", as_lookup(asn, &from->sin_addr));
+ Printf(" [AS%u]", as_lookup(asn, addr, AF_INET));
if (nflag)
- Printf(" %s", inet_ntoa(from->sin_addr));
+ Printf(" %s", addr);
else
- Printf(" %s (%s)", inetname(from->sin_addr),
- inet_ntoa(from->sin_addr));
+ Printf(" %s (%s)", inetname(from->sin_addr), addr);
if (verbose)
Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
diff --git a/usr.sbin/traceroute6/Makefile b/usr.sbin/traceroute6/Makefile
index 6ff72d2..60618a2 100644
--- a/usr.sbin/traceroute6/Makefile
+++ b/usr.sbin/traceroute6/Makefile
@@ -13,12 +13,17 @@
# A PARTICULAR PURPOSE.
# $FreeBSD$
+TRACEROUTE_DISTDIR?= ${.CURDIR}/../../contrib/traceroute
+.PATH: ${TRACEROUTE_DISTDIR}
+
PROG= traceroute6
MAN= traceroute6.8
+SRCS= as.c traceroute6.c
BINOWN= root
BINMODE= 4555
CFLAGS+= -DIPSEC -DUSE_RFC2292BIS -DHAVE_POLL
+CFLAGS+= -I${.CURDIR} -I${TRACEROUTE_DISTDIR} -I.
DPADD= ${LIBIPSEC}
LDADD= -lipsec
diff --git a/usr.sbin/traceroute6/traceroute6.8 b/usr.sbin/traceroute6/traceroute6.8
index b6116f0..884ad6d 100644
--- a/usr.sbin/traceroute6/traceroute6.8
+++ b/usr.sbin/traceroute6/traceroute6.8
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 17, 1998
+.Dd August 24, 2009
.Dt TRACEROUTE6 8
.Os
.\"
@@ -40,7 +40,7 @@
.Sh SYNOPSIS
.Nm
.Bk -words
-.Op Fl dIlnNrvU
+.Op Fl adIlnNrvU
.Ek
.Bk -words
.Op Fl f Ar firsthop
@@ -64,6 +64,9 @@
.Op Fl w Ar waittime
.Ek
.Bk -words
+.Op Fl A Ar as_server
+.Ek
+.Bk -words
.Ar target
.Op Ar datalen
.Ek
@@ -84,6 +87,10 @@ after the destination host name.
.Pp
Other options are:
.Bl -tag -width Ds
+.It Fl a
+Turn on AS# lookups for each hop encountered.
+.It Fl A Ar as_server
+Turn on AS# lookups and use the given server instead of the default.
.It Fl d
Debug mode.
.It Fl f Ar firsthop
diff --git a/usr.sbin/traceroute6/traceroute6.c b/usr.sbin/traceroute6/traceroute6.c
index d06502f..699af68 100644
--- a/usr.sbin/traceroute6/traceroute6.c
+++ b/usr.sbin/traceroute6/traceroute6.c
@@ -282,6 +282,8 @@ static const char rcsid[] =
#include <netipsec/ipsec.h>
#endif
+#include "as.h"
+
#define DUMMY_PORT 10010
#define MAXPACKET 65535 /* max ip packet size */
@@ -359,6 +361,9 @@ int waittime = 5; /* time to wait for response (in seconds) */
int nflag; /* print addresses numerically */
int useproto = IPPROTO_UDP; /* protocol to use to send packet */
int lflag; /* print both numerical address & hostname */
+int as_path; /* print as numbers for each hop */
+char *as_server = NULL;
+void *asn;
int
main(argc, argv)
@@ -411,8 +416,15 @@ main(argc, argv)
seq = 0;
- while ((ch = getopt(argc, argv, "df:g:Ilm:nNp:q:rs:Uvw:")) != -1)
+ while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:Uvw:")) != -1)
switch (ch) {
+ case 'a':
+ as_path = 1;
+ break;
+ case 'A':
+ as_path = 1;
+ as_server = optarg;
+ break;
case 'd':
options |= SO_DEBUG;
break;
@@ -867,6 +879,17 @@ main(argc, argv)
srcport = ntohs(Src.sin6_port);
}
+ if (as_path) {
+ asn = as_setup(as_server);
+ if (asn == NULL) {
+ fprintf(stderr,
+ "traceroute6: as_setup failed, AS# lookups"
+ " disabled\n");
+ (void)fflush(stderr);
+ as_path = 0;
+ }
+ }
+
/*
* Message to users
*/
@@ -948,6 +971,8 @@ main(argc, argv)
exit(0);
}
}
+ if (as_path)
+ as_shutdown(asn);
exit(0);
}
@@ -1361,6 +1386,8 @@ print(mhdr, cc)
if (getnameinfo((struct sockaddr *)from, from->sin6_len,
hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
strlcpy(hbuf, "invalid", sizeof(hbuf));
+ if (as_path)
+ printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6));
if (nflag)
printf(" %s", hbuf);
else if (lflag)
OpenPOWER on IntegriCloud