发送SKB用于从内核空间传输

Mac*_*ion 5 c linux kernel kernel-module linux-kernel

我目前正在编写一个内核模块,它将数据包有效负载修改为学习体验.我已完成数据包修改,但现在我想在原始后发送这个新修改的数据包(我不想丢弃原始数据包).我似乎无法找到发送SKB进行传输的内核函数.我已经尝试了,dev_queue_xmit(nskb)但这导致内核恐慌,我也尝试过,skb->next = nskb但没有做任何事情.我是否必须实施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;
}
Run Code Online (Sandbox Code Playgroud)

我的网络设置如下,它是3个Ubuntu Server VM,所有这些都是从主机进入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).

Mac*_*ion 1

我发现,skb_copy 不会复制 skb 的以太网标头,因此发送的数据包永远不会到达其目的地。