我正在实现一个IP头压缩协议作为可加载的内核模块,它采用IPv4标头并将其压缩为较小的标头(让我们称之为“iphc”标头)。
为此,对于传出数据包,我已经使用NF_IP_POST_ROUTING
netfilter挂钩在路由决策完成后抓取数据包。然后,我想用IPHC头(压缩IP)替换IP头,将ethertype更改为其他内容,将其发送到堆栈(到以太网)并输出。从我所看到的情况来看,当我在NF_IP_POST_ROUTING
挂钩处拦截数据包时,尚未添加MAC头。
我有几个问题:
鉴于我正在更换IP标头,是否会影响以太网查找MAC硬件地址的能力?我在ip_finish_output2()
函数中看到,它们使用skbuff中的dst值(使用skb_dst()
函数)在邻居表中搜索ARP条目。如果我只使用IPHC标头交换IP标头并更改协议,ARP查找是否会失败?我不认为我已经触及了skbuff中的“dst”字段。
我是否只需用IPHC标头替换IP标头,更改以太网类型,然后将其发送回堆栈?或者我应该直接传输它而不将其返回到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;
我在这里遗漏了什么吗?谢谢!
答案 0 :(得分:0)
skb_pull()和skb_push()。
当数据包在NF_IP_POST_ROUTING被截获时,很可能skb->数据指向帧的开头,这也是MAC头的开头。
因此,在进行任何skb_push()操作之前,应先使用skb_pull()先拔出MAC头,然后再拔出IP头。然后将数据(MAC + IPHDR)缩小为(MAC + IPHC),并将skb_push()合并为(MAC + IPHC) - 或者您可以先将IPHC推送到MAC。
有关这些skb函数的详细信息,请参阅skbuff.h,可以找到关于skb的优秀教程here。