2012-12-29 22 views
3

我正在使用C++和原始套接字向路由器發送ICMP請求,之後我想讀取ICMP回覆。我的問題是,select()始終沒有收到重播和超時。我沒有收到任何錯誤(errno正在返回成功)。路由器正在發送ICMP回覆,因爲我可以使用Wireshark查看響應。使用C++在Linux中讀取ICMP回覆選擇

http://i.imgur.com/0Wra1.png Wireshark的截圖

爲了測試我的節目,我使用Ubuntu 12.10上的VirtualBox 4.2.6和GN3運行的虛擬網絡。

我的源代碼:

char buffer[IP_MAXPACKET]; // for the received ICMP reply 
struct iphdr *ipRec; // ICMP header 
timeval tv; // timeout 
fd_set mySet; // descriptor set 
... 
tv.tv_sec = 3; // default time-out 3s 
tv.tv_usec = 0; 

int retval; // select 
... 
do { 
     FD_ZERO(&mySet); 
     FD_SET(mysocket, &mySet); 

     retval = select(mysocket+1, &mySet, NULL, NULL, &tv); 

     cout << "Errno after select:" << strerror(errno) << endl; 

     if(retval == -1) { 
      cerr << "select error" << endl; 
      break; 
     } 
     else if (retval) { 
      if((length = recvfrom(mysocket, buffer, MAX, 0, result->ai_addr, &(result->ai_addrlen))) == -1) { 
       cerr << "Error: while receiving data." << endl; 
      } 
      else { 
       cout << "good" << endl; 

       ipRec = (struct iphdr*) buffer; 
       icmpRec = (struct icmphdr*) (buffer + ipRec->ihl * 4); 

       cout << "the packet." << " PID: " << ntohs(icmpRec->un.echo.id) << " Seq: " << ntohs(icmpRec->un.echo.sequence) << endl; 

       if ((icmpRec->type == ICMP_ECHOREPLY) && (ntohs(icmpRec->un.echo.id) == pid) && (ntohs(icmpRec->un.echo.sequence) == (seq - 1))) { 
        minBuff = lengthBuff; 
       } 
      } 
     } else { 
      // getting here all the time = select times-out and reads no data 

      cout << "mysocket:" << mysocket << endl; 
      cout << "retval:" << retval << endl; 
      maxBuff = lengthBuff; 
      break; 
     } 
    } while (!((icmpRec->type == ICMP_ECHOREPLY) && (ntohs(icmpRec->un.echo.id) == pid) && (ntohs(icmpRec->un.echo.sequence) == (seq - 1)))); 

    if (packet) 
     delete(packet); 
    ... 

感謝您的任何幫助。

+0

注意<<運算符不允許將字符串作爲其操作數。也許你正在使用C++? – wildplasser

+0

是的,我的錯,顯然是C++ :) –

+0

recvfrom中MAX是什麼?不應該是IP_MAXPACKET? – Icarus3

回答

1

修復了這個問題。在另一個線程中找到解決方案:ICMP packets are not being sent C。將IPPROTO_RAW更改爲IPPROTO_ICMP修復了它。現在選擇讀取ICMP回覆數據包。