Ping test
BlitzMax Forums/BlitzMax Programming/Ping test
| ||
I write a ping function for my network module BNetEx and I can only test it on my Win2k x86. I don't know if it works correct on MacOS(with Motorola processor) or on Linux. It can be different byte orders or so on...SuperStrict Framework Pub.StdC Extern "OS" Const INVALID_SOCKET_ : Int = -1 Const SOCK_RAW_ : Int = 3 Const IPPROTO_ICMP : Int = 1 ?Win32 Const SOL_SOCKET_ : Int = $FFFF Function inet_addr_:Int(Address$z) = "inet_addr@4" Function GetCurrentProcessId:Int() = "GetCurrentProcessId@0" ?MacOS Const SOL_SOCKET_ : Int = $FFFF Function inet_addr_:Int(Address$z) = "inet_addr" Function GetCurrentProcessId:Int() = "getpid" ?Linux Const SOL_SOCKET_ : Int = 1 Function inet_addr_:Int(Address$z) = "inet_addr" Function GetCurrentProcessId:Int() = "getpid" ? End Extern Type TICMP Field _Type : Byte Field Code : Byte Field Checksum : Short Field ID : Short Field Sequence : Short Function BuildChecksum:Short(Buffer:Short Ptr, Size:Int) Local Checksum:Long While Size > 1 Checksum :+ Buffer[0] Buffer :+ 1 Size :- 2 Wend If Size Then Checksum :+ (Byte Ptr(Buffer))[0] Checksum = (Checksum Shr 16) + (Checksum & $FFFF) Checksum :+ Checksum Shr 16 Return htons_(~Checksum) End Function End Type Const ICMP_ECHOREPLY : Byte = 0 Const ICMP_UNREACHABLE : Byte = 3 Const ICMP_ECHO : Byte = 8 Const ICMP_CODE_NETWORK_UNREACHABLE : Byte = 0 Const ICMP_CODE_HOST_UNREACHABLE : Byte = 1 Function Ping:Int(RemoteIP:Int, Data:Byte Ptr, Size:Int, Sequence:Int = 0, .. Timeout:Int = 5000) Local Socket:Int, ProcessID:Int, ICMP:TICMP, Buffer:Byte Ptr, .. Start:Int, Stop:Int, Result:Int, SenderIP:Int, SenderPort:Int, .. IPSize:Int Socket = socket_(AF_INET_, SOCK_RAW_, IPPROTO_ICMP) If Socket = INVALID_SOCKET_ Then Return -1 If setsockopt_(Socket, SOL_SOCKET_, SO_RCVTIMEO, Varptr(Timeout), 4) = .. SOCKET_ERROR_ Then closesocket_(Socket) Return -1 EndIf ProcessID = GetCurrentProcessID() ICMP = New TICMP ICMP._Type = ICMP_ECHO ICMP.Code = 0 ICMP.Checksum = 0 ICMP.ID = ProcessID ICMP.Sequence = 0 Buffer = MemAlloc(65536) MemCopy(Buffer, ICMP, 8) MemCopy(Buffer + 8, Data, Size) Short Ptr(Buffer)[1] = htons_(TICMP.BuildChecksum(Short Ptr(Buffer), 8 + Size)) If sendto_(Socket, Buffer, 8 + Size, 0, RemoteIP, 0) = SOCKET_ERROR_ Then MemFree(Buffer) closesocket_(Socket) Return -1 EndIf Start = MilliSecs() Repeat Result = recvfrom_(Socket, Buffer, 65536, 0, SenderIP, SenderPort) Stop = MilliSecs() If Result = SOCKET_ERROR_ Then MemFree(Buffer) closesocket_(Socket) Return -1 EndIf ?X86 IPSize = (Buffer[0] & $0F)*4 ?PPC IPSize = (Buffer[0] & $F0)*4 ? MemCopy(ICMP, Buffer + IPSize, 8) If ICMP.ID <> ProcessID Then Continue ElseIf ICMP._Type = ICMP_UNREACHABLE Then If ICMP.Code = ICMP_CODE_HOST_UNREACHABLE Or .. ICMP.Code = ICMP_CODE_NETWORK_UNREACHABLE Then MemFree(Buffer) closesocket_(Socket) Return -1 EndIf ElseIf ICMP.Code = ICMP_ECHOREPLY Then Exit EndIf Forever MemFree(Buffer) closesocket_(Socket) Return Stop - Start End Function Function IntIP:Int(IP:String) Return htonl_(inet_addr_(IP)) End Function Function GetHostIP:Int(HostName:String) Local Addresses:Byte Ptr Ptr, AddressType:Int, AddressLength:Int Local PAddress:Byte Ptr, Address:Int Addresses = gethostbyname_(HostName, AddressType, AddressLength) If (Not Addresses) Or AddressType <> AF_INET_ Or AddressLength <> 4 Then Return 0 If Addresses[0] Then PAddress = Addresses[0] Address = (PAddress[0] Shl 24) | (PAddress[1] Shl 16) | .. (PAddress[2] Shl 8) | PAddress[3] Return Address Else Return 0 EndIf End Function Global RemoteIP : Int, .. Message : String, .. Data : Byte Ptr, .. Result : Int RemoteIP = GetHostIP("google.com") If Not RemoteIP Then WriteStdout("Host not found~n") End EndIf Message = "Hello, world!" Data = Message.ToCString() Result = Ping(RemoteIP, Data, Message.Length) If Result = -1 Then WriteStdout("Ping failed~n") MemFree(Data) End EndIf WriteStdout("Ping tooks " + Result + "ms~n") MemFree(Data) End (Test is at the end of the sourcecode) If it's work, please remove the ! from "Hello, world!" so that is an odd data size and test it again. Thank you! cu olli |