【问题标题】:Finalizing Xmit of Compressed IP Header完成压缩 IP 标头的 Xmit
【发布时间】:2012-09-07 21:00:40
【问题描述】:

我正在将 IP 标头压缩协议实现为可加载的内核模块,该模块采用 IPv4 标头并将其压缩为更小的标头(我们称之为“iphc”标头)。

为此,对于传出的数据包,我使用NF_IP_POST_ROUTING netfilter 挂钩在路由决策完成后抓取数据包。然后,我想用 IPHC 标头(压缩 IP)替换 IP 标头,将 ethertype 更改为其他类型,将其发送到堆栈(到以太网)并发送出去。据我所见,当我在NF_IP_POST_ROUTING 钩子处截获数据包时,尚未添加 MAC 标头。

我有几个问题:

  1. 鉴于我正在替换 IP 标头,这会影响以太网查找 MAC 硬件地址的能力吗?我看到在ip_finish_output2() 函数中,他们取skbuff 中的dst 值(使用skb_dst() 函数)来搜索邻居表中的ARP 条目。如果我只是用 IPHC 标头交换 IP 标头并更改协议,那么 ARP 查找会失败吗?我认为我没有触及 skbuff 中的“dst”字段。

  2. 仅用 IPHC 标头替换 IP 标头、更改 Ethertype 并将其发送回堆栈就足够了吗?还是我应该自己直接传输而不返回到 ip_finish_output2

出于某种原因,如果我执行 #2,我的代码会崩溃。下面是我在钩入 NF_IP_POST_ROUTING netfilter 钩子(传入 skb)后尝试做的一个示例:

struct iphc *my_hdr;

/* stripping the IPv4 header from skbuff */
skb_pull(skb, sizeof (struct iphdr));

/* adding my header skb */
skb_push(skb, IPHC_HDR_SIZE);

/* reset network header */
skb_reset_network_header(skb);

my_hdr = (struct iphc *)skb;

my_hdr->field1 = 1;
my_hdr->field2 = 2;

/* change ethertype */
skb->protocol = __constant_htons(ETH_P_IPHC);

return NF_ACCEPT;

我在这里错过了什么吗?谢谢!

【问题讨论】:

    标签: linux network-programming linux-kernel network-protocols


    【解决方案1】:

    skb_pull() 和 skb_push() 不能在不知道 skb->data 当前指向的位置的情况下使用。

    当数据包在NF_IP_POST_ROUTING被截获时,很可能skb->data指向了帧的开始,也就是MAC头的开始。

    因此,在进行任何 skb_push() 操作之前,您应该先使用 skb_pull() 拉出 MAC 标头,然后再拉出 IP 标头。然后将数据 (MAC+IPHDR) 压缩为 (MAC+IPHC),然后 skb_push() 完全组合 (MAC+IPHC) - 或者您可以先推送 IPHC,然后再推送 MAC。

    有关这些 skb 函数的详细信息,请参阅 skbuff.h,有关 skb 的优秀教程可以在 here 找到。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-19
      • 2016-04-29
      • 1970-01-01
      相关资源
      最近更新 更多