【问题标题】:Extending packet header from within a Netfilter hook从 Netfilter 挂钩中扩展数据包标头
【发布时间】:2011-08-05 11:40:28
【问题描述】:

我想在 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 重组代码)?

【问题讨论】:

    标签: network-programming linux-kernel ip netfilter


    【解决方案1】:

    这对我有用,在 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;
    

    希望对你有帮助。

    【讨论】:

    • 谢谢弗雷德。它适用于较小的修正:pskb_expand_head 成功时返回 0。所以检查应该改为 if (0 != pskb_expand_head(skb, sizeof(struct iphdr) - skb_headroom(skb), 0, GFP_ATOMIC))。
    • 我忘了在这篇文章中添加一些内容。我使用 kfree_skb 因为我要返回 NF_STOLEN。您可以返回 NF_DROP,但不能释放 skb。 NF_DROP 将告诉应用程序数据包发送失败。但是 NF_STOLEN 没有。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-01
    • 1970-01-01
    • 2016-10-01
    • 2020-03-14
    • 1970-01-01
    • 2011-10-16
    • 1970-01-01
    相关资源
    最近更新 更多