tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: IPv6 fragmentation issue for first fragment



On Sun, Oct 21, 2012 at 6:50 PM, Greg Troxel <gdt%ir.bbn.com@localhost> wrote:
>
> Loganaden Velvindron <loganaden%gmail.com@localhost> writes:
>
>> An interesting case is explained here about:
>>
>> http://tools.ietf.org/id/draft-ietf-6man-oversized-header-chain-01.txt
>>
>> Quote:
>>
>>    If a packet is fragmented, the first fragment of the packet (i.e.,
>>    that with a Fragment Offset of 0) MUST contain the entire IPv6 header
>>    chain.
>>
>> I'm still new to ipv6 and i was thinking about something like this:
>>
>> if fragoff == 0 && q6->ip6q_unfraglen > 1280, drop_packet(); else 
>> process_it();
>
> Are you worrying about outbound or inbound processing?
>
Inbound for now.

> The headers are variable length.  So on outbound, if one is creating a
> fragment that won't include all of them, I think you have to return an
> error (probably to the socket, but tunnel-mode IPsec packets can count
> as locally sourced).
>

According to my understanding of the draft, the first fragment should include
all the headers including the extension headers as well as TCP/UDP, if present.

I still haven't looked at the outbound part.

> On inbound, absent trying to firewall, I'm not sure there is much to be
> done, other than to check for this and drop.

Yes. I'm interested in that part: detecting that this has occured in
the first fragment,
and drop the packet if the headers don't fit below the MTU.

>But a firewall probably
> should chase the header chain for first fragments and verify that it
> fits.  A firewall probably should be validating all the headers anyway.
>
> Can you point to something in the NetBSD code that's wrong?  (I'm not
> trying to claim that there is nothing wrong.)

I'm not sure about this part, as NetBSD already implements many checks.

From cvsweb:
        /*
         * If it's the 1st fragment, record the length of the
         * unfragmentable part and the next header of the fragment header.
         */

        if (fragoff == 0) {
                q6->ip6q_unfrglen = offset - sizeof(struct ip6_hdr) -
                    sizeof(struct ip6_frag);
                q6->ip6q_nxt = ip6f->ip6f_nxt;
        }

        /*
         * Check that the reassembled packet would not exceed 65535 bytes
         * in size.
         * If it would exceed, discard the fragment and return an ICMP error.
         */
        frgpartlen = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen) - offset;
        if (q6->ip6q_unfrglen >= 0) {
                /* The 1st fragment has already arrived. */
                if (q6->ip6q_unfrglen + fragoff + frgpartlen > IPV6_MAXPACKET) {
                        mutex_exit(&frag6_lock);
                        icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
                            offset - sizeof(struct ip6_frag) +
                            offsetof(struct ip6_frag, ip6f_offlg));
                        return IPPROTO_DONE;
                }
        } else if (fragoff + frgpartlen > IPV6_MAXPACKET) {
                mutex_exit(&frag6_lock);
                icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
                            offset - sizeof(struct ip6_frag) +
                                offsetof(struct ip6_frag, ip6f_offlg));
                return IPPROTO_DONE;
        }


I was thinking about a similar check for the first fragment. What do
you think :-) ?

I should add that I just started reading the RFCs :-)


-- 
Brightest day,
Blackest night,
No bug shall escape my sight,
And those who worship evil's mind,
be wary of my powers,
puffy lantern's light !


Home | Main Index | Thread Index | Old Index