Jump to content

Recommended Posts

Posted (edited)

I needed to ping Proxmox but it didn't so, let's "ping" the web interface ( or any TCP IPv4 in sight really ).
If it connects, there is something there.

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <AutoItConstants.au3>
#include <Date.au3>
#include <GuiIPAddress.au3>

Local $iW = 400, $iH = 200
Global $hGui = GUICreate(Chr(160) & "Find web interface", $iW, $iH)
Global $idInput = _GUICtrlIpAddress_Create($hGui, nextLeft(5), 5, nextLeft(120), 21, -1, BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE))
_GUICtrlIpAddress_Set($idInput, GetDefaultRange())
Global $idPort = GUICtrlCreateInput("8006", nextLeft(), 5, nextLeft(100), 21, -1, BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE))
Global $idBttn = GUICtrlCreateButton("Run", nextLeft(), 5, nextLeft(125), 21)
Global $idEdit = GUICtrlCreateEdit("The default port is 8006 because" & @CRLF & 'am looking for the running Proxmox.', 5, 30, $iW - 10, $iH - 30)
GUICtrlSetData($idEdit, @CRLF & @CRLF & "Can take comma delimited (8006,443)" & @CRLF & "Use at will.", 1)
GUISetState()

While 1
    Switch GUIGetMsg()
        Case -3
            GUIDelete()
            Exit
        Case $idBttn
            idCtrlsSetState($GUI_DISABLE)
            GUICtrlSetData($idEdit, "")
            findSite()
            idCtrlsSetState($GUI_ENABLE)
    EndSwitch
WEnd

Func findSite()
    Local $aETTF ; "Estimated Time To Finish" data holder
    _EstimatedTime($aETTF) ; called with just the data holder to init. it
    Local $sHint, $vData, $n, $iSocket, $octets = _GUICtrlIpAddress_Get($idInput)
    Local $aPorts = StringSplit(StringReplace(GUICtrlRead($idPort), '(', ''), ',')
    For $m = 1 To $aPorts[0]
        $aPorts[$m] = Int($aPorts[$m])
        If $aPorts[$m] < 1 Or $aPorts[$m] > 65535 Then Return GUICtrlSetData($idEdit, '..port(s) should be that of a web site')
    Next
    Local $aOct = StringSplit($octets, ".")
    If UBound($aOct) <> 5 Then Return GUICtrlSetData($idEdit, '..IPv4 should be X.X.X.')
    $octets = $aOct[1] & '.' & $aOct[2] & '.' & $aOct[3] & '.'
    TCPStartup()
    Opt("TCPTimeout", 100)
    For $n = 1 To 254
        _EstimatedTime($aETTF, $n, 255)
        If GUIGetMsg() = -3 Then ExitLoop
        GUICtrlSetData($idBttn, $aETTF[1] & "  -  " & $aETTF[4] & " %")
        For $m = 1 To $aPorts[0]
            If Int($aPorts[$m]) < 1 Or $aPorts[$m] > 65535 Then ContinueLoop
            $iSocket = TCPConnect($octets & $n, $aPorts[$m])
            If @error Then ContinueLoop
            $vData = Binary("")
            Sleep(10)
            $vData = TCPRecv($iSocket, 4096, 1)
            TCPCloseSocket($iSocket)
            If BinaryLen($vData) Then
                $sHint = Get22hint($vData)
            Else
                $sHint = GetHint($octets & $n, $aPorts[$m])
            EndIf
            GUICtrlSetData($idEdit, $octets & $n & ':' & $aPorts[$m] & (StringLen($sHint) ? ' ' & @TAB & '[ ' & $sHint & ' ]' : '') & @CRLF, 1)
        Next
    Next
    TCPShutdown()
    GUICtrlSetData($idBttn, "...")
    While GUIGetMsg()
    WEnd
    GUICtrlSetData($idEdit, ($n = 255 ? "Done" : "Canceled") & '  ( ' & $aETTF[0] & ' )' & @CRLF, 1)
    GUICtrlSetData($idBttn, "Run")
EndFunc   ;==>findSite

Func Get22hint($vData)
    Local $a1 = StringSplit(BinaryToString($vData), Chr(0)) ; filter nul
    Local $a2 = StringSplit(BinaryToString($a1[1]), @CRLF) ; get 1st line/only line
    Return $a2[1]
EndFunc   ;==>Get22hint

Func GetHint($IPv4, $iPort)
    Local $sHttp = ($iPort = 80 ? "http" : "https")
    Local $iPID = Run(@ComSpec & ' /C curl -k -v -L ' & $sHttp & '://"' & $IPv4 & ':' & $iPort, @ScriptDir, @SW_HIDE, BitOR($STDERR_CHILD, $STDOUT_CHILD))
    ProcessWaitClose($iPID)
    Local $sHint = "", $sTxt = StdoutRead($iPID) & StderrRead($iPID)
    If StringInStr($sTxt, '<title>') Then
        $sHint = StringMid($sTxt, StringInStr($sTxt, '<title>') + 7, StringInStr($sTxt, '</title>') - StringInStr($sTxt, '<title>') - 7)
        Return $sHint
    EndIf ; to dig deep use something like NMAP ( https://nmap.org/ ). This is just a simple tool.
    If StringInStr($sTxt, 'TrueNAS') Then Return 'TrueNAS'
    If StringInStr($sTxt, "Issue another request to this URL: 'https://" & $IPv4 & "/ui/'") Then Return 'TrueNAS'
    If StringInStr($sTxt, 'HTTP/1.1 403 Forbidden') Then Return 'HTTP/1.1 403 Forbidden'
    If StringInStr($sTxt, '< Server: ') Then
        Local $a1 = StringSplit($sTxt, '< Server: ', 1)
        Local $a2 = StringSplit($a1[2], @CRLF, 0)
        Return 'Server: ' & $a2[1]
    EndIf
    Return ""
EndFunc   ;==>GetHint

Func nextLeft($i = 0)
    Local Static $iLeft = 0
    $iLeft += $i
    Return ($i ? $i : $iLeft)
EndFunc   ;==>nextLeft

Func idCtrlsSetState($iState)
    GUICtrlSetState($idBttn, $iState)
    _GUICtrlIpAddress_ShowHide($idInput, ($iState = $GUI_DISABLE ? @SW_HIDE : @SW_SHOW))
    GUICtrlSetState($idPort, ($iState = $GUI_DISABLE ? $GUI_HIDE : $GUI_SHOW))
    GUICtrlSetState($idEdit, $iState)
EndFunc   ;==>idCtrlsSetState

Func GetDefaultRange()
    Local $sTxt = GetDefaultGateway()
    Return StringLeft($sTxt, StringInStr($sTxt, '.', 0, 3)) & 'X'
EndFunc   ;==>GetDefaultRange

Func GetDefaultGateway() ; https://www.autoitscript.com/forum/topic/193342-how-to-change-default-gateway-and-preferred-dns-server/?do=findComment&comment=1387443
    Local $out = "", $PID = Run(@ComSpec & " /c route print", @ScriptDir, @SW_HIDE, $STDOUT_CHILD)
    While 1
        $out &= StdoutRead($PID)
        If @error Then ExitLoop
    WEnd
    Return StringRegExp($out, "\s*0.0.0.0\s+0.0.0.0\s+(\d+\.\d+\.\d+\.\d+).*", 1)[0]
EndFunc   ;==>GetDefaultGateway

;===============================================================================
;
; Function Name:    _EstimatedTime() ; https://www.autoitscript.com/forum/topic/177371-_estimatedtime-calculate-estimated-time-of-completion/
; Description:      calculate estimated time of completion
; Parameter(s):     $a  - holds the data
;                   $iCurrentCount  - Current count
;                   $iTotalCount - Total count
; Requirement(s):   #include <Date.au3>
; Return Value(s):  false on incomplete data for assessment
; Author(s):        argumentum
; Note(s):          read the comments
;
;===============================================================================
Func _EstimatedTime(ByRef $a, $iCurrentCount = "", $iTotalCount = "")
    If $iCurrentCount & $iTotalCount = "" Then ; initialize
        $a = ""
        Dim $a[12]
        $a[5] = TimerInit() ; handle for TimerDiff()
        $a[0] = "00:00:00"
        $a[1] = "00:00:00"
        $a[2] = _NowCalc() ; starting date and time
        $a[3] = ""
        $a[4] = "0"
    Else
        If $iTotalCount = 0 Then Return False
        If $iCurrentCount > $iTotalCount Then $iCurrentCount = $iTotalCount
        _TicksToTime(Int(TimerDiff($a[5])), $a[6], $a[7], $a[8])
        _TicksToTime(Int((TimerDiff($a[5]) / $iCurrentCount) * ($iTotalCount - $iCurrentCount)), $a[9], $a[10], $a[11])
        $a[0] = StringFormat("%02i:%02i:%02i", $a[6], $a[7], $a[8]) ; elapsed time
        $a[1] = StringFormat("%02i:%02i:%02i", $a[9], $a[10], $a[11]) ; estimated total time
        $a[3] = _DateAdd("s", Int((TimerDiff($a[5]) / $iCurrentCount) * ($iTotalCount) / 1000), $a[2]) ; estimated date and time of completion
        $a[4] = Int($iCurrentCount / $iTotalCount * 100) ; percentage done
    EndIf
    Return True
EndFunc   ;==>_EstimatedTime

Not much of an example but I scanned my network in under 30 secs. Nice toy to have :)

Edit: added a hint of what may be at that IPv4 and comma delimited ports can be used.

Edit2:  Version with IP and mask:

image.png.37f4dcb68f0c341d30f963bcc9fabd86.png

  Reveal hidden contents

for those that may need it. ( or just @MattyD :D )

Edit3: Compiled it and placed it in the download area.
..and I should have put the data in a listview with a click-click to open the finding but, how many times will one not find their computers :lol:

Edit4: Added the listview to double-click and go to the ip:port.

Edited by argumentum
newer version

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

  • 2 weeks later...
Posted (edited)

Nice, I was more thinking along the lines of something like this though - it'll allow you scan to scan an entire subnet if you're not using a /24.

GetRange("10.0.0.78", "255.255.240.0")

Func GetRange($sIP, $sNetMask)
    Local $aIPRange[2][4], $iIP, $iMask
    $aIP = StringSplit($sIP, ".", 2)
    $aMask = StringSplit($sNetMask, ".", 2)

    For $i = 0 To 3
        $iIP = BitShift($iIP, -8)
        $iMask = BitShift($iMask, -8)
        $iIP += $aIP[$i]
        $iMask += $aMask[$i]
    Next

    Local $iNet =  BitAND($iIP, $iMask)
    Local $iFirst = $iNet + 1
    Local $iBCast = BitOr($iNet, BitNot($iMask))
    Local $iLast = $iBCast - 1

    Local $sIP2, $iIP
    For $i = $iFirst To $iLast
        $iIP = $i
        $sIP2 = ""
        For $j = 1 To 4
            $sIP2 = BitAND($iIP, 0xFF) & "." & $sIP2
            $iIP = BitShift($iIP, 8)
        Next
        ConsoleWrite(StringTrimRight($sIP2, 1) & @CRLF)
    Next
EndFunc

you'd then just nest the for loops...   On second thought, its probably better to calculate the dotted notation on the fly. - Updated example!
 

Edited by MattyD
Posted (edited)

>GetRange("10.0.0.78", "255.255.240.0")
GetDefaultGateway() gets the IP but I'll need a get-default-mask() and I don't know a simple ( copy'n'paste ) way to do it. Can you give me that ?
Else, I'll do it searching line by line ( ugly looking ) 🤔

Edit: done.

  On 9/21/2024 at 2:52 PM, MattyD said:

its probably better to calculate the dotted notation on the fly

Expand  

on that regard, I'll build an array so the estimated-time() has a min/max to calculate that :)

Edited by argumentum
done

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted
  On 9/10/2024 at 9:19 AM, argumentum said:

for those that may need it. ( or just @MattyD :D )

Expand  

hehe - looking good. Pulling that default mask is a nice touch.

It's obviously not an issue, but to be hyper nit-picky there's no real need to keep expanding that array.  ($iLast - $iFirst) + 1 will get you a count :)

Also putting that limit on IP addresses was probably a good idea too. God help anyone who actually has need of a /16 subnet!!

Posted (edited)

Hey mate, just a correction from my side -

I've found our IP integer rolls over to a "double" in some scenarios, which invalidates the bit-wise operations later in the function. So it looks like we'll need to force the values to be 32 bit at line 189

Never mind, I can't reproduce the issue - so I've probably done something dumb. (I thought I was pulling an incorrect range).

Edit 2: Ok so we're getting the double type because we're incrementing with a string. Essentially we're doing things like $iNetMask += "255".  The the bitwise funcs do look to be  converting back to 32bit for their operations though.

Just as a float  255.255.255.0 (0xFFFFFF00) was showing up as (0xC070000000000000).  I had assumed BitAnd etc was complaining about that!

Edited by MattyD
Posted
  On 9/22/2024 at 2:10 PM, MattyD said:

...so I've probably done something dumb...

Expand  

Well, is your code !  :P

Yes, ...when releasing code for general consumption, the code should have stupid checking error checking because the user may enter something outside the scope of the code's evaluation. Say : mask = 256.256.256.0 or some other non-sense that in a moment of ... oops ?, may/will crash the script.

If you find that something should be better post the code or let me know. :) 

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...