0

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;
    }
}

0 Answers0