从 Netfilter 挂钩内扩展数据包标头

发布于 2024-11-01 02:48:35 字数 411 浏览 0 评论 0原文

我想在 NF_HOOK_LOCAL_OUT 内部的现有 IP 数据包上添加 IP 标头。我面临的问题是skb扩展函数(例如复制/克隆/扩展/重新分配标头)分配一个新的sk_buff。我们无法返回这个新分配的指针,因为 netfilter 钩子函数(内核版本 2.6.31)不再传递 skb 指针的地址(按值传递)。我解决这个问题的方法如下: 1.我使用skb_header_realloc()获得了一个新的skb。这会复制 skb 中的所有数据。 2.我修改了新的skb(称为skb2)以添加新的IP标头,在新的IP标头中设置适当的值。 3. 使用skb_morph()将原始skb的内容(在Netfilter钩子函数中传递)替换为skb2的内容。返回 NF_ACCEPT。

这是实现我的目的的唯一方法吗?有更有效的解决方案吗? skb_morph 是否还有其他用例(除了 IP 重组代码)?

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)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

榕城若虚 2024-11-08 02:48:35

这对我有用,在 2.6 内核中:

...
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;

希望它有帮助。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文