summaryrefslogtreecommitdiffstats
path: root/source/n/traceroute/traceroute_1.4a12-5.diff
diff options
context:
space:
mode:
author Patrick J Volkerding <volkerdi@slackware.com>2009-08-26 10:00:38 -0500
committer Eric Hameleers <alien@slackware.com>2018-05-31 22:41:17 +0200
commit5a12e7c134274dba706667107d10d231517d3e05 (patch)
tree55718d5acb710fde798d9f38d0bbaf594ed4b296 /source/n/traceroute/traceroute_1.4a12-5.diff
downloadcurrent-5a12e7c134274dba706667107d10d231517d3e05.tar.gz
current-5a12e7c134274dba706667107d10d231517d3e05.tar.xz
Slackware 13.0slackware-13.0
Wed Aug 26 10:00:38 CDT 2009 Slackware 13.0 x86_64 is released as stable! Thanks to everyone who helped make this release possible -- see the RELEASE_NOTES for the credits. The ISOs are off to the replicator. This time it will be a 6 CD-ROM 32-bit set and a dual-sided 32-bit/64-bit x86/x86_64 DVD. We're taking pre-orders now at store.slackware.com. Please consider picking up a copy to help support the project. Once again, thanks to the entire Slackware community for all the help testing and fixing things and offering suggestions during this development cycle. As always, have fun and enjoy! -P.
Diffstat (limited to 'source/n/traceroute/traceroute_1.4a12-5.diff')
-rw-r--r--source/n/traceroute/traceroute_1.4a12-5.diff1152
1 files changed, 1152 insertions, 0 deletions
diff --git a/source/n/traceroute/traceroute_1.4a12-5.diff b/source/n/traceroute/traceroute_1.4a12-5.diff
new file mode 100644
index 000000000..8cf3d1fe1
--- /dev/null
+++ b/source/n/traceroute/traceroute_1.4a12-5.diff
@@ -0,0 +1,1152 @@
+--- 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