2014-03-29 9 views
1

Я пытаюсь получить пакеты 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. Он никогда не пересекает выделение и не достигает инструкции печати.

ping -I ve12p 1.1.1.1 

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

+0

Следует избегать использования 'goto', это не Fortran. Почему вы используете 'goto EXIT', когда можете просто использовать' return -1'? – Havenard

+0

, когда 'select' success вы можете вызвать функцию' recv', например 'recv (sockfd, buf, sizeof (buf), 0))' И 'print' данные' buf'. –

+1

@havanard .. это что-то сделать, чтобы код не работал? – Rags

ответ

2

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

socket(AF_PACKET, SOCK_RAW,htons(ETH_P_ALL)) 

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

socket(AF_INET, SOCK_RAW, IPPROTO_ICMP) 

Edit:

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