Annotation of 43BSDReno/usr.sbin/traceroute/README, revision 1.1.1.1

1.1       root        1: Tue Dec 27 06:24:24 PST 1988
                      2: 
                      3: Traceroute is a system administrators utility to trace the route
                      4: ip packets from the current system take in getting to some
                      5: destination system.  See the comments at the front of the
                      6: program for a description of its use.
                      7: 
                      8: This program 
                      9: 
                     10:  a) can only be run by root (it uses raw ip sockets).
                     11: 
                     12:  b) REQUIRES A KERNEL MOD to the raw ip output code to run.
                     13: 
                     14: If you want to hack on your kernel, my modified version of the
                     15: routine rip_output (in file /sys/netinet/raw_ip.c) is attached.
                     16: This code may or may not resemble the code in your kernel.
                     17: It may offer you a place to start but I make no promises.
                     18: If you do hack your kernel, remember to test everything that uses
                     19: raw ip sockets (e.g., ping and egpup/gated) & make sure they still
                     20: work.  I wish you the best of luck and you're on your own.
                     21: 
                     22: If your system has the ttl bug mentioned in the source, you
                     23: might want to fix it while you're in the kernel.  (This bug
                     24: appears in all releases of BSD up to but not including 4.3tahoe.
                     25: If your version of netinet/ip_icmp.c is any earlier than 7.3
                     26: (April, '87), it has the bug.)  The fix is just to add the line
                     27:        ip->ip_ttl = MAXTTL;
                     28: after the line
                     29:        ip->ip_src = t;
                     30: (or anywhere before the call to icmp_send) in routine icmp_reflect.
                     31: 
                     32: If you're running this on a pre-4.3bsd system (e.g., Sun 3.x,
                     33: Ultrix) that strips ip headers from icmp messages, add -DARCHAIC
                     34: to CFLAGS in the Makefile.  Also note that rip_output contains
                     35: a conditional for a 4.2/4.3 change in the location of a raw
                     36: socket's protocol number.  I've checked this under 4.3 & Sun OS
                     37: 3.5 but you should double-check your system to make sure the
                     38: appropriate branch of the #if is taken (check the line that
                     39: assigned to ip->ip_p in your system's original rip_output).
                     40: 
                     41: A couple of awk programs to massage the traceroute output are
                     42: included.  "mean.awk" and "median.awk" compute the mean and median
                     43: time to each hop, respectively.  I've found that something like
                     44: 
                     45:        traceroute -q 7 foo.somewhere >t
                     46:        awk -f median.awk t | graph
                     47: 
                     48: can give you a quick picture of the bad spots on a long
                     49: path (median is usually a better noise filter than mean).
                     50: 
                     51: Enjoy.
                     52: 
                     53:  - Van Jacobson ([email protected])
                     54: 
                     55: -------------------- rip_output from /sys/netinet/raw_ip.c
                     56: rip_output(m, so)
                     57:        register struct mbuf *m;
                     58:        struct socket *so;
                     59: {
                     60:        register struct ip *ip;
                     61:        int error;
                     62:        struct rawcb *rp = sotorawcb(so);
                     63:        struct sockaddr_in *sin;
                     64: #if BSD>=43
                     65:        short proto = rp->rcb_proto.sp_protocol;
                     66: #else
                     67:        short proto = so->so_proto->pr_protocol;
                     68: #endif
                     69:        /*
                     70:         * if the protocol is IPPROTO_RAW, the user handed us a 
                     71:         * complete IP packet.  Otherwise, allocate an mbuf for a
                     72:         * header and fill it in as needed.
                     73:         */
                     74:        if (proto != IPPROTO_RAW) {
                     75:                /*
                     76:                 * Calculate data length and get an mbuf
                     77:                 * for IP header.
                     78:                 */
                     79:                int len = 0;
                     80:                struct mbuf *m0;
                     81: 
                     82:                for (m0 = m; m; m = m->m_next)
                     83:                        len += m->m_len;
                     84: 
                     85:                m = m_get(M_DONTWAIT, MT_HEADER);
                     86:                if (m == 0) {
                     87:                        m = m0;
                     88:                        error = ENOBUFS;
                     89:                        goto bad;
                     90:                }
                     91:                m->m_off = MMAXOFF - sizeof(struct ip);
                     92:                m->m_len = sizeof(struct ip);
                     93:                m->m_next = m0;
                     94: 
                     95:                ip = mtod(m, struct ip *);
                     96:                ip->ip_tos = 0;
                     97:                ip->ip_off = 0;
                     98:                ip->ip_p = proto;
                     99:                ip->ip_len = sizeof(struct ip) + len;
                    100:                ip->ip_ttl = MAXTTL;
                    101:        } else
                    102:                ip = mtod(m, struct ip *);
                    103: 
                    104:        if (rp->rcb_flags & RAW_LADDR) {
                    105:                sin = (struct sockaddr_in *)&rp->rcb_laddr;
                    106:                if (sin->sin_family != AF_INET) {
                    107:                        error = EAFNOSUPPORT;
                    108:                        goto bad;
                    109:                }
                    110:                ip->ip_src.s_addr = sin->sin_addr.s_addr;
                    111:        } else
                    112:                ip->ip_src.s_addr = 0;
                    113: 
                    114:        ip->ip_dst = ((struct sockaddr_in *)&rp->rcb_faddr)->sin_addr;
                    115: 
                    116: #if BSD>=43
                    117:        return (ip_output(m, rp->rcb_options, &rp->rcb_route, 
                    118:           (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST));
                    119: #else
                    120:        return (ip_output(m, (struct mbuf *)0, &rp->rcb_route, 
                    121:           (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST));
                    122: #endif
                    123: bad:
                    124:        m_freem(m);
                    125:        return (error);
                    126: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.