IPv6: incorrect routing header should yield ICMP6_PARAMPROB_HEADER

2012-04-03 Thread Mike Belopuhov
According to the RFC 2460 and RFC 5095, ICMP Parameter Problem, Code 0
should be sent, not Code 2.  OK?

(while at the spot, kill a trailing whitespace)

diff --git sys/netinet6/ip6_input.c sys/netinet6/ip6_input.c
index 6afde60..e554ad7 100644
--- sys/netinet6/ip6_input.c
+++ sys/netinet6/ip6_input.c
@@ -328,12 +328,12 @@ ip6_input(struct mbuf *m)
ip6stat.ip6s_badoptions++;
in6_ifstat_inc(m-m_pkthdr.rcvif, ifs6_in_discard);
in6_ifstat_inc(m-m_pkthdr.rcvif, ifs6_in_hdrerr);
-   icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, 0);
+   icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, 0);
/* m is already freed */
return;
}
 
-#if NPF  0 
+#if NPF  0
 /*
  * Packet filter
  */



Re: IPv6: incorrect routing header should yield ICMP6_PARAMPROB_HEADER

2012-04-03 Thread Mike Belopuhov
On Tue, Apr 03, 2012 at 13:15 +0200, Mike Belopuhov wrote:
 According to the RFC 2460 and RFC 5095, ICMP Parameter Problem, Code 0
 should be sent, not Code 2.  OK?
 
 (while at the spot, kill a trailing whitespace)
 

we have improved the diff with sperreault@ to set a pointer field as
well as leaving it as zero is not correct.  so now we'll be pointing
to the unrecognized Routing Type if we encounter a RH0 header or
to the header itself in two other cases when ip6_check_rh0hdr fails:
when there are multiple routing headers or when it's lenght is
incorrect.

i have an OK from sperreault already, but would like to get one more.


diff --git sys/netinet6/ip6_input.c sys/netinet6/ip6_input.c
index 6afde60..4f0d6e1 100644
--- sys/netinet6/ip6_input.c
+++ sys/netinet6/ip6_input.c
@@ -129,7 +129,7 @@ struct ifqueue ip6intrq;
 struct ip6stat ip6stat;
 
 void ip6_init2(void *);
-int ip6_check_rh0hdr(struct mbuf *);
+int ip6_check_rh0hdr(struct mbuf *, int *);
 
 int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
 struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int);
@@ -197,7 +197,7 @@ void
 ip6_input(struct mbuf *m)
 {
struct ip6_hdr *ip6;
-   int off = sizeof(struct ip6_hdr), nest;
+   int off, nest;
u_int32_t plen;
u_int32_t rtalert = ~0;
int nxt, ours = 0;
@@ -324,16 +324,16 @@ ip6_input(struct mbuf *m)
}
 #endif
 
-   if (ip6_check_rh0hdr(m)) {
+   if (ip6_check_rh0hdr(m, off)) {
ip6stat.ip6s_badoptions++;
in6_ifstat_inc(m-m_pkthdr.rcvif, ifs6_in_discard);
in6_ifstat_inc(m-m_pkthdr.rcvif, ifs6_in_hdrerr);
-   icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, 0);
+   icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, off);
/* m is already freed */
return;
}
 
-#if NPF  0 
+#if NPF  0
 /*
  * Packet filter
  */
@@ -572,6 +572,7 @@ ip6_input(struct mbuf *m)
 * If a JumboPayload option is included, plen will also be modified.
 */
plen = (u_int32_t)ntohs(ip6-ip6_plen);
+   off = sizeof(struct ip6_hdr);
if (ip6-ip6_nxt == IPPROTO_HOPOPTS) {
struct ip6_hbh *hbh;
 
@@ -731,7 +732,7 @@ ip6_input(struct mbuf *m)
 
 /* scan packet for RH0 routing header. Mostly stolen from pf.c:pf_test() */
 int
-ip6_check_rh0hdr(struct mbuf *m)
+ip6_check_rh0hdr(struct mbuf *m, int *offp)
 {
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
struct ip6_rthdr rthdr;
@@ -744,6 +745,7 @@ ip6_check_rh0hdr(struct mbuf *m)
do {
switch (proto) {
case IPPROTO_ROUTING:
+   *offp = off;
if (rh_cnt++) {
/* more then one rh header present */
return (1);
@@ -756,8 +758,10 @@ ip6_check_rh0hdr(struct mbuf *m)
 
m_copydata(m, off, sizeof(rthdr), (caddr_t)rthdr);
 
-   if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0)
+   if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0) {
+   *offp += offsetof(struct ip6_rthdr, ip6r_type);
return (1);
+   }
 
off += (rthdr.ip6r_len + 1) * 8;
proto = rthdr.ip6r_nxt;