4.4BSD snapshot (revision 8.1); add 1993 to copyright
[unix-history] / usr / src / usr.sbin / traceroute / traceroute.c
index bbada89..6101614 100644 (file)
@@ -1,6 +1,6 @@
 /*-
 /*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * Van Jacobson.
  *
  * This code is derived from software contributed to Berkeley by
  * Van Jacobson.
@@ -9,13 +9,13 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1990 The Regents of the University of California.\n\
- All rights reserved.\n";
+static char copyright[] =
+"@(#) Copyright (c) 1990, 1993\n\
      The Regents of the University of California.  All rights reserved.\n";
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)traceroute.c       5.3 (Berkeley) %G%";
+static char sccsid[] = "@(#)traceroute.c       8.1 (Berkeley) %G%";
 #endif /* not lint */
 
 /*
 #endif /* not lint */
 
 /*
@@ -189,12 +189,8 @@ static char sccsid[] = "@(#)traceroute.c   5.3 (Berkeley) %G%";
  *     Tue Dec 20 03:50:13 PST 1988
  */
 
  *     Tue Dec 20 03:50:13 PST 1988
  */
 
-#include <stdio.h>
-#include <errno.h>
-#include <strings.h>
-#include <sys/time.h>
-
 #include <sys/param.h>
 #include <sys/param.h>
+#include <sys/time.h>
 #include <sys/socket.h>
 #include <sys/file.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/file.h>
 #include <sys/ioctl.h>
@@ -204,7 +200,15 @@ static char sccsid[] = "@(#)traceroute.c   5.3 (Berkeley) %G%";
 #include <netinet/ip.h>
 #include <netinet/ip_icmp.h>
 #include <netinet/udp.h>
 #include <netinet/ip.h>
 #include <netinet/ip_icmp.h>
 #include <netinet/udp.h>
+
+#include <arpa/inet.h>
+
 #include <netdb.h>
 #include <netdb.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 
 #define        MAXPACKET       65535   /* max ip packet size */
 #ifndef MAXHOSTNAMELEN
 
 #define        MAXPACKET       65535   /* max ip packet size */
 #ifndef MAXHOSTNAMELEN
@@ -223,10 +227,6 @@ static char sccsid[] = "@(#)traceroute.c   5.3 (Berkeley) %G%";
 #define Fprintf (void)fprintf
 #define Sprintf (void)sprintf
 #define Printf (void)printf
 #define Fprintf (void)fprintf
 #define Sprintf (void)sprintf
 #define Printf (void)printf
-extern int errno;
-extern  char *malloc();
-extern  char *inet_ntoa();
-extern  u_long inet_addr();
 
 /*
  * format of a (udp) probe packet.
 
 /*
  * format of a (udp) probe packet.
@@ -241,7 +241,15 @@ struct opacket {
 
 u_char packet[512];            /* last inbound (icmp) packet */
 struct opacket *outpacket;     /* last output (udp) packet */
 
 u_char packet[512];            /* last inbound (icmp) packet */
 struct opacket *outpacket;     /* last output (udp) packet */
-char *inetname();
+
+int wait_for_reply __P((int, struct sockaddr_in *));
+void send_probe __P((int, int));
+double deltaT __P((struct timeval *, struct timeval *));
+int packet_ok __P((u_char *, int, struct sockaddr_in *, int));
+void print __P((u_char *, int, struct sockaddr_in *));
+void tvsub __P((struct timeval *, struct timeval *));
+char *inetname __P((struct in_addr));
+void usage __P(());
 
 int s;                         /* receive (icmp) socket file descriptor */
 int sndsock;                   /* send (udp) socket file descriptor */
 
 int s;                         /* receive (icmp) socket file descriptor */
 int sndsock;                   /* send (udp) socket file descriptor */
@@ -262,7 +270,9 @@ int verbose;
 int waittime = 5;              /* time to wait for response (in seconds) */
 int nflag;                     /* print addresses numerically */
 
 int waittime = 5;              /* time to wait for response (in seconds) */
 int nflag;                     /* print addresses numerically */
 
+int
 main(argc, argv)
 main(argc, argv)
+       int argc;
        char *argv[];
 {
        extern char *optarg;
        char *argv[];
 {
        extern char *optarg;
@@ -342,7 +352,7 @@ main(argc, argv)
        argc -= optind;
        argv += optind;
 
        argc -= optind;
        argv += optind;
 
-       if (argc < 1) 
+       if (argc < 1)
                usage();
 
        setlinebuf (stdout);
                usage();
 
        setlinebuf (stdout);
@@ -350,7 +360,7 @@ main(argc, argv)
        (void) bzero((char *)&whereto, sizeof(struct sockaddr));
        to->sin_family = AF_INET;
        to->sin_addr.s_addr = inet_addr(*argv);
        (void) bzero((char *)&whereto, sizeof(struct sockaddr));
        to->sin_family = AF_INET;
        to->sin_addr.s_addr = inet_addr(*argv);
-       if (to->sin_addr.s_addr != -1) 
+       if (to->sin_addr.s_addr != -1)
                hostname = *argv;
        else {
                hp = gethostbyname(*argv);
                hostname = *argv;
        else {
                hp = gethostbyname(*argv);
@@ -364,7 +374,7 @@ main(argc, argv)
                        exit(1);
                }
        }
                        exit(1);
                }
        }
-       if (*++argv) 
+       if (*++argv)
                datalen = atoi(*argv);
        if (datalen < 0 || datalen >= MAXPACKET - sizeof(struct opacket)) {
                Fprintf(stderr,
                datalen = atoi(*argv);
        if (datalen < 0 || datalen >= MAXPACKET - sizeof(struct opacket)) {
                Fprintf(stderr,
@@ -381,6 +391,8 @@ main(argc, argv)
        (void) bzero((char *)outpacket, datalen);
        outpacket->ip.ip_dst = to->sin_addr;
        outpacket->ip.ip_tos = tos;
        (void) bzero((char *)outpacket, datalen);
        outpacket->ip.ip_dst = to->sin_addr;
        outpacket->ip.ip_tos = tos;
+       outpacket->ip.ip_v = IPVERSION;
+       outpacket->ip.ip_id = 0;
 
        ident = (getpid() & 0xffff) | 0x8000;
 
 
        ident = (getpid() & 0xffff) | 0x8000;
 
@@ -456,19 +468,20 @@ main(argc, argv)
                Printf("%2d ", ttl);
                for (probe = 0; probe < nprobes; ++probe) {
                        int cc;
                Printf("%2d ", ttl);
                for (probe = 0; probe < nprobes; ++probe) {
                        int cc;
-                       struct timeval tv;
+                       struct timeval t1, t2;
+                       struct timezone tz;
                        struct ip *ip;
 
                        struct ip *ip;
 
-                       (void) gettimeofday(&tv, &tz);
+                       (void) gettimeofday(&t1, &tz);
                        send_probe(++seq, ttl);
                        while (cc = wait_for_reply(s, &from)) {
                        send_probe(++seq, ttl);
                        while (cc = wait_for_reply(s, &from)) {
+                               (void) gettimeofday(&t2, &tz);
                                if ((i = packet_ok(packet, cc, &from, seq))) {
                                if ((i = packet_ok(packet, cc, &from, seq))) {
-                                       int dt = deltaT(&tv);
                                        if (from.sin_addr.s_addr != lastaddr) {
                                                print(packet, cc, &from);
                                                lastaddr = from.sin_addr.s_addr;
                                        }
                                        if (from.sin_addr.s_addr != lastaddr) {
                                                print(packet, cc, &from);
                                                lastaddr = from.sin_addr.s_addr;
                                        }
-                                       Printf("  %d ms", dt);
+                                       Printf("  %g ms", deltaT(&t1, &t2));
                                        switch(i - 1) {
                                        case ICMP_UNREACH_PORT:
 #ifndef ARCHAIC
                                        switch(i - 1) {
                                        case ICMP_UNREACH_PORT:
 #ifndef ARCHAIC
@@ -512,6 +525,7 @@ main(argc, argv)
        }
 }
 
        }
 }
 
+int
 wait_for_reply(sock, from)
        int sock;
        struct sockaddr_in *from;
 wait_for_reply(sock, from)
        int sock;
        struct sockaddr_in *from;
@@ -533,7 +547,9 @@ wait_for_reply(sock, from)
 }
 
 
 }
 
 
+void
 send_probe(seq, ttl)
 send_probe(seq, ttl)
+       int seq, ttl;
 {
        struct opacket *op = outpacket;
        struct ip *ip = &op->ip;
 {
        struct opacket *op = outpacket;
        struct ip *ip = &op->ip;
@@ -541,9 +557,12 @@ send_probe(seq, ttl)
        int i;
 
        ip->ip_off = 0;
        int i;
 
        ip->ip_off = 0;
+       ip->ip_hl = sizeof(*ip) >> 2;
        ip->ip_p = IPPROTO_UDP;
        ip->ip_len = datalen;
        ip->ip_ttl = ttl;
        ip->ip_p = IPPROTO_UDP;
        ip->ip_len = datalen;
        ip->ip_ttl = ttl;
+       ip->ip_v = IPVERSION;
+       ip->ip_id = htons(ident+seq);
 
        up->uh_sport = htons(ident);
        up->uh_dport = htons(port+seq);
 
        up->uh_sport = htons(ident);
        up->uh_dport = htons(port+seq);
@@ -566,14 +585,15 @@ send_probe(seq, ttl)
 }
 
 
 }
 
 
-deltaT(tp)
-       struct timeval *tp;
+double
+deltaT(t1p, t2p)
+       struct timeval *t1p, *t2p;
 {
 {
-       struct timeval tv;
+       register double dt;
 
 
-       (void) gettimeofday(&tv, &tz);
-       tvsub(&tv, tp);
-       return (tv.tv_sec*1000 + (tv.tv_usec + 500)/1000);
+       dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
+            (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
+       return (dt);
 }
 
 
 }
 
 
@@ -599,6 +619,7 @@ pr_type(t)
 }
 
 
 }
 
 
+int
 packet_ok(buf, cc, from, seq)
        u_char *buf;
        int cc;
 packet_ok(buf, cc, from, seq)
        u_char *buf;
        int cc;
@@ -655,6 +676,7 @@ packet_ok(buf, cc, from, seq)
 }
 
 
 }
 
 
+void
 print(buf, cc, from)
        u_char *buf;
        int cc;
 print(buf, cc, from)
        u_char *buf;
        int cc;
@@ -682,9 +704,10 @@ print(buf, cc, from)
 /*
  * Checksum routine for Internet Protocol family headers (C Version)
  */
 /*
  * Checksum routine for Internet Protocol family headers (C Version)
  */
+u_short
 in_cksum(addr, len)
 in_cksum(addr, len)
-u_short *addr;
-int len;
+       u_short *addr;
+       int len;
 {
        register int nleft = len;
        register u_short *w = addr;
 {
        register int nleft = len;
        register u_short *w = addr;
@@ -720,8 +743,9 @@ int len;
  * Subtract 2 timeval structs:  out = out - in.
  * Out is assumed to be >= in.
  */
  * Subtract 2 timeval structs:  out = out - in.
  * Out is assumed to be >= in.
  */
+void
 tvsub(out, in)
 tvsub(out, in)
-register struct timeval *out, *in;
+       register struct timeval *out, *in;
 {
        if ((out->tv_usec -= in->tv_usec) < 0)   {
                out->tv_sec--;
 {
        if ((out->tv_usec -= in->tv_usec) < 0)   {
                out->tv_sec--;
@@ -733,7 +757,7 @@ register struct timeval *out, *in;
 
 /*
  * Construct an Internet address representation.
 
 /*
  * Construct an Internet address representation.
- * If the nflag has been supplied, give 
+ * If the nflag has been supplied, give
  * numeric value, otherwise try for symbolic name.
  */
 char *
  * numeric value, otherwise try for symbolic name.
  */
 char *
@@ -775,9 +799,10 @@ inetname(in)
        return (line);
 }
 
        return (line);
 }
 
+void
 usage()
 {
 usage()
 {
-       (void)fprintf(stderr, 
+       (void)fprintf(stderr,
 "usage: traceroute [-dnrv] [-m max_ttl] [-p port#] [-q nqueries]\n\t\
 [-s src_addr] [-t tos] [-w wait] host [data size]\n");
        exit(1);
 "usage: traceroute [-dnrv] [-m max_ttl] [-p port#] [-q nqueries]\n\t\
 [-s src_addr] [-t tos] [-w wait] host [data size]\n");
        exit(1);