Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Indy Ping Broken?



Permlink Replies: 1 - Last Post: Jan 29, 2018 9:53 AM Last Post By: Remy Lebeau (Te... Threads: [ Previous | Next ]
Colin Maharaj

Posts: 122
Registered: 12/2/99
Indy Ping Broken?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 28, 2018 3:48 AM
Any suggestions......

Had this but hangs (the compiler too) I am using BCBXE4 on Windows 10 64 bit.
//---------------------------------------------------------------------------
AnsiString PingX(const char *Addr)
{
TIdIcmpClient * c = new TIdIcmpClient(NULL);
AnsiString ret = "";
try
{
c->Host = Addr;
c->ReceiveTimeout = 2000;
c->Ping ();
ret = c->ReplyStatus->BytesReceived; ret += " Bytes ";
ret += "From: "; ret += c->ReplyStatus->FromIpAddress; ret += " ";
ret += "TTL: " ; ret += c->ReplyStatus->TimeToLive;
}

catch(...)
{
ret = "Socket error in ping";
}

delete c;

return ret;
}

//-------------------------------------------------------------------------
Tried this and it works.....(winapi)
//-------------------------------------------------------------------------
AnsiString return : returns verbose description of the PING situation.
char * ret : returns the typical ping like description of the ping.
//-------------------------------------------------------------------------

AnsiString ping2(const char *ip, char *ret)
{

// Declare and initialize variables
AnsiString A = "PING : ";
HANDLE hIcmpFile;
struct hostent *host;
struct in_addr *ptr; // To retrieve the IP Address

char strTemp[64];

unsigned long ipaddr = INADDR_NONE;
DWORD dwRetVal = 0;
char SendData[32] = "Data Buffer";
LPVOID ReplyBuffer = NULL;
DWORD ReplySize = 0;

ipaddr = inet_addr(ip);
if (ipaddr == INADDR_NONE)
{
A = "Cannot resolve IP from hostname";
host = gethostbyname(ip);
if(host == NULL) return A;
A = " PING: ";

ptr = (struct in_addr *)
host->h_addr_list[0];

// Eg. 211.40.35.76 split up like this.
int a = ptr->S_un.S_un_b.s_b1; // 211
int b = ptr->S_un.S_un_b.s_b2; // 40
int c = ptr->S_un.S_un_b.s_b3; // 35
int d = ptr->S_un.S_un_b.s_b4; // 76
char strTemp[32]={0};
sprintf(strTemp, "%d.%d.%d.%d", a,b,c,d);
ipaddr = inet_addr(strTemp);
// A += "usage: "; A+= ip; A += " IP address ";
}

hIcmpFile = IcmpCreateFile();
if (hIcmpFile == INVALID_HANDLE_VALUE)
{
A += "Unable to open handle.";
A += " IcmpCreatefile returned error: "; A += GetLastError();
return A;
}

ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
ReplyBuffer = (VOID*) malloc(ReplySize);
if (ReplyBuffer == NULL)
{
A = "Unable to allocate memory";
return A;
}

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;
A += " Sent icmp message to ";
A += ip;

if (dwRetVal > 1)
{
A += " Received "; A += dwRetVal; A += " icmp message responses ";
A += " Information from the first response: ";
}
else
{
A += " Received "; A += dwRetVal; A += " icmp message response ";
A += " Information from this response: ";
}
A += " Received from "; A += inet_ntoa( ReplyAddr ) ;
A += " Status = ", A += pEchoReply->Status;
A += " Roundtrip time = "; A += pEchoReply->RoundTripTime; A += " milliseconds ";

strcpy(ret, "Reply from "); strcat(ret, ip);
strcat(ret, ": bytes="); intcat(ret, pEchoReply->DataSize); // Sorry intcat is my function
strcat(ret, " time<"ms ");
strcat(ret, " TTL="); intcat(ret, pEchoReply->Options.Ttl);


}
else
{
A += " Call to IcmpSendEcho failed.";
A += " IcmpSendEcho returned error: "; A += GetLastError() ;
return A;
}
free(ReplyBuffer);
return A;
}

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Indy Ping Broken?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 29, 2018 9:53 AM   in response to: Colin Maharaj in response to: Colin Maharaj
Colin Maharaj wrote:

Any suggestions......

TIdICMPClient uses a RAW socket to implement ICMP manually. RAW
sockets require admin rights on most platforms, including Windows. Is
your app running with admin rights? Microsoft's ICMP API does not
require admin rights.

Had this but hangs (the compiler too)

What do you mean it "hangs" exactly? And how is it hanging the
compiler?

AnsiString PingX(const char *Addr) {

Why are you using ANSI in a Unicode environment?

ipaddr = inet_addr(ip);
if (ipaddr == INADDR_NONE)
{
A = "Cannot resolve IP from hostname";
host = gethostbyname(ip);

You should be using getaddrinfo() instead.

// Eg. 211.40.35.76 split up like this.
int a = ptr->S_un.S_un_b.s_b1; // 211
int b = ptr->S_un.S_un_b.s_b2; // 40
int c = ptr->S_un.S_un_b.s_b3; // 35
int d = ptr->S_un.S_un_b.s_b4; // 76
char strTemp[32]={0};
sprintf(strTemp, "%d.%d.%d.%d", a,b,c,d);
ipaddr = inet_addr(strTemp);

You don't need to do that, gethostbyname() gives you the IP in numeric
format:

ptr = (struct in_addr *) host->h_addr_list[0];
ipaddr = ptr->s_addr;


In fact, IcmpSendEcho() takes an IPAddr (a typedef of the in_addr
struct) as input, not a ULONG, so your code shouldn't even compile as
shown.

ReplyBuffer = (VOID*) malloc(ReplySize);

You should not be using malloc() in C++. Use new[] instead.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02