1

我有一个用户空间程序,它构建自己的数据包(应用程序、UDP、IP)并将write()其发送到 TUN 设备。该数据包被我自己的 Netfilter 模块拦截,它检查它收到的数据包是否是我们要处理的数据包。然后我的 Netfilter 模块将skb_clone()原始skb并创建一个响应数据包,我用一些数据填充该数据包以返回给用户空间程序。要发送响应,我使用dev_queue_xmit(). NET_XMIT_CN即使我刚刚创建了一个新的 TUN 设备并且没有其他流量通过,它也会随机返回。如果我继续执行用户空间程序(向 TUN 设备发送新数据包),最终 TUN 设备会响应,但不会始终如一。我似乎无法追查为什么它的行为如此不规律。

本质上,我使用 TUN 设备作为从用户空间到内核空间进行通信的机制,反之亦然。

这是我的用户空间应用程序:

tun_fd = tun_alloc(dev_name);
packet = ... /* Construct request...*/
nwrite = write(tun_fd, packet, packet_len);
...
unsigned recv_buf[1500];
int received = 0;
while (!received) {
    nread = read(tun_fd, recv_buf, 1500);
    ...
}
...
close(tun_fd);

这是我的 Netfilter 模块:

static struct nf_hook_ops nfho;

static int __init my_hook(void)
{
    nfho.hook = hook_func;
    nfho.hooknum = 0;
    nfho.hook = PF_INET;
    nfho.hook = NF_IP_PRI_FIRST;
    nf_register_hook(&nfho);
}

unsigned int hook_func(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
    struct sk_buff *clone_skb = skb_clone(skb, GFP_KERNEL):
    ...
    /*
     * Check if packet is for us.
     * Check IP & UDP header, etc
     * If so, parse request, put together response clone_skb
     */
    ...

    if ((err = dev_queue_xmit(clone_skb)) != 0) {
        printk(....)
        /* Either it return 0 (success) or 2, meaning NET_XMIT_CN */
    }

    return NF_STOLEN;
}

我似乎无法弄清楚这种行为。我是否误用了 TUN 设备?还有比这更简单的方法吗?

请让我知道我是否应该提供任何额外的细节或澄清一些事情。

4

0 回答 0