Skip to content

Commit b36d831

Browse files
committed
Performance when resolving MAC Vendor improved
1 parent e23a1f4 commit b36d831

File tree

4 files changed

+75
-22390
lines changed

4 files changed

+75
-22390
lines changed

Scripts/Create-OUIListFromWeb.ps1

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#$LatestOUI = Get-Content -Path "$PSScriptRoot\oui_from_web.txt"
2+
$LatestOUIs = (Invoke-WebRequest -Uri "http://linuxnet.ca/ieee/oui.txt").Content
3+
4+
$Output = ""
5+
6+
foreach($Line in $LatestOUIs -split '[\r\n]')
7+
{
8+
if($Line -match "^[A-F0-9]{6}")
9+
{
10+
# Line looks like: 2405F5 (base 16) Integrated Device Technology (Malaysia) Sdn. Bhd.
11+
$Output += ($Line -replace '\s+', ' ').Replace(' (base 16) ', '|').Trim() + "`n"
12+
}
13+
}
14+
15+
Out-File -InputObject $Output -FilePath "$PSScriptRoot\Resources\oui.txt"

Scripts/IPv4NetworkScan.ps1

+60-147
Original file line numberDiff line numberDiff line change
@@ -123,69 +123,14 @@ Param(
123123
[Parameter(
124124
Position=7,
125125
HelpMessage='Include inactive devices in result')]
126-
[Switch]$IncludeInactive,
127-
128-
[Parameter(
129-
Position=8,
130-
HelpMessage='Update IEEE Standards Registration Authority from IEEE.org (https://standards.ieee.org/develop/regauth/oui/oui.csv)')]
131-
[Switch]$UpdateList
126+
[Switch]$IncludeInactive
132127
)
133128

134129
Begin{
135130
Write-Verbose -Message "Script started at $(Get-Date)"
136131

137-
# IEEE -> The Public Listing For IEEE Standards Registration Authority -> CSV-File
138-
$IEEE_MACVendorList_WebUri = "http://standards.ieee.org/develop/regauth/oui/oui.csv"
139-
140-
# MAC-Vendor list path
141-
$CSV_MACVendorList_Path = "$PSScriptRoot\Resources\IEEE_Standards_Registration_Authority.csv"
142-
$CSV_MACVendorList_BackupPath = "$PSScriptRoot\Resources\IEEE_Standards_Registration_Authority.csv.bak"
143-
144-
# Function to update the list from IEEE (MAC-Vendor)
145-
function UpdateListFromIEEE
146-
{
147-
# Try to download the MAC-Vendor list from IEEE
148-
try{
149-
Write-Verbose -Message "Create backup of the IEEE Standards Registration Authority list..."
150-
151-
# Backup file, before download a new version
152-
if(Test-Path -Path $CSV_MACVendorList_Path -PathType Leaf)
153-
{
154-
Rename-Item -Path $CSV_MACVendorList_Path -NewName $CSV_MACVendorList_BackupPath
155-
}
156-
157-
Write-Verbose -Message "Updating IEEE Standards Registration Authority from IEEE.org..."
158-
159-
# Download csv-file from IEEE
160-
Invoke-WebRequest -Uri $IEEE_MACVendorList_WebUri -OutFile $CSV_MACVendorList_Path -ErrorAction Stop
161-
162-
Write-Verbose -Message "Remove backup of the IEEE Standards Registration Authority list..."
163-
164-
# Remove Backup, if no error
165-
if(Test-Path -Path $CSV_MACVendorList_BackupPath -PathType Leaf)
166-
{
167-
Remove-Item -Path $CSV_MACVendorList_BackupPath
168-
}
169-
}
170-
catch{
171-
Write-Verbose -Message "Cleanup downloaded file and restore backup..."
172-
173-
# On error: cleanup downloaded file and restore backup
174-
if(Test-Path -Path $CSV_MACVendorList_Path -PathType Leaf)
175-
{
176-
Remove-Item -Path $CSV_MACVendorList_Path -Force
177-
}
178-
179-
if(Test-Path -Path $CSV_MACVendorList_BackupPath -PathType Leaf)
180-
{
181-
Rename-Item -Path $CSV_MACVendorList_BackupPath -NewName $CSV_MACVendorList_Path
182-
}
132+
$OUIListPath = "$PSScriptRoot\Resources\oui.txt"
183133

184-
$_.Exception.Message
185-
}
186-
}
187-
188-
# Helper function to convert a subnetmask
189134
function Convert-Subnetmask
190135
{
191136
[CmdLetBinding(DefaultParameterSetName='CIDR')]
@@ -395,69 +340,10 @@ Begin{
395340
End{
396341

397342
}
398-
}
399-
400-
# Assign vendor to MAC
401-
function AssignVendorToMAC
402-
{
403-
param(
404-
$Result
405-
)
406-
407-
Begin{
408-
409-
}
410-
411-
Process {
412-
$Vendor = [String]::Empty
413-
414-
# Check if MAC is null or empty
415-
if(-not([String]::IsNullOrEmpty($Result.MAC)))
416-
{
417-
# Split it, so we can search the vendor (XX-XX-XX-XX-XX-XX to XX-XX-XX)
418-
$MAC_VendorSearch = $Job_Result.MAC.Replace("-","").Substring(0,6)
419-
420-
foreach($ListEntry in $MAC_VendorList)
421-
{
422-
if($ListEntry.Assignment -eq $MAC_VendorSearch)
423-
{
424-
$Vendor = $ListEntry."Organization Name"
425-
break
426-
}
427-
}
428-
}
429-
430-
[pscustomobject] @{
431-
IPv4Address = $Result.IPv4Address
432-
Status = $Result.Status
433-
Hostname = $Result.Hostname
434-
MAC = $Result.MAC
435-
Vendor = $Vendor
436-
BufferSize = $Result.BufferSize
437-
ResponseTime = $Result.ResponseTime
438-
TTL = $Result.TTL
439-
}
440-
}
441-
442-
End {
443-
444-
}
445-
}
343+
}
446344
}
447345

448346
Process{
449-
$CSV_MACVendorList_Available = Test-Path -Path $CSV_MACVendorList_Path -PathType Leaf
450-
451-
# Check for vendor list update
452-
if($UpdateList)
453-
{
454-
UpdateListFromIEEE
455-
}
456-
elseif(($EnableMACResolving) -and ($CSV_MACVendorList_Available -eq $false))
457-
{
458-
Write-Warning -Message "No CSV-File to assign vendor with MAC-Address found! Use the parameter ""-UpdateList"" to download the latest version from IEEE.org. This warning does not affect the scanning procedure."
459-
}
460-
461347
# Calculate Subnet (Start and End IPv4-Address)
462348
if($PSCmdlet.ParameterSetName -eq 'CIDR' -or $PSCmdlet.ParameterSetName -eq 'Mask')
463349
{
@@ -490,7 +376,7 @@ Process{
490376

491377
Write-Verbose -Message "Scanning range from $StartIPv4Address to $EndIPv4Address ($($IPsToScan + 1) IPs)"
492378
Write-Verbose -Message "Running with max $Threads threads"
493-
Write-Verbose -Message "ICMP checks per IP is set to $Tries"
379+
Write-Verbose -Message "ICMP checks per IP: $Tries"
494380

495381
# Properties which are displayed in the output
496382
$PropertiesToDisplay = @()
@@ -507,18 +393,37 @@ Process{
507393
}
508394

509395
# Check if it is possible to assign vendor to MAC --> import CSV-File
510-
if($EnableMACResolving -and $CSV_MACVendorList_Available)
396+
if($EnableMACResolving)
511397
{
512-
$AssignVendorToMAC = $true
398+
if(Test-Path -Path $OUIListPath -PathType Leaf)
399+
{
400+
$OUIHashTable = @{ }
513401

514-
$PropertiesToDisplay += "Vendor"
515-
516-
$MAC_VendorList = Import-Csv -Path $CSV_MACVendorList_Path | Select-Object -Property "Assignment", "Organization Name"
517-
}
518-
else
519-
{
520-
$AssignVendorToMAC = $false
521-
}
402+
Write-Verbose -Message "Read oui.txt and fill hash table..."
403+
404+
foreach($Line in Get-Content -Path $OUIListPath)
405+
{
406+
if(-not([String]::IsNullOrEmpty($Line)))
407+
{
408+
try{
409+
$HashTableData = $Line.Split('|')
410+
$OUIHashTable.Add($HashTableData[0], $HashTableData[1])
411+
}
412+
catch [System.ArgumentException] { } # Catch if mac is already added to hash table
413+
}
414+
}
415+
416+
$AssignVendorToMAC = $true
417+
418+
$PropertiesToDisplay += "Vendor"
419+
}
420+
else
421+
{
422+
$AssignVendorToMAC = $false
423+
424+
Write-Warning -Message "No OUI-File to assign vendor with MAC-Address found! Execute the script ""Create-OUIListFromWeb.ps1"" to download the latest version. This warning does not affect the scanning procedure."
425+
}
426+
}
522427

523428
if($ExtendedInformations)
524429
{
@@ -591,17 +496,6 @@ Process{
591496
$MAC = [Regex]::Matches($Line,"([0-9A-F][0-9A-F]-){5}([0-9A-F][0-9A-F])").Value
592497
}
593498
}
594-
595-
# If the first function is not able to get the MAC-Address
596-
if([String]::IsNullOrEmpty($MAC))
597-
{
598-
try{
599-
$Nbtstat_Result = nbtstat -A $IPv4Address | Select-String -Pattern "MAC"
600-
$MAC = [Regex]::Matches($Nbtstat_Result, "([0-9A-F][0-9A-F]-){5}([0-9A-F][0-9A-F])").Value
601-
}
602-
catch{ } # No MAC
603-
}
604-
605499
}
606500

607501
# +++ Get extended informations +++
@@ -619,8 +513,7 @@ Process{
619513
catch{ } # Failed to get extended informations
620514
}
621515

622-
# +++ Result +++
623-
516+
# +++ Result +++
624517
if(($Status -eq "Up") -or ($IncludeInactive))
625518
{
626519
[pscustomobject] @{
@@ -646,9 +539,9 @@ Process{
646539
$RunspacePool.Open()
647540
[System.Collections.ArrayList]$Jobs = @()
648541

649-
Write-Verbose -Message "Setting up Jobs..."
542+
Write-Verbose -Message "Setting up jobs..."
650543

651-
# Set up Jobs for each IP...
544+
# Set up jobs for each IP...
652545
for ($i = $StartIPv4Address_Int64; $i -le $EndIPv4Address_Int64; $i++)
653546
{
654547
# Convert IP back from Int64
@@ -701,9 +594,9 @@ Process{
701594
# If no jobs finished yet, wait 500 ms and try again
702595
if($null -eq $Jobs_ToProcess)
703596
{
704-
Write-Verbose -Message "No jobs completed, wait 500ms..."
597+
Write-Verbose -Message "No jobs completed, wait 250ms..."
705598

706-
Start-Sleep -Milliseconds 500
599+
Start-Sleep -Milliseconds 250
707600
continue
708601
}
709602

@@ -736,8 +629,28 @@ Process{
736629
if($Job_Result.Status)
737630
{
738631
if($AssignVendorToMAC)
739-
{
740-
AssignVendorToMAC -Result $Job_Result | Select-Object -Property $PropertiesToDisplay
632+
{
633+
$Vendor = [String]::Empty
634+
635+
# Check if MAC is null or empty
636+
if(-not([String]::IsNullOrEmpty($Job_Result.MAC)))
637+
{
638+
# Split it, so we can search the vendor (XX-XX-XX-XX-XX-XX to XXXXXX)
639+
$MAC_VendorSearch = $Job_Result.MAC.Replace("-","").Substring(0,6)
640+
641+
$Vendor = $OUIHashTable.Get_Item($MAC_VendorSearch)
642+
}
643+
644+
[pscustomobject] @{
645+
IPv4Address = $Job_Result.IPv4Address
646+
Status = $Job_Result.Status
647+
Hostname = $Job_Result.Hostname
648+
MAC = $Job_Result.MAC
649+
Vendor = $Vendor
650+
BufferSize = $Job_Result.BufferSize
651+
ResponseTime = $Job_Result.ResponseTime
652+
TTL = $ResuJob_Resultlt.TTL
653+
} | Select-Object -Property $PropertiesToDisplay
741654
}
742655
else
743656
{

0 commit comments

Comments
 (0)