tcpdump запускает запуск сетевой ссылки IFF_RUNNING/изменение ссылки

#c #linux #netlink

Вопрос:

У меня есть эти 3 функции для обработки событий netlink интерфейса вверх/вниз (init, receive_msg и handle_msg) Когда я делаю ifconfig eth0 вниз/вверх, я вижу, что флаг IFF_RUNNING установлен/снят правильно ifconfig eth0 вниз: событие IFF_BROADCAST IFF_MULTICAST Ссылка 16 ifindex 2 флага 4098 (ifi->ifi_flags amp; IFF_RUNNING)=0

ifconifg eth0 вверх: IFF_UP IFF_BROADCAST IFF_RUNNING Событие IFF_MULTICAST Ссылка 16 ifindex 2 флага 69699 (ifi->ifi_flags и IFF_RUNNING)=64 Но при запуске tcpdump-i eth0 я также получаю эти сообщения дважды (когда запускается tcpdump и когда он закрывается)

tcpdump -i eth0: Событие IFF_BROADCAST IFF_RUNNING IFF_MULTICAST Ссылка 16 флагов ifindex 2 69699 (ifi->ifi_flags и IFF_RUNNING)=64

Есть идеи, почему ? Могу ли я отфильтровать его ?

Спасибо!

 int init()
{
    struct sockaddr_nl snl;
    
    netlink_socket = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
    if (netlink_socket < 0) {
        return -1;
    }
    
    memset((void *)amp;snl, 0, sizeof(snl));
    snl.nl_family = AF_NETLINK;
    snl.nl_pid = getpid();
    snl.nl_groups = RTMGRP_LINK;

    if (bind(netlink_socket, (struct sockaddr *)amp;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*)amp;snl;
    msg.msg_namelen = sizeof(snl);
    msg.msg_control = 0;
    msg.msg_iov = amp;iov;
    msg.msg_iovlen = 1;
    msg.msg_flags = 0;

    cc = recvmsg(sock, amp;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 amp; 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;
    }
}

 

Комментарии:

1. Вы уверены, что получаете ссылку на событие RTM_DELLINK? можете ли вы добавить разрыв в случае RTM_NEWLINK и попробовать?

2. Я удалил RTM_DELLINK. Это не тип сообщения для событий tcpdump или ссылок. Тот же результат только для RTM_NEWLINK.

3. Происходит, когда tcpdump переводит интерфейс в беспорядочный режим (не воспроизводится с помощью tcpdump-pi eth0)