if (hlen < sizeof(struct iphdr))
                        return hdr.network - data;
 
-               /* record next protocol */
-               nexthdr = hdr.ipv4->protocol;
-               hdr.network += hlen;
+               /* record next protocol if header is present */
+               if (!hdr.ipv4->frag_off)
+                       nexthdr = hdr.ipv4->protocol;
        } else if (protocol == __constant_htons(ETH_P_IPV6)) {
                if ((hdr.network - data) > (max_len - sizeof(struct ipv6hdr)))
                        return max_len;
 
                /* record next protocol */
                nexthdr = hdr.ipv6->nexthdr;
-               hdr.network += sizeof(struct ipv6hdr);
+               hlen = sizeof(struct ipv6hdr);
        } else {
                return hdr.network - data;
        }
 
+       /* relocate pointer to start of L4 header */
+       hdr.network += hlen;
+
        /* finally sort out TCP */
        if (nexthdr == IPPROTO_TCP) {
                if ((hdr.network - data) > (max_len - sizeof(struct tcphdr)))