2

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

为此,对于传出数据包,我使用NF_IP_POST_ROUTINGnetfilter 钩子在路由决策完成后抓取数据包。然后,我想用 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;

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

4

1 回答 1

0

如果不知道 skb->data 当前指向的位置,就不能使用 skb_pull() 和 skb_push()。

当数据包在 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 的优秀教程可以在这里找到。

于 2012-11-02T06:43:54.100 回答