slackware-current/source/n/traceroute/traceroute_1.4a12-5.diff

1153 lines
29 KiB
Diff
Raw Normal View History

--- traceroute-1.4a12.orig/aclocal.m4
+++ traceroute-1.4a12/aclocal.m4
@@ -47,7 +47,7 @@
AC_BEFORE([$0], [AC_LBL_FIXINCLUDES])
AC_BEFORE([$0], [AC_LBL_DEVEL])
AC_ARG_WITH(gcc, [ --without-gcc don't use gcc])
- $1="-O"
+ $1="-g -O"
$2=""
if test "${srcdir}" != "." ; then
$2="-I\$\(srcdir\)"
@@ -677,12 +677,11 @@
AC_TRY_LINK(dnl
ifelse([$2], [main], , dnl Avoid conflicting decl of main.
[/* Override any gcc2 internal prototype to avoid an error. */
-]ifelse(AC_LANG, CPLUSPLUS, [#ifdef __cplusplus
+#ifdef __cplusplus
extern "C"
#endif
-])dnl
-[/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
char $2();
]),
[$2()],
--- traceroute-1.4a12.orig/configure.in
+++ traceroute-1.4a12/configure.in
@@ -22,7 +22,7 @@
net/if_dl.h inet/mib2.h)
AC_REPLACE_FUNCS(strerror usleep)
-AC_CHECK_FUNCS(setlinebuf)
+AC_CHECK_FUNCS(setlinebuf snprintf)
if test $ac_cv_func_usleep = "no" ; then
AC_CHECK_FUNCS(nanosleep)
fi
@@ -44,8 +44,9 @@
;;
linux*)
- V_INCLS="$V_INCLS -Ilinux-include"
+ V_INCLS="$V_INCLS -Ilinux-include -DUSE_KERNEL_ROUTING_TABLE"
AC_DEFINE(BYTESWAP_IP_HDR)
+ AC_DEFINE(HAVE_RAW_OPTIONS)
;;
osf3*)
--- traceroute-1.4a12.orig/findsaddr-generic.c
+++ traceroute-1.4a12/findsaddr-generic.c
@@ -82,7 +82,11 @@
static char errbuf[132];
/* Get the interface address list */
+#if HAVE_SNPRINTF
+ if ((n = ifaddrlist(&al, errbuf, sizeof(errbuf))) < 0)
+#else
if ((n = ifaddrlist(&al, errbuf)) < 0)
+#endif
return (errbuf);
if (n == 0)
--- traceroute-1.4a12.orig/findsaddr-linux.c
+++ traceroute-1.4a12/findsaddr-linux.c
@@ -90,7 +90,11 @@
static char errbuf[132];
if ((f = fopen(route, "r")) == NULL) {
+#if HAVE_SNPRINTF
+ snprintf(errbuf, sizeof(errbuf), "open %s: %.128s", route, strerror(errno));
+#else
sprintf(errbuf, "open %s: %.128s", route, strerror(errno));
+#endif
return (errbuf);
}
@@ -102,7 +106,7 @@
++n;
if (n == 1 && strncmp(buf, "Iface", 5) == 0)
continue;
- if ((i = sscanf(buf, "%s %x %*s %*s %*s %*s %*s %x",
+ if ((i = sscanf(buf, "%255s %x %*s %*s %*s %*s %*s %x",
tdevice, &dest, &tmask)) != 3)
return ("junk in buffer");
if ((to->sin_addr.s_addr & tmask) == dest &&
@@ -117,7 +121,11 @@
return ("Can't find interface");
/* Get the interface address list */
+#if HAVE_SNPRINTF
+ if ((n = ifaddrlist(&al, errbuf, sizeof(errbuf))) < 0)
+#else
if ((n = ifaddrlist(&al, errbuf)) < 0)
+#endif
return (errbuf);
if (n == 0)
@@ -128,7 +136,11 @@
if (strcmp(device, al->device) == 0)
break;
if (i <= 0) {
+#if HAVE_SNPRINTF
+ snprintf(errbuf, sizeof(errbuf), "Can't find interface \"%.32s\"", device);
+#else
sprintf(errbuf, "Can't find interface \"%.32s\"", device);
+#endif
return (errbuf);
}
--- traceroute-1.4a12.orig/findsaddr-socket.c
+++ traceroute-1.4a12/findsaddr-socket.c
@@ -114,7 +114,11 @@
s = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
if (s < 0) {
+#if HAVE_SNPRINTF
+ snprintf(errbuf, sizeof(errbuf), "socket: %.128s", strerror(errno));
+#else
sprintf(errbuf, "socket: %.128s", strerror(errno));
+#endif
return (errbuf);
}
@@ -134,12 +138,20 @@
cc = write(s, (char *)rp, size);
if (cc < 0) {
+#if HAVE_SNPRINTF
+ snprintf(errbuf, sizeof(errbuf), "write: %.128s", strerror(errno));
+#else
sprintf(errbuf, "write: %.128s", strerror(errno));
+#endif
close(s);
return (errbuf);
}
if (cc != size) {
+#if HAVE_SNPRINTF
+ snprintf(errbuf, sizeof(errbuf), "short write (%d != %d)", cc, size);
+#else
sprintf(errbuf, "short write (%d != %d)", cc, size);
+#endif
close(s);
return (errbuf);
}
@@ -149,7 +161,11 @@
memset(rp, 0, size);
cc = read(s, (char *)rp, size);
if (cc < 0) {
+#if HAVE_SNPRINTF
+ snprintf(errbuf, sizeof(errbuf), "read: %.128s", strerror(errno));
+#else
sprintf(errbuf, "read: %.128s", strerror(errno));
+#endif
close(s);
return (errbuf);
}
@@ -159,15 +175,27 @@
if (rp->rtm_version != RTM_VERSION) {
+#if HAVE_SNPRINTF
+ snprintf(errbuf, sizeof(errbuf), "bad version %d", rp->rtm_version);
+#else
sprintf(errbuf, "bad version %d", rp->rtm_version);
+#endif
return (errbuf);
}
if (rp->rtm_msglen > cc) {
+#if HAVE_SNPRINTF
+ snprintf(errbuf, sizeof(errbuf), "bad msglen %d > %d", rp->rtm_msglen, cc);
+#else
sprintf(errbuf, "bad msglen %d > %d", rp->rtm_msglen, cc);
+#endif
return (errbuf);
}
if (rp->rtm_errno != 0) {
+#if HAVE_SNPRINTF
+ snprintf(errbuf, sizeof(errbuf), "rtm_errno: %.128s", strerror(rp->rtm_errno));
+#else
sprintf(errbuf, "rtm_errno: %.128s", strerror(rp->rtm_errno));
+#endif
return (errbuf);
}
--- traceroute-1.4a12.orig/ifaddrlist.c
+++ traceroute-1.4a12/ifaddrlist.c
@@ -72,7 +72,12 @@
* Return the interface list
*/
int
+#if HAVE_SNPRINTF
+ifaddrlist(register struct ifaddrlist **ipaddrp, register char *errbuf,
+ size_t nerrbuf)
+#else
ifaddrlist(register struct ifaddrlist **ipaddrp, register char *errbuf)
+#endif
{
register int fd, nipaddr;
#ifdef HAVE_SOCKADDR_SA_LEN
@@ -89,7 +94,11 @@
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
+#if HAVE_SNPRINTF
+ (void)snprintf(errbuf, nerrbuf, "socket: %s", strerror(errno));
+#else
(void)sprintf(errbuf, "socket: %s", strerror(errno));
+#endif
return (-1);
}
ifc.ifc_len = sizeof(ibuf);
@@ -98,12 +107,23 @@
if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 ||
ifc.ifc_len < sizeof(struct ifreq)) {
if (errno == EINVAL)
+#if HAVE_SNPRINTF
+ (void)snprintf(errbuf, nerrbuf,
+ "SIOCGIFCONF: ifreq struct too small (%d bytes)",
+ sizeof(ibuf));
+#else
(void)sprintf(errbuf,
"SIOCGIFCONF: ifreq struct too small (%d bytes)",
sizeof(ibuf));
+#endif
else
+#if HAVE_SNPRINTF
+ (void)snprintf(errbuf, nerrbuf, "SIOCGIFCONF: %s",
+ strerror(errno));
+#else
(void)sprintf(errbuf, "SIOCGIFCONF: %s",
strerror(errno));
+#endif
(void)close(fd);
return (-1);
}
@@ -135,9 +155,15 @@
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
if (errno == ENXIO)
continue;
+#if HAVE_SNPRINTF
+ (void)snprintf(errbuf, nerrbuf, "SIOCGIFFLAGS: %.*s: %s",
+ (int)sizeof(ifr.ifr_name), ifr.ifr_name,
+ strerror(errno));
+#else
(void)sprintf(errbuf, "SIOCGIFFLAGS: %.*s: %s",
(int)sizeof(ifr.ifr_name), ifr.ifr_name,
strerror(errno));
+#endif
(void)close(fd);
return (-1);
}
@@ -155,21 +181,35 @@
continue;
#endif
if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
+#if HAVE_SNPRINTF
+ (void)snprintf(errbuf, nerrbuf, "SIOCGIFADDR: %s: %s",
+ device, strerror(errno));
+#else
(void)sprintf(errbuf, "SIOCGIFADDR: %s: %s",
device, strerror(errno));
+#endif
(void)close(fd);
return (-1);
}
if (nipaddr >= MAX_IPADDR) {
+#if HAVE_SNPRINTF
+ (void)snprintf(errbuf, nerrbuf, "Too many interfaces (%d)",
+ MAX_IPADDR);
+#else
(void)sprintf(errbuf, "Too many interfaces (%d)",
MAX_IPADDR);
+#endif
(void)close(fd);
return (-1);
}
sin = (struct sockaddr_in *)&ifr.ifr_addr;
al->addr = sin->sin_addr.s_addr;
al->device = strdup(device);
+ if (al->device == NULL) {
+ fputs("ifaddrlist: strdup\n", stderr);
+ exit(1);
+ }
++al;
++nipaddr;
}
--- traceroute-1.4a12.orig/ifaddrlist.h
+++ traceroute-1.4a12/ifaddrlist.h
@@ -26,4 +26,8 @@
char *device;
};
+#if HAVE_SNPRINTF
+int ifaddrlist(struct ifaddrlist **, char *, size_t);
+#else
int ifaddrlist(struct ifaddrlist **, char *);
+#endif
--- traceroute-1.4a12.orig/traceroute.8
+++ traceroute-1.4a12/traceroute.8
@@ -23,7 +23,7 @@
.na
.B traceroute
[
-.B \-dFInrvx
+.B \-dFIlnrvx
] [
.B \-f
.I first_ttl
@@ -110,6 +110,10 @@
.B \-I
Use ICMP ECHO instead of UDP datagrams.
.TP
+.B \-l
+Display the ttl value of the returned packet. This is useful for
+checking for assymetric routing.
+.TP
.B \-m
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 TCP
@@ -146,9 +150,8 @@
multi-homed hosts (those with more than one IP
address), this option can be used to
force the source address to be something other than the IP address
-of the interface the probe packet is sent on. If the IP address
-is not one of this machine's interface addresses, an error is
-returned and nothing is sent. (See the
+of the interface the probe packet is sent on. This option can only
+be used by the super-user. (See the
.B \-i
flag for another way to do this.)
.TP
@@ -329,6 +332,9 @@
or
.B !P
(host, network or protocol unreachable),
+.BR !A ,
+.BR !C
+(access to the network or host, respectively, is prohibited),
.B !S
(source route failed),
.B !F\-<pmtu>
--- traceroute-1.4a12.orig/traceroute.c
+++ traceroute-1.4a12/traceroute.c
@@ -271,7 +271,7 @@
struct outdata {
u_char seq; /* sequence number of this packet */
u_char ttl; /* ttl packet left with */
- struct timeval tv; /* time packet left */
+ struct timeval tv __attribute__((packed)); /* time packet left */
};
#ifndef HAVE_ICMP_NEXTMTU
@@ -296,8 +296,8 @@
int s; /* receive (icmp) socket file descriptor */
int sndsock; /* send (udp/icmp) socket file descriptor */
-struct sockaddr whereto; /* Who to try to reach */
-struct sockaddr wherefrom; /* Who we are */
+struct sockaddr_storage whereto; /* Who to try to reach */
+struct sockaddr_storage wherefrom; /* Who we are */
int packlen; /* total length of packet */
int minpacket; /* min ip packet size */
int maxpacket = 32 * 1024; /* max ip packet size */
@@ -352,6 +352,11 @@
int usleep(u_int);
#endif
+#ifdef USE_KERNEL_ROUTING_TABLE
+struct ifaddrlist *search_routing_table(struct sockaddr_in *to, struct ifaddrlist *al, int n);
+#endif
+
+
int
main(int argc, char **argv)
{
@@ -370,8 +375,12 @@
int tos = 0, settos = 0;
register int lsrr = 0;
register u_short off = 0;
- struct ifaddrlist *al;
+ struct ifaddrlist *al, *allist;
char errbuf[132];
+ int ttl_flag = 0;
+ int uid;
+
+ uid = getuid();
if (argv[0] == NULL)
prog = "traceroute";
@@ -381,7 +390,7 @@
prog = argv[0];
opterr = 0;
- while ((op = getopt(argc, argv, "dFInrvxf:g:i:m:p:q:s:t:w:z:")) != EOF)
+ while ((op = getopt(argc, argv, "dFIlnrvxf:g:i:m:p:q:s:t:w:z:")) != EOF)
switch (op) {
case 'd':
@@ -397,6 +406,10 @@
break;
case 'g':
+ if (strlen(optarg) >= MAXHOSTNAMELEN) {
+ Fprintf(stderr, "%s: Nice Try !\n", prog);
+ exit(-1);
+ }
if (lsrr >= NGATEWAYS) {
Fprintf(stderr,
"%s: No more than %d gateways\n",
@@ -409,12 +422,21 @@
case 'i':
device = optarg;
+ if (strlen(device) >= 16) { /* that is the IFNAMSIZ
+ * from kernel headers */
+ Fprintf(stderr, "%s: Nice try !\n", prog);
+ exit(-1);
+ }
break;
case 'I':
++useicmp;
break;
+ case 'l':
+ ++ttl_flag;
+ break;
+
case 'm':
max_ttl = str2val(optarg, "max ttl", 1, 255);
break;
@@ -441,7 +463,19 @@
* set the ip source address of the outbound
* probe (e.g., on a multi-homed host).
*/
+ if (uid) {
+ Fprintf(
+ stderr,
+ "%s: -s %s: Permission denied\n",
+ prog, optarg
+ );
+ exit(-1);
+ }
source = optarg;
+ if (strlen(source) >= MAXHOSTNAMELEN) {
+ Fprintf(stderr, "%s: Nice Try !\n", prog);
+ exit(-1);
+ }
break;
case 't':
@@ -500,6 +534,10 @@
case 1:
hostname = argv[optind];
+ if (strlen(hostname) >= MAXHOSTNAMELEN) {
+ Fprintf(stderr, "%s: Nice try !\n", prog);
+ exit(-1);
+ }
hi = gethostinfo(hostname);
setsin(to, hi->addrs[0]);
if (hi->n > 1)
@@ -515,75 +553,6 @@
usage();
}
-#ifdef HAVE_SETLINEBUF
- setlinebuf (stdout);
-#else
- setvbuf(stdout, NULL, _IOLBF, 0);
-#endif
-
- outip = (struct ip *)malloc((unsigned)packlen);
- if (outip == NULL) {
- Fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno));
- exit(1);
- }
- memset((char *)outip, 0, packlen);
-
- outip->ip_v = IPVERSION;
- if (settos)
- outip->ip_tos = tos;
-#ifdef BYTESWAP_IP_HDR
- outip->ip_len = htons(packlen);
- outip->ip_off = htons(off);
-#else
- outip->ip_len = packlen;
- outip->ip_off = off;
-#endif
- outp = (u_char *)(outip + 1);
-#ifdef HAVE_RAW_OPTIONS
- if (lsrr > 0) {
- register u_char *optlist;
-
- optlist = outp;
- outp += optlen;
-
- /* final hop */
- gwlist[lsrr] = to->sin_addr.s_addr;
-
- outip->ip_dst.s_addr = gwlist[0];
-
- /* force 4 byte alignment */
- optlist[0] = IPOPT_NOP;
- /* loose source route option */
- optlist[1] = IPOPT_LSRR;
- i = lsrr * sizeof(gwlist[0]);
- optlist[2] = i + 3;
- /* Pointer to LSRR addresses */
- optlist[3] = IPOPT_MINOFF;
- memcpy(optlist + 4, gwlist + 1, i);
- } else
-#endif
- outip->ip_dst = to->sin_addr;
-
- outip->ip_hl = (outp - (u_char *)outip) >> 2;
- ident = (getpid() & 0xffff) | 0x8000;
- if (useicmp) {
- outip->ip_p = IPPROTO_ICMP;
-
- outicmp = (struct icmp *)outp;
- outicmp->icmp_type = ICMP_ECHO;
- outicmp->icmp_id = htons(ident);
-
- outdata = (struct outdata *)(outp + 8); /* XXX magic number */
- } else {
- outip->ip_p = IPPROTO_UDP;
-
- outudp = (struct udphdr *)outp;
- outudp->uh_sport = htons(ident);
- outudp->uh_ulen =
- htons((u_short)(packlen - (sizeof(*outip) + optlen)));
- outdata = (struct outdata *)(outudp + 1);
- }
-
cp = "icmp";
if ((pe = getprotobyname(cp)) == NULL) {
Fprintf(stderr, "%s: unknown protocol %s\n", prog, cp);
@@ -591,12 +560,15 @@
}
/* Insure the socket fds won't be 0, 1 or 2 */
- if (open(devnull, O_RDONLY) < 0 ||
- open(devnull, O_RDONLY) < 0 ||
- open(devnull, O_RDONLY) < 0) {
- Fprintf(stderr, "%s: open \"%s\": %s\n",
- prog, devnull, strerror(errno));
- exit(1);
+ do {
+ if ((n = open(devnull, O_RDONLY)) < 0) {
+ Fprintf(stderr, "%s: open \"%s\": %s\n",
+ prog, devnull, strerror(errno));
+ exit(1);
+ }
+ } while (n < 2);
+ if (n > 2) {
+ close(n);
}
if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0) {
Fprintf(stderr, "%s: icmp socket: %s\n", prog, strerror(errno));
@@ -662,7 +634,7 @@
#endif
#ifdef IP_HDRINCL
if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
- sizeof(on)) < 0) {
+ sizeof(on)) < 0 && errno != ENOPROTOOPT) {
Fprintf(stderr, "%s: IP_HDRINCL: %s\n", prog, strerror(errno));
exit(1);
}
@@ -683,8 +655,88 @@
(void)setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
sizeof(on));
+ /* Revert to non-privileged user after opening sockets */
+ setgid(getgid());
+ setuid(uid);
+
+#ifndef __GLIBC__
+#ifdef HAVE_SETLINEBUF
+ setlinebuf (stdout);
+#else
+ setvbuf(stdout, NULL, _IOLBF, 0);
+#endif
+#endif
+
+ outip = (struct ip *)malloc((unsigned)packlen);
+ if (outip == NULL) {
+ Fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno));
+ exit(1);
+ }
+ memset((char *)outip, 0, packlen);
+
+ outip->ip_v = IPVERSION;
+ if (settos)
+ outip->ip_tos = tos;
+#ifdef BYTESWAP_IP_HDR
+ outip->ip_len = htons(packlen);
+ outip->ip_off = htons(off);
+#else
+ outip->ip_len = packlen;
+ outip->ip_off = off;
+#endif
+ outp = (u_char *)(outip + 1);
+#ifdef HAVE_RAW_OPTIONS
+ if (lsrr > 0) {
+ register u_char *optlist;
+
+ optlist = outp;
+ outp += optlen;
+
+ /* final hop */
+ gwlist[lsrr] = to->sin_addr.s_addr;
+
+ outip->ip_dst.s_addr = gwlist[0];
+
+ /* force 4 byte alignment */
+ optlist[0] = IPOPT_NOP;
+ /* loose source route option */
+ optlist[1] = IPOPT_LSRR;
+ i = lsrr * sizeof(gwlist[0]);
+ optlist[2] = i + 3;
+ /* Pointer to LSRR addresses */
+ optlist[3] = IPOPT_MINOFF;
+ memcpy(optlist + 4, gwlist + 1, i);
+ } else
+#endif
+ outip->ip_dst = to->sin_addr;
+
+ outip->ip_hl = (outp - (u_char *)outip) >> 2;
+ ident = (getpid() & 0xffff) | 0x8000;
+ if (useicmp) {
+ outip->ip_p = IPPROTO_ICMP;
+
+ outicmp = (struct icmp *)outp;
+ outicmp->icmp_type = ICMP_ECHO;
+ outicmp->icmp_id = htons(ident);
+
+ outdata = (struct outdata *)(outp + 8); /* XXX magic number */
+ } else {
+ outip->ip_p = IPPROTO_UDP;
+
+ outudp = (struct udphdr *)outp;
+ outudp->uh_sport = htons(ident);
+ outudp->uh_ulen =
+ htons((u_short)(packlen - (sizeof(*outip) + optlen)));
+ outdata = (struct outdata *)(outudp + 1);
+ }
+
/* Get the interface address list */
- n = ifaddrlist(&al, errbuf);
+#if HAVE_SNPRINTF
+ n = ifaddrlist(&allist, errbuf, sizeof(errbuf));
+#else
+ n = ifaddrlist(&allist, errbuf);
+#endif
+ al = allist;
if (n < 0) {
Fprintf(stderr, "%s: ifaddrlist: %s\n", prog, errbuf);
exit(1);
@@ -709,6 +761,15 @@
/* Determine our source address */
if (source == NULL) {
+#ifdef USE_KERNEL_ROUTING_TABLE
+ /* Search the kernel routing table for a match with the
+ * destination address. Then use that interface. If
+ * there is no match, default to using the first
+ * interface found.
+ */
+ al = search_routing_table(to, allist, n);
+ setsin(from, al->addr);
+#else
/*
* If a device was specified, use the interface address.
* Otherwise, try to determine our source address.
@@ -720,6 +781,7 @@
prog, err);
exit(1);
}
+#endif
} else {
hi = gethostinfo(source);
source = hi->name;
@@ -751,10 +813,6 @@
freehostinfo(hi);
}
- /* Revert to non-privileged user after opening sockets */
- setgid(getgid());
- setuid(getuid());
-
outip->ip_src = from->sin_addr;
#ifndef IP_HDRINCL
if (bind(sndsock, (struct sockaddr *)from, sizeof(*from)) < 0) {
@@ -803,9 +861,11 @@
++gotlastaddr;
}
Printf(" %.3f ms", deltaT(&t1, &t2));
+ ip = (struct ip *)packet;
+ if (ttl_flag)
+ Printf(" (%d)", ip->ip_ttl);
if (i == -2) {
#ifndef ARCHAIC
- ip = (struct ip *)packet;
if (ip->ip_ttl <= 1)
Printf(" !");
#endif
@@ -820,7 +880,6 @@
case ICMP_UNREACH_PORT:
#ifndef ARCHAIC
- ip = (struct ip *)packet;
if (ip->ip_ttl <= 1)
Printf(" !");
#endif
@@ -853,8 +912,14 @@
break;
case ICMP_UNREACH_FILTER_PROHIB:
+ case ICMP_UNREACH_NET_PROHIB: /* misuse */
+ ++unreachable;
+ Printf(" !A");
+ break;
+
+ case ICMP_UNREACH_HOST_PROHIB:
++unreachable;
- Printf(" !X");
+ Printf(" !C");
break;
case ICMP_UNREACH_HOST_PRECEDENCE:
@@ -867,6 +932,23 @@
Printf(" !C");
break;
+ case ICMP_UNREACH_NET_UNKNOWN:
+ case ICMP_UNREACH_HOST_UNKNOWN:
+ ++unreachable;
+ Printf(" !U");
+ break;
+
+ case ICMP_UNREACH_ISOLATED:
+ ++unreachable;
+ Printf(" !I");
+ break;
+
+ case ICMP_UNREACH_TOSNET:
+ case ICMP_UNREACH_TOSHOST:
+ ++unreachable;
+ Printf(" !T");
+ break;
+
default:
++unreachable;
Printf(" !<%d>", code);
@@ -894,7 +976,7 @@
struct timeval now, wait;
struct timezone tz;
register int cc = 0;
- int fromlen = sizeof(*fromp);
+ socklen_t fromlen = sizeof(*fromp);
FD_ZERO(&fds);
FD_SET(sock, &fds);
@@ -938,7 +1020,7 @@
/* Payload */
outdata->seq = seq;
outdata->ttl = ttl;
- outdata->tv = *tp;
+ memcpy(&outdata->tv, tp, sizeof(outdata->tv));
if (useicmp)
outicmp->icmp_seq = htons(seq);
@@ -1003,12 +1085,13 @@
#ifdef __hpux
cc = sendto(sndsock, useicmp ? (char *)outicmp : (char *)outudp,
- packlen - (sizeof(*outip) + optlen), 0, &whereto, sizeof(whereto));
+ packlen - (sizeof(*outip) + optlen), 0,
+ (struct sockaddr *)&whereto, sizeof(whereto));
if (cc > 0)
cc += sizeof(*outip) + optlen;
#else
cc = sendto(sndsock, (char *)outip,
- packlen, 0, &whereto, sizeof(whereto));
+ packlen, 0, (struct sockaddr *)&whereto, sizeof(whereto));
#endif
if (cc < 0 || cc != packlen) {
if (cc < 0)
@@ -1039,12 +1122,12 @@
static char *ttab[] = {
"Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable",
"Source Quench", "Redirect", "ICMP 6", "ICMP 7",
- "Echo", "ICMP 9", "ICMP 10", "Time Exceeded",
+ "Echo", "Router Advert", "Router Solicit", "Time Exceeded",
"Param Problem", "Timestamp", "Timestamp Reply", "Info Request",
- "Info Reply"
+ "Info Reply", "Mask Request", "Mask Reply"
};
- if (t > 16)
+ if (t > 18)
return("OUT-OF-RANGE");
return(ttab[t]);
@@ -1272,6 +1355,11 @@
addr = inet_addr(hostname);
if ((int32_t)addr != -1) {
hi->name = strdup(hostname);
+ if (hi->name == NULL) {
+ Fprintf(stderr, "%s: strdup %s\n",
+ prog, strerror(errno));
+ exit(1);
+ }
hi->n = 1;
hi->addrs = calloc(1, sizeof(hi->addrs[0]));
if (hi->addrs == NULL) {
@@ -1293,6 +1381,11 @@
exit(1);
}
hi->name = strdup(hp->h_name);
+ if (hi->name == NULL) {
+ Fprintf(stderr, "%s: strdup %s\n",
+ prog, strerror(errno));
+ exit(1);
+ }
for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
continue;
hi->n = n;
@@ -1381,8 +1474,96 @@
Fprintf(stderr, "Version %s\n", version);
Fprintf(stderr,
- "Usage: %s [-dFInrvx] [-g gateway] [-i iface] [-f first_ttl]\n"
+ "Usage: %s [-dFIlnrvx] [-g gateway] [-i iface] [-f first_ttl]\n"
"\t[-m max_ttl] [ -p port] [-q nqueries] [-s src_addr] [-t tos]\n"
"\t[-w waittime] [-z pausemsecs] host [packetlen]\n", prog);
exit(1);
}
+
+
+#ifdef USE_KERNEL_ROUTING_TABLE
+
+/* This function currently only supports IPv4. Someone who knows
+ * more about multi-protocol socket stuff should take a look at this.
+ *
+ * (But does it make any sense for traceroute to support other
+ * protocols? Maybe IPv6...
+ */
+
+struct ifaddrlist *search_routing_table(struct sockaddr_in *to, struct ifaddrlist *al, int n)
+{
+ struct ifaddrlist *first_if;
+ FILE *fp;
+ char buf[1024];
+ char ifname[128];
+ unsigned int route_dest;
+ unsigned int mask;
+ char best_name[128];
+ unsigned int best_mask;
+ unsigned int dest_addr;
+ unsigned int convs;
+
+ /* How come using ntohl(to->sin_addr.s_addr) doesn't work here? */
+ dest_addr = to->sin_addr.s_addr;
+
+ fp = fopen("/proc/net/route", "r");
+ if (fp == NULL) {
+ return al;
+ }
+
+ /* Skip the first line (the column headings) */
+ if (fgets(buf, sizeof(buf), fp) == NULL) {
+ fclose(fp);
+ return al;
+ }
+
+ best_name[0] = '\0';
+ best_mask = 0;
+
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ /* Field 1: interface name
+ * Field 2: dest addr
+ * Field 8: genmask
+ */
+ convs = sscanf(buf, "%127s %x %*s %*s %*s %*s %*s %x",
+ ifname, &route_dest, &mask);
+ if (convs != 3) {
+ /* format error .... */
+ fclose(fp);
+ return al;
+ }
+
+ if ((dest_addr & mask) == route_dest) {
+ /* This routing entry applies to
+ * our destination addr
+ */
+ if ((mask > best_mask) || (best_mask == 0)) {
+ /* And it is more specific than any
+ * previous match (or is the first match)
+ */
+ best_mask = mask;
+ strncpy(best_name, ifname,
+ sizeof(best_name) - 1);
+ best_name[sizeof(best_name) - 1] = 0;
+ }
+ }
+ }
+
+ fclose(fp);
+
+ /* If we don't find a match, we'll return the first entry */
+ first_if = al;
+
+ while (al < first_if + n) {
+ if (strcmp(best_name, al->device) == 0) {
+ /* Got a match */
+ return al;
+ }
+ al++;
+ }
+
+ return first_if;
+}
+
+#endif
+
--- traceroute-1.4a12.orig/debian/changelog
+++ traceroute-1.4a12/debian/changelog
@@ -0,0 +1,63 @@
+traceroute (1.4a12-5) unstable; urgency=low
+
+ * Restrict the -s option to the super-user.
+ * Updated documentation for the -s option (closes: #105362).
+
+ -- Herbert Xu <herbert@debian.org> Mon, 16 Jul 2001 19:28:45 +1000
+
+traceroute (1.4a12-4) unstable; urgency=low
+
+ * Updated aclocal.m4 for autoconf 2.50 (closes: #98367).
+
+ -- Herbert Xu <herbert@debian.org> Wed, 23 May 2001 18:48:59 +1000
+
+traceroute (1.4a12-3) unstable; urgency=low
+
+ * Drop privileges earlier.
+ * Applied "paranoia" patch from Richard Kettlewell (closes: #85619).
+ - eliminate unbounded sprintf calls
+ - eliminate unbounded sscanf calls
+ - strncpy final-null paranoia
+ * Set HAVE_RAW_OPTIONS (closes: #78475).
+ * Added missing option to usage (Neale Banks, closes: #88892).
+
+ -- Herbert Xu <herbert@debian.org> Fri, 9 Mar 2001 22:24:11 +1100
+
+traceroute (1.4a12-2) unstable; urgency=low
+
+ * Made changes for dpkg-statoverride (closes: #83817).
+
+ -- Herbert Xu <herbert@debian.org> Sun, 28 Jan 2001 21:49:35 +1100
+
+traceroute (1.4a12-1) unstable; urgency=low
+
+ * New upstream release (closes: #79920, #81395).
+ * Use struct sockaddr_stroage (closes: #79348).
+
+ -- Herbert Xu <herbert@debian.org> Fri, 26 Jan 2001 20:57:21 +1100
+
+traceroute (1.4a8-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Herbert Xu <herbert@debian.org> Sat, 9 Dec 2000 14:18:00 +1100
+
+traceroute (1.4a5-3) stable unstable; urgency=low
+
+ * Fixed a bug where free(3) was called on non-malloced memory.
+
+ -- Herbert Xu <herbert@debian.org> Thu, 24 Aug 2000 20:44:51 +1000
+
+traceroute (1.4a5-2) frozen unstable; urgency=low
+
+ * Use config.* from automake, needed for building traceroute on ARM
+ (closes: #61267).
+
+ -- Herbert Xu <herbert@debian.org> Fri, 31 Mar 2000 07:50:33 +1000
+
+traceroute (1.4a5-1) unstable; urgency=low
+
+ * Initial release (closes: #34166).
+
+ -- Herbert Xu <herbert@debian.org> Mon, 1 Nov 1999 15:11:06 +1100
+
--- traceroute-1.4a12.orig/debian/control
+++ traceroute-1.4a12/debian/control
@@ -0,0 +1,22 @@
+Source: traceroute
+Section: net
+Priority: optional
+Maintainer: Herbert Xu <herbert@debian.org>
+Standards-Version: 3.5.5
+Build-Depends: automake, autoconf, debhelper
+
+Package: traceroute
+Architecture: any
+Depends: ${shlibs:Depends}
+Conflicts: suidmanager (<< 0.50)
+Replaces: netstd
+Description: Traces the route taken by packets over a TCP/IP network.
+ The traceroute utility displays the route used by IP packets on their way to a
+ specified network (or Internet) host. Traceroute displays the IP number and
+ host name (if possible) of the machines along the route taken by the packets.
+ Traceroute is used as a network debugging tool. If you're having network
+ connectivity problems, traceroute will show you where the trouble is coming
+ from along the route.
+ .
+ Install traceroute if you need a tool for diagnosing network connectivity
+ problems.
--- traceroute-1.4a12.orig/debian/copyright
+++ traceroute-1.4a12/debian/copyright
@@ -0,0 +1,16 @@
+This package was split from netstd by Herbert Xu herbert@debian.org on
+Mon, 1 Nov 1999 15:14:03 +1100.
+
+netstd was created by Peter Tobias tobias@et-inf.fho-emden.de on
+Wed, 20 Jul 1994 17:23:21 +0200.
+
+It was downloaded from ftp://ftp.ee.lbl.gov/.
+
+Copyright:
+
+Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996, 1997
+The Regents of the University of California. All rights reserved.
+
+The license can be found in /usr/share/common-licenses/BSD.
+
+$Id: copyright,v 1.1 1999/11/01 04:34:49 herbert Exp $
--- traceroute-1.4a12.orig/debian/rules
+++ traceroute-1.4a12/debian/rules
@@ -0,0 +1,96 @@
+#!/usr/bin/make -f
+# GNU copyright 1997 to 1999 by Joey Hess.
+# Copyright (c) 1999 Herbert Xu <herbert@debian.org>
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+# This is the debhelper compatability version to use.
+export DH_COMPAT=2
+
+build: build-stamp
+build-stamp:
+ dh_testdir
+
+ if [ ! -f configure.old ]; then \
+ mv configure configure.old; \
+ mv config.guess config.guess.old; \
+ mv config.sub config.sub.old; \
+ mv linux-include/netinet/in_systm.h linux-include; \
+ mv linux-include/netinet/ip.h linux-include; \
+ mv linux-include/netinet/ip_icmp.h linux-include; \
+ cp /usr/share/automake/config.guess .; \
+ cp /usr/share/automake/config.sub .; \
+ autoconf; \
+ fi
+ if [ ! -f Makefile ]; then ./configure; fi
+ $(MAKE) CCOPT="-g -O2"
+
+ touch build-stamp
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp install-stamp
+
+ -$(MAKE) distclean
+ if [ -f configure.old ]; then \
+ mv configure.old configure; \
+ mv config.guess.old config.guess; \
+ mv config.sub.old config.sub; \
+ mv linux-include/in_systm.h linux-include/netinet; \
+ mv linux-include/ip.h linux-include/netinet; \
+ mv linux-include/ip_icmp.h linux-include/netinet; \
+ fi
+
+ dh_clean
+
+install: build install-stamp
+install-stamp:
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ install traceroute debian/traceroute/usr/sbin
+ cp traceroute.8 debian/traceroute/usr/share/man/man8
+
+ touch install-stamp
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+# dh_testversion
+ dh_testdir
+ dh_testroot
+# dh_installdebconf
+ dh_installdocs
+ dh_installexamples
+ dh_installmenu
+# dh_installemacsen
+# dh_installpam
+# dh_installinit
+ dh_installcron
+ dh_installmanpages
+ dh_installinfo
+# dh_undocumented
+ dh_installchangelogs CHANGES
+ dh_link
+ dh_strip
+ dh_compress
+ dh_fixperms
+ # You may want to make some executables suid here.
+ chmod u+s debian/traceroute/usr/sbin/traceroute
+# dh_makeshlibs
+ dh_installdeb
+# dh_perl
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install
--- traceroute-1.4a12.orig/debian/traceroute.dirs
+++ traceroute-1.4a12/debian/traceroute.dirs
@@ -0,0 +1,2 @@
+usr/sbin
+usr/share/man/man8
--- traceroute-1.4a12.orig/debian/traceroute.docs
+++ traceroute-1.4a12/debian/traceroute.docs
@@ -0,0 +1 @@
+README
--- traceroute-1.4a12.orig/debian/traceroute.examples
+++ traceroute-1.4a12/debian/traceroute.examples
@@ -0,0 +1,2 @@
+mean.awk
+median.awk