Extending packet header from within a Netfilter ho

2019-04-17 13:07发布

问题:

I want to prepend IP header on an existing IP packet while inside NF_HOOK_LOCAL_OUT. The issue I face is that the skb expansion functions (such as copy/clone/expand/reallocate header) allocate a new sk_buff. We can not return this newly allocated pointer since netfilter hook function no longer (kernel version 2.6.31) passes the skb pointer's address (passes by value). How I solved the issue is as follows: 1. I got a new skb using skb_header_realloc(). This copies all the data from skb. 2. I modified the new skb (call it skb2) to prepend the new IP header, set appropriate values in the new IP header. 3. Replace the contents of the original skb (passed in the Netfilter hook function) with the contents of the skb2 using skb_morph(). Returned NF_ACCEPT.

Is this the only way of achieving what I intended to? Is there a more efficient solution? Are there other use cases of skb_morph (besides the IP reassembly code)?

回答1:

This works for me, in 2.6 kernels:

...
struct iphdr* iph;
if (skb_headroom(skb) < sizeof(struct iphdr))
  if (0 != pskb_expand_head(skb, sizeof(struct iphdr) - skb_headroom(skb), 0, GFP_ATOMIC)) {
    printk("YOUR FAVOURITE ERROR MESSAGE");
    kfree_skb(skb);
    return NF_STOLEN;
  }
iph = (struct iphdr*) skb_push(skb, sizeof(struct iphdr));
//Fill ip packet
return NF_ACCEPT;

Hope it helps.