다음 코드는 ICMP 에코 요청을 보내고 응답을 받기 위해 고안된 프로그램입니다.RAW ICMP 소켓 : recvfrom()이 데이터를 수신하지 않습니다.
/*
Forgive my lack of error handling :)
*/
SOCKET ASOCKET = INVALID_SOCKET;
struct sockaddr saddr;
struct sockaddr_in *to = (struct sockaddr_in *) &saddr;
struct sockaddr_in from;
int fromsize = sizeof(from);
std::string ip = "[arbitrary ip address]";
struct ICMP {
USHORT type;
USHORT code;
USHORT cksum;
USHORT id;
USHORT seq;
}*_ICMP;
char sendBuffer[sizeof(struct ICMP)];
char recvBuffer[256];
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
memset(&saddr, NULL, sizeof(saddr));
ASOCKET = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
// Configure timeout
DWORD timeoutmilsec = 3000;
setsockopt(ASOCKET, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeoutmilsec, sizeof(timeoutmilsec));
to->sin_family = AF_INET;
inet_pton(AF_INET, ip.c_str(), &(to->sin_addr));
_ICMP = new ICMP();
_ICMP->type = 8;
_ICMP->code = 0;
_ICMP->cksum = 0;
_ICMP->id = rand();
_ICMP->seq++;
// I have omitted my declaration of checksum() for simplicity
_ICMP->cksum = checksum((u_short *)_ICMP, sizeof(struct ICMP));
memcpy(sendBuffer, _ICMP, sizeof(struct ICMP));
if (sendto(ASOCKET, sendBuffer, sizeof(sendBuffer), NULL, (sockaddr *)&saddr, sizeof(saddr)) == SOCKET_ERROR)
{
printf("sendto() failed with error: %u\n", WSAGetLastError());
return false;
}
if (recvfrom(ASOCKET, recvBuffer, sizeof(recvBuffer), NULL, (sockaddr *)&from, &fromsize) == SOCKET_ERROR)
{
if (WSAGetLastError() == TIMEOUTERROR)
{
printf("Timed out\n\n");
return false;
}
printf("recvfrom() failed with error: %u\n", WSAGetLastError());
return false;
}
내 문제는 내 recvfrom()
전화가 데이터를 수신하지 않는다는 것입니다 및 핑 이이 회신되었다는 사실에도 불구하고 (10060) TIMEOUTERROR를 반환 (와이어 샤크는 요청을 캡처하고 전송되는 응답). sendto()
은 작동하지만 recvfrom()
은 이상하게 작동하며 문제가 무엇인지 파악할 수 없습니다.
흥미로운 점은 recvfrom()
은 게이트웨이가 호스트에 도달 할 수 없다고 알리는 경우에만 데이터를 수신합니다. 호스트가 도달 가능하고 핑에 응답 한 경우에는 그렇지 않습니다.
패킷을 차단하는 Windows 방화벽이있을 수 있습니까? –