首页 > 解决方案 > 使用socket api,如何将额外的数据结构传递给内核模块中的fd?

问题描述

我正在使用 4.x linux 内核并有一个内核模块,在打开套接字时我会在其中接收套接字信息。

if ((fd = socket(sai.sin_family, skt_type, skt_protocol)) < 0)
    // ...

在这种情况下,我使用 UDP 并且在使用 传输我的第一个数据之前sendto(),我希望能够将数据结构从我的客户端程序传递到我的内核模块。然后我可以将额外的信息添加到我的协议中,并将这些数据与文件描述符相关联。这不是用户数据,而是用于控制我的协议的运行方式。

我想传入并与套接字相关的数据结构如下所示。

struct some_tag_info_t {
    int field_t;
    char field_a[MAX_A];
    void *field_b;
};

我有一种感觉 ioctl 可能会为我做点什么,因为它似乎能够使用文件描述符来操作底层设备参数。

net/socket.c中,ioctl()是:

static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)

在函数之后,我看到了这个评论。

/*
 *  With an ioctl, arg may well be a user mode pointer, but we don't know
 *  what to do with it - that's up to the protocol still.
 */

看来我可以arg用来传递我的struct some_tag_info_t上面?任何人都可以对此发表评论吗?有什么想法吗?

标签: csocketslinux-kernelkernel-module

解决方案


您的理解是正确的,您可以将任何内容ioctl()从用户空间传递给您的处理程序,然后由内核模块正确处理您传递的任何命令和参数。但是,由于您正在使用套接字并编写自己的协议,因此通过getsockopt(2)/实现此功能会更合适setsockopt(2)。参数setsockopt(2)可以是任何你想要的。从用户空间你会做类似的事情:

res = setsockopt(sock_fd, &your_struct, sizeof(your_struct));

推荐阅读