IonicWind Software

IWBasic => General Questions => Topic started by: Locodarwin on April 10, 2008, 04:42:22 PM

Title: Implementing a "Ping" function
Post by: Locodarwin on April 10, 2008, 04:42:22 PM
Hello, folks,

My experience with Winsock is limited.  I'm attempting to create a pinging function that attempts to ping a remote host and returns a pass/fail.  Parameters would include the remote IP/hostname to reach and a timeout threshold.

I have a few C/C++ examples I can leverage for conversion - some of them use sockets and one of them uses IcmpSendEcho() (ICMP.DLL) , but I wanted to see if anyone else has created such a subroutine already before I bother knocking my head against it.

Has anyone played with this?

-S
Title: Re: Implementing a "Ping" function
Post by: JoaoAfonso on April 10, 2008, 07:03:50 PM
Hello. I use this code in a game I am making, which was got from IB STD and changed somewhat to EB and to my purposes:

DECLARE Import,send(s:int,buf:string,buflen:int,flags:int),int

if send(socket,chr$(0),len(chr$(0))+1,5)<>len(chr$(0))+1
     'NO PING FOR THIS SOCKET CODE
endif


In my code I have a socket list, which are the players, and each 5 minutes I check all sockets. If no ping, I close those sockets. Hope this is useful.
Title: Re: Implementing a "Ping" function
Post by: Locodarwin on April 11, 2008, 09:36:54 AM
I appreciate your response.  Unfortunately it doesn't help me much.  The send() function is a one-way transmission, with no guarantee or verification of delivery.  It's fine for checking the status of the established socket itself, but it's not the same thing as a ping.  The other machines that I'm reaching aren't using a client - they're just machines sitting on the network.  I need to send and receive ICMP traffic.

Thanks,

-S
Title: Re: Implementing a "Ping" function
Post by: pistol350 on April 11, 2008, 07:26:30 PM
hi!
Maybe this can help
found in my code samples archive


'Icmp constants converted from
'http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/win32_pingstatus.asp

$use "icmp.lib"
$use "ws2_32.lib"

CONST ICMP_SUCCESS=0
CONST ICMP_STATUS_BUFFER_TO_SMALL=11001:            'Buffer Too Small
CONST ICMP_STATUS_DESTINATION_NET_UNREACH=11002:      'Destination Net Unreachable
CONST ICMP_STATUS_DESTINATION_HOST_UNREACH=11003:      'Destination Host Unreachable
CONST ICMP_STATUS_DESTINATION_PROTOCOL_UNREACH=11004:   'Destination Protocol Unreachable
CONST ICMP_STATUS_DESTINATION_PORT_UNREACH=11005:      'Destination Port Unreachable
CONST ICMP_STATUS_NO_RESOURCE=11006:               'No Resources
CONST ICMP_STATUS_BAD_OPTION=11007:                  'Bad Option
CONST ICMP_STATUS_HARDWARE_ERROR=11008:               'Hardware Error
CONST ICMP_STATUS_LARGE_PACKET=11009:               'Packet Too Big
CONST ICMP_STATUS_REQUEST_TIMED_OUT=11010:            'Request Timed Out
CONST ICMP_STATUS_BAD_REQUEST=11011:               'Bad Request
CONST ICMP_STATUS_BAD_ROUTE=11012:                  'Bad Route
CONST ICMP_STATUS_TTL_EXPIRED_TRANSIT=11013:         'TimeToLive Expired Transit
CONST ICMP_STATUS_TTL_EXPIRED_REASSEMBLY=11014:         'TimeToLive Expired Reassembly
CONST ICMP_STATUS_PARAMETER=11015:                  'Parameter Problem
CONST ICMP_STATUS_SOURCE_QUENCH=11016:               'Source Quench
CONST ICMP_STATUS_OPTION_TOO_BIG=11017:               'Option Too Big
CONST ICMP_STATUS_BAD_DESTINATION=11018:            'Bad Destination
CONST ICMP_STATUS_NEGOTIATING_IPSEC=11032:            'Negotiating IPSEC
CONST ICMP_STATUS_GENERAL_FAILURE=11050:            'General Failure

'CONST WINSOCK_ERROR="Windows Sockets not responding correctly"

CONST INADDR_NONE=0xFFFFFFFF
CONST WSA_SUCCESS=0
CONST WS_VERSION_REQD=0x101

'Clean up sockets
'http://support.microsoft.com/default.aspx?scid=kb;EN-US;q154512
DECLARE IMPORT,WSACleanup(),INT

'Open the socket connection
'http://support.microsoft.com/default.aspx?scid=kb;EN-US;q154512
DECLARE IMPORT,WSAStartup(wVersionRequired:INT,lpWSADATA:POINTER),INT

'Create a handle on which Internet Control Message Protocol (ICMP) requests can be issued
'http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcesdkr/htm/_wcesdk_icmpcreatefile.asp
DECLARE IMPORT,IcmpCreateFile(),INT

'Convert a string that contains an (Ipv4) Internet Protocol dotted address into a correct address
'http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/wsapiref_4esy.asp
DECLARE IMPORT,inet_addr(cp:STRING),INT

'Close an Internet Control Message Protocol (ICMP) handle that IcmpCreateFile opens
'http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcesdkr/htm/_wcesdk_icmpclosehandle.asp
DECLARE IMPORT,IcmpCloseHandle(IcmpHandle:INT),INT

'Information about the Windows Sockets implementation
'http://support.microsoft.com/default.aspx?scid=kb;EN-US;q154512
TYPE WSADATA
   WORD wVersion
   WORD wHighVersion
   ISTRING strDescription[256]
   ISTRING strSystemStatus[128]
   INT iMaxSockets
   INT iMaxUdpDg
   POINTER lpVendorInfo
ENDTYPE

'Send an Internet Control Message Protocol (ICMP) echo request, and then return one or more replies
'http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcetcpip/htm/cerefIcmpSendEcho.asp
DECLARE IMPORT,IcmpSendEcho(IcmpHandle:INT,DestinationAddress:INT,RequestData:STRING,RequestSize:INT,RequestOptions:INT,ReplyBuffer:ICMP_ECHO_REPLY,ReplySize:INT,Timeout:INT),INT
'This structure describes the options that will be included in the header of an IP packet
'http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcetcpip/htm/cerefIP_OPTION_INFORMATION.asp
TYPE IP_OPTION_INFORMATION
   CHAR Ttl
   CHAR Tos
   CHAR Flags
   CHAR OptionsSize
   INT OptionsData
ENDTYPE

'This structure describes the data that is returned in response to an echo request
'http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcesdkr/htm/_wcesdk_icmp_echo_reply.asp
TYPE ICMP_ECHO_REPLY
   INT address
   INT Status
   INT RoundTripTime
   INT DataSize
   INT Reserved
   POINTER ptrData
   IP_OPTION_INFORMATION Options
   ISTRING iData[250]
ENDTYPE

TYPE Hostent 
   DEF h_name:POINTER  /* official name of host */
   DEF h_aliases:POINTER      /*  list (pointer to string pointer list) */
   DEF h_addrtype:SWORD   /* host address type */
   DEF h_len:SWORD /* length of address */
   DEF h_list:POINTER /* list of addresses (pointer to string pointer list) */
ENDTYPE
Declare IMPORT,gethostbyname(HostName As String),Hostent

'-- Ping a string representation of an IP address
' -- Return a reply
' -- Return long code
'DECLARE PingIt(sAddress:STRING,Reply:ICMP_ECHO_REPLY),INT

OPENCONSOLE

   Dim Reply As ICMP_ECHO_REPLY
   Dim lngSuccess As INT
   Dim strIPAddress As String

   'Get the sockets ready.
   If SocketsInitialize() Then

    'Address to ping
    strIPAddress = "192.168.1.1"
    'Ping the IP that is passing the address and get a reply.
'    strIPAddress = "64.233.167.99" :'google.com

      print "BY ADDRESS"
     lngSuccess = PingAddress("192.168.1.1", Reply)
    'Display the results.
    Print "RESULTS:"
    Print "Raw ICMP code: ", lngSuccess
    Print "Ping Response Message : ", EvaluatePingResponse(lngSuccess)
    Print "Time : ", Reply.RoundTripTime,  " ms"

      PRINT

      print "BY NAME"
    lngSuccess = PingName("google.com", Reply)
    'Display the results.
    Print "RESULTS:"
    Print "Raw ICMP code: ", lngSuccess
    Print "Ping Response Message : ", EvaluatePingResponse(lngSuccess)
    Print "Time : ", Reply.RoundTripTime,  " ms"

    'Clean up the sockets.
    SocketsCleanup()

   Else

   'Winsock error failure, initializing the sockets.
   Print "WINSOCK_ERROR"

   EndIf

PRINT:PRINT "Press any key to close"
DO:UNTIL INKEY$<>""
CLOSECONSOLE
END

SUB PingAddress(sAddress:STRING,Reply:ICMP_ECHO_REPLY),INT
INT hIcmp,lAddress,lTimeOut,ping,Status
STRING StringToSend
'Short string of data to send
   StringToSend="Hello"

'ICMP (ping) timeout
   lTimeOut=1000:'ms
print "Pinging Address: ", sAddress
'Convert string address to a long representation
   lAddress=inet_addr(sAddress)
IF (lAddress<>-1) AND (lAddress<>0)
   hIcmp=IcmpCreateFile():'Create the handle for ICMP requests
IF hIcmp:'Ping the destination IP address
   hIcmp=IcmpSendEcho(hIcmp,lAddress,StringToSend,LEN(StringToSend),0,Reply,LEN(Reply),lTimeOut)
'Reply status
   ping=Reply.Status
'Close the Icmp handle
   IcmpCloseHandle(hIcmp)
ELSE
   PRINT "Failure opening icmp handle"
   ping=-1
ENDIF
ELSE
   ping=-1
ENDIF
RETURN ping
ENDSUB

SUB PingName(sHostName:STRING,Reply:ICMP_ECHO_REPLY),INT
INT hIcmp,lAddress,lTimeOut,ping,Status
STRING StringToSend,strIPAddress
'Short string of data to send
   StringToSend="Hello"
'ICMP (ping) timeout
   lTimeOut=1000:'ms
hHostent = gethostbyname(sHostName)
strIPAddress  = ltrim$(str$(hHostent.*<CHAR>*<POINTER>h_list[0])) + "."_
                      +ltrim$(str$(hHostent.*<CHAR>*<POINTER>h_list[1])) + "."_
                      +ltrim$(str$(hHostent.*<CHAR>*<POINTER>h_list[2])) + "."_
                      +ltrim$(str$(hHostent.*<CHAR>*<POINTER>h_list[3]))

print "Pinging Address: ", strIPAddress
'Convert string address to a long representation
   lAddress=inet_addr(strIPAddress)
IF (lAddress<>-1) AND (lAddress<>0)
   hIcmp=IcmpCreateFile():'Create the handle for ICMP requests
IF hIcmp:'Ping the destination IP address
   hIcmp=IcmpSendEcho(hIcmp,lAddress,StringToSend,LEN(StringToSend),0,Reply,LEN(Reply),lTimeOut)
'Reply status
   ping=Reply.Status
'   ping=Status
'Close the Icmp handle
   IcmpCloseHandle(hIcmp)
ELSE
   PRINT "Failure opening icmp handle"
   ping=-1
ENDIF
ELSE
   ping=-1
ENDIF
RETURN ping
ENDSUB

'Clean up the sockets
'http://support.microsoft.com/default.aspx?scid=kb;EN-US;q154512
SUB SocketsCleanup()
   WSACleanup()
RETURN:ENDSUB

'Get the sockets ready
'http://support.microsoft.com/default.aspx?scid=kb;EN-US;q154512
SUB SocketsInitialize(),INT
   DEF WSAD:WSADATA
   if WSAStartup(WS_VERSION_REQD,WSAD) = ICMP_SUCCESS then RETURN 1
RETURN 0
ENDSUB

'Convert the ping response to a message that you can read easily from constants
'For more information about these constants, visit the following Microsoft Web site:
'http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/win32_pingstatus.asp
SUB EvaluatePingResponse(PingResponse As INT),String
STRING RET$
  Select PingResponse
  'Success
  Case ICMP_SUCCESS: RET$="Success!"
  'Some error occurred
  Case ICMP_STATUS_BUFFER_TO_SMALL:    RET$="Buffer Too Small"
  Case ICMP_STATUS_DESTINATION_NET_UNREACH: RET$="Destination Net Unreachable"
  Case ICMP_STATUS_DESTINATION_HOST_UNREACH: RET$="Destination Host Unreachable"
  Case ICMP_STATUS_DESTINATION_PROTOCOL_UNREACH: RET$="Destination Protocol Unreachable"
  Case ICMP_STATUS_DESTINATION_PORT_UNREACH: RET$="Destination Port Unreachable"
  Case ICMP_STATUS_NO_RESOURCE: RET$="No Resources"
  Case ICMP_STATUS_BAD_OPTION: RET$="Bad Option"
  Case ICMP_STATUS_HARDWARE_ERROR: RET$="Hardware Error"
  Case ICMP_STATUS_LARGE_PACKET: RET$="Packet Too Big"
  Case ICMP_STATUS_REQUEST_TIMED_OUT: RET$="Request Timed Out"
  Case ICMP_STATUS_BAD_REQUEST: RET$="Bad Request"
  Case ICMP_STATUS_BAD_ROUTE: RET$="Bad Route"
  Case ICMP_STATUS_TTL_EXPIRED_TRANSIT: RET$="TimeToLive Expired Transit"
  Case ICMP_STATUS_TTL_EXPIRED_REASSEMBLY: RET$="TimeToLive Expired Reassembly"
  Case ICMP_STATUS_PARAMETER: RET$="Parameter Problem"
  Case ICMP_STATUS_SOURCE_QUENCH: RET$="Source Quench"
  Case ICMP_STATUS_OPTION_TOO_BIG: RET$="Option Too Big"
  Case ICMP_STATUS_BAD_DESTINATION: RET$="Bad Destination"
  Case ICMP_STATUS_NEGOTIATING_IPSEC: RET$="Negotiating IPSEC"
  Case ICMP_STATUS_GENERAL_FAILURE: RET$="General Failure"
  'Unknown error occurred
  Default: RET$="Unknown Response"
   EndSelect
RETURN RET$
ENDSUB
Title: Re: Implementing a "Ping" function
Post by: Locodarwin on April 12, 2008, 04:08:49 PM
That's a hell of a find, there, Peter.  Thanks!

-S
Title: Re: Implementing a "Ping" function
Post by: Egil on April 13, 2008, 09:58:25 AM
pistol350:
That example came in handy for me as well. Thanks.
Just one question... where can I find the file icmp.lib??
Title: Re: Implementing a "Ping" function
Post by: DominiqueB on April 13, 2008, 10:13:42 AM
simple:

just use the menu "tools - Create Import Library" in the ide, and then choose the "icmp.dll"

That's all

Dominique
Title: Re: Implementing a "Ping" function
Post by: pistol350 on April 13, 2008, 01:54:29 PM
Hi Egil!
Just do as DominiqueB said,
and if you have any trouble to get the source compiled,
I / we will be glad to help  :)
Title: Re: Implementing a "Ping" function
Post by: Egil on April 14, 2008, 03:43:44 AM
Thanks to both of you! Now my compiling problems have gone.
After playing with the EB-package for a few days, examining the example code and some snippets here from the forum, I finally see what a powerful tool this package really is. But I still have a long way to go, so you guys must still bare over with me and my silly qquestions for a while ;D
Title: Re: Implementing a "Ping" function
Post by: pistol350 on April 14, 2008, 04:00:48 AM
As Larry usually says,
there is no stupid question, what can be stupid is not asking for help when needed  ;)
Title: Re: Implementing a "Ping" function
Post by: sapero on April 28, 2008, 04:13:10 PM
Pistol, hIcmp=IcmpSendEcho is incorrect, you are overwriting the hIcmp handle!
Title: Re: Implementing a "Ping" function
Post by: Locodarwin on April 28, 2008, 04:23:23 PM
Quote from: sapero on April 28, 2008, 04:13:10 PM
Pistol, hIcmp=IcmpSendEcho is incorrect, you are overwriting the hIcmp handle!

Good catch, as usual, sapero.  I'd better update my subroutine in the Winsock feature request thread.

-S
Title: Re: Implementing a "Ping" function
Post by: pistol350 on April 28, 2008, 11:54:19 PM
Thank you Sapero.

I may have other codes with that same mistake, i will update them.
But, unfortunately, i am not the author of this code and i don't know who wrote it either.