如何在用户 space 中使用 NETLINK_KOBJECT_UEVENT 协议?
How to work with NETLINK_KOBJECT_UEVENT protocol in user space?
让我们考虑这个示例代码:
#include <linux/netlink.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#define BUF_SIZE 4096
int main() {
int fd, res;
unsigned int i, len;
char buf[BUF_SIZE];
struct sockaddr_nl nls;
fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
if (fd == -1) {
return 1;
}
memset(&nls, 0, sizeof(nls));
nls.nl_family = AF_NETLINK;
nls.nl_pid = getpid();
nls.nl_groups = 1;
res = bind(fd, (struct sockaddr *)&nls, sizeof(nls));
if (res == -1) {
return 2;
}
while (1) {
len = recv(fd, buf, sizeof(buf), 0);
printf("============== Received %d bytes\n", len);
for (i = 0; i < len; ++i) {
if (buf[i] == 0) {
printf("[0x00]\n");
} else if (buf[i] < 33 || buf[i] > 126) {
printf("[0x%02hhx]", buf[i]);
} else {
printf("%c", buf[i]);
}
}
printf("<END>\n");
}
close(fd);
return 0;
}
它在 netlink 套接字上侦听与热插拔相关的事件。基本上,它有效。然而,即使在整个晚上都在谷歌搜索、阅读不同的文档和手册并研究示例之后,有些部分对我来说还是不清楚。
基本上,我有两个问题。
sockaddr_nl.nl_groups
的不同值意味着什么?至少对于 NETLINK_KOBJECT_UEVENT
协议。
- 如果为消息分配的缓冲区太小,消息将被截断(您可以调整
BUF_SIZE
大小来查看)。这个缓冲区大小应该是多少才不会丢失任何数据?是否可以在用户 space 中知道传入消息的长度以分配足够的 space?
我将不胜感激直接回答作为对内核代码的引用。
这些值代表不同的组播组。一个 netlink 套接字可以有 31 个不同的多播组(0 表示单播),多播消息可以发送到这些多播组。对于 NETLINK_KOBJECT_UEVENT
,它似乎已固定为 1
see f.ex. here。
您应该可以使用 getsockopt,将 level
设置为 SOL_SOCKET
,将 optname
设置为 SO_RCVBUF
。
让我们考虑这个示例代码:
#include <linux/netlink.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#define BUF_SIZE 4096
int main() {
int fd, res;
unsigned int i, len;
char buf[BUF_SIZE];
struct sockaddr_nl nls;
fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
if (fd == -1) {
return 1;
}
memset(&nls, 0, sizeof(nls));
nls.nl_family = AF_NETLINK;
nls.nl_pid = getpid();
nls.nl_groups = 1;
res = bind(fd, (struct sockaddr *)&nls, sizeof(nls));
if (res == -1) {
return 2;
}
while (1) {
len = recv(fd, buf, sizeof(buf), 0);
printf("============== Received %d bytes\n", len);
for (i = 0; i < len; ++i) {
if (buf[i] == 0) {
printf("[0x00]\n");
} else if (buf[i] < 33 || buf[i] > 126) {
printf("[0x%02hhx]", buf[i]);
} else {
printf("%c", buf[i]);
}
}
printf("<END>\n");
}
close(fd);
return 0;
}
它在 netlink 套接字上侦听与热插拔相关的事件。基本上,它有效。然而,即使在整个晚上都在谷歌搜索、阅读不同的文档和手册并研究示例之后,有些部分对我来说还是不清楚。
基本上,我有两个问题。
sockaddr_nl.nl_groups
的不同值意味着什么?至少对于NETLINK_KOBJECT_UEVENT
协议。- 如果为消息分配的缓冲区太小,消息将被截断(您可以调整
BUF_SIZE
大小来查看)。这个缓冲区大小应该是多少才不会丢失任何数据?是否可以在用户 space 中知道传入消息的长度以分配足够的 space?
我将不胜感激直接回答作为对内核代码的引用。
这些值代表不同的组播组。一个 netlink 套接字可以有 31 个不同的多播组(0 表示单播),多播消息可以发送到这些多播组。对于
NETLINK_KOBJECT_UEVENT
,它似乎已固定为1
see f.ex. here。您应该可以使用 getsockopt,将
level
设置为SOL_SOCKET
,将optname
设置为SO_RCVBUF
。