BSD 4_4_Lite2 development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Sat, 14 Jan 1989 12:57:31 +0000 (04:57 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Sat, 14 Jan 1989 12:57:31 +0000 (04:57 -0800)
Work on file usr/src/usr.sbin/traceroute/README

Synthesized-from: CSRG/cd3/4.4BSD-Lite2

usr/src/usr.sbin/traceroute/README [new file with mode: 0644]

diff --git a/usr/src/usr.sbin/traceroute/README b/usr/src/usr.sbin/traceroute/README
new file mode 100644 (file)
index 0000000..6d33c6c
--- /dev/null
@@ -0,0 +1,126 @@
+Tue Dec 27 06:24:24 PST 1988
+
+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).
+
+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
+
+       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).
+
+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);
+}