我编写了一段代码,每当相关(对我)网络信息发生变化时(主要是监听 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 表示“设备或资源忙”。
如果我在每次发送后读取套接字,我就不会遇到问题。但我宁愿能够完成我的所有请求,然后才能收集所有回复......