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;

Reply via email to