I post this sample code forwarding posts on the french forum.
It shows a way to scan IPs quickly using threads. It remains some possible display bugs because of multi-threading mess when using strings ... which I don't know really to secure or make definiteely stable.
Well, this can start a better release able to scan both IPs and ports, if anyone is interested in co-designing this.
Enjoy and give any feedback / suggestion.
Code: Select all
Enumeration
#Window_Main
#StatusBar
#Gadget_Text_Start
#Gadget_Text_End
#Gadget_Button_OK
#Gadget_Button_Cancel
#Gadget_IP_Start
#Gadget_IP_End
#Gadget_ListIcon
EndEnumeration
#MaxThreads = 1000
Global NewList Threads.l()
Global StartAddress.l, EndAddress.l, sStartAddress.s, sEndAddress.s
Global Run.l
Global TotalConnections.l, TotalThreads.l, CurrentConnection.s
Global OldTotalConnections.l, OldTotalThreads.l, OldCurrentConnection.s
Global hListIconGadget.l
Procedure UpdateListIcon(String.s)
EndProcedure
Procedure TestConnectionToIP(IPAddress.l)
sIPAddress.s = IPString(IPAddress)
#PING_TIMEOUT = 1000
strMessage.s
Echo.ICMP_ECHO_REPLY
EchoMessage.s = "Hello there " + Space(20)
tz = GetTickCount_()
hFile = IcmpCreateFile_()
lngResult = IcmpSendEcho_(hFile, IPAddress, EchoMessage, Len(EchoMessage), 0, Echo, SizeOf(ICMP_ECHO_REPLY), #PING_TIMEOUT)
If lngResult = 0
PingResult = Echo\Status * -1
Else
PingResult = Echo\RoundTripTime
EndIf
lngResult = IcmpCloseHandle_(hFile)
If PingResult >= 0
While WindowEvent() : Wend
CurrentConnection = "Scanning " + sIPAddress + " OK"
If ListSize(Threads()) > #MaxThreads
While ListSize(Threads()) > #MaxThreads / 2
ResetList(Threads())
NextElement(Threads())
WaitThread(Threads())
Sleep_(2500)
DeleteElement(Threads())
TotalThreads - 1
Wend
EndIf
AddGadgetItem(#Gadget_ListIcon, -1, sIPAddress + Chr(10) + Str(GetTickCount_() - tz))
While WindowEvent() : Wend
EndIf
TotalConnections - 1
TotalThreads - 1
EndProcedure
Procedure RunScan(a=0)
Sleep_(500)
StartAddress.l = GetGadgetState(#Gadget_IP_Start)
EndAddress.l = GetGadgetState(#Gadget_IP_End)
iStartAddress = IPAddressField(StartAddress, 0) << 24 + IPAddressField(StartAddress, 1) << 16 + IPAddressField(StartAddress, 2) << 8 + IPAddressField(StartAddress, 3)
iEndAddress = IPAddressField(EndAddress, 0) << 24 + IPAddressField(EndAddress, 1) << 16 + IPAddressField(EndAddress, 2) << 8 + IPAddressField(EndAddress, 3)
For iIPAddress = iStartAddress To iEndAddress
IPAddress = MakeIPAddress(IPAddressField(iIPAddress, 3), IPAddressField(iIPAddress, 2), IPAddressField(iIPAddress, 1), IPAddressField(iIPAddress, 0))
sIPAddress.s = IPString(IPAddress)
CurrentConnection = "Scanning " + sIPAddress
ParameterString.s = Str(IPAddress)
TotalConnections + 1
ThreadID = CreateThread(@TestConnectionToIP(), IPAddress)
TotalThreads + 1
Delay(50)
Next
Run = #False
TotalThreads - 1
EndProcedure
Procedure Stop(ThreadID)
Run = #False
CurrentConnection = "Canceling ..."
If ThreadID <> 0
CurrentConnection = "Canceling " + Str(ThreadID)
KillThread(ThreadID)
TotalThreads - 1
EndIf
ResetList(Threads())
While NextElement(Threads())
CurrentConnection = "Canceling " + Str(Threads())
KillThread(Threads())
TotalThreads - 1
Wend
ClearList(Threads())
CurrentConnection = "Done"
EndProcedure
Procedure DoWeRun(ThreadID.l)
If ThreadID <> 0
Stop(ThreadID)
SendMessage_(hListIconGadget, #LVM_DELETEALLITEMS, 0, 0)
EndIf
Run = #True
CurrentConnection = "Scanning ..."
ThreadID = CreateThread(@RunScan(), 0)
TotalThreads + 1
ProcedureReturn ThreadID
EndProcedure
;
;
;
sStartAddress.s = "194.79.120.0"
sEndAddress.s = "194.79.120.255"
StartAddress.l
EndAddress.l
Quit = #False
Run = #False
WindowXSize = 640
WindowYSize = 480
If InitNetwork()
If OpenWindow(#Window_Main, 0, 0, WindowXSize, WindowYSize, "Ip sniffer", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
AddKeyboardShortcut(#Window_Main, #PB_Shortcut_Escape, #PB_Shortcut_Escape)
AddKeyboardShortcut(#Window_Main, #PB_Shortcut_Return, #PB_Shortcut_Return)
AddKeyboardShortcut(#Window_Main, #PB_Shortcut_Delete, #PB_Shortcut_Delete)
If CreateStatusBar(#StatusBar, WindowID(#Window_Main))
AddStatusBarField(400)
AddStatusBarField(120)
AddStatusBarField(120)
EndIf
;If CreateGadgetList(WindowID(0))
TextGadget(#Gadget_Text_Start, 10, 10, 80, 20, "Start address")
TextGadget(#Gadget_Text_End, 10, 30, 80, 20, "End address")
ButtonGadget(#Gadget_Button_OK, 230, 10, 60, 20, "Go")
ButtonGadget(#Gadget_Button_Cancel, 230, 30, 60, 20, "Cancel")
IPAddressGadget(#Gadget_IP_Start, 100, 10, 120, 20)
IPAddressGadget(#Gadget_IP_End, 100, 30, 120, 20)
hListIconGadget = ListIconGadget(#Gadget_ListIcon, 10, 50, WindowXSize - 20, WindowYSize - 80, "Server found", 120)
AddGadgetColumn(#Gadget_ListIcon, 1, "Time", 80)
;EndIf
SetGadgetState(#Gadget_IP_Start, MakeIPAddress(Val(StringField(sStartAddress, 1, ".")), Val(StringField(sStartAddress, 2, ".")), Val(StringField(sStartAddress, 3, ".")), Val(StringField(sStartAddress, 4, "."))))
SetGadgetState(#Gadget_IP_End, MakeIPAddress(Val(StringField(sEndAddress, 1, ".")), Val(StringField(sEndAddress, 2, ".")), Val(StringField(sEndAddress, 3, ".")), Val(StringField(sEndAddress, 4, "."))))
StartAddress = GetGadgetState(#Gadget_IP_Start)
EndAddress = GetGadgetState(#Gadget_IP_End)
Repeat
Select WindowEvent()
Case #PB_Event_CloseWindow
Quit = #True
Case #PB_Event_Menu
Select EventMenu()
Case #PB_Shortcut_Escape
If Run
Stop(ThreadID)
Else
Quit = #True
EndIf
Case #PB_Shortcut_Return
ThreadID = DoWeRun(ThreadID)
Case #PB_Shortcut_Delete
Stop(ThreadID)
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #Gadget_IP_Start
sStartAddress = GetGadgetText(#Gadget_IP_Start)
StartAddress = GetGadgetState(#Gadget_IP_Start)
Case #Gadget_IP_End
sEndAddress = GetGadgetText(#Gadget_IP_End)
EndAddress = GetGadgetState(#Gadget_IP_End)
Case #Gadget_Button_OK
ThreadID = DoWeRun(ThreadID)
Case #Gadget_Button_Cancel
Stop(ThreadID)
EndSelect
EndSelect
If OldCurrentConnection <> CurrentConnection
OldCurrentConnection = CurrentConnection
StatusBarText(#StatusBar, 0, CurrentConnection)
EndIf
If OldTotalConnections <> TotalConnections
OldTotalConnections = TotalConnections
StatusBarText(#StatusBar, 1, Str(TotalConnections))
EndIf
If OldTotalThreads <> TotalThreads
OldTotalThreads = TotalThreads
StatusBarText(#StatusBar, 2, Str(TotalThreads))
EndIf
Sleep_(1)
Until Quit
Stop(ThreadID)
EndIf
EndIf
TerminateProcess_(GetCurrentProcess_(), 0)
End


