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.
This commit is contained in:
pst 1996-03-13 08:04:29 +00:00
parent 8c5e343745
commit 725860a887
5 changed files with 298 additions and 342 deletions

View File

@ -4,5 +4,6 @@ PROG= traceroute
MAN8= traceroute.8
BINOWN= root
BINMODE=4555
CFLAGS+=-DHAVE_BZERO=1 -DHAVE_SETLINEBUF=1
.include <bsd.prog.mk>

View File

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

View File

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

View File

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

View File

@ -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 <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/time.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/ip_icmp.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#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);
}