1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
| // -----------------------------------------------------------------------------
class function TConfigController.Ping(const IP: string): Boolean;
type
TECHO_REPLY_MSG = record
Status: ULONG;
Message: string;
end;
const
MSG: array[1..27] of TECHO_REPLY_MSG = (
(Status: 0; Message: 'The status was success.'),
(Status: 1; Message: 'The reply buffer was too small.'),
(Status: 2; Message: 'The destination network was unreachable. In IPv6 terminology, this status value is also defined as IP_DEST_NO_ROUTE.'),
(Status: 3; Message: 'The destination host was unreachable. In IPv6 terminology, this status value is also defined as IP_DEST_ADDR_UNREACHABLE.'),
(Status: 4; Message: 'The destination protocol was unreachable. In IPv6 terminology, this status value is also defined as IP_DEST_PROHIBITED.'),
(Status: 5; Message: 'The destination port was unreachable.'),
(Status: 6; Message: 'No IP resources were available.'),
(Status: 7; Message: 'A bad IP option was specified.'),
(Status: 8; Message: 'A hardware error occurred.'),
(Status: 9; Message: 'The packet was too big.'),
(Status: 10; Message: 'The request timed out.'),
(Status: 11; Message: 'A bad request.'),
(Status: 12; Message: 'A bad route.'),
(Status: 13; Message: 'The Time to Live (IPv4) or Hop Limit (IPv6) expired in transit. In IPv6 terminology, this status value is also defined as IP_HOP_LIMIT_EXCEEDED.'),
(Status: 14; Message: 'The Time to Live (IPv4) or Hop Limit (IPv6) expired during fragment reassembly. In IPv6 terminology, this status value is also defined as IP_REASSEMBLY_TIME_EXCEEDED.'),
(Status: 15; Message: 'A parameter problem. In IPv6 terminology, this status value is also defined as IP_PARAMETER_PROBLEM.'),
(Status: 16; Message: ' Message: ''Datagrams are arriving too fast to be processed and datagrams may have been discarded.'),
(Status: 17; Message: 'An IP option was too big.'),
(Status: 18; Message: 'A bad destination.'),
(Status: 40; Message: 'The destination was unreachable. The value is only applicable to IPv6.'),
(Status: 41; Message: 'The time was exceeded. The value is only applicable to IPv6.'),
(Status: 42; Message: 'A bad IP header was encountered. The value is only applicable to IPv6.'),
(Status: 43; Message: 'An unrecognized next header was encountered. The value is only applicable to IPv6.'),
(Status: 44; Message: 'An ICMP error occurred. The value is only applicable to IPv6.'),
(Status: 45; Message: 'A destination scope ID mismatch occurred. The value is only applicable to IPv6.'),
(Status: 50; Message: 'General Failure.'),
(Status: 255; Message: 'IP Pending.')
);
function GetStatus(Status: ULONG): string;
var
iMsg: Integer;
begin
Result := SysErrorMessage(Status);
if Status >= 11000 then
Status := Status - 11000;
for iMsg := Low(MSG) to High(MSG) do
begin
if MSG[iMsg].Status = Status then
begin
Result := MSG[iMsg].Message;
Exit;
end;
end;
end;
type
PIP_OPTION_INFORMATION = ^TIP_OPTION_INFORMATION;
TIP_OPTION_INFORMATION = record
Ttl: UCHAR;
Tos: UCHAR;
Flags: UCHAR;
OptionsSize: UCHAR;
OptionsData: PUCHAR;
end;
PICMP_ECHO_REPLY = ^TICMP_ECHO_REPLY;
TICMP_ECHO_REPLY = record
Address: TInAddr;
Status: ULONG;
RoundTripTime: ULONG;
DataSize: Word;
Reserved: Word;
Data: Pointer;
Options: TIP_OPTION_INFORMATION;
end;
var
IphlpapiHandle: THandle;
_IcmpCreateFile: function(): THandle; stdcall;
_IcmpCloseHandle: function(IcmpHandle: THandle): BOOL; stdcall;
_IcmpSendEcho: function(IcmpHandle: THandle; DestinationAddress: TInAddr; RequestData: Pointer; RequestSize: WORD; RequestOptions: PIP_OPTION_INFORMATION; ReplyBuffer: Pointer; ReplySize: DWORD; Timeout: DWORD): DWORD; stdcall;
var
InAddr: TInAddr;
IcmpHandle: THandle;
SendData: PChar;
dwRetVal: DWORD;
Reply: PICMP_ECHO_REPLY;
TimeStr: string;
begin
try
IphlpapiHandle := LoadLibrary('Iphlpapi');
Result := IphlpapiHandle > 0;
if Result then
begin
try
@_IcmpCreateFile := GetProcAddress(IphlpapiHandle, 'IcmpCreateFile');
@_IcmpCloseHandle := GetProcAddress(IphlpapiHandle, 'IcmpCloseHandle');
@_IcmpSendEcho := GetProcAddress(IphlpapiHandle, 'IcmpSendEcho');
Result := Assigned(@_IcmpCreateFile) and Assigned(@_IcmpCloseHandle) and Assigned(@_IcmpSendEcho);
if Result then
begin
SendData := 'Shai - Test de la Connexion (Ping) par un Send Echo (ICMP) !';
InAddr.S_addr := inet_addr(PChar(IP));
IcmpHandle := _IcmpCreateFile();
try
GetMem(Reply, StrLen(SendData) + SizeOf(TICMP_ECHO_REPLY));
try
dwRetVal := _IcmpSendEcho(IcmpHandle, InAddr, SendData, StrLen(SendData), nil, Reply, StrLen(SendData) + SizeOf(TICMP_ECHO_REPLY), 1000);
Result := dwRetVal <> 0;
if Result then
begin
if Reply^.RoundTripTime <= 0 then
TimeStr := ' < 1ms'
else
TimeStr := Format(' = %dms', [Reply^.RoundTripTime]);
_CCReport.AddInfo('IP', Format('Ping sur %s, Status : "%s", Temps%s, Message Reçu %d/1, TTL = %d', [IP, GetStatus(Reply^.Status), TimeStr, dwRetVal, Reply^.Options.Ttl]));
end else
begin
_CCReport.AddError('IP', Format('Echec du Ping sur %s, Erreur %d : %s', [IP, Windows.GetLastError(), GetStatus(Windows.GetLastError())]));
end;
finally
FreeMem(Reply);
end;
finally
_IcmpCloseHandle(IcmpHandle);
end;
end else
_CCReport.AddError('IP', 'Impossible d''Obtenir les Procédures "IcmpCreateFile", "IcmpCloseHandle" et "IcmpSendEcho"');
finally
FreeLibrary(IphlpapiHandle);
end;
end else
_CCReport.AddError('IP', 'Impossible de Charger "Iphlpapi.dll"');
except
on E: Exception do
begin
_CCReport.AddError('IP', E.Message);
Result := False;
end;
end;
end; |
Partager