Пинг-пакеты на сырых сокетах

Я пытаюсь получать пакеты ping на интерфейсе veth. Но я не вижу ничего на принимающей стороне. Я могу увидеть пакет, когда я делаю дамп TCP. Вот мой код

s_int32_t checkingRawSocket(void) {

    int sockfd;
    char ifName[IFNAMSIZ];
    fd_set readfds;
    int m_sd;
    int retVal;
    int sockopt;

    strcpy(ifName, "ve12");

    if ((sockfd = socket(AF_PACKET, SOCK_RAW,htons(IPPROTO_ICMP))) == -1) {
        perror("NOT LISTNER: socket");  
        goto EXIT;     
    }    

    retVal = setsockopt(sockfd, SOL_SOCKET,  SO_REUSEADDR,
                    (char *)&sockopt, sizeof(sockopt));
    if (retVal < 0){
        perror("setsockopt() failed");
        goto EXIT;
    }

    if (setsockopt(sockfd, SOL_SOCKET, 
               SO_BINDTODEVICE, ifName, IFNAMSIZ-1) == -1)  {
        perror("SO_BINDTODEVICE");
        retVal = -1;
        goto EXIT;
    }       
    FD_ZERO(&readfds);
    m_sd = sockfd;
    FD_SET(sockfd, &readfds);

    if(select(m_sd + 1, &readfds, NULL, NULL, 0) < 0){
        perror("SELECT FAILED ");
        goto EXIT;
    }

    printf("I got something after select");

    EXIT:
    return -1;
 }

Так что я делаю пинг на ve12p. Он никогда не пересекает select и не достигает оператора print.

ping -I ve12p 1.1.1.1

Я проверил интерфейсы veth, они работают, и я вижу пакет на tcpdump ve12.

1 ответ

Я не верю IPPROTO_ICMP является действительным протоколом при использовании AF_PACKET домен. Вы можете попробовать получить все протоколы, используя:

socket(AF_PACKET, SOCK_RAW,htons(ETH_P_ALL))

Или вы можете использовать правильный домен AF_INET для протокола IPPOROTO_ICMP:

socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)

Редактировать:

Страница man socket(7) утверждает, что SO_BINDTODEVICE не поддерживается для сокетов пакетов и что это нормальное bind() должен быть использован.

Другие вопросы по тегам