发送SKB从内核空间传输
我目前正在编写一个内核模块,将数据包有效载荷修改为学习体验。我已经完成了数据包修改,但是现在我想在原始数据(我不想删除原始数据)之后发出这个新的修改数据包。我似乎无法找到发送SKB的内核函数。我试过dev_queue_xmit(nskb)
但是导致内核恐慌,我也试过skb->next = nskb
,但是什么也没做。我是否必须实施SKB清单处理?自从这篇文章seems to be outdated以来,我不确定如何做到这一点。发送SKB从内核空间传输
编辑:
所以我能够调用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的,如果它很重要,我不知道在这一点)。运行上述内核模块的计算机会双向欺骗另外两台虚拟机。另外两个虚拟机然后通过netcat会话相互通话。我希望当我使用ip 10.0.2.13从虚拟机发送一条消息时,10.0.2.12会看到两条相同的消息。我知道确认号码的事故会中断连接,但我不明白。任何3台计算机上的TCPDump都不会显示任何应该发送的数据包。
我到目前为止试过dev_queue_xmit(nskb)
以及nskb->dev->netdev_ops->ndo_start_xmit(nskb, skb->dev)
。
我想明白了,skb_copy不会复制skb的以太网报头,所以发送的数据包永远不会到达目的地。
据我记得dev_queue_xmit()是正确的发送过程。问题是你如何准备你想发送的skb?当内核出现恐慌时,也给我们dmesg的calltrace。你设置skb-> dev吗?
当我检查时,Dmesg为空,并且设置了skb-> dev,我认为,当我执行if(skb-> dev)时,它返回true。此外,现在我只是试图发送第二个数据包,所以通过网络过滤器函数向我提供的skb,我在其上执行'dev_queue_xmit(skb)',希望看到两个重复数据包。 – MacStation
最重要的事情是:当发生内核恐慌时,我们需要确切地知道dmesg中的内容(屏幕上)。我知道当内核发生时它可能不会被记录到系统文件中 - 所以你可以使用连接了串行控制台的第二个系统并执行这个控制台的转储。 – user2699113
第二件事 - 你如何复制skb? – user2699113