- 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
6 changed files with 87 additions and 60 deletions

View File

@ -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));
error = getaddrinfo(server, "43", &hints, &res0);
}
if (error != 0) {
warnx("%s: %s", server, gai_strerror(error));
return (NULL);
}
if ((s = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
warn("socket");
return (NULL);
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;
close(s);
s = -1;
}
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) {
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;

View File

@ -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 *);

View File

@ -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));

View File

@ -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

View File

@ -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

View File

@ -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)