我目前正在编写一个内核模块,它将数据包有效负载修改为学习体验。我已完成数据包修改,但现在我想在原始之后发送这个新修改的数据包(我不想丢弃原始数据包)。我似乎无法找到一个发送SKB进行传输的内核函数。我已经尝试了dev_queue_xmit(nskb)
,但这导致内核恐慌,我也尝试了skb->next = nskb
但是什么也没做。我是否必须实施SKB列表处理?自本文seems to be outdated 以来,我不确定如何做到这一点。
编辑:
所以我在调用dev_queue_xmit(nskb)时能够修复内核恐慌,我不小心做了dev_queue_xmit(skb),它会删除skb并导致网络过滤器出现恐慌。问题是现在一切正常,但我没有看到重复的数据包被发送出去,没有第二个数据包的踪迹被发送。机器上的TCPDump看不到任何东西,目标上的TPCDump也看不到任何东西,以下是我的代码。
unsigned int in_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) {
struct sk_buff *nskb = skb_copy(skb, GFP_KERNEL);
/* Various other variables not relevant to the problem */
__u32 saddr, daddr;
saddr = ntohl(iph->saddr);
if (saddr == ipToInt(10,0,2,12) || saddr == ipToInt(10,0,2,13)) {
/*For loop that saves the payload contents into a variable */
/* Here is where the problem is,
I have this if statement to prevent a feedback loop
then if the ip matches, I call dev_queue_xmit(nskb)
which is supposed to send out sk_buff's, but TCPDump doesn't
show anything on any computer */
if (saddr == ipToInt(10,0,2,13)) {
dev_queue_xmit(nskb);
}
/* Rest of the code that isn't relevant to sending packets */
}
return NF_ACCEPT;
}
我的网络设置如下,它是3个Ubuntu服务器虚拟机,所有这些都是从主机进入SSH(macOS如果重要,我不会'我知道这一点)。运行上述内核模块的计算机双向欺骗其他两个VM。然后另外两个VM通过netcat会话相互通信。我希望当我用VM 10.0.2.13从VM发送一条消息时,10.0.2.12会看到两条相同的消息。我知道确认号码不幸会破坏连接,但我没有得到这个。除了应该发送的数据包之外,3台计算机中的任何一台计算机上的TCPDump都没有显示任何内容。
到目前为止,我已尝试dev_queue_xmit(nskb)
以及nskb->dev->netdev_ops->ndo_start_xmit(nskb, skb->dev)
。
答案 0 :(得分:1)
据我所知,dev_queue_xmit()是发送的正确程序。问题是你如何准备要发送的skb?当发生内核恐慌时,也给我们来自dmesg的calltrace。你设置了skb-> dev?
答案 1 :(得分:0)
我想通了,skb_copy没有复制skb的以太网头,所以发送的数据包永远不会到达目的地。