Monday, March 9, 2020

Implementing PING Without Using Raw Sockets

Implementing PING Without Using Raw Sockets 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 administrators 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 units source code. Here are two examples of usage. Example 1: Code Snippet uses Ping;...​const ADP_IP 208.185.127.40; (* http://delphi.about.com *)beginIf Ping.Ping(ADP_IP) then ShowMessage(About Delphi Programming reachable!);end; Example 2: Console Mode  Delphi Program Our next example is a console mode Delphi program  that uses the Ping unit:  . Heres  the Ping units source: unit Ping;​interfaceusesWindows, SysUtils, Classes;typeTSunB packed records_b1, s_b2, s_b3, s_b4: byte;end;TSunW packed records_w1, s_w2: word;end;PIPAddr ^TIPAddr;TIPAddr recordcase integer of0: (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.dllfunction 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;implementationusesWinSock;function Fetch(var AInput: string;const ADelim: string ;const ADelete: Boolean true): string;variPos: Integer;beginif ADelim #0 then begin// AnsiPos does not work with #0iPos : Pos(ADelim, AInput);end else beginiPos : Pos(ADelim, AInput);end;if iPos 0 the n beginResult : AInput;if ADelete then beginAInput : ;end;end else beginresult : Copy(AInput, 1, iPos - 1);if ADelete then beginDelete(AInput, 1, iPos Length(ADelim) - 1);end;end;end;procedure TranslateStringToTInAddr(AIP: string; var AInAddr);varphe: PHostEnt;pac: PChar;GInitData: TWSAData;beginWSAStartup($101, GInitData);tryphe : GetHostByName(PChar(AIP));if Assigned(phe) thenbeginpac : phe^.h_addr_list^;if Assigned(pac) thenbeginwith TIPAddr(AInAddr).S_un_b do begins_b1 : Byte(pac[0]);s_b2 : Byte(pac[1]);s_b3 : Byte(pac[2]);s_b4 : Byte(pac[3]);end;endelsebeginraise Exception.Create(Error getting IP from HostName);end;endelsebeginraise Exception.Create(Error getting HostName);end;exceptFillChar(AInAddr, SizeOf(AInAddr), #0);end;WSACleanup;end;function Ping(InetAddress : string) : boolean;varHandle : THandle;InAddr : IPAddr;DW : DWORD;rep : array[1..128] of byte;beginresult : false;Handle : IcmpCreateFile;if Handle INVALID_HANDLE_VALUE thenExit;TranslateStringToTInAddr(InetAddres s, InAddr);DW : IcmpSendEcho(Handle, InAddr, nil, 0, nil, rep, 128, 0);Result : (DW 0);IcmpCloseHandle(Handle);end;​end.