I'm trying to understand how i can get a subnet address using ICMP. In the Wikipedia (other sources as well), there is a message example, but all I was able to find has nothing to do with this message.
Tried to use IcmpSendEcho (from msdn example), but it seemed to me, that it performs only ping function, correct me if i'm wrong.
Can you give me some code example (c/c++), or may be links?
Edit:
The code I used:
int __cdecl main() {
// Declare and initialize variables
HANDLE hIcmpFile;
unsigned long ipaddr = INADDR_NONE;
DWORD dwRetVal = 0;
char SendData[12] = "Data Buffer";
LPVOID ReplyBuffer = NULL;
DWORD ReplySize = 0;
ipaddr = inet_addr("217.71.130.248");
hIcmpFile = IcmpCreateFile();
if (hIcmpFile == INVALID_HANDLE_VALUE) {
printf("\tUnable to open handle.\n");
printf("IcmpCreatefile returned error: %ld\n", GetLastError());
return 1;
}
ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
ReplyBuffer = (VOID*)malloc(ReplySize);
if (ReplyBuffer == NULL) {
printf("\tUnable to allocate memory\n");
return 1;
}
dwRetVal = IcmpSendEcho(hIcmpFile, ipaddr, SendData, sizeof(SendData),
NULL, ReplyBuffer, ReplySize, 1000);
if (dwRetVal != 0) {
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
struct in_addr ReplyAddr;
ReplyAddr.S_un.S_addr = pEchoReply->Address;
printf("\tSent icmp message to %s\n", "217.71.130.248");
printf("\tReceived %ld icmp message response\n", dwRetVal);
printf("\tInformation from this response:\n");
printf("\t Received from %s\n", inet_ntoa(ReplyAddr));
printf("\t Status = %ld\n",
pEchoReply->Status);
printf("\t Roundtrip time = %ld milliseconds\n",
pEchoReply->RoundTripTime);
}
else {
printf("\tCall to IcmpSendEcho failed.\n");
printf("\tIcmpSendEcho returned error: %ld\n", GetLastError());
return 1;
}
return 0;
}
I get an answer from the IP, that works alright. But I need to get subnet address and I'm stuck at it
ECHO
(aka ping) is a specific type of ICMP request. ICMP supports other types of messages, butIcmpSendEcho()
can only sendECHO
requests and receiveECHO
replies, hence its name. So you cannot use it to send anADDRESS MASK
request to your router to get the subnet address.Microsoft does not have an API to send general-purpose ICMP requests. You would have to use the standard socket API (WinSock on Windows) to create a socket with a type of
SOCK_RAW
and a protocol ofIPPROTO_ICMP
(as ICMP runs on top of IP but is separate from TCP/UDP), then you can manually construct and send your own ICMP requests, and then read and parse the ICMP replies. Do be aware thatSOCK_RAW
requires admin rights on most platforms, including Windows.That being said, you do not need to resort to ICMP to get your machine's subnet address. The OS already knows it, and there are OS-specific APIs available to get that information, such as
GetAdaptersInfo()
andGetAdaptersAddresses()
on Windows, andgetifaddrs()
on POSIX systems.