发送SKB以从内核空间传输

时间:2017-08-25 02:52:30

标签: c linux linux-kernel kernel kernel-module

我目前正在编写一个内核模块,它将数据包有效负载修改为学习体验。我已完成数据包修改,但现在我想在原始之后发送这个新修改的数据包(我不想丢弃原始数据包)。我似乎无法找到一个发送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)

2 个答案:

答案 0 :(得分:1)

据我所知,dev_queue_xmit()是发送的正确程序。问题是你如何准备要发送的skb?当发生内核恐慌时,也给我们来自dmesg的calltrace。你设置了skb-> dev?

答案 1 :(得分:0)

我想通了,skb_copy没有复制skb的以太网头,所以发送的数据包永远不会到达目的地。