Fix for dropping of 4.3BSD IP options
David P. Zimmerman
dpz at rutgers.rutgers.edu
Mon Jan 9 20:56:10 AEST 1989
The problem:
4.3BSD drops the IP options on the floor when it turns an ICMP request
into a reply. This doesn't make things easy, especially for doing
useful things like ping with record route.
The fix:
Apply these two patches. The first is for sys/netinet/ip_input.c, the
second is for sys/netinet/ip_icmp.c.
No, it isn't backwards compatible with the original way
ip_stripoptions(ip, real_mbuf) worked, but nothing was using it that
way anyway. Looked like a half-solution waiting for a problem.
ip_stripoptions(ip, (struct mbuf *)0)) still works normally.
David
: This is a shell archive.
: Remove everything above this line and
: run the following text with /bin/sh to create:
: ip_input.c.diff
: ip_icmp.c.diff
: This archive created: Mon Jan 9 05:51:11 1989
cat << 'SHAR_EOF' > ip_input.c.diff
*** /tmp/geta4604 Mon Jan 9 05:10:02 1989
--- /tmp/getb4604 Mon Jan 9 05:10:02 1989
***************
*** 783,798 ****
register int i;
register struct mbuf *m;
register caddr_t opts;
! int olen;
olen = (ip->ip_hl<<2) - sizeof (struct ip);
m = dtom(ip);
opts = (caddr_t)(ip + 1);
if (mopt) {
! mopt->m_len = olen;
! mopt->m_off = MMINOFF;
! bcopy(opts, mtod(mopt, caddr_t), (unsigned)olen);
! }
i = m->m_len - (sizeof (struct ip) + olen);
bcopy(opts + olen, opts, (unsigned)i);
m->m_len -= olen;
--- 783,834 ----
register int i;
register struct mbuf *m;
register caddr_t opts;
! int olen, optsoff = 0;
olen = (ip->ip_hl<<2) - sizeof (struct ip);
m = dtom(ip);
opts = (caddr_t)(ip + 1);
+
if (mopt) {
!
! /* If m_len is 0, we're dealing with an option set which ip_srcroute
! ** found no source routing in. So, we've got an empty mbuf, into the
! ** beginning of which we have to coerce a "first hop" address. In a
! ** packet with no source routing, this would be the destination
! ** address. Otherwise, m_len is real, and we're just appending to
! ** the mbuf coming out of ip_srcroute. */
!
! if (!mopt->m_len) {
! mopt->m_len = sizeof(struct in_addr);
! bcopy(&ip->ip_dst, mtod(mopt, caddr_t), mopt->m_len);
! }
!
! /* Push the rest of the options in. We don't have to worry about the
! ** other IP level options like we do the source routing, so just
! ** search for them and insert them into the mbuf. Notice that
! ** anything dealing with source routing is ignored, since you would
! ** want to do that in ip_srcroute instead. */
!
! while (optsoff + 1 <= olen)
! switch(opts[optsoff]) {
! case IPOPT_LSRR:
! case IPOPT_SSRR:
! optsoff += opts[optsoff + IPOPT_OLEN];
! break;
! case IPOPT_EOL:
! case IPOPT_NOP:
! mopt->m_dat[mopt->m_len++] = opts[optsoff++];
! break;
! default:
! bcopy(&opts[optsoff], &mopt->m_dat[mopt->m_len],
! opts[optsoff + IPOPT_OLEN]);
! mopt->m_len += opts[optsoff + IPOPT_OLEN];
! optsoff += opts[optsoff + IPOPT_OLEN];
! break;
! }
! mopt->m_off = MMINOFF;
! }
!
i = m->m_len - (sizeof (struct ip) + olen);
bcopy(opts + olen, opts, (unsigned)i);
m->m_len -= olen;
SHAR_EOF
cat << 'SHAR_EOF' > ip_icmp.c.diff
*** /tmp/geta4590 Mon Jan 9 05:09:27 1989
--- /tmp/getb4590 Mon Jan 9 05:09:27 1989
***************
*** 376,386 ****
if (optlen > 0) {
/*
* Retrieve any source routing from the incoming packet
! * and strip out other options. Adjust the IP length.
*/
opts = ip_srcroute();
ip->ip_len -= optlen;
- ip_stripoptions(ip, (struct mbuf *)0);
}
icmp_send(ip, opts);
if (opts)
--- 376,393 ----
if (optlen > 0) {
/*
* Retrieve any source routing from the incoming packet
! * and merge in the other non-routing options.
! * Adjust the IP length.
*/
opts = ip_srcroute();
+ if (!opts)
+ if (opts = m_get(M_DONTWAIT, MT_SOOPTS))
+ opts->m_len = 0;
+ if (opts)
+ ip_stripoptions(ip, opts);
+ else /* admit defeat */
+ ip_stripoptions(ip, (struct mbuf *)0);
ip->ip_len -= optlen;
}
icmp_send(ip, opts);
if (opts)
SHAR_EOF
: End of shell archive
exit 0
--
David P. Zimmerman, the Dorm Networking Pilot Project, the UUCP Project, etc
dpz at dorm.rutgers.edu rutgers!dpz dpzimmerman at zodiac.bitnet
More information about the Comp.bugs.4bsd.ucb-fixes
mailing list