tcpdump触发netlink IFF_运行/链路更改
我有这3个函数来处理上/下接口的netlink事件(init、receive_msg和handle_msg) 当我执行ifconfig eth0 down/up时,我看到IFF_RUNNING标志设置/取消设置正确 ifconfig eth0关闭: IFF_广播 IFF_多播 链接事件16 ifindex 2标志4098(ifi->ifi_标志和IFF_运行)=0 ifconifg eth0向上: 伊芙 IFF_广播 IFF_运行 IFF_多播 链接事件16 ifindex 2标志69699(ifi->ifi_标志和IFF_运行)=64 但是当运行tcpdump-i eth0时,我也会收到这些消息,两次(wehn tcpdump启动和关闭时) tcpdump-i eth0: IFF_广播 IFF_运行 IFF_多播 链接事件16 ifindex 2标志69699(ifi->ifi_标志和IFF_运行)=64 知道为什么吗?我能把它过滤掉吗 谢谢tcpdump触发netlink IFF_运行/链路更改,c,linux,netlink,C,Linux,Netlink,我有这3个函数来处理上/下接口的netlink事件(init、receive_msg和handle_msg) 当我执行ifconfig eth0 down/up时,我看到IFF_RUNNING标志设置/取消设置正确 ifconfig eth0关闭: IFF_广播 IFF_多播 链接事件16 ifindex 2标志4098(ifi->ifi_标志和IFF_运行)=0 ifconifg eth0向上: 伊芙 IFF_广播 IFF_运行 IFF_多播 链接事件16 ifindex 2标志69699(i
int init()
{
struct sockaddr_nl snl;
netlink_socket = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (netlink_socket < 0) {
return -1;
}
memset((void *)&snl, 0, sizeof(snl));
snl.nl_family = AF_NETLINK;
snl.nl_pid = getpid();
snl.nl_groups = RTMGRP_LINK;
if (bind(netlink_socket, (struct sockaddr *)&snl, sizeof(snl)) < 0) {
return -1;
}
return 0;
}
int receive_msg()
{
int cc;
char buf[4096];
struct iovec iov = {.iov_base = buf, .iov_len = sizeof buf};
struct sockaddr_nl snl;
struct msghdr msg;
struct nlmsghdr *h;
msg.msg_name = (void*)&snl;
msg.msg_namelen = sizeof(snl);
msg.msg_control = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_flags = 0;
cc = recvmsg(sock, &msg, MSG_DONTWAIT);
if (cc < 0) {
return -1;
}
/* We need to handle more than one message per 'recvmsg' */
for (h = (struct nlmsghdr *)buf; NLMSG_OK(h, cc); h = NLMSG_NEXT(h, cc)) {
/* Finish reading */
if (h->nlmsg_type == NLMSG_DONE) {
return 0;
}
/* Message is some kind of error */
if (h->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr err = (struct nlmsgerr)(NLMSG_DATA(h));
return -1;
}
/* Call message handler */
handle_msg(h);
}
return 0;
}
int handle_msg()
{
struct ifinfomsg ifi = (struct ifinfomsg)NLMSG_DATA(msg);
switch (msg->nlmsg_type) {
case RTM_NEWLINK:
case RTM_DELLINK:
int is_up = (ifi->ifi_flags & IFF_RUNNING);
printf("Link event %d ifindex %u flags %d link %d", _FUNCTION_, msg->nlmsg_type,
ifi->ifi_index, ifi->ifi_flags, is_up);
break;
default:
break;
}
}
intinit()
{
结构sockaddr_nl snl;
netlink\u socket=套接字(AF\u netlink、SOCK\u RAW、netlink\u路由);
if(网络链接_插座<0){
返回-1;
}
memset((void*)&snl,0,sizeof(snl));
snl.nl_family=AF_NETLINK;
snl.nl_pid=getpid();
snl.nl_groups=RTMGRP_链接;
if(bind(netlink_socket,(struct sockaddr*)&snl,sizeof(snl))<0{
返回-1;
}
返回0;
}
int receive_msg()
{
int cc;
char-buf[4096];
结构iovec iov={.iov_base=buf,.iov_len=sizeof buf};
结构sockaddr_nl snl;
结构msghdr msg;
结构nlmsghdr*h;
msg.msg_name=(void*)&snl;
msg.msg_namelen=sizeof(snl);
msg.msg_control=0;
msg.msg_iov=&iov;
msg.msg_iovlen=1;
msg.msg_标志=0;
cc=recvmsg(sock,&msg,msg_DONTWAIT);
if(cc<0){
返回-1;
}
/*我们需要为每个“recvmsg”处理多条消息*/
对于(h=(结构nlmsghdr*)buf;NLMSG_OK(h,cc);h=NLMSG_NEXT(h,cc)){
/*读完*/
如果(h->nlmsg\U类型==nlmsg\U完成){
返回0;
}
/*消息是某种错误*/
如果(h->nlmsg\U类型==nlmsg\U错误){
结构nlmsgerr err=(结构nlmsgerr)(NLMSG_数据(h));
返回-1;
}
/*调用消息处理程序*/
处理味精(h);
}
返回0;
}
int handle_msg()
{
结构ifinfomsg ifi=(结构ifinfomsg)NLMSG_数据(msg);
开关(msg->nlmsg\U类型){
案例RTM_NEWLINK:
案例RTM_DELLINK:
int是向上=(ifi->ifi\U标志和IFF\U运行);
printf(“链接事件%d ifindex%u标志%d链接%d”,\u函数\u,消息->nlmsg\u类型,
ifi->ifi_索引,ifi->ifi_标志,为向上);
打破
违约:
打破
}
}
您确定要获得事件RTM\u DELLINK吗?你能在RTM_NEWLINK案例中添加一个中断并尝试吗?我删除了RTM_DELLINK。它不是tcpdump或link事件的消息类型。仅RTM_NEWLINK的结果相同。当tcpdump将接口设置为混杂模式时发生(不使用tcpdump-pi eth0复制)