|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.