recvfrom仅捕获发送到255.255.255.255的数据包

时间:2012-05-05 19:27:15

标签: c++ network-programming udp recv

我正在与这个奇怪的问题作斗争,其中recvfrom仅在捕获目标地址为255.255.255.255的广播数据包时返回。直接发送到客户端的数据包(即使用客户端IP)将被忽略。

现在有一些背景(你可以跳过它,它只是为了澄清我正在尝试做什么) - 我正在尝试实现一个简单的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;
    }

1 个答案:

答案 0 :(得分:1)

好的,我花了几天时间想出来,但我终于解决了。

问题实际上是我试图回收的数据包不适合我。让我详细说明一下。在bootp协议中,您向您发送MAC地址,服务器使用广播或与MAC地址连接的IP发送回复。问题是我使用了我的其他计算机的MAC地址,因此回复是针对该计算机而不是我。

就是这样 - 如果你没有收到任何东西,请确保你是目的地。