Click to See Complete Forum and Search --> : IcmpSendEcho problem
jlewicki
July 5th, 2007, 03:47 PM
I'm trying to ping a computer on the network, but I'm receiving a 11001 error(no such host is known). Any help si extremely appreciated:
below are 2 outputs and the code:
Output:
CreatePipe: The operation completed successfully.
File created.
ip: 16777343
IcmpSendEcho
: No such host is known.
Call to IcmpSendEcho() failed.
Error: 11001
Press any key to continue . . .
by mistake i entered in 128.0.0.1 and this was the output:
CreatePipe: The operation completed successfully.
File created.
ip: 16777344
Received 1 messages.
Message:
IPaddress: 895096836
Status: 11003
RoundTripTime: 14
DataSize: 0
Data: 00354FB4
Press any key to continue . . .
Code:
#include <Winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <windows.h>
#include <iostream>
#include <Icmpapi.h>
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "Ws2_32.lib")
void main()
{
HANDLE hIcmpFile;
//PICMP_ECHO_REPLY *reply;
DWORD dwRetVal;
LPVOID ReplyBuffer;
char SendData[] = "12345678";
ReplyBuffer = (VOID*) malloc(sizeof(ICMP_ECHO_REPLY) + sizeof(SendData));
if ((hIcmpFile = IcmpCreateFile()) == INVALID_HANDLE_VALUE)
{
printf("\tUnable to open file.\n");
}
else
{
printf("\tFile created.\n");
}
char *IPtable[1];
unsigned long ip;
IPtable[0] = ("127.0.0.1");
//IPtable[0] = ("216.109.112.135");
//inet_addr("123.456.789.0"
if(!(ip = inet_addr(IPtable[0])))
printf("conversion failed\n");
std::cout<<"\n" << "ip: "<<ip<<std::endl;
if((dwRetVal = IcmpSendEcho(hIcmpFile, ip, SendData, sizeof(SendData) + sizeof(ICMP_ECHO_REPLY), NULL, ReplyBuffer, sizeof(ReplyBuffer) + sizeof(ICMP_ECHO_REPLY), 1000)) != 0)
{
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
printf("\tReceived %ld messages.\n", dwRetVal);
printf("\tMessage: %s\n\n", pEchoReply->Data);
std::cout<<"IPaddress: "<<pEchoReply->Address<<std::endl;
std::cout<<"Status: "<<pEchoReply->Status<<std::endl;
std::cout<<"RoundTripTime: "<<pEchoReply->RoundTripTime<<std::endl;
std::cout<<"DataSize: "<<pEchoReply->DataSize<<std::endl;
std::cout<<"Data: "<<pEchoReply->Data<<std::endl;
}
else
{
printf("\tCall to IcmpSendEcho() failed.\n");
printf("\tError: %ld\n", GetLastError());
}
CloseHandle(hIcmpFile); //clean stuff up
return;
}
MikeAThon
July 5th, 2007, 07:44 PM
Obviously that's not your real code (there are significant mismatches between the outputs you quoted and the possible outputs from the code).
I don't think any good purpose is served by trying to debug fake or pseudo-code code. Please post your actual code.
Mike
jlewicki
July 5th, 2007, 09:40 PM
the full code, as requested:
//#include <winsock.h>
#include <Winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <windows.h>
#include <iostream>
//#include <winsock.h>
//#include <Ipexport.h>
#include <Icmpapi.h>
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "Ws2_32.lib")
void ErrorMessage(char *str) //display detailed error info
{
LPVOID msg;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &msg,
0,
NULL
);
printf("%s: %s\n",str,msg);
LocalFree(msg);
}
void main()
{
HANDLE hIcmpFile;
//PICMP_ECHO_REPLY *reply;
DWORD dwRetVal;
LPVOID ReplyBuffer;
char SendData[] = "12345678";
ReplyBuffer = (VOID*) malloc(sizeof(ICMP_ECHO_REPLY) + sizeof(SendData));
if ((hIcmpFile = IcmpCreateFile()) == INVALID_HANDLE_VALUE)
{
ErrorMessage("CreatePipe");
printf("\tUnable to open file.\n");
}
else
{
ErrorMessage("CreatePipe");
printf("\tFile created.\n");
}
char *IPtable[1];
unsigned long ip;
IPtable[0] = ("127.0.0.1");
//IPtable[0] = ("216.109.112.135");
//inet_addr("123.456.789.0"
if(!(ip = inet_addr(IPtable[0])))
printf("conversion failed\n");
std::cout<<"\n" << "ip: "<<ip<<std::endl;
if((dwRetVal = IcmpSendEcho(hIcmpFile, ip, SendData, sizeof(SendData) + sizeof(ICMP_ECHO_REPLY), NULL, ReplyBuffer, sizeof(ReplyBuffer) + sizeof(ICMP_ECHO_REPLY), 1000)) != 0)
{
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
printf("\tReceived %ld messages.\n", dwRetVal);
printf("\tMessage: %s\n\n", pEchoReply->Data);
std::cout<<"IPaddress: "<<pEchoReply->Address<<std::endl;
std::cout<<"Status: "<<pEchoReply->Status<<std::endl;
std::cout<<"RoundTripTime: "<<pEchoReply->RoundTripTime<<std::endl;
std::cout<<"DataSize: "<<pEchoReply->DataSize<<std::endl;
std::cout<<"Data: "<<pEchoReply->Data<<std::endl;
}
else
{
ErrorMessage("IcmpSendEcho\n\n");
printf("\tCall to IcmpSendEcho() failed.\n");
printf("\tError: %ld\n", GetLastError());
}
CloseHandle(hIcmpFile); //clean stuff up
return;
}
jlewicki
July 6th, 2007, 12:09 AM
I was about to tear my hair out until by chance i spotted a sinister function called IcmpSendEcho2...
If someone could shed some light as to why this segment works while the other doesn't, I could put this behind me.
WORKS
if ((dwRetVal = IcmpSendEcho2(hIcmpFile,
NULL,
NULL,
NULL,
ip,
SendData,
sizeof(SendData),
NULL,
ReplyBuffer,
8*sizeof(ReplyBuffer) + sizeof(ICMP_ECHO_REPLY),
1000)) != 0)
DOESN'T WORK
if((dwRetVal = IcmpSendEcho(hIcmpFile,
ip,
SendData,
sizeof(SendData),
NULL,
ReplyBuffer,
sizeof(ReplyBuffer) + sizeof(ICMP_ECHO_REPLY),
1000)) != 0)
jlewicki
July 6th, 2007, 12:12 AM
meh, turns out the "8*" when calculating the buffer size, makes all of the difference.
Sad thing is that both segments of code are verbatim from the SDK :/ oh well
MikeAThon
July 6th, 2007, 12:21 AM
The following code, which uses IcmpSendEcho(), works fine for me. Maybe it's the "+1" in the size of the receive buffer:
// Icmp.cpp : Defines the entry point for the console application.
//
#include <stdio.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <icmpapi.h>
#pragma comment(lib, "Iphlpapi.lib")
#pragma comment(lib, "Ws2_32.lib")
int main(int argc, char* argv[])
{
HANDLE hIcmp;
char *SendData = "ICMP Test of Sending Data";
LPVOID ReplyBuffer;
DWORD dwRetVal;
DWORD buflen;
PICMP_ECHO_REPLY pIcmpEchoReply;
hIcmp = IcmpCreateFile();
buflen = sizeof(ICMP_ECHO_REPLY) + strlen(SendData) + 1;
ReplyBuffer = (VOID*) malloc(buflen);
if (ReplyBuffer == NULL) {
return 1;
}
memset(ReplyBuffer, 0, buflen);
pIcmpEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
dwRetVal = IcmpSendEcho(hIcmp,
inet_addr("127.0.0.1"),
SendData, strlen(SendData),
NULL, ReplyBuffer,
buflen,
1000);
if (dwRetVal != 0) {
printf("Received %ld messages.\n", dwRetVal);
printf("\n");
printf("RTT: %d\n", pIcmpEchoReply->RoundTripTime);
printf("Data Size: %d\n", pIcmpEchoReply->DataSize);
printf("Message: %s\n", pIcmpEchoReply->Data);
} else {
printf("Call to IcmpSendEcho() failed.\n");
printf("Error: %ld\n", GetLastError());
}
IcmpCloseHandle(hIcmp);
getchar();
return 0;
}
Output:
Received 1 messages.
RTT: 0
Data Size: 25
Message: ICMP Test of Sending Data
I did not try the IcmpSendEcho2() function.
Mike
MikeAThon
July 6th, 2007, 12:26 AM
With respect to IcmpSendEcho2(), the following code is taken from http://cboard.cprogramming.com/printthread.php?t=65419 , and is said to test all 256 nodes in the local subnet in under one second:
#include <winsock2.h>
#include <windows.h>
#include <Ipexport.h>
#include <icmpapi.h>
#include <stdio.h>
#if defined(_MSC_VER)
#pragma comment(lib, "Iphlpapi.lib")
#pragma comment(lib, "Ws2_32.lib")
#endif
/*
* Simple structure of arrays to create Targets collection.
*/
#define MAX_TARGETS 300
struct
{
struct in_addr IPAddresses[MAX_TARGETS];
BYTE Buffers [MAX_TARGETS][sizeof(ICMP_ECHO_REPLY) + 32];
HANDLE Events [MAX_TARGETS];
UINT cTargets;
} Targets;
/*
* Add an IP address to the Targets collection.
*/
BOOL new_Target(LPCSTR szIPAddress)
{
if (Targets.cTargets < MAX_TARGETS)
{
Targets.Events[Targets.cTargets] = CreateEvent(NULL, FALSE, FALSE, NULL);
Targets.IPAddresses[Targets.cTargets].S_un.S_addr = inet_addr(szIPAddress);
Targets.cTargets++;
return TRUE;
}
return FALSE;
}
/*
* There appears to be a problem with the import lib for IcmpParseReplies
* so we load it at run-time.
*/
DWORD wrapIcmpParseReplies(LPVOID ReplyBuffer, DWORD ReplySize)
{
typedef (WINAPI * pIPR)(LPVOID, DWORD);
static pIPR dl_IcmpParseReplies;
if (!dl_IcmpParseReplies)
{
HMODULE hICMP = LoadLibrary(TEXT("ICMP.dll"));
dl_IcmpParseReplies = (pIPR) GetProcAddress(hICMP, "IcmpParseReplies");
}
if (dl_IcmpParseReplies)
return dl_IcmpParseReplies(ReplyBuffer, ReplySize);
else
return 0;
}
/*
* main function.
*/
int main(void)
{
size_t i;
DWORD ret;
HANDLE hIcmp;
BYTE PingData[16];
/* Add IP Addresses to check. */
new_Target( "66.139.79.229" );
new_Target( "192.168.0.1" );
new_Target( "192.168.0.2" );
new_Target( "192.168.0.17" );
new_Target( "10.0.0.1" );
new_Target( "10.0.0.2" );
/* You can also check your entire subnet with something like: */
for (i = 1;i < 256;i++)
{
char buf[50];
sprintf(buf, "192.168.0.%d", i);
new_Target(buf);
}
hIcmp = IcmpCreateFile();
/* Send out all our async ping requests. Timeout is 250ms. Change if needed. */
for (i = 0; i < Targets.cTargets; i++)
{
IcmpSendEcho2(hIcmp, Targets.Events[i], NULL, 0,
Targets.IPAddresses[i].S_un.S_addr, PingData, sizeof(PingData),
NULL, Targets.Buffers[i], sizeof(Targets.Buffers[i]), 250);
}
/* Wait for all our ping requests to return or timeout. */
WaitForMultipleObjects(Targets.cTargets, Targets.Events, TRUE, 2500);
/* Check the results. */
for (i = 0; i < Targets.cTargets; i++)
{
ret = wrapIcmpParseReplies(Targets.Buffers[i], sizeof(Targets.Buffers[i]));
printf("%s: %s\n", ret != 0 ? "UP " : "DOWN", inet_ntoa(Targets.IPAddresses[i]));
}
IcmpCloseHandle(hIcmp);
getchar();
return 0;
}
Mike
jlewicki
July 6th, 2007, 06:35 AM
Thanks Mike
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.