- 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.
This commit is contained in:
Hajimu UMEMOTO 2009-08-23 17:00:16 +00:00
parent 2f1ff7669c
commit d429d7201e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=196475
6 changed files with 87 additions and 60 deletions

View File

@ -63,55 +63,42 @@ struct aslookup {
}; };
void * void *
as_setup(server) as_setup(char *server)
char *server;
{ {
struct aslookup *asn; struct aslookup *asn;
struct hostent *he = NULL; struct addrinfo hints, *res0, *res;
struct servent *se;
struct sockaddr_in in;
FILE *f; FILE *f;
int s; int s, error;
if (server == NULL)
server = getenv("RA_SERVER");
if (server == NULL) if (server == NULL)
server = DEFAULT_AS_SERVER; server = DEFAULT_AS_SERVER;
(void)memset(&in, 0, sizeof(in)); memset(&hints, 0, sizeof(hints));
in.sin_family = AF_INET; hints.ai_family = PF_UNSPEC;
in.sin_len = sizeof(in); hints.ai_socktype = SOCK_STREAM;
if ((se = getservbyname("whois", "tcp")) == NULL) { error = getaddrinfo(server, "whois", &hints, &res0);
if (error == EAI_SERVICE) {
warnx("warning: whois/tcp service not found"); warnx("warning: whois/tcp service not found");
in.sin_port = ntohs(43); error = getaddrinfo(server, "43", &hints, &res0);
} else }
in.sin_port = se->s_port; if (error != 0) {
warnx("%s: %s", server, gai_strerror(error));
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); return (NULL);
} }
if ((s = socket(PF_INET, SOCK_STREAM, 0)) == -1) { for (res = res0; res; res = res->ai_next) {
warn("socket"); s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
return (NULL); if (s < 0)
continue;
if (connect(s, res->ai_addr, res->ai_addrlen) >= 0)
break;
close(s);
s = -1;
} }
freeaddrinfo(res0);
do { if (s < 0) {
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"); warn("connect");
return (NULL); return (NULL);
} }
@ -137,23 +124,23 @@ as_setup(server)
return (asn); return (asn);
} }
int unsigned int
as_lookup(_asn, addr) as_lookup(void *_asn, char *addr, sa_family_t family)
void *_asn;
struct in_addr *addr;
{ {
struct aslookup *asn = _asn; struct aslookup *asn = _asn;
char buf[1024]; char buf[1024];
int as, rc, dlen; unsigned int as;
int rc, dlen, plen;
as = rc = dlen = 0; as = 0;
(void)fprintf(asn->as_f, "!r%s/32,l\n", inet_ntoa(*addr)); 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); (void)fflush(asn->as_f);
#ifdef AS_DEBUG_FILE #ifdef AS_DEBUG_FILE
if (asn->as_debug) { if (asn->as_debug) {
(void)fprintf(asn->as_debug, ">> !r%s/32,l\n", (void)fprintf(asn->as_debug, ">> !r%s/%d,l\n", addr, plen);
inet_ntoa(*addr));
(void)fflush(asn->as_debug); (void)fflush(asn->as_debug);
} }
#endif /* AS_DEBUG_FILE */ #endif /* AS_DEBUG_FILE */
@ -182,7 +169,7 @@ as_lookup(_asn, addr)
} }
#endif /* AS_DEBUG_FILE */ #endif /* AS_DEBUG_FILE */
break; break;
case 'C': case 'C':
case 'D': case 'D':
case 'E': case 'E':
case 'F': case 'F':
@ -209,7 +196,7 @@ as_lookup(_asn, addr)
/* origin line is the interesting bit */ /* origin line is the interesting bit */
if (as == 0 && strncasecmp(buf, "origin:", 7) == 0) { if (as == 0 && strncasecmp(buf, "origin:", 7) == 0) {
sscanf(buf + 7, " AS%d", &as); sscanf(buf + 7, " AS%u", &as);
#ifdef AS_DEBUG_FILE #ifdef AS_DEBUG_FILE
if (asn->as_debug) { if (asn->as_debug) {
(void)fprintf(asn->as_debug, "as: %d\n", as); (void)fprintf(asn->as_debug, "as: %d\n", as);
@ -223,8 +210,7 @@ as_lookup(_asn, addr)
} }
void void
as_shutdown(_asn) as_shutdown(void *_asn)
void *_asn;
{ {
struct aslookup *asn = _asn; struct aslookup *asn = _asn;

View File

@ -37,6 +37,6 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
void *as_setup __P((char *)); void *as_setup(char *);
int as_lookup __P((void *, struct in_addr *)); unsigned int as_lookup(void *, char *, sa_family_t);
void as_shutdown __P((void *)); void as_shutdown(void *);

View File

@ -1477,19 +1477,21 @@ print(register u_char *buf, register int cc, register struct sockaddr_in *from)
{ {
register struct ip *ip; register struct ip *ip;
register int hlen; register int hlen;
char addr[INET_ADDRSTRLEN];
ip = (struct ip *) buf; ip = (struct ip *) buf;
hlen = ip->ip_hl << 2; hlen = ip->ip_hl << 2;
cc -= hlen; cc -= hlen;
strlcpy(addr, inet_ntoa(from->sin_addr), sizeof(addr));
if (as_path) if (as_path)
Printf(" [AS%d]", as_lookup(asn, &from->sin_addr)); Printf(" [AS%u]", as_lookup(asn, addr, AF_INET));
if (nflag) if (nflag)
Printf(" %s", inet_ntoa(from->sin_addr)); Printf(" %s", addr);
else else
Printf(" %s (%s)", inetname(from->sin_addr), Printf(" %s (%s)", inetname(from->sin_addr), addr);
inet_ntoa(from->sin_addr));
if (verbose) if (verbose)
Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst)); Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));

View File

@ -13,12 +13,17 @@
# A PARTICULAR PURPOSE. # A PARTICULAR PURPOSE.
# $FreeBSD$ # $FreeBSD$
TRACEROUTE_DISTDIR?= ${.CURDIR}/../../contrib/traceroute
.PATH: ${TRACEROUTE_DISTDIR}
PROG= traceroute6 PROG= traceroute6
MAN= traceroute6.8 MAN= traceroute6.8
SRCS= as.c traceroute6.c
BINOWN= root BINOWN= root
BINMODE= 4555 BINMODE= 4555
CFLAGS+= -DIPSEC -DUSE_RFC2292BIS -DHAVE_POLL CFLAGS+= -DIPSEC -DUSE_RFC2292BIS -DHAVE_POLL
CFLAGS+= -I${.CURDIR} -I${TRACEROUTE_DISTDIR} -I.
DPADD= ${LIBIPSEC} DPADD= ${LIBIPSEC}
LDADD= -lipsec LDADD= -lipsec

View File

@ -29,7 +29,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd May 17, 1998 .Dd August 24, 2009
.Dt TRACEROUTE6 8 .Dt TRACEROUTE6 8
.Os .Os
.\" .\"
@ -40,7 +40,7 @@
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Bk -words .Bk -words
.Op Fl dIlnNrvU .Op Fl adIlnNrvU
.Ek .Ek
.Bk -words .Bk -words
.Op Fl f Ar firsthop .Op Fl f Ar firsthop
@ -64,6 +64,9 @@
.Op Fl w Ar waittime .Op Fl w Ar waittime
.Ek .Ek
.Bk -words .Bk -words
.Op Fl A Ar as_server
.Ek
.Bk -words
.Ar target .Ar target
.Op Ar datalen .Op Ar datalen
.Ek .Ek
@ -84,6 +87,10 @@ after the destination host name.
.Pp .Pp
Other options are: Other options are:
.Bl -tag -width Ds .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 .It Fl d
Debug mode. Debug mode.
.It Fl f Ar firsthop .It Fl f Ar firsthop

View File

@ -282,6 +282,8 @@ static const char rcsid[] =
#include <netipsec/ipsec.h> #include <netipsec/ipsec.h>
#endif #endif
#include "as.h"
#define DUMMY_PORT 10010 #define DUMMY_PORT 10010
#define MAXPACKET 65535 /* max ip packet size */ #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 nflag; /* print addresses numerically */
int useproto = IPPROTO_UDP; /* protocol to use to send packet */ int useproto = IPPROTO_UDP; /* protocol to use to send packet */
int lflag; /* print both numerical address & hostname */ int lflag; /* print both numerical address & hostname */
int as_path; /* print as numbers for each hop */
char *as_server = NULL;
void *asn;
int int
main(argc, argv) main(argc, argv)
@ -411,8 +416,15 @@ main(argc, argv)
seq = 0; 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) { switch (ch) {
case 'a':
as_path = 1;
break;
case 'A':
as_path = 1;
as_server = optarg;
break;
case 'd': case 'd':
options |= SO_DEBUG; options |= SO_DEBUG;
break; break;
@ -867,6 +879,17 @@ main(argc, argv)
srcport = ntohs(Src.sin6_port); 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 * Message to users
*/ */
@ -948,6 +971,8 @@ main(argc, argv)
exit(0); exit(0);
} }
} }
if (as_path)
as_shutdown(asn);
exit(0); exit(0);
} }
@ -1361,6 +1386,8 @@ print(mhdr, cc)
if (getnameinfo((struct sockaddr *)from, from->sin6_len, if (getnameinfo((struct sockaddr *)from, from->sin6_len,
hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
strlcpy(hbuf, "invalid", sizeof(hbuf)); strlcpy(hbuf, "invalid", sizeof(hbuf));
if (as_path)
printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6));
if (nflag) if (nflag)
printf(" %s", hbuf); printf(" %s", hbuf);
else if (lflag) else if (lflag)