Jump to content
Sign in to follow this  
guinness

Parsing netstat using a regular expression.

Recommended Posts

guinness

In an effort to improve my SRE knowledge, I'm taking 'real world' examples and apply the SRE knowledge I have, though it's somewhat limited. So here is the example. Is there a better approach?

Working Code: Parse netstat into a multidimensional array $aArray[n][3] = [source IP, Destination IP, Process]

#include <Array.au3>
#include <Constants.au3>

_ParseNetStat()

Func _ParseNetStat()
    Local $sData = _RunStdOutRead('netstat -n -b', @SystemDir)
    Local $aArray = StringRegExp($sData, '((?:d{1,3}.){3}d{1,3}:d+)s+((?:d{1,3}.){3}d{1,3}:d+).*ns*[(.*?)]', 3) ; $sIPAddress & '(?:.d{1,3})+:d+s*(?:d{1,3}.){3}d{1,3}:d+',
    Local $aReturn[(UBound($aArray, 1) / 3) + 1][3] = [[0]]

    For $i = 0 To UBound($aArray, 1) - 1
        $aReturn[0][0] += 1
        For $j = 0 To 2
            $aReturn[$aReturn[0][0]][$j] = $aArray[$i]
            $i += 1
        Next
        $i -= 1
    Next
    _ArrayDisplay($aReturn)
EndFunc   ;==>_ParseNetStat

Func _RunStdOutRead($sCommand, $sWorkingDirectory = @SystemDir)
    Local $iPID = Run(@ComSpec & ' /c ' & $sCommand, $sWorkingDirectory, @SW_HIDE, $STDOUT_CHILD + $STDERR_CHILD), $sOutput = ''
    While 1
        $sOutput &= StdoutRead($iPID)
        If @error Then
            ExitLoop
        EndIf
    WEnd
    Return $sOutput
EndFunc   ;==>_RunStdOutRead

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Share this post


Link to post
Share on other sites
UEZ

What about this here?

#include <array.au3>
#include <constants.au3>

_ParseNetStat()

Func _ParseNetStat()
    Local $sData = _RunStdOutRead('netstat -n -b', @SystemDir)
;~  ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sData = ' & $sData & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    Local $aArray = StringRegExp($sData, "(?im:)(TCP|UDP)s+(.*:d+)s*(.*:d+)s*(w*)s*(rn|[.*]+)", 3)
    If Mod(UBound($aArray), 5) Then Return SetError(1, 0, 0) ;unexpected array size
    Local $ub = UBound($aArray, 1) / 5, $i, $j = -1
    Local $aReturn[$ub][5]
    While $i < UBound($aArray)
        If Not Mod($i, 5) Then $j += 1
        $aReturn[$j][Mod($i, 5)] = StringReplace(StringReplace($aArray[$i], "[", ""), "]", "")
        $i += 1
    WEnd
    _ArrayDisplay($aReturn, "Active Connections", -1, 0, "", "|", "Index|Protocol|Local Address|Foreign Address|State|Application" )
EndFunc   ;==>_ParseNetStat

Func _RunStdOutRead($sCommand, $sWorkingDirectory = @SystemDir)
    Local $iPID = Run(@ComSpec & ' /c ' & $sCommand, $sWorkingDirectory, @SW_HIDE, $STDOUT_CHILD + $STDERR_CHILD), $sOutput = ''
    While 1
        $sOutput &= StdoutRead($iPID)
        If @error Then
            ExitLoop
        EndIf
    WEnd
    Return $sOutput
EndFunc   ;==>_RunStdOutRead

Edit: currently I'm too silly to eliminate the brackets with regex and added check when array is <> Mod(Ubound, 5)

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
Robjong

Hi,

Your pattern is fine, except for one small part, it's better to use negated character set than a lazy dot.

[(.*?)]
to
[([^]]*)]

And because there is no need to validate, as the format is known, there is no need to match an IPv4 so strictly.

([d.]+:d+) ; the simplest option
([d.]{7,15}:d+) ; same count as IPv4
(d[d.]{5,13}d:d+) ; or if you want to make sure it begins and ends with a digit so it looks more like an IPv4

And since your exploring you could also go for global matching.

#include <Array.au3>
#include <Constants.au3>


$aNetStat = _ParseNetStat()
_ArrayDisplay($aNetStat)


Func _ParseNetStat()
    Local $sData = _RunStdOutRead('netstat -n -b', @SystemDir)
    Local $aArray = StringRegExp($sData, '(w+)h+([d.]{7,15}:d+)h+([d.]{7,15}:d+)h+(w+).*nh*(?:[([^]]+)]|())', 4)
    If @error Then Return SetError(1, 0, False)
    Local $aSubArray, $aReturn[UBound($aArray)][5]
    For $i = 0 To UBound($aArray) - 1
        $aSubArray = $aArray[$i]
        $aReturn[$i][0] = $aSubArray[0]
        $aReturn[$i][1] = $aSubArray[1]
        $aReturn[$i][2] = $aSubArray[2]
        $aReturn[$i][3] = $aSubArray[3]
        $aReturn[$i][4] = $aSubArray[4]
    Next
    Return $aReturn
EndFunc   ;==>_ParseNetStat

Func _RunStdOutRead($sCommand, $sWorkingDirectory = @SystemDir)
    Local $iPID = Run(@ComSpec & ' /c ' & $sCommand, $sWorkingDirectory, @SW_HIDE, $STDOUT_CHILD + $STDERR_CHILD), $sOutput = ''
    While 1
        $sOutput &= StdoutRead($iPID)
        If @error Then
            ExitLoop
        EndIf
    WEnd
    Return $sOutput
EndFunc ;==>_RunStdOutRead

@UEZ "Array variable subscript badly formatted." enough said? ;) also (rn|[.*]+) will capture line breaks or inlude the square brackets.

Edit: Updated the script to include TIME_WAIT like entries (without a process name).

Edit 2: addressed the issue mentioned, should now work on every OS.

Edited by Robjong

Share this post


Link to post
Share on other sites
guinness

UEZ,

Thanks for that, it worked a lot better than mine did. I also didn't receive the error as Robjong did, strange.

Robjong,

Firstly thanks for the explanation of not using the 'lazy dot' because I do have this tendency to use it. By the way what version of Windows do you have? Because I tried your version and the array didn't populate.


UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Share this post


Link to post
Share on other sites
UEZ

guinness,

it depends on the output of netstat. That means when the output is unexpected the array calculation will be mixed up and the em will appear.

Robjong's version captures only the established connection and what I'm trying is to get all values. I'm a regex noob I'm trying to get the last token [app.exe] without the brackets which are only available on established status.

Br,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

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
Sign in to follow this  

×