私は、この奇妙な問題に取り組んでいます。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;
}
ファイアウォールはブロードキャストを除いてUDPをブロックしますか?簡単な説明。 –
私はファイアウォールを有効にしていないので、そうではありません。さらに、bootpcクライアントは期待通りに動作します。実際には、このコードのrecvを除いてすべてが期待通りに機能します。私はちょうどなぜUDP recvが他の場所でも動作しているのですが、ここでは動作しません。 – stativ