I have these 3 function to handle netlink events of interface up/down (init, receive_msg and handle_msg) When I do ifconfig eth0 down/up I see that the IFF_RUNNING flag is set/unset correctly ifconfig eth0 down: IFF_BROADCAST IFF_MULTICAST Link event 16 ifindex 2 flags 4098 (ifi->ifi_flags & IFF_RUNNING)=0
ifconifg eth0 up: IFF_UP IFF_BROADCAST IFF_RUNNING IFF_MULTICAST Link event 16 ifindex 2 flags 69699 (ifi->ifi_flags & IFF_RUNNING)=64 But when running tcpdump -i eth0 I also get these messages, twice (wehn tcpdump starts and when it is closed)
tcpdump -i eth0: IFF_BROADCAST IFF_RUNNING IFF_MULTICAST Link event 16 ifindex 2 flags 69699 (ifi->ifi_flags & IFF_RUNNING)=64
Any idea why ? Can I filter it out ?
Thanks !
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;
}
}