1

我正在尝试在 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 上看到数据包。

4

1 回答 1

4

我不相信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()应使用普通套接字。

于 2014-03-29T07:31:07.583 回答