Implementing PING Without Using Raw Sockets
Zarko Gajic - April 03, 2019
Zarko Gajic - April 03, 2019
[SHOWTOGROUPS=4,20]
Internet PINGs Using Delphi and Icmp.dll (this DLL can be founded in C:\Windows\System32 or SysWOW64 in 64bit edition)
Windows supports an Internet Control Message Protocol (ICMP) to determine whether or not a particular host is available.
What Is a Ping?
A ping is the process of sending an echo message to an IP address and reading the reply to verify a connection between TCP/IP hosts. If you are writing a new application, you will be better to use the Winsock 2 raw sockets support, implemented in Indy, for example.
Please note, however, that for Windows NT and Windows 2000 implementations, Raw Sockets are subject to security checks and are accessible only to members of the administrator's group.
Icmp.dll provides functionality that allows developers to write Internet ping applications on Windows systems without Winsock 2 support.
Note that the Winsock 1.1 WSAStartup function must be called prior to using the functions exposed by ICMP.DLL.
If you do not do this, the first call to IcmpSendEcho will fail with error 10091 (WSASYSNOTREADY).
Below you can find the Ping unit's source code. Here are two examples of usage.
Example 1: Code Snippet
Example 2: Console Mode Delphi Program
Our next example is a console mode Delphi program that uses the Ping unit: . Here's the Ping unit's source:
[/SHOWTOGROUPS]
Internet PINGs Using Delphi and Icmp.dll (this DLL can be founded in C:\Windows\System32 or SysWOW64 in 64bit edition)
Windows supports an Internet Control Message Protocol (ICMP) to determine whether or not a particular host is available.
- ICMP is a network layer protocol that delivers flow control, error messages, routing, and other data between Internet hosts.
- ICMP is primarily used by application developers for a network ping.
What Is a Ping?
A ping is the process of sending an echo message to an IP address and reading the reply to verify a connection between TCP/IP hosts. If you are writing a new application, you will be better to use the Winsock 2 raw sockets support, implemented in Indy, for example.
Please note, however, that for Windows NT and Windows 2000 implementations, Raw Sockets are subject to security checks and are accessible only to members of the administrator's group.
Icmp.dll provides functionality that allows developers to write Internet ping applications on Windows systems without Winsock 2 support.
Note that the Winsock 1.1 WSAStartup function must be called prior to using the functions exposed by ICMP.DLL.
If you do not do this, the first call to IcmpSendEcho will fail with error 10091 (WSASYSNOTREADY).
Below you can find the Ping unit's source code. Here are two examples of usage.
Example 1: Code Snippet
Код:
uses
Ping;
const
ADP_IP = 'YOUR_IP_FOR_TEST_HERE_or_YOUR_URL_DOMAIN'; // www.google.com or aaa.bbb.ccc.ddd
begin
If Ping.Ping(ADP_IP) then
ShowMessage('Your IP is reachable!')
else
ShowMessage('Your IP is not reachable!')
end;
Our next example is a console mode Delphi program that uses the Ping unit: . Here's the Ping unit's source:
Код:
unit Ping;
interface
uses
Windows,
SysUtils,
Classes;
type
TSunB = packed record
s_b1, s_b2, s_b3, s_b4: byte;
end;
TSunW = packed record
s_w1, s_w2: word;
end;
PIPAddr = ^TIPAddr;
TIPAddr = record
case integer of
0:
(S_un_b: TSunB);
1:
(S_un_w: TSunW);
2:
(S_addr: longword);
end;
IPAddr = TIPAddr;
function IcmpCreateFile: THandle; stdcall; external 'icmp.dll';
//
function IcmpCloseHandle(icmpHandle: THandle): boolean; stdcall; external 'icmp.dll';
//
function IcmpSendEcho(IcmpHandle: THandle; DestinationAddress: IPAddr; { }
RequestData: Pointer; RequestSize: Smallint; RequestOptions: pointer; { }
ReplyBuffer: Pointer; ReplySize: DWORD; Timeout: DWORD): DWORD; stdcall; external 'icmp.dll';
//
function Ping(InetAddress: string): boolean;
//
implementation
uses
WinSock;
function Fetch(var AInput: string; const ADelim: string = ' '; { }
const ADelete: Boolean = true): string;
var
iPos: Integer;
begin
if ADelim = #0 then
begin
// AnsiPos does not work with #0
iPos := Pos(ADelim, AInput);
end
else
begin
iPos := Pos(ADelim, AInput);
end;
if iPos = 0 then
begin
Result := AInput;
if ADelete then
begin
AInput := '';
end;
end
else
begin
result := Copy(AInput, 1, iPos - 1);
if ADelete then
begin
Delete(AInput, 1, iPos + Length(ADelim) - 1);
end;
end;
end;
procedure TranslateStringToTInAddr(AIP: string; var AInAddr);
var
lHostEnt : PHostEnt;
lAddressList: PAnsiChar;
lInitWSAData: TWSAData;
begin
lHostEnt := nil;
lAddressList := nil;
//
WSAStartup($101, lInitWSAData);
//
try
try
lHostEnt := GetHostByName(PAnsiChar(AIP));
//
if (lHostEnt = nil) then
raise Exception.Create('Error getting HostName');
//
lAddressList := lHostEnt^.h_addr_list^;
//
if (lAddressList = nil) then
raise Exception.Create('Error getting IP from HostName');
//
with TIPAddr(AInAddr).S_un_b do
begin
s_b1 := Byte(lAddressList[0]);
s_b2 := Byte(lAddressList[1]);
s_b3 := Byte(lAddressList[2]);
s_b4 := Byte(lAddressList[3]);
end;
except
FillChar(AInAddr, SizeOf(AInAddr), #0);
end;
finally
WSACleanup;
end;
end;
function Ping(InetAddress: string): boolean;
var
lHandle : THandle;
lIPAddressTarget: IPAddr;
lResult : DWORD;
lReplyBuffer : array [1 .. 128] of byte;
begin
result := false;
//
lHandle := IcmpCreateFile;
//
try
try
if not(lHandle = INVALID_HANDLE_VALUE) then
begin
//
TranslateStringToTInAddr(InetAddress, lIPAddressTarget);
//
// ICMPHandle, IPAddressTarget, RequestData, RequestSize, RequestOptions, ReplyBuffer, ReplySize, Timeout
lResult := IcmpSendEcho(lHandle, lIPAddressTarget, nil, 0, nil, @lReplyBuffer, 128, 0);
//
Result := not(lResult = 0);
end;
except
// result := false;
end;
finally
IcmpCloseHandle(lHandle);
end;
end;
Последнее редактирование: