|
|
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.