使用套接字api,如何将额外的数据结构传递给内核模块中的fd?
Using socket api, how to pass in an extra data structure to a fd in kernel module?
我正在使用 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
?有人可以对此发表评论吗?有什么想法吗?
您的理解是正确的,您可以从用户空间向 ioctl()
处理程序传递任何内容,然后由内核模块正确处理您传递的任何命令和参数。但是,由于您正在使用套接字并编写自己的协议,因此通过 getsockopt(2)
/setsockopt(2)
来实现此功能会更合适。 setsockopt(2)
的参数可以是任何你想要的。从用户空间你会做这样的事情:
res = setsockopt(sock_fd, &your_struct, sizeof(your_struct));
我正在使用 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
?有人可以对此发表评论吗?有什么想法吗?
您的理解是正确的,您可以从用户空间向 ioctl()
处理程序传递任何内容,然后由内核模块正确处理您传递的任何命令和参数。但是,由于您正在使用套接字并编写自己的协议,因此通过 getsockopt(2)
/setsockopt(2)
来实现此功能会更合适。 setsockopt(2)
的参数可以是任何你想要的。从用户空间你会做这样的事情:
res = setsockopt(sock_fd, &your_struct, sizeof(your_struct));