gpt4 book ai didi

c - 监听 PF_NETLINK 套接字时获取所有链接和地址信息

转载 作者:行者123 更新时间:2023-12-01 16:23:34 27 4
gpt4 key购买 nike

我编写了一段代码,每当(对我而言)相关的网络信息发生变化时,它都会通知我(主要是监听 RTM_NEWADDR、RTM_DELADDR、RTM_NEWLINK 和 RTM_DELLINK)。这工作得很好,每次我拔掉插头、改变IP或者任何我收到通知的时候。唯一的问题是,我第一次启动代码时,我希望它能够提供整个当前状态(RTM_GETLINK 和 RTM_GETADDR)。

我可以请求 RTM_GETLINK 或 RTM_GETADDR:

memset(&req, 0, sizeof(req));
req.nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
req.nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; /* request to dump all kernel subsystem */
req.nlmsghdr.nlmsg_type = RTM_GETLINK; /* link information */
req.nlmsghdr.nlmsg_seq = 1;
req.nlmsghdr.nlmsg_pid = pid;
req.rtgenmsg.rtgen_family = AF_UNSPEC;

iovec.iov_base = &req;
iovec.iov_len = req.nlmsghdr.nlmsg_len;

memset(&msghdr, 0, sizeof(msghdr));
msghdr.msg_iov = &iovec;
msghdr.msg_iovlen = 1;
msghdr.msg_name = &addr;
msghdr.msg_namelen = sizeof(addr);

/*
** TODO: check for number of sent characters
** on error display errno
*/
sendmsg(nls, &msghdr, 0);

/* do listening stuff... */

但是如果我同时请求两者:

req.nlmsghdr.nlmsg_type  = RTM_GETLINK | RTM_GETADDR;

我只获取ip信息。

我是否应该使用两个不同的套接字,一个用于请求,另一个用于监听,或者是否可以在同一个套接字中完成所有这些操作?

我尝试为每个请求执行一次发送,并使用 seq (为第二个请求增加它),我可以看到第二个回复只有 40 个字节长:(

memset(&kms.addr, 0, sizeof(kms.addr));
kms.addr.nl_family = AF_NETLINK;

/* prepare request */
memset(&req, 0, sizeof(req));
req.nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
req.nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP /*| NLM_F_ACK*/; /* request to dump all kernel subsystem */
req.nlmsghdr.nlmsg_type = RTM_GETLINK; /* link information */
req.nlmsghdr.nlmsg_seq = 1;
req.nlmsghdr.nlmsg_pid = pid;
req.rtgenmsg.rtgen_family = AF_UNSPEC;

iovec.iov_base = &req;
iovec.iov_len = req.nlmsghdr.nlmsg_len;

memset(&msghdr, 0, sizeof(msghdr));
msghdr.msg_iov = &iovec;
msghdr.msg_iovlen = 1;
msghdr.msg_name = &kms.addr;
msghdr.msg_namelen = sizeof(kms.addr);

/*
** TODO: check for number of sent characters
** on error display errno
*/
sendmsg(kms.nls, &msghdr, 0);

memset(&req, 0, sizeof(req));
req.nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
req.nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP /*| NLM_F_ACK*/; /* request to dump all kernel subsystem */
req.nlmsghdr.nlmsg_type = RTM_GETADDR; /* link information */
req.nlmsghdr.nlmsg_seq = 2;
req.nlmsghdr.nlmsg_pid = pid;
req.rtgenmsg.rtgen_family = AF_UNSPEC;

iovec.iov_base = &req;
iovec.iov_len = req.nlmsghdr.nlmsg_len;

memset(&msghdr, 0, sizeof(msghdr));
msghdr.msg_iov = &iovec;
msghdr.msg_iovlen = 1;
msghdr.msg_name = &kms.addr;
msghdr.msg_namelen = sizeof(kms.addr);

/* do listening stuff... */

再分析一下,我似乎得到了 NLMSG_ERROR 消息类型。错误代码-16意思是“设备或资源繁忙”。

如果我在每次发送后读取套接字,我就不会遇到问题。但我宁愿能够完成我所有的请求,然后才收集所有答复...

最佳答案

在向 netlink 套接字发送下一个请求之前,用户空间需要等待 NLMSG_DONE netlink 控制消息。换句话说,如果你想连续发送多个netlink请求,那么顺序应该是这样的:

  1. 发送请求 1
  2. 等待 NLMSG_DONE
  3. 发送请求2
  4. 等待 NLMSG_DONE
  5. ...

关于c - 监听 PF_NETLINK 套接字时获取所有链接和地址信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22545607/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com