From 725860a88783a1f8445ff3abee3dc06ecfad2bdd Mon Sep 17 00:00:00 2001 From: pst Date: Wed, 13 Mar 1996 08:04:29 +0000 Subject: [PATCH] Bring in LBL traceroute, which has the '-g' option. This is a bugfixed and modified version of Leres' latest work. No FreeBSD changes have been spammed. --- usr.sbin/traceroute/Makefile | 1 + usr.sbin/traceroute/README | 133 ++------- usr.sbin/traceroute/gnuc.h | 43 +++ usr.sbin/traceroute/traceroute.8 | 14 +- usr.sbin/traceroute/traceroute.c | 449 ++++++++++++++++--------------- 5 files changed, 298 insertions(+), 342 deletions(-) create mode 100644 usr.sbin/traceroute/gnuc.h diff --git a/usr.sbin/traceroute/Makefile b/usr.sbin/traceroute/Makefile index 7bbc57bc685b..b9d6c20c89f3 100644 --- a/usr.sbin/traceroute/Makefile +++ b/usr.sbin/traceroute/Makefile @@ -4,5 +4,6 @@ PROG= traceroute MAN8= traceroute.8 BINOWN= root BINMODE=4555 +CFLAGS+=-DHAVE_BZERO=1 -DHAVE_SETLINEBUF=1 .include diff --git a/usr.sbin/traceroute/README b/usr.sbin/traceroute/README index 6d33c6cdb767..9d9f4e25640b 100644 --- a/usr.sbin/traceroute/README +++ b/usr.sbin/traceroute/README @@ -1,126 +1,29 @@ -Tue Dec 27 06:24:24 PST 1988 +@(#) $Header: README,v 1.6 95/08/27 16:58:04 leres Exp $ (LBL) + +TRACEROUTE 1.2 +Lawrence Berkeley National Laboratory +Network Research Group +traceroute@ee.lbl.gov +ftp://ftp.ee.lbl.gov/traceroute-*.tar.Z Traceroute is a system administrators utility to trace the route ip packets from the current system take in getting to some destination system. See the comments at the front of the program for a description of its use. -This program - - a) can only be run by root (it uses raw ip sockets). - - b) REQUIRES A KERNEL MOD to the raw ip output code to run. - -If you want to hack on your kernel, my modified version of the -routine rip_output (in file /sys/netinet/raw_ip.c) is attached. -This code may or may not resemble the code in your kernel. -It may offer you a place to start but I make no promises. -If you do hack your kernel, remember to test everything that uses -raw ip sockets (e.g., ping and egpup/gated) & make sure they still -work. I wish you the best of luck and you're on your own. - -If your system has the ttl bug mentioned in the source, you -might want to fix it while you're in the kernel. (This bug -appears in all releases of BSD up to but not including 4.3tahoe. -If your version of netinet/ip_icmp.c is any earlier than 7.3 -(April, '87), it has the bug.) The fix is just to add the line - ip->ip_ttl = MAXTTL; -after the line - ip->ip_src = t; -(or anywhere before the call to icmp_send) in routine icmp_reflect. - -If you're running this on a pre-4.3bsd system (e.g., Sun 3.x, -Ultrix) that strips ip headers from icmp messages, add -DARCHAIC -to CFLAGS in the Makefile. Also note that rip_output contains -a conditional for a 4.2/4.3 change in the location of a raw -socket's protocol number. I've checked this under 4.3 & Sun OS -3.5 but you should double-check your system to make sure the -appropriate branch of the #if is taken (check the line that -assigned to ip->ip_p in your system's original rip_output). +This program uses raw ip sockets and must be run as root (or installed +setuid to root). A couple of awk programs to massage the traceroute output are -included. "mean.awk" and "median.awk" compute the mean and median -time to each hop, respectively. I've found that something like +included. "mean.awk" and "median.awk" compute the mean and median time +to each hop, respectively. I've found that something like - traceroute -q 7 foo.somewhere >t - awk -f median.awk t | graph + traceroute -q 7 foo.somewhere >t + awk -f median.awk t | graph -can give you a quick picture of the bad spots on a long -path (median is usually a better noise filter than mean). +can give you a quick picture of the bad spots on a long path (median is +usually a better noise filter than mean). -Enjoy. - - - Van Jacobson (van@helios.ee.lbl.gov) - --------------------- rip_output from /sys/netinet/raw_ip.c -rip_output(m, so) - register struct mbuf *m; - struct socket *so; -{ - register struct ip *ip; - int error; - struct rawcb *rp = sotorawcb(so); - struct sockaddr_in *sin; -#if BSD>=43 - short proto = rp->rcb_proto.sp_protocol; -#else - short proto = so->so_proto->pr_protocol; -#endif - /* - * if the protocol is IPPROTO_RAW, the user handed us a - * complete IP packet. Otherwise, allocate an mbuf for a - * header and fill it in as needed. - */ - if (proto != IPPROTO_RAW) { - /* - * Calculate data length and get an mbuf - * for IP header. - */ - int len = 0; - struct mbuf *m0; - - for (m0 = m; m; m = m->m_next) - len += m->m_len; - - m = m_get(M_DONTWAIT, MT_HEADER); - if (m == 0) { - m = m0; - error = ENOBUFS; - goto bad; - } - m->m_off = MMAXOFF - sizeof(struct ip); - m->m_len = sizeof(struct ip); - m->m_next = m0; - - ip = mtod(m, struct ip *); - ip->ip_tos = 0; - ip->ip_off = 0; - ip->ip_p = proto; - ip->ip_len = sizeof(struct ip) + len; - ip->ip_ttl = MAXTTL; - } else - ip = mtod(m, struct ip *); - - if (rp->rcb_flags & RAW_LADDR) { - sin = (struct sockaddr_in *)&rp->rcb_laddr; - if (sin->sin_family != AF_INET) { - error = EAFNOSUPPORT; - goto bad; - } - ip->ip_src.s_addr = sin->sin_addr.s_addr; - } else - ip->ip_src.s_addr = 0; - - ip->ip_dst = ((struct sockaddr_in *)&rp->rcb_faddr)->sin_addr; - -#if BSD>=43 - return (ip_output(m, rp->rcb_options, &rp->rcb_route, - (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST)); -#else - return (ip_output(m, (struct mbuf *)0, &rp->rcb_route, - (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST)); -#endif -bad: - m_freem(m); - return (error); -} +Problems, bugs, questions, desirable enhancements, source code +contributions, etc., should be sent to the email address +"traceroute@ee.lbl.gov". diff --git a/usr.sbin/traceroute/gnuc.h b/usr.sbin/traceroute/gnuc.h new file mode 100644 index 000000000000..9a3200c83632 --- /dev/null +++ b/usr.sbin/traceroute/gnuc.h @@ -0,0 +1,43 @@ +/* @(#) $Header: gnuc.h,v 1.3 95/10/09 02:47:01 leres Exp $ (LBL) */ + +/* Define __P() macro, if necessary */ +#ifndef __P +#if __STDC__ +#define __P(protos) protos +#else +#define __P(protos) () +#endif +#endif + +/* inline foo */ +#ifdef __GNUC__ +#define inline __inline +#else +#define inline +#endif + +/* + * Handle new and old "dead" routine prototypes + * + * For example: + * + * __dead void foo(void) __attribute__((volatile)); + * + */ +#ifdef __GNUC__ +#ifndef __dead +#define __dead volatile +#endif +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) +#ifndef __attribute__ +#define __attribute__(args) +#endif +#endif +#else +#ifndef __dead +#define __dead +#endif +#ifndef __attribute__ +#define __attribute__(args) +#endif +#endif diff --git a/usr.sbin/traceroute/traceroute.8 b/usr.sbin/traceroute/traceroute.8 index c1e13bbcdd24..15001e9d5f98 100644 --- a/usr.sbin/traceroute/traceroute.8 +++ b/usr.sbin/traceroute/traceroute.8 @@ -34,7 +34,7 @@ .\" .\" @(#)traceroute.8 8.1 (Berkeley) 6/6/93 .\" -.Dd June 6, 1993 +.Dd March 7, 1996 .Dt TRACEROUTE 8 .Os BSD 4.3 .Sh NAME @@ -42,6 +42,7 @@ .Nd print the route packets take to network host .Sh SYNOPSIS .Nm traceroute +.Op Fl g Ar gateway .Op Fl m Ar max_ttl .Op Fl n .Op Fl p Ar port @@ -51,6 +52,7 @@ .Op Fl s Ar src_addr .Ek .Op Fl t Ar tos +.Op Fl v .Op Fl w Ar waittime .Ar host .Op Ar packetsize @@ -73,6 +75,10 @@ name. .Pp Other options are: .Bl -tag -width Ds +.It Fl g Ar gateway +Add a loose-source-route IP option onto the ICMP packet to direct traffic +to traverse the specified gateway. +Multiple gateway options may be specified on the command line. .It Fl m Ar max_ttl Set the max time-to-live (max number of hops) used in outgoing probe packets. The default is 30 hops (the same default used for @@ -331,6 +337,6 @@ C. Philip Wood, Tim Seaver and Ken Adelman. .Xr ping 8 .Sh HISTORY The -.Nm -command -.Bt +.Nm traceroute +command first appeard in 4.4 +.Tn BSD diff --git a/usr.sbin/traceroute/traceroute.c b/usr.sbin/traceroute/traceroute.c index 5c18e383a019..652f503200b4 100644 --- a/usr.sbin/traceroute/traceroute.c +++ b/usr.sbin/traceroute/traceroute.c @@ -1,48 +1,7 @@ -/*- - * 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. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - #ifndef lint -static char copyright[] = -"@(#) Copyright (c) 1990, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -static char sccsid[] = "@(#)traceroute.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ +static char *rcsid = + "@(#)$Header: traceroute.c,v 1.27 95/10/18 00:17:06 leres Exp $ (LBL)"; +#endif /* * traceroute host - trace the route ip packets follow going to "host". @@ -211,43 +170,51 @@ static char sccsid[] = "@(#)traceroute.c 8.1 (Berkeley) 6/6/93"; * back to yourself. Unfortunately, SO many gateways botch source * routing, the thing is almost worthless. Maybe one day... * - * -- Van Jacobson (van@helios.ee.lbl.gov) + * -- Van Jacobson (van@ee.lbl.gov) * Tue Dec 20 03:50:13 PST 1988 */ #include -#include -#include #include #include +#include +#include #include #include #include +#include #include #include #include +#include +#include +#include #include #include -#include #include #include -#include + +#include "gnuc.h" +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif #define MAXPACKET 65535 /* max ip packet size */ + #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 64 #endif -#ifndef FD_SET -#define NFDBITS (8*sizeof(fd_set)) -#define FD_SETSIZE NFDBITS -#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) -#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) -#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) -#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) +#if !defined(HAVE_BZERO) && !defined(bzero) +#define bzero(s, n) memset(s, 0, n) +#define bcopy(s, d, n) memcpy(d, s, n) +#endif + +#if !defined(HAVE_SETLINEBUF) && !defined(setlinebuf) +#define setlinebuf(f) setvbuf(f, NULL, _IOLBF, 0) #endif #define Fprintf (void)fprintf @@ -268,144 +235,201 @@ struct opacket { u_char packet[512]; /* last inbound (icmp) packet */ struct opacket *outpacket; /* last output (udp) packet */ -int wait_for_reply __P((int, struct sockaddr_in *, struct timeval *)); -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 */ -struct timezone tz; /* leftover */ struct sockaddr whereto; /* Who to try to reach */ int datalen; /* How much data */ char *source = 0; char *hostname; +char hnamebuf[MAXHOSTNAMELEN]; int nprobes = 3; int max_ttl = 30; u_short ident; u_short port = 32768+666; /* start udp dest port # for probe packets */ + int options; /* socket options */ int verbose; int waittime = 5; /* time to wait for response (in seconds) */ int nflag; /* print addresses numerically */ -int -main(argc, argv) - int argc; - char *argv[]; +char usage[] = + "Usage: traceroute [-dnrv] [-w wait] [-m max_ttl] [-p port#] [-q nqueries] [-t tos] [-s src_addr] [-g gateway] host [data size]\n"; + +/* Forwards */ +double deltaT(struct timeval *, struct timeval *); +int main(int, char **); +int wait_for_reply(int, struct sockaddr_in *, struct timeval *); +void send_probe(int, int, struct timeval *); +char *pr_type(u_char); +int packet_ok(u_char *, int, struct sockaddr_in *, int); +void print(u_char *, int, struct sockaddr_in *); +void tvsub(struct timeval *, struct timeval *); +char *inetname(struct in_addr); + +double +deltaT(struct timeval *t1p, struct timeval *t2p) { - extern char *optarg; - extern int optind; - struct hostent *hp; + register double dt; + + dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 + + (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0; + return (dt); +} + +int +main(int argc, char **argv) +{ + struct sockaddr_in from; + char **av = argv; + struct sockaddr_in *to = (struct sockaddr_in *) &whereto; + int on = 1; struct protoent *pe; - struct sockaddr_in from, *to; - int ch, i, on, probe, seq, tos, ttl; + int ttl, probe, i; + int seq = 0; + int tos = 0; + struct hostent *hp; + int lsrr = 0; + u_long gw; + u_char optlist[MAX_IPOPTLEN], *oix; - on = 1; - seq = tos = 0; - to = (struct sockaddr_in *)&whereto; - while ((ch = getopt(argc, argv, "dm:np:q:rs:t:w:v")) != EOF) - switch(ch) { - case 'd': - options |= SO_DEBUG; - break; - case 'm': - max_ttl = atoi(optarg); - if (max_ttl <= 1) { - Fprintf(stderr, - "traceroute: max ttl must be >1.\n"); - exit(1); - } - break; - case 'n': - nflag++; - break; - case 'p': - port = atoi(optarg); - if (port < 1) { - Fprintf(stderr, - "traceroute: port must be >0.\n"); - exit(1); - } - break; - case 'q': - nprobes = atoi(optarg); - if (nprobes < 1) { - Fprintf(stderr, - "traceroute: nprobes must be >0.\n"); - exit(1); - } - break; - case 'r': - options |= SO_DONTROUTE; - break; - case 's': - /* - * set the ip source address of the outbound - * probe (e.g., on a multi-homed host). - */ - source = optarg; - break; - case 't': - tos = atoi(optarg); - if (tos < 0 || tos > 255) { - Fprintf(stderr, - "traceroute: tos must be 0 to 255.\n"); - exit(1); - } - break; - case 'v': - verbose++; - break; - case 'w': - waittime = atoi(optarg); - if (waittime <= 1) { - Fprintf(stderr, - "traceroute: wait must be >1 sec.\n"); - exit(1); - } - break; - default: - usage(); - } - argc -= optind; - argv += optind; - - if (argc < 1) - usage(); + oix = optlist; + bzero(optlist, sizeof(optlist)); + argc--, av++; + while (argc && *av[0] == '-') { + while (*++av[0]) + switch (*av[0]) { + case 'd': + options |= SO_DEBUG; + break; + case 'g': + argc--, av++; + if ((lsrr+1) >= ((MAX_IPOPTLEN-IPOPT_MINOFF)/sizeof(u_long))) { + Fprintf(stderr,"No more than %d gateways\n", + (u_int)((MAX_IPOPTLEN-IPOPT_MINOFF)/sizeof(u_long))-1); + exit(1); + } + if (lsrr == 0) { + *oix++ = IPOPT_LSRR; + oix++; /* Fill in total length later */ + *oix++ = IPOPT_MINOFF; /* Pointer to LSRR addresses */ + } + lsrr++; + if (isdigit(*av[0])) { + gw = inet_addr(*av); + if (gw) { + bcopy(&gw, oix, sizeof(u_long)); + } else { + Fprintf(stderr, "Unknown host %s\n",av[0]); + exit(1); + } + } else { + hp = gethostbyname(av[0]); + if (hp) { + bcopy(hp->h_addr, oix, sizeof(u_long)); + } else { + Fprintf(stderr, "Unknown host %s\n",av[0]); + exit(1); + } + } + oix += sizeof(u_long); + goto nextarg; + case 'm': + argc--, av++; + max_ttl = atoi(av[0]); + if (max_ttl <= 1) { + Fprintf(stderr, "max ttl must be >1\n"); + exit(1); + } + goto nextarg; + case 'n': + nflag++; + break; + case 'p': + argc--, av++; + port = atoi(av[0]); + if (port < 1) { + Fprintf(stderr, "port must be >0\n"); + exit(1); + } + goto nextarg; + case 'q': + argc--, av++; + nprobes = atoi(av[0]); + if (nprobes < 1) { + Fprintf(stderr, "nprobes must be >0\n"); + exit(1); + } + goto nextarg; + case 'r': + options |= SO_DONTROUTE; + break; + case 's': + /* + * set the ip source address of the outbound + * probe (e.g., on a multi-homed host). + */ + argc--, av++; + source = av[0]; + goto nextarg; + case 't': + argc--, av++; + tos = atoi(av[0]); + if (tos < 0 || tos > 255) { + Fprintf(stderr, "tos must be 0 to 255\n"); + exit(1); + } + goto nextarg; + case 'v': + verbose++; + break; + case 'w': + argc--, av++; + waittime = atoi(av[0]); + if (waittime <= 1) { + Fprintf(stderr, "wait must be >1 sec\n"); + exit(1); + } + goto nextarg; + default: + Printf(usage); + exit(1); + } + nextarg: + argc--, av++; + } + if (argc != 1) { + Printf(usage); + exit(1); + } setlinebuf (stdout); - (void) bzero((char *)&whereto, sizeof(struct sockaddr)); + 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) - hostname = *argv; - else { - hp = gethostbyname(*argv); + to->sin_addr.s_addr = inet_addr(av[0]); + if (to->sin_addr.s_addr != -1) { + (void) strcpy(hnamebuf, av[0]); + hostname = hnamebuf; + } else { + hp = gethostbyname(av[0]); if (hp) { to->sin_family = hp->h_addrtype; bcopy(hp->h_addr, (caddr_t)&to->sin_addr, hp->h_length); hostname = strdup(hp->h_name); } else { - (void)fprintf(stderr, - "traceroute: unknown host %s\n", *argv); + Printf("%s: unknown host %s\n", argv[0], av[0]); exit(1); } } - if (*++argv) - datalen = atoi(*argv); + + if (argc >= 2) + datalen = atoi(av[1]); if (datalen < 0 || datalen >= MAXPACKET - sizeof(struct opacket)) { - Fprintf(stderr, - "traceroute: packet size must be 0 <= s < %ld.\n", - MAXPACKET - sizeof(struct opacket)); + Fprintf(stderr, "traceroute: packet size must be 0 <= s < %d\n", + (u_int)(MAXPACKET - sizeof(struct opacket))); exit(1); } datalen += sizeof(struct opacket); @@ -414,11 +438,11 @@ main(argc, argv) perror("traceroute: malloc"); exit(1); } - (void) bzero((char *)outpacket, datalen); + 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; + outpacket->ip.ip_v = IPVERSION; + outpacket->ip.ip_hl = sizeof(struct ip) >> 2; ident = (getpid() & 0xffff) | 0x8000; @@ -441,6 +465,26 @@ main(argc, argv) perror("traceroute: raw socket"); exit(5); } + + if (lsrr > 0) { + lsrr++; + optlist[IPOPT_OLEN]=IPOPT_MINOFF-1+(lsrr*sizeof(u_long)); + bcopy((caddr_t)&to->sin_addr, oix, sizeof(u_long)); + oix += sizeof(u_long); + while ((oix - optlist)&3) oix++; /* Pad to an even boundry */ + + if ((pe = getprotobyname("ip")) == NULL) { + perror("traceroute: unknown protocol ip\n"); + exit(10); + } +#ifdef IP_OPTIONS + if ((setsockopt(sndsock, pe->p_proto, IP_OPTIONS, optlist, oix-optlist)) < 0) { + perror("traceroute: lsrr options"); + exit(5); + } +#endif + } + #ifdef SO_SNDBUF if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen, sizeof(datalen)) < 0) { @@ -463,7 +507,7 @@ main(argc, argv) (char *)&on, sizeof(on)); if (source) { - (void) bzero((char *)&from, sizeof(struct sockaddr)); + bzero((char *)&from, sizeof(struct sockaddr)); from.sin_family = AF_INET; from.sin_addr.s_addr = inet_addr(source); if (from.sin_addr.s_addr == -1) { @@ -499,8 +543,8 @@ main(argc, argv) struct ip *ip; (void) gettimeofday(&t1, &tz); - send_probe(++seq, ttl); - while (cc = wait_for_reply(s, &from, &t1)) { + send_probe(++seq, ttl, &t1); + while ((cc = wait_for_reply(s, &from, &t1)) != 0) { (void) gettimeofday(&t2, &tz); if ((i = packet_ok(packet, cc, &from, seq))) { if (from.sin_addr.s_addr != lastaddr) { @@ -549,13 +593,11 @@ main(argc, argv) if (got_there || unreachable >= nprobes-1) exit(0); } + exit(0); } int -wait_for_reply(sock, from, sent) - int sock; - struct sockaddr_in *from; - struct timeval *sent; +wait_for_reply(int sock, struct sockaddr_in *from, struct timeval *sent) { fd_set fds; struct timeval now, wait; @@ -566,13 +608,13 @@ wait_for_reply(sock, from, sent) FD_SET(sock, &fds); gettimeofday(&now, NULL); wait.tv_sec = (sent->tv_sec + waittime) - now.tv_sec; - wait.tv_usec = sent->tv_usec - now.tv_usec; + wait.tv_usec = sent->tv_usec - now.tv_usec; if (wait.tv_usec < 0) { - wait.tv_usec += 1000000; - wait.tv_sec--; + wait.tv_usec += 1000000; + wait.tv_sec--; } if (wait.tv_sec < 0) - wait.tv_sec = wait.tv_usec = 0; + wait.tv_sec = wait.tv_usec = 0; if (select(sock+1, &fds, (fd_set *)0, (fd_set *)0, &wait) > 0) cc=recvfrom(s, (char *)packet, sizeof(packet), 0, @@ -583,8 +625,7 @@ wait_for_reply(sock, from, sent) void -send_probe(seq, ttl) - int seq, ttl; +send_probe(int seq, int ttl, struct timeval *tp) { struct opacket *op = outpacket; struct ip *ip = &op->ip; @@ -592,12 +633,9 @@ send_probe(seq, ttl) 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_v = IPVERSION; - ip->ip_id = htons(ident+seq); up->uh_sport = htons(ident); up->uh_dport = htons(port+seq); @@ -606,7 +644,7 @@ send_probe(seq, ttl) op->seq = seq; op->ttl = ttl; - (void) gettimeofday(&op->tv, &tz); + op->tv = *tp; i = sendto(sndsock, (char *)outpacket, datalen, 0, &whereto, sizeof(struct sockaddr)); @@ -619,25 +657,11 @@ send_probe(seq, ttl) } } - -double -deltaT(t1p, t2p) - struct timeval *t1p, *t2p; -{ - register double dt; - - dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 + - (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0; - return (dt); -} - - /* * Convert an ICMP "type" field to a printable string. */ char * -pr_type(t) - u_char t; +pr_type(u_char t) { static char *ttab[] = { "Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable", @@ -655,11 +679,7 @@ pr_type(t) int -packet_ok(buf, cc, from, seq) - u_char *buf; - int cc; - struct sockaddr_in *from; - int seq; +packet_ok(u_char *buf, int cc, struct sockaddr_in *from, int seq) { register struct icmp *icp; u_char type, code; @@ -712,10 +732,7 @@ packet_ok(buf, cc, from, seq) void -print(buf, cc, from) - u_char *buf; - int cc; - struct sockaddr_in *from; +print(u_char *buf, int cc, struct sockaddr_in *from) { struct ip *ip; int hlen; @@ -739,10 +756,7 @@ print(buf, cc, from) /* * Checksum routine for Internet Protocol family headers (C Version) */ -u_short -in_cksum(addr, len) - u_short *addr; - int len; +in_cksum(u_short *addr, int len) { register int nleft = len; register u_short *w = addr; @@ -779,8 +793,7 @@ in_cksum(addr, len) * Out is assumed to be >= in. */ void -tvsub(out, in) - register struct timeval *out, *in; +tvsub(register struct timeval *out, register struct timeval *in) { if ((out->tv_usec -= in->tv_usec) < 0) { out->tv_sec--; @@ -796,8 +809,7 @@ tvsub(out, in) * numeric value, otherwise try for symbolic name. */ char * -inetname(in) - struct in_addr in; +inetname(struct in_addr in) { register char *cp; static char line[50]; @@ -808,7 +820,7 @@ inetname(in) if (first && !nflag) { first = 0; if (gethostname(domain, MAXHOSTNAMELEN) == 0 && - (cp = index(domain, '.'))) + (cp = strchr(domain, '.'))) (void) strcpy(domain, cp + 1); else domain[0] = 0; @@ -817,7 +829,7 @@ inetname(in) if (!nflag && in.s_addr != INADDR_ANY) { hp = gethostbyaddr((char *)&in, sizeof (in), AF_INET); if (hp) { - if ((cp = index(hp->h_name, '.')) && + if ((cp = strchr(hp->h_name, '.')) && !strcmp(cp + 1, domain)) *cp = 0; cp = hp->h_name; @@ -833,12 +845,3 @@ inetname(in) } return (line); } - -void -usage() -{ - (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); -}