在原始套接字上ping数据包

时间:2014-03-29 03:09:00

标签: c linux sockets raw-sockets select-function

我正在尝试在veth接口上接收ping数据包。但我在接收方面看不到任何东西。我在进行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。它永远不会越过select并达到print语句。

ping -I ve12p 1.1.1.1

我检查了veth接口,它们已经启动,我可以看到ve12的tcpdump上的数据包。

1 个答案:

答案 0 :(得分:3)

使用IPPROTO_ICMP域时,我认为AF_PACKET不是有效的协议。您可以尝试使用以下方法接收所有协议:

socket(AF_PACKET, SOCK_RAW,htons(ETH_P_ALL))

或者,您可以使用正确的域AF_INET作为协议IPPOROTO_ICMP

socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)

编辑:

socket(7)手册页指出数据包套接字不支持SO_BINDTODEVICE,并且应该使用正常的bind()