Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!uunet!ibmpa!bullhead!brunner From: brunner@bullhead.uucp Newsgroups: comp.sys.ibm.pc.rt Subject: Traceroute support (part 1) Summary: Fixes two network bugs, includes Van Jacobson's traceroute Keywords: V1.30_kit.1 netinet traceroute IBM/4.3 Message-ID: <4307@ibmpa.UUCP> Date: 1 Mar 90 20:02:45 GMT Sender: news@ibmpa.UUCP Reply-To: brunner@ibmsupt.UUCP () Organization: IBM AWD Palo Alto Lines: 200 Subject: Traceroute support (part 1) Fix: /sys/netinet/{raw_ip.c, ip_icmp.c} IBM/4.3 Description: This patch (part 1 of this kit) fixes a bug in the icmp_reflect routine. This bug appears in all releases of BSD up to but not including 4.3tahoe. Versions of netinet/ip_icmp.c earlier than 7.3 (April, '87) have the bug. icmp messages are sent using a TTL ("time to live", actually a hop count) that is copied from the header of the packet that provoked a control message reply (e.g., time exceeded or unreachable). This bug is a flaw in hosts which are configured as gateways in large networks. This patch also modifies the rip_output routine, allowing a raw ip socket using proto IPPROTO_RAW to interpret the data sent as an ip datagram (as opposed to data to be wrapped in a ip datagram). The second part of this kit contains a shar file of Van Jacobson's traceroute source, documentation and awk scripts. These files are available for anonymous ftp at several sites on the internet, but which are not well known outside the network research community. They are provided as a convienence to IBM/4.3 sites as an aid to understanding internet routing. Traceroute is a system administrator's utility to trace the route that ip packets from the localhost take going to some destination host or gateway. See the comments in traceroute.c, the README, and traceroute.8 for further details. part 1 patches to the following files in /sys/netinet: raw_ip.c, ip_icmp.c part 2 shar file containing the following files in /usr/local/traceroute: Makefile, README, mean.awk, median.awk, traceroute.8, traceroute.c Fix: Change directories to /sys/netinet and apply the following patch, e.g., patch < this_file Proceede to the next part of the kit. diff -r -c netinet/ip_icmp.c netinet.fix/ip_icmp.c *** netinet/ip_icmp.c Wed Feb 14 17:48:36 1990 --- netinet.fix/ip_icmp.c Wed Feb 14 17:48:13 1990 *************** *** 370,375 **** --- 370,376 ---- ia = in_ifaddr; t = IA_SIN(ia)->sin_addr; ip->ip_src = t; + ip->ip_ttl = MAXTTL; if (optlen > 0) { /* diff -r -c netinet/raw_ip.c netinet.fix/raw_ip.c *** netinet/raw_ip.c Wed Feb 14 17:48:36 1990 --- netinet.fix/raw_ip.c Wed Feb 14 17:47:25 1990 *************** *** 61,100 **** /* * Generate IP header and pass packet to ip_output. * Tack on options user may have setup with control call. */ ! rip_output(m0, so) ! struct mbuf *m0; struct socket *so; { - register struct mbuf *m; register struct ip *ip; ! int len = 0, error; struct rawcb *rp = sotorawcb(so); struct sockaddr_in *sin; ! /* ! * Calculate data length and get an mbuf ! * for IP header. */ ! for (m = m0; m; m = m->m_next) ! len += m->m_len; ! m = m_get(M_DONTWAIT, MT_HEADER); ! if (m == 0) { ! error = ENOBUFS; ! goto bad; ! } ! ! /* ! * Fill in IP header as needed. ! */ ! 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 = rp->rcb_proto.sp_protocol; ! ip->ip_len = sizeof(struct ip) + len; if (rp->rcb_flags & RAW_LADDR) { sin = (struct sockaddr_in *)&rp->rcb_laddr; if (sin->sin_family != AF_INET) { --- 61,117 ---- /* * Generate IP header and pass packet to ip_output. * Tack on options user may have setup with control call. + * + * Van Jacobson's traceroute support added. */ ! 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) { *************** *** 104,118 **** 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; ! ip->ip_ttl = MAXTTL; return (ip_output(m, rp->rcb_options, &rp->rcb_route, (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST)); bad: m_freem(m); return (error); } - /* * Raw IP socket option processing. */ --- 121,140 ---- 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); } /* * Raw IP socket option processing. */ Eric Brunner, Consultant, IBM AWD Palo Alto (415) 855-4486 inet: brunner@monet.berkeley.edu uucp: uunet!ibmsupt!brunner