unit hostalive;
interface
uses
Windows, Winsock;
// Winapi.Windows, Winapi.Winsock;
function IsHostAlive(Hostname:
String; pTripTime: PCardinal=nil; Timeout: Integer=1000; TTL: Integer=255): Boolean;
implementation
type
IP_OPTION_INFORMATION =
packed record
TTL: Byte;
TOS: Byte;
Flags: Byte;
OptionsSize: Byte;
OptionsData: PAnsiChar;
end;
PIP_OPTION_INFORMATION = ^IP_OPTION_INFORMATION;
ICMP_ECHO_REPLY =
packed record
Address: in_addr;
Status: Cardinal;
RoundTripTime: Cardinal;
DataSize: Word;
Reserved: Word;
Data: Pointer;
Options: IP_OPTION_INFORMATION;
end;
PICMP_ECHO_REPLY = ^ICMP_ECHO_REPLY;
function IcmpCreateFile: THandle;
stdcall;
external '
Iphlpapi.dll';
function IcmpCloseHandle(IcmpHandle: THandle): Boolean;
stdcall;
external '
Iphlpapi.dll';
function IcmpSendEcho(IcmpHandle: THandle; DestinationAddress: Cardinal; RequestData: Pointer; RequestSize: Word; RequestOptions: PIP_OPTION_INFORMATION; ReplyBuffer: Pointer; ReplySize: Cardinal; Timeout: Cardinal): Cardinal;
stdcall;
external '
Iphlpapi.dll';
function ResolveHost(Hostname: AnsiString): Cardinal;
var
HostInfo: PHostEnt;
T: ^PInAddr;
begin
Result := inet_addr(PAnsiChar(Hostname));
if Result = INADDR_NONE
then begin
HostInfo := gethostbyname(PAnsiChar(Hostname));
if Assigned(HostInfo)
then begin
T := Pointer(HostInfo^.h_addr_list);
if Assigned(T)
and Assigned(T^)
then
Result := T^^.S_addr;
end;
end;
end;
function IsHostAlive(Hostname:
String; pTripTime: PCardinal; Timeout, TTL: Integer): Boolean;
const
SendBuffer:
array[0..31]
of AnsiChar = '
pingpongpingpongpingpongpingpong';
var
WSA: TWSADATA;
Reply: PICMP_ECHO_REPLY;
Addr: Cardinal;
hIcmp: THandle;
Options: IP_OPTION_INFORMATION;
begin
Result := False;
FillChar(Options, SizeOf(IP_OPTION_INFORMATION), #0);
Options.TTL := TTL;
Options.TOS := 1;
if WSAStartUp(((0
shl 8) + 2), WSA) = 0
then begin
Addr := ResolveHost(AnsiString(Hostname));
if Addr <> INADDR_NONE
then begin
hIcmp := IcmpCreateFile;
if hicmp <> INVALID_HANDLE_VALUE
then begin
Reply :=
nil;
try
Reply := AllocMem(SizeOf(ICMP_ECHO_REPLY) + SizeOf(SendBuffer));
IcmpSendEcho(hIcmp, Addr, @SendBuffer[0], SizeOf(SendBuffer), @Options, Reply, SizeOf(ICMP_ECHO_REPLY) + SizeOf(SendBuffer), Timeout);
Result := Reply^.Status = 0;
if Result
and Assigned(pTripTime)
then
pTripTime^ := Reply^.RoundTripTime;
finally
IcmpCloseHandle(hIcmp);
if Assigned(Reply)
then
FreeMem(Reply);
WSACleanup;
end;
end;
end else begin
// Hostname konnte nicht aufgelöst werden.
WSACleanup;
end;
end else begin
// Winsock konnte nicht gestartet werden.
end;
end;
end.