Page 1 of 1

Quick IP scanner

Posted: Tue May 25, 2004 1:15 am
by fweil
Code updated for 5.20+

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

Posted: Tue May 25, 2004 6:20 am
by DarkDragon
I get a Linker Error(PB 3.91beta) - Corrupt Library /PureLibrarys/Windows/Librarys/ICMP.LIB

Posted: Tue May 25, 2004 9:35 am
by fweil
Well it works fine on my 3.90.

Don't know from where ICMP may crash because of PB libs update ...

Posted: Tue May 25, 2004 12:27 pm
by freak
DarkDragon:
Grab the new lib here: http://www.purebasic.com/beta/

Timo