Subject: kern/7818: ICMP protocol packets are not handled for localhost
To: None <tech-net@netbsd.org>
From: Darren Reed <darrenr@reed.wattle.id.au>
List: tech-net
Date: 06/20/1999 20:00:30
Folks,
I've submitted a PR on bad ICMP behaviour and in researching a fix,
found that the bug which causes the "unknown protocol" counter to get
increased is what (on BSD) makes the UDP traceroute possible. The bug
appears to be that in ip_icmp.c, at about line 363 (in the code section
after the "deliver" label) there's a "break" rather than a "return". The
subsequent effect is to let the packet drop through to the "raw" label
and get fed into rip_input() and hence traceroute is able to get it. I'm
sure there's a good reason to pass processed packets on to rip_input()
that have already been processed...I'm just not sure I understand what
that would be and if so, why it would be limited to ICMP (other than to
support traceroute). Anyway, the easiest fix I can think of which won't
disturb anything (except for correcting the "unknown protocol" statistics
count) is to add another mbuf flag - M_DELIVERED (0x800) - set that in
icmp_input() before calling rip_input() and not fiddle with the statistics
counters in the tail end of rip_input() if M_DELIVERED is set. If this
is an acceptable patch, I'd like for it to be pulled up into 1.4.1.
Darren
*** sys/mbuf.h.dist Sun Jun 20 19:53:16 1999
--- sys/mbuf.h Sun Jun 20 19:55:30 1999
***************
*** 171,176 ****
--- 171,178 ----
#define M_MCAST 0x0200 /* send/received as link-level multicast */
#define M_CANFASTFWD 0x0400 /* used by filters to indicate packet can
be fast-forwarded */
+ #define M_DELIVERED 0x0800 /* used to tell rip_input that it isn't an
+ unknown packet and has been delivered */
#define M_LINK0 0x1000 /* link layer specific flag */
#define M_LINK1 0x2000 /* link layer specific flag */
#define M_LINK2 0x4000 /* link layer specific flag */
*** netinet/ip_icmp.c.dist Sun Jun 20 19:53:23 1999
--- netinet/ip_icmp.c Sun Jun 20 19:56:38 1999
***************
*** 458,463 ****
--- 458,464 ----
}
raw:
+ m->m_flags |= M_DELIVERED;
rip_input(m);
return;
*** netinet/raw_ip.c.dist Sun Jun 20 19:53:27 1999
--- netinet/raw_ip.c Sun Jun 20 19:54:42 1999
***************
*** 160,168 ****
} else
sorwakeup(last->inp_socket);
} else {
m_freem(m);
- ipstat.ips_noproto++;
- ipstat.ips_delivered--;
}
}
--- 160,170 ----
} else
sorwakeup(last->inp_socket);
} else {
+ if ((m->m_flags & M_DELIVERED) == 0) {
+ ipstat.ips_noproto++;
+ ipstat.ips_delivered--;
+ }
m_freem(m);
}
}