tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

traceroute6 -a diff



Hello list,

Attached is a patch that implements -a (AS lookups) for traceroute6,
which already exists for traceroute, but is missing in traceroute6.
As of recently I enjoy having native ipv6 on one of my servers.
The patch is based on the FreeBSD traceroute6 implementation
and is against NetBSD-5.1.

Please have a look.

Zafer.
Index: traceroute/as.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/traceroute/as.c,v
retrieving revision 1.2
diff -u -r1.2 as.c
--- traceroute/as.c     28 Apr 2008 20:24:17 -0000      1.2
+++ traceroute/as.c     10 May 2011 00:28:03 -0000
@@ -55,55 +55,44 @@
 };
 
 void *
-as_setup(server)
-       char *server;
+as_setup(const 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;
 
+       s = -1;
+       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)
-                       break;
-               if (he == NULL || he->h_addr == NULL) {
-                       close(s);
-                       s = -1;
+       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;
-               }
-       } while (1);
-
-       if (s == -1) {
+               close(s);
+               s = -1;
+       }
+       freeaddrinfo(res0);
+       if (s < 0) {
                warn("connect");
                return (NULL);
        }
@@ -129,23 +118,23 @@
        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 */
@@ -201,7 +190,7 @@
 
                /* 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);
@@ -215,8 +204,7 @@
 }
 
 void
-as_shutdown(_asn)
-       void *_asn;
+as_shutdown(void *_asn)
 {
        struct aslookup *asn = _asn;
 
Index: traceroute/as.h
===================================================================
RCS file: /cvsroot/src/usr.sbin/traceroute/as.h,v
retrieving revision 1.3
diff -u -r1.3 as.h
--- traceroute/as.h     28 Apr 2008 20:24:17 -0000      1.3
+++ traceroute/as.h     10 May 2011 00:28:03 -0000
@@ -29,6 +29,6 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-void   *as_setup(char *);
-int    as_lookup(void *, struct in_addr *);
+void   *as_setup(const char *);
+unsigned int as_lookup(void *, char *, sa_family_t);
 void   as_shutdown(void *);
Index: traceroute/traceroute.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/traceroute/traceroute.c,v
retrieving revision 1.74
diff -u -r1.74 traceroute.c
--- traceroute/traceroute.c     21 Jul 2008 13:37:00 -0000      1.74
+++ traceroute/traceroute.c     10 May 2011 00:28:03 -0000
@@ -1523,23 +1523,25 @@
 }
 
 void
-print(u_char *buf, int cc, struct sockaddr_in *from)
+print(register u_char *buf, int cc, struct sockaddr_in *from)
 {
-       struct ip *ip;
-       int hlen;
+       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));
Index: traceroute6/Makefile
===================================================================
RCS file: /cvsroot/src/usr.sbin/traceroute6/Makefile,v
retrieving revision 1.7
diff -u -r1.7 Makefile
--- traceroute6/Makefile        28 May 2007 12:06:42 -0000      1.7
+++ traceroute6/Makefile        10 May 2011 00:28:03 -0000
@@ -2,6 +2,9 @@
 
 USE_FORT?= yes # network client
 
+TRACEROUTE?= ${.CURDIR}/../traceroute
+
+SRCS=  traceroute6.c as.c
 PROG=  traceroute6
 MAN=   traceroute6.8
 
@@ -14,5 +17,8 @@
 DPADD+=        ${LIBIPSEC}
 
 CPPFLAGS+=-DHAVE_POLL
+CPPFLAGS+=-I${TRACEROUTE}
+
+.PATH: ${TRACEROUTE}
 
 .include <bsd.prog.mk>
Index: traceroute6/traceroute6.8
===================================================================
RCS file: /cvsroot/src/usr.sbin/traceroute6/traceroute6.8,v
retrieving revision 1.11
diff -u -r1.11 traceroute6.8
--- traceroute6/traceroute6.8   17 Sep 2005 15:16:11 -0000      1.11
+++ traceroute6/traceroute6.8   10 May 2011 00:28:03 -0000
@@ -39,7 +39,7 @@
 .Sh SYNOPSIS
 .Nm traceroute6
 .Bk -words
-.Op Fl dIlnrv
+.Op Fl adIlnrv
 .Ek
 .Bk -words
 .Op Fl f Ar firsthop
@@ -63,12 +63,19 @@
 .Op Fl w Ar waittime
 .Ek
 .Bk -words
+.Op Fl A Ar as_server
+.Ek
+.Bk -words
 .Ar target
 .Op Ar datalen
 .Ek
 .\"
 .Sh DESCRIPTION
 .Bl -tag -width Ds
+.It Fl a
+Turn on AS# lookups for each hop encountered.
+.It Fl A
+Turn on AS# lookups and use the given server instead of the default.
 .It Fl d
 Debug mode.
 .It Fl f Ar firsthop
Index: traceroute6/traceroute6.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/traceroute6/traceroute6.c,v
retrieving revision 1.37.24.1
diff -u -r1.37.24.1 traceroute6.c
--- traceroute6/traceroute6.c   24 Feb 2009 02:41:50 -0000      1.37.24.1
+++ traceroute6/traceroute6.c   10 May 2011 00:28:03 -0000
@@ -282,6 +282,8 @@
 #include <netinet6/ipsec.h>
 #endif
 
+#include "as.h"
+
 #define DUMMY_PORT 10010
 
 #define        MAXPACKET       65535   /* max ip packet size */
@@ -359,6 +361,9 @@
 int nflag;                     /* print addresses numerically */
 int useicmp;
 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)
@@ -414,8 +419,15 @@
 
        seq = 0;
 
-       while ((ch = getopt(argc, argv, "df:g:Ilm:np:q:rs:w:v")) != -1)
+       while ((ch = getopt(argc, argv, "aA:df:g:Ilm:np:q:rs:w:v")) != -1)
                switch (ch) {
+               case 'a':
+                       as_path = 1;
+                       break;
+               case 'A':
+                       as_path = 1;
+                       as_server = optarg;
+                       break;
                case 'd':
                        options |= SO_DEBUG;
                        break;
@@ -832,6 +844,16 @@
                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
         */
@@ -914,6 +936,9 @@
                }
        }
 
+       if (as_path)
+               as_shutdown(asn);
+
        exit(0);
 }
 
@@ -1301,6 +1326,8 @@
        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)


Home | Main Index | Thread Index | Old Index