2012-05-05 74 views
0

我與這個奇怪的問題鬥爭,其中recvfrom只有當它捕獲目標地址爲255.255.255.255的廣播數據包時才返回。直接發往客戶端的數據包(即使用客戶端IP)將被忽略。recvfrom捕獲只發送到255.255.255.255的數據包

現在一些背景(你可以跳過它,這只是爲了澄清我想要做什麼) - 我試圖實現一個簡單的BOOTP客戶端。我能夠創建BOOTREQUEST,並且服務器用正確的BOOTREPLY(使用wireshark和使用libpcap編寫的簡單分析器進行檢查)回覆它。但是,即使我在wireshark中看到答覆,但我無法在客戶端中收到它,因爲它將客戶端的IP地址用作目標。

我試圖在網絡上,我可以從其他計算機捕獲BOOTP數據包以及。我發現recvfrom可以接收帶廣播地址的BOOTREPLY包。壞事是這些不是我的,因爲我允許服務器使用單播進行回覆。

我使用的代碼:

sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
if (sockfd < 0) { 
    std::cerr << "Cannot create socket" << std::endl; 
    return; 
} 

int broadcastON = 1; 
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcastON, sizeof(broadcastON)); 

sockaddr_in recv_address; 
memset((char *) &recv_address, 0, sizeof(recv_address)); 
recv_address.sin_family = AF_INET; 
recv_address.sin_port = htons(68); 
recv_address.sin_addr.s_addr = htonl(INADDR_ANY); 
int recv_sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
if (recv_sockfd < 0) 
{ 
    std::cerr << "Cannot create socket" << std::endl; 
    return; 
} 
if (bind(recv_sockfd, (sockaddr *) &recv_address, sizeof(recv_address)) < 0) 
{ 
    std::cerr << "Cannot bind socket" << std::endl; 
    perror("bind"); 
    return; 
} 

sniff_bootp packet = createBootpPacket(mac); 
sockaddr_in server_address; 
memset((char *) &server_address, 0, sizeof(server_address)); 
server_address.sin_family = AF_INET; 
server_address.sin_port = htons(67); 
server_address.sin_addr.s_addr = htonl(INADDR_BROADCAST); 
if (sendto(sockfd, &packet, sizeof(packet),0,(sockaddr *) &server_address, sizeof(server_address)) < 0) 
{ 
    perror("sendto"); 
    return; 
} 
char msg[512]; 
while(1) 
{ 
    sockaddr_in source_address; 
    unsigned int cli_addr_len = sizeof(source_address); 
    // HERE IS THE PROBLEM 
    // returns only if the destination is broadcast 
    int msg_length = recvfrom(recv_sockfd, msg, 512, 0, (sockaddr *) &source_address, &cli_addr_len); 
    if (msg_length < 0) { 
     perror("rcvfrom"); 
     continue; 
    } 
+0

因此,您的防火牆阻止UDP,除了廣播?簡單的解釋。 –

+0

我沒有啓用防火牆,所以不,這不是。而且,bootpc客戶端按預期工作。實際上,除了本代碼中的recv之外,其他一切都按預期工作。我只是不明白爲什麼UDP recv在其他地方工作,但不在這裏。 – stativ

回答

1

OK,我花了幾天摸不着頭腦,但我終於固定它。

問題是事實上,我試圖從recvfrom包不是註定要給我。讓我詳細說明一下。在bootp協議中,您向您發送MAC地址,並且服務器使用廣播或連接到MAC地址的IP發送回覆。問題是我使用了另一臺計算機的MAC地址,因此回覆是發給那臺計算機,而不是我。

就是這樣 - 如果您沒有收到任何東西,請確保您是目的地。

相關問題