From 2275c078eb05b7a26d3f2fa1b7b2e3016cdcf00b Mon Sep 17 00:00:00 2001 From: hololu Date: Wed, 6 May 2026 10:43:38 +0300 Subject: [PATCH] Ilk Commit --- Install-Dependencies.ps1 | 134 + Invoke-SwitchDiscovery.ps1 | 578 ++++ README.md | 245 ++ Start-SwitchDiscovery.ps1 | 232 ++ lib/README.txt | 1 + lib/SharpSnmpLib.dll | Bin 0 -> 169280 bytes lib/SharpSnmpLib.pdb | Bin 0 -> 69932 bytes lib/SharpSnmpLib.xml | 6541 ++++++++++++++++++++++++++++++++++++ 8 files changed, 7731 insertions(+) create mode 100644 Install-Dependencies.ps1 create mode 100644 Invoke-SwitchDiscovery.ps1 create mode 100644 README.md create mode 100644 Start-SwitchDiscovery.ps1 create mode 100644 lib/README.txt create mode 100644 lib/SharpSnmpLib.dll create mode 100644 lib/SharpSnmpLib.pdb create mode 100644 lib/SharpSnmpLib.xml diff --git a/Install-Dependencies.ps1 b/Install-Dependencies.ps1 new file mode 100644 index 0000000..83fb69b --- /dev/null +++ b/Install-Dependencies.ps1 @@ -0,0 +1,134 @@ +#Requires -Version 5.1 +Set-StrictMode -Version Latest + +function wStep { param([string]$t); Write-Host " [>] $t" -ForegroundColor Yellow } +function wOK { param([string]$t); Write-Host " [+] $t" -ForegroundColor Green } +function wFail { param([string]$t); Write-Host " [-] $t" -ForegroundColor Red } +function wInfo { param([string]$t); Write-Host " [i] $t" -ForegroundColor Gray } + +Clear-Host +Write-Host " ================================================" -ForegroundColor Cyan +Write-Host " NetworkSwitchDiscovery - Kurulum Sihirbazi" -ForegroundColor Cyan +Write-Host " ================================================" -ForegroundColor Cyan +Write-Host "" + +# 1. PowerShell versiyonu +wStep "PowerShell versiyonu..." +if ($PSVersionTable.PSVersion.Major -lt 5) { + wFail "PowerShell 5.1+ gerekli. Mevcut: $($PSVersionTable.PSVersion)"; exit 1 +} +wOK "PowerShell $($PSVersionTable.PSVersion) - Uyumlu" + +# 2. ExecutionPolicy +wStep "ExecutionPolicy kontrol..." +$pol = Get-ExecutionPolicy -Scope CurrentUser +if ($pol -in @("Restricted","AllSigned")) { + wInfo "Policy $pol - RemoteSigned olarak degistiriliyor..." + Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force + wOK "ExecutionPolicy: RemoteSigned" +} else { + wOK "ExecutionPolicy: $pol (uygun)" +} + +# 3. Klasor yapisi +wStep "Klasor yapisi..." +$libDir = Join-Path $PSScriptRoot "lib" +if (-not (Test-Path $libDir)) { + New-Item -ItemType Directory -Path $libDir | Out-Null + wOK "lib\ olusturuldu" +} else { + wOK "lib\ mevcut" +} + +# 4. NuGet +wStep "NuGet provider..." +$nuget = Get-PackageProvider -Name NuGet -ErrorAction SilentlyContinue +if (-not $nuget -or $nuget.Version -lt [version]"2.8.5.201") { + wInfo "NuGet kuruluyor..." + Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Scope CurrentUser -Force | Out-Null + wOK "NuGet kuruldu" +} else { + wOK "NuGet: $($nuget.Version)" +} + +# 5. PSGallery +wStep "PSGallery trust..." +$gal = Get-PSRepository -Name PSGallery -ErrorAction SilentlyContinue +if ($gal -and $gal.InstallationPolicy -ne "Trusted") { + Set-PSRepository -Name PSGallery -InstallationPolicy Trusted + wOK "PSGallery: Trusted" +} else { + wOK "PSGallery: Trusted (zaten)" +} + +# 6. Posh-SSH +wStep "Posh-SSH..." +$posh = Get-Module -ListAvailable -Name Posh-SSH | Select-Object -First 1 +if (-not $posh) { + wInfo "Posh-SSH bulunamadi, kuruluyor..." + try { + Install-Module -Name Posh-SSH -Scope CurrentUser -Force -AllowClobber + wOK "Posh-SSH kuruldu" + } catch { + wFail "Posh-SSH kurulamadi: $($_.Exception.Message)" + wInfo "Manuel: Install-Module Posh-SSH -Scope CurrentUser -Force" + } +} else { + wOK "Posh-SSH v$($posh.Version) mevcut" +} + +# 7. ThreadJob (PS 5.1 icin) +wStep "ThreadJob (PS 5.1 icin)..." +if ($PSVersionTable.PSVersion.Major -ge 7) { + wOK "PS 7+ - ThreadJob gereksiz, RunspacePool kullaniliyor" +} else { + $tj = Get-Module -ListAvailable -Name ThreadJob | Select-Object -First 1 + if (-not $tj) { + wInfo "ThreadJob bulunamadi, kuruluyor..." + try { + Install-Module -Name ThreadJob -Scope CurrentUser -Force + wOK "ThreadJob kuruldu" + } catch { + wInfo "ThreadJob kurulamadi (opsiyonel): $($_.Exception.Message)" + } + } else { + wOK "ThreadJob v$($tj.Version) mevcut" + } +} + +# 8. SharpSnmpLib (opsiyonel) +wStep "SharpSnmpLib.dll (opsiyonel)..." +$dll = Join-Path $PSScriptRoot "lib\SharpSnmpLib.dll" +if (Test-Path $dll) { + wOK "SharpSnmpLib.dll mevcut" +} else { + wInfo "SharpSnmpLib.dll yok - yerlesik UDP SNMP (v1/v2c) kullanilacak" + wInfo "v3 icin: https://www.nuget.org/packages/SharpSnmpLib" + wInfo "Indirip lib\ klasorune kopyalayin" +} + +# 9. Script dosyalari +wStep "Script dosyalari..." +$ok = $true +foreach ($f in @("Invoke-SwitchDiscovery.ps1","Start-SwitchDiscovery.ps1")) { + $p = Join-Path $PSScriptRoot $f + if (Test-Path $p) { wOK "$f mevcut" } + else { wFail "$f EKSIK!"; $ok = $false } +} + +Write-Host "" +Write-Host " ================================================" -ForegroundColor Cyan +if ($ok) { + Write-Host " Kurulum TAMAMLANDI!" -ForegroundColor Green + Write-Host "" + Write-Host " Baslangic:" -ForegroundColor White + Write-Host " .\Start-SwitchDiscovery.ps1" -ForegroundColor Cyan + Write-Host "" + Write-Host " Veya dogrudan:" -ForegroundColor White + Write-Host " .\Invoke-SwitchDiscovery.ps1 -IPRange '192.168.1.0/24' -Username admin" -ForegroundColor Cyan +} else { + Write-Host " UYARI: Bazi dosyalar eksik!" -ForegroundColor Yellow +} +Write-Host " ================================================" -ForegroundColor Cyan +Write-Host "" +Read-Host " Cikmak icin Enter" diff --git a/Invoke-SwitchDiscovery.ps1 b/Invoke-SwitchDiscovery.ps1 new file mode 100644 index 0000000..1f03aa7 --- /dev/null +++ b/Invoke-SwitchDiscovery.ps1 @@ -0,0 +1,578 @@ +#Requires -Version 5.1 +[CmdletBinding()] +param( + [Parameter(Mandatory = $true)] [string]$IPRange, + [Parameter(Mandatory = $false)] [string]$Username = "", + [Parameter(Mandatory = $false)] [string]$Password = "", + [Parameter(Mandatory = $false)] [string]$SNMPCommunity = "public", + [ValidateSet("v1", "v2c", "v3")] [string]$SNMPVersion = "v2c", + [ValidateSet("SSH", "SNMP", "Telnet", "Both", "All")] [string]$Method = "All", + [string]$OutputPath = $PSScriptRoot, + [ValidateRange(1, 100)] [int]$MaxThreads = 20, + [int]$SSHPort = 22, + [int]$Timeout = 5 +) +Set-StrictMode -Version Latest +$ErrorActionPreference = "SilentlyContinue" + +function Write-Header { param([string]$t); Write-Host "`n$('-'*60)" -ForegroundColor DarkCyan; Write-Host " $t" -ForegroundColor Cyan; Write-Host "$('-'*60)" -ForegroundColor DarkCyan } +function Write-Step { param([string]$t); Write-Host " [>] $t" -ForegroundColor Yellow } +function Write-OK { param([string]$t); Write-Host " [+] $t" -ForegroundColor Green } +function Write-Fail { param([string]$t); Write-Host " [-] $t" -ForegroundColor Red } +function Write-Info { param([string]$t); Write-Host " [i] $t" -ForegroundColor Gray } + +function Test-Dependencies { + Write-Header "Bagimlilik Kontrolu" + $missing = @() + if (-not (Get-Module -ListAvailable -Name Posh-SSH)) { + Write-Fail "Posh-SSH bulunamadi"; $missing += "Posh-SSH" + } + else { Write-OK "Posh-SSH mevcut" } + $script:SnmpLibAvailable = $false + $dll = Join-Path $PSScriptRoot "lib\SharpSnmpLib.dll" + if (Test-Path $dll) { + Add-Type -Path $dll -ErrorAction SilentlyContinue + $script:SnmpLibAvailable = $true + Write-OK "SharpSnmpLib.dll mevcut" + } + else { Write-Info "SharpSnmpLib.dll yok - yerlesik UDP SNMP kullanilacak" } + if ($missing.Count -gt 0) { + Write-Host "`n Eksik: Install-Module Posh-SSH -Scope CurrentUser -Force" -ForegroundColor Magenta + $ans = Read-Host " Simdi kurulsun mu? (E/H)" + if ($ans -match '^[Ee]') { + foreach ($m in $missing) { + Write-Step "$m kuruluyor..." + Install-Module -Name $m -Scope CurrentUser -Force -AllowClobber + Write-OK "$m kuruldu" + } + } + } +} + +function Resolve-IPRange { + param([string]$Range) + $ips = [System.Collections.Generic.List[string]]::new() + if ($Range -match '^(\d{1,3}(?:\.\d{1,3}){3})/(\d{1,2})$') { + $bytes = [System.Net.IPAddress]::Parse($Matches[1]).GetAddressBytes() + [array]::Reverse($bytes) + $ipInt = [System.BitConverter]::ToUInt32($bytes, 0) + $prefix = [int]$Matches[2] + $mask = [uint32]([math]::Pow(2, 32) - [math]::Pow(2, 32 - $prefix)) + $net = $ipInt -band $mask + $count = [math]::Pow(2, 32 - $prefix) + for ($i = 1; $i -lt ($count - 1); $i++) { + $b = [System.BitConverter]::GetBytes([uint32]($net + $i)); [array]::Reverse($b) + $ips.Add(([System.Net.IPAddress]::new($b)).ToString()) + } + } + elseif ($Range -match '^(\d{1,3}(?:\.\d{1,3}){3})-(\d{1,3}(?:\.\d{1,3}){3})$') { + $sb = [System.Net.IPAddress]::Parse($Matches[1]).GetAddressBytes(); [array]::Reverse($sb) + $eb = [System.Net.IPAddress]::Parse($Matches[2]).GetAddressBytes(); [array]::Reverse($eb) + $s = [System.BitConverter]::ToUInt32($sb, 0); $e = [System.BitConverter]::ToUInt32($eb, 0) + for ($i = $s; $i -le $e; $i++) { + $b = [System.BitConverter]::GetBytes([uint32]$i); [array]::Reverse($b) + $ips.Add(([System.Net.IPAddress]::new($b)).ToString()) + } + } + elseif ($Range -match '^\d{1,3}(?:\.\d{1,3}){3}$') { + $ips.Add($Range) + } + else { throw "Gecersiz IP formati: $Range" } + return $ips +} + +function Get-AliveHosts { + param([System.Collections.Generic.List[string]]$IPs) + Write-Header "Canli Host Taramasi (Ping)" + Write-Info "Toplam $($IPs.Count) IP taranacak..." + $pool = [runspacefactory]::CreateRunspacePool(1, $MaxThreads) + $pool.Open() + $jobs = [System.Collections.Generic.List[hashtable]]::new() + foreach ($ip in $IPs) { + $ps = [powershell]::Create() + $ps.RunspacePool = $pool + [void]$ps.AddScript({ + param($ip, $t) + try { + $ping = [System.Net.NetworkInformation.Ping]::new() + $r = $ping.Send($ip, $t * 1000) + if ($r.Status -eq 'Success') { return $ip } + } + catch { } + return $null + }).AddArgument($ip).AddArgument($Timeout) + $jobs.Add(@{ PS = $ps; Handle = $ps.BeginInvoke() }) + } + $alive = [System.Collections.Generic.List[string]]::new() + foreach ($j in $jobs) { + $result = $j.PS.EndInvoke($j.Handle) + if ($result) { $alive.Add($result) } + $j.PS.Dispose() + } + $pool.Close(); $pool.Dispose() + Write-OK "$($alive.Count) canli host bulundu" + return ($alive | Sort-Object { [System.Version]$_ }) +} + +function Invoke-SNMPQuery { + param([string]$IP, [string]$Community, [string]$OID) + $parts = $OID.TrimStart('.').Split('.') | ForEach-Object { [int]$_ } + function eLen([int]$n) { + if ($n -lt 128) { return [byte[]]@($n) } + $bl = [System.Collections.Generic.List[byte]]::new(); $tmp = $n + while ($tmp -gt 0) { $bl.Insert(0, [byte]($tmp -band 0xFF)); $tmp = $tmp -shr 8 } + return [byte[]](@([byte](0x80 + $bl.Count)) + $bl) + } + function eInt([int]$v) { + $bl = [System.Collections.Generic.List[byte]]::new(); $tmp = $v + do { $bl.Insert(0, [byte]($tmp -band 0xFF)); $tmp = $tmp -shr 8 }while ($tmp -gt 0) + if ($bl[0] -band 0x80) { $bl.Insert(0, [byte]0) } + return [byte[]](@([byte]0x02) + (eLen $bl.Count) + $bl) + } + function eOID([int[]]$p) { + $enc = [System.Collections.Generic.List[byte]]::new() + $enc.Add([byte](40 * $p[0] + $p[1])) + for ($i = 2; $i -lt $p.Count; $i++) { + $v = $p[$i] + if ($v -lt 128) { $enc.Add([byte]$v) } + else { + $sub = [System.Collections.Generic.List[byte]]::new() + while ($v -gt 0) { $sub.Insert(0, [byte]($v -band 0x7F)); $v = $v -shr 7 } + for ($j = 0; $j -lt $sub.Count - 1; $j++) { $sub[$j] = [byte]($sub[$j] -bor 0x80) } + foreach ($b in $sub) { $enc.Add($b) } + } + } + return [byte[]](@([byte]0x06) + (eLen $enc.Count) + $enc) + } + try { + $oidB = [byte[]](eOID $parts) + $nul = [byte[]]@(0x05, 0x00) + $vb = [byte[]](@([byte]0x30) + (eLen($oidB.Count + $nul.Count)) + $oidB + $nul) + $vbl = [byte[]](@([byte]0x30) + (eLen $vb.Count) + $vb) + $cb = [System.Text.Encoding]::ASCII.GetBytes($Community) + $cf = [byte[]](@([byte]0x04) + (eLen $cb.Count) + $cb) + $ver = eInt 1; $rid = eInt(Get-Random -Min 1 -Max 99999); $es = eInt 0; $ei = eInt 0 + $pdu = [byte[]](@([byte]0xA0) + (eLen($rid.Count + $es.Count + $ei.Count + $vbl.Count)) + $rid + $es + $ei + $vbl) + $msg = [byte[]]($ver + $cf + $pdu) + $pkt = [byte[]](@([byte]0x30) + (eLen $msg.Count) + $msg) + $udp = [System.Net.Sockets.UdpClient]::new() + $udp.Client.ReceiveTimeout = 2000 + $ep = [System.Net.IPEndPoint]::new([System.Net.IPAddress]::Parse($IP), 161) + [void]$udp.Send($pkt, $pkt.Count, $ep) + $rem = [System.Net.IPEndPoint]::new([System.Net.IPAddress]::Any, 0) + $resp = $udp.Receive([ref]$rem); $udp.Close() + $skip = $true + for ($i = 0; $i -lt $resp.Count - 2; $i++) { + if ($resp[$i] -eq 0x04 -and $resp[$i + 1] -gt 0 -and $resp[$i + 1] -lt 200) { + $len = $resp[$i + 1]; $st = $i + 2 + if (($st + $len) -le $resp.Count) { + if ($skip) { $skip = $false; $i = $st + $len - 1; continue } + $val = [System.Text.Encoding]::ASCII.GetString($resp, $st, $len).Trim() + if ($val -match '\S') { return $val } + } + } + } + } + catch { } + return $null +} + +function Get-Vendor { + param([string]$d) + if (-not $d) { return "Bilinmiyor" } + $dl = $d.ToLower() + if ($dl -match "cisco|sg[1-5]\d{2}|cbs\d{3}|catalyst|nexus") { return "Cisco" } + if ($dl -match "hp|hewlett|procurve|aruba") { return "HP/Aruba" } + if ($dl -match "ubiquiti|unifi|edgeswitch") { return "Ubiquiti" } + if ($dl -match "mikrotik") { return "MikroTik" } + if ($dl -match "huawei") { return "Huawei" } + if ($dl -match "tp-link|tplink") { return "TP-Link" } + if ($dl -match "juniper") { return "Juniper" } + if ($dl -match "dell|force10") { return "Dell" } + if ($dl -match "netgear") { return "Netgear" } + if ($dl -match "zyxel") { return "ZyXEL" } + if ($dl -match "dlink|d-link") { return "D-Link" } + return "Bilinmiyor" +} + +function Get-Model { + param([string]$desc, [string]$vendor) + if (-not $desc) { return "Bilinmiyor" } + switch ($vendor) { + "Cisco" { + if ($desc -match '(?i)(Catalyst\s*[\w-]+)') { return $Matches[1].Trim() } + if ($desc -match '(?i)\b(C\d{4}[A-Za-z0-9-]*|SG[1-5]\d{2}[A-Za-z0-9-]*|CBS\d{3}[A-Za-z0-9-]*|Nexus\s*[\w-]+|N\d{4}[A-Za-z0-9-]*)\b') { return $Matches[1].Trim() } + if ($desc -match '(?i)Cisco\s+(?!IOS\b)([\w-]+)') { return $Matches[1].Trim() } + } + "HP/Aruba" { if ($desc -match 'HP\s+([\w\s-]+?)(?:\s*,|\s*Switch|\s*$)') { return $Matches[1].Trim() } } + "Ubiquiti" { + if ($desc -match 'EdgeSwitch\s+([\w-]+)') { return "EdgeSwitch $($Matches[1])" } + if ($desc -match 'UniFi\s+([\w-]+)') { return "UniFi $($Matches[1])" } + } + "Huawei" { if ($desc -match 'Huawei\s+([\w-]+)') { return $Matches[1] } } + "TP-Link" { if ($desc -match '(TL-[\w-]+)') { return $Matches[1] } } + } + if ($desc -cmatch '\b([A-Z]{1,5}[\w-]{2,15})\b') { + $m = $Matches[1] + if ($m -notmatch '(?i)^(User|Password|System|Switch|Terminal|Length|Screen|Display|Show|Version|Login|Name|Host|Line|Console|Ethernet|Vlan|Port|Interface)$') { + return $m + } + } + return "Bilinmiyor" +} + +function Get-DeviceViaSNMP { + param([string]$IP, [string]$Community) + $info = [PSCustomObject]@{IP = "$IP"; Hostname = ""; Vendor = "Bilinmiyor"; Model = "Bilinmiyor"; SysDescr = ""; SysContact = ""; SysLocation = ""; FirmwareVer = ""; Method = "SNMP"; Status = "Basarisiz"; Error = "" } + try { + $sysDescr = Invoke-SNMPQuery $IP $Community "1.3.6.1.2.1.1.1.0" + $sysName = Invoke-SNMPQuery $IP $Community "1.3.6.1.2.1.1.5.0" + $sysContact = Invoke-SNMPQuery $IP $Community "1.3.6.1.2.1.1.4.0" + $sysLocation = Invoke-SNMPQuery $IP $Community "1.3.6.1.2.1.1.6.0" + if ($sysDescr -or $sysName) { + $info.SysDescr = "$sysDescr"; $info.Hostname = "$sysName" + $info.SysContact = "$sysContact"; $info.SysLocation = "$sysLocation" + $info.Vendor = Get-Vendor $sysDescr + $m = Get-Model $sysDescr $info.Vendor + if ($info.Hostname -and $m -eq $info.Hostname) { $info.Model = "Bilinmiyor" } else { $info.Model = $m } + $info.Status = "Basarili" + } + else { $info.Error = "SNMP yanit vermedi" } + } + catch { $info.Error = "$($_.Exception.Message)" } + return $info +} + +function Get-DeviceViaSSH { + param([string]$IP, [string]$User, [string]$Pass, [int]$Port) + $info = [PSCustomObject]@{IP = "$IP"; Hostname = ""; Vendor = "Bilinmiyor"; Model = "Bilinmiyor"; SysDescr = ""; SysContact = ""; SysLocation = ""; FirmwareVer = ""; Method = "SSH"; Status = "Basarisiz"; Error = "" } + if (-not (Get-Module -ListAvailable -Name Posh-SSH)) { $info.Error = "Posh-SSH yuklu degil"; return $info } + Import-Module Posh-SSH -ErrorAction SilentlyContinue + try { + $secPass = ConvertTo-SecureString $Pass -AsPlainText -Force + $cred = [System.Management.Automation.PSCredential]::new($User, $secPass) + $session = New-SSHSession -ComputerName $IP -Credential $cred -Port $Port -AcceptKey -ConnectionTimeout($Timeout * 1000) -ErrorAction Stop + if (-not $session) { $info.Error = "SSH oturumu acilamadi"; return $info } + $stream = $session.Session.CreateShellStream("xterm", 80, 24, 800, 600, 1024) + Start-Sleep -Milliseconds 1500; $banner = $stream.Read() + $vendor = "Unknown" + if ($banner -match "Cisco") { $vendor = "Cisco" } + elseif ($banner -match "HP|ProCurve|Aruba") { $vendor = "HP/Aruba" } + elseif ($banner -match "Ubiquiti|EdgeOS") { $vendor = "Ubiquiti" } + elseif ($banner -match "MikroTik") { $vendor = "MikroTik" } + elseif ($banner -match "Huawei") { $vendor = "Huawei" } + $cmds = switch ($vendor) { + "Cisco" { @("terminal length 0", "show version", "show running-config | include hostname") } + "HP/Aruba" { @("no page", "show system information", "show version") } + "Ubiquiti" { @("show version", "show system") } + "MikroTik" { @("/system identity print", "/system resource print", "/system routerboard print") } + "Huawei" { @("screen-length 0 temporary", "display version", "display sysname") } + default { @("show version", "show system", "uname -a") } + } + $out = "" + foreach ($cmd in $cmds) { $stream.WriteLine($cmd); Start-Sleep -Milliseconds 800; $out += $stream.Read() } + if ($out) { + $cleanOut = $out -replace '\x1B\[[0-9;?]*[a-zA-Z]', '' + $info.SysDescr = (($cleanOut -split "`n" | Select-Object -First 3) -join " ").Trim() + if ($cleanOut -match '(?im)(?:hostname|sysname)[:\s]+([^\r\n]+)') { + $info.Hostname = $Matches[1].Trim() + } + else { + $pMatches = [regex]::Matches($cleanOut, '[<\[]*([A-Za-z0-9_-]{3,})[#>\]]') + if ($pMatches.Count -gt 0) { $info.Hostname = $pMatches[$pMatches.Count - 1].Groups[1].Value.Trim() } + } + $info.Vendor = if ($vendor -ne "Unknown") { $vendor }else { Get-Vendor $cleanOut } + $m = Get-Model $cleanOut $info.Vendor + if ($info.Hostname -and $m -eq $info.Hostname) { $info.Model = "Bilinmiyor" } else { $info.Model = $m } + if ($cleanOut -match '(?i)Version[:\s]+([\d\.A-Za-z\(\)]+)') { $info.FirmwareVer = $Matches[1] } + $info.Status = "Basarili" + } + } + catch { $info.Error = "$($_.Exception.Message)" } + return $info +} + +function Get-DeviceViaTelnet { + param([string]$IP, [string]$User, [string]$Pass, [int]$Port = 23) + $info = [PSCustomObject]@{IP = "$IP"; Hostname = ""; Vendor = "Bilinmiyor"; Model = "Bilinmiyor"; SysDescr = ""; SysContact = ""; SysLocation = ""; FirmwareVer = ""; Method = "Telnet"; Status = "Basarisiz"; Error = "" } + try { + $tcp = [System.Net.Sockets.TcpClient]::new() + $res = $tcp.BeginConnect($IP, $Port, $null, $null) + $wait = $res.AsyncWaitHandle.WaitOne(3000) + if (-not $wait -or -not $tcp.Connected) { $info.Error = "Port kapali veya zaman asimi"; return $info } + $tcp.EndConnect($res) + $stream = $tcp.GetStream() + $reader = [System.IO.StreamReader]::new($stream, [System.Text.Encoding]::ASCII) + $writer = [System.IO.StreamWriter]::new($stream, [System.Text.Encoding]::ASCII) + $writer.AutoFlush = $true + + $sb = [System.Text.StringBuilder]::new() + $start = [datetime]::UtcNow + $loggedIn = $false + + while (([datetime]::UtcNow - $start).TotalSeconds -lt 5) { + if ($stream.DataAvailable) { + while ($stream.DataAvailable) { [void]$sb.Append([char]$stream.ReadByte()) } + $out = $sb.ToString() + if ($out -match "(?i)username:|login:") { + $writer.WriteLine($User); Start-Sleep -Milliseconds 500; $sb.Clear() + } + elseif ($out -match "(?i)password:") { + $writer.WriteLine($Pass); Start-Sleep -Milliseconds 500; $sb.Clear() + } + elseif ($out -match ">|#") { + $loggedIn = $true; break + } + } + else { Start-Sleep -Milliseconds 200 } + } + + if (-not $loggedIn) { $writer.WriteLine(""); Start-Sleep -Milliseconds 500 } + + $cmds = @("terminal length 0", "screen-length 0 temporary", "no page", "show version", "show system", "display version") + foreach ($cmd in $cmds) { + $writer.WriteLine($cmd); Start-Sleep -Milliseconds 500 + while ($stream.DataAvailable) { [void]$sb.Append([char]$stream.ReadByte()) } + } + $tcp.Close() + + $fullOut = $sb.ToString() + if ($fullOut -match '\S') { + $cleanOut = $fullOut -replace '\x1B\[[0-9;?]*[a-zA-Z]', '' + $info.SysDescr = (($cleanOut -split "`n" | Select-Object -First 3) -join " ").Trim() + if ($cleanOut -match '(?im)(?:hostname|sysname)[:\s]+([^\r\n]+)') { + $info.Hostname = $Matches[1].Trim() + } + else { + $pMatches = [regex]::Matches($cleanOut, '[<\[]*([A-Za-z0-9_-]{3,})[#>\]]') + if ($pMatches.Count -gt 0) { $info.Hostname = $pMatches[$pMatches.Count - 1].Groups[1].Value.Trim() } + } + $info.Vendor = Get-Vendor $cleanOut + $m = Get-Model $cleanOut $info.Vendor + if ($info.Hostname -and $m -eq $info.Hostname) { $info.Model = "Bilinmiyor" } else { $info.Model = $m } + if ($cleanOut -match '(?i)Version[:\s]+([\d\.A-Za-z\(\)]+)') { $info.FirmwareVer = $Matches[1] } + $info.Status = "Basarili" + } + } + catch { $info.Error = "$($_.Exception.Message)" } + return $info +} + +function Get-DNS { + param([string]$IP) + try { return([System.Net.Dns]::GetHostEntry($IP)).HostName }catch { return "" } +} + +function Merge-Info { + param($ssh, $telnet, $snmp, [string]$ip) + $m = [PSCustomObject]@{IP = "$ip"; Hostname = ""; DNSName = (Get-DNS $ip); Vendor = "Bilinmiyor"; Model = "Bilinmiyor"; FirmwareVer = ""; SysLocation = ""; SysContact = ""; SSHStatus = "Atlandi"; TelnetStatus = "Atlandi"; SNMPStatus = "Atlandi"; SysDescr = "" } + if ($snmp) { $m.SNMPStatus = $snmp.Status; if ($snmp.Status -eq "Basarili") { $m.Hostname = $snmp.Hostname; $m.Vendor = $snmp.Vendor; $m.Model = $snmp.Model; $m.SysLocation = $snmp.SysLocation; $m.SysContact = $snmp.SysContact; $m.SysDescr = $snmp.SysDescr } } + if ($telnet) { $m.TelnetStatus = $telnet.Status; if ($telnet.Status -eq "Basarili") { if (-not $m.Hostname) { $m.Hostname = $telnet.Hostname }; if ($m.Vendor -eq "Bilinmiyor") { $m.Vendor = $telnet.Vendor }; if ($m.Model -eq "Bilinmiyor") { $m.Model = $telnet.Model }; if (-not $m.FirmwareVer) { $m.FirmwareVer = $telnet.FirmwareVer } } } + if ($ssh) { $m.SSHStatus = $ssh.Status; if ($ssh.Status -eq "Basarili") { if (-not $m.Hostname) { $m.Hostname = $ssh.Hostname }; if ($m.Vendor -eq "Bilinmiyor") { $m.Vendor = $ssh.Vendor }; if ($m.Model -eq "Bilinmiyor") { $m.Model = $ssh.Model }; if (-not $m.FirmwareVer) { $m.FirmwareVer = $ssh.FirmwareVer } } } + if ((-not $m.Hostname) -and $m.DNSName) { $m.Hostname = $m.DNSName } + return $m +} + +function Export-ToCSV { + param($res, [string]$path) + $ts = Get-Date -Format "yyyyMMdd_HHmmss"; $out = Join-Path $path "SwitchDiscovery_$ts.csv" + $res | Select-Object IP, Hostname, DNSName, Vendor, Model, FirmwareVer, SysLocation, SysContact, SSHStatus, TelnetStatus, SNMPStatus, SysDescr | Export-Csv -Path $out -NoTypeInformation -Encoding UTF8 + Write-OK "CSV: $out"; return $out +} + +function Export-ToHTML { + param($res, [string]$path) + $ts = Get-Date -Format "yyyyMMdd_HHmmss"; $outPath = Join-Path $path "SwitchDiscovery_$ts.html" + $genDate = Get-Date -Format "dd.MM.yyyy HH:mm:ss" + $total = $res.Count + $sshOK = ($res | Where-Object { $_.SSHStatus -eq "Basarili" }).Count + $telnetOK = ($res | Where-Object { $_.TelnetStatus -eq "Basarili" }).Count + $snmpOK = ($res | Where-Object { $_.SNMPStatus -eq "Basarili" }).Count + $sb = [System.Text.StringBuilder]::new() + foreach ($r in $res) { + $s1 = if ($r.SSHStatus -eq "Basarili") { 'SSH OK' }elseif ($r.SSHStatus -eq "Atlandi") { 'SSH -' }else { 'SSH X' } + $s3 = if ($r.TelnetStatus -eq "Basarili") { 'TELNET OK' }elseif ($r.TelnetStatus -eq "Atlandi") { 'TELNET -' }else { 'TELNET X' } + $s2 = if ($r.SNMPStatus -eq "Basarili") { 'SNMP OK' }elseif ($r.SNMPStatus -eq "Atlandi") { 'SNMP -' }else { 'SNMP X' } + [void]$sb.Append("$($r.IP)$($r.Hostname)
$($r.DNSName)$($r.Vendor)$($r.Model)$($r.FirmwareVer)$($r.SysLocation)$s1 $s3 $s2`n") + } + $lines = [System.Collections.Generic.List[string]]::new() + $lines.Add('Switch Discovery

Network Switch Discovery Raporu

') + $lines.Add("
Olusturulma: $genDate | IP: $IPRange | Yontem: $Method
") + $lines.Add("
$total
Toplam
$sshOK
SSH Basarili
$telnetOK
Telnet Basarili
$snmpOK
SNMP Basarili
") + $lines.Add('
') + $lines.Add('') + $lines.Add($sb.ToString()) + $lines.Add('
IPHostnameMarkaModelFirmwareKonumDurum
') + [System.IO.File]::WriteAllLines($outPath, $lines, [System.Text.UTF8Encoding]::new($false)) + Write-OK "HTML: $outPath"; return $outPath +} + +# ================================================================ ANA AKIS +Clear-Host +Write-Host " =====================================================" -ForegroundColor Cyan +Write-Host " Network Switch Discovery Tool v1.2" -ForegroundColor Cyan +Write-Host " SSH + SNMP | Cisco / HP / Ubiquiti / Huawei / TP-Link" -ForegroundColor Cyan +Write-Host " =====================================================" -ForegroundColor Cyan + +if ($Method -ne "SNMP" -and -not $Password) { + if (-not $Username) { $Username = Read-Host " SSH Kullanici adi" } + $sp = Read-Host " SSH Sifre" -AsSecureString + $Password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($sp)) +} + +Test-Dependencies + +Write-Header "IP Araligi Cozumleniyor" +Write-Step "Aralik: $IPRange" +$allIPs = Resolve-IPRange -Range $IPRange +Write-OK "$($allIPs.Count) IP belirlendi" + +$aliveHosts = Get-AliveHosts -IPs $allIPs +if ($aliveHosts.Count -eq 0) { Write-Fail "Canli host yok."; exit 1 } + +Write-Header "Cihaz Bilgisi Toplama" +Write-Info "Yontem: $Method | Canli: $($aliveHosts.Count)" + +$scriptRoot = $PSScriptRoot +$pool2 = [runspacefactory]::CreateRunspacePool(1, $MaxThreads) +$pool2.Open() +$jobs2 = [System.Collections.Generic.List[hashtable]]::new() + +$funcDefs = " +function Invoke-SNMPQuery { ${function:Invoke-SNMPQuery} } +function Get-Vendor { ${function:Get-Vendor} } +function Get-Model { ${function:Get-Model} } +function Get-DeviceViaSNMP { ${function:Get-DeviceViaSNMP} } +function Get-DeviceViaSSH { ${function:Get-DeviceViaSSH} } +function Get-DeviceViaTelnet { ${function:Get-DeviceViaTelnet} } +function Get-DNS { ${function:Get-DNS} } +function Merge-Info { ${function:Merge-Info} } +" + +$discoverScript = [scriptblock]::Create(' + param($ip,$method,$user,$pass,$comm,$port,$tout) +' + $funcDefs + ' + $sshR=$null; $snmpR=$null; $telR=$null + if($method -in @("SSH","Both","All")) { $sshR = Get-DeviceViaSSH $ip $user $pass $port } + if($method -in @("Telnet","Both","All")) { $telR = Get-DeviceViaTelnet $ip $user $pass 23 } + if($method -in @("SNMP","Both","All")) { $snmpR = Get-DeviceViaSNMP $ip $comm } + return (Merge-Info $sshR $telR $snmpR $ip) +') + +foreach ($ip in $aliveHosts) { + $ps = [powershell]::Create() + $ps.RunspacePool = $pool2 + [void]$ps.AddScript($discoverScript).AddArgument($ip).AddArgument($Method).AddArgument($Username).AddArgument($Password).AddArgument($SNMPCommunity).AddArgument($SSHPort).AddArgument($Timeout) + $jobs2.Add(@{ PS = $ps; Handle = $ps.BeginInvoke(); IP = $ip; Done = $false }) +} + +$allResults = [System.Collections.Generic.List[object]]::new() +$total = $jobs2.Count +$done = 0 +$startTime = [datetime]::UtcNow +$lastPrint = [datetime]::MinValue # konsol satirlari icin debounce + +Write-Host "" + +while ($done -lt $total) { + # O an islenen IP'leri goster + if (([datetime]::UtcNow - $lastPrint).TotalSeconds -ge 1) { + $runningIPs = $jobs2 | Where-Object { -not $_.Done } | Select-Object -ExpandProperty IP + $runningStr = ($runningIPs | Select-Object -First 3) -join ", " + if ($runningIPs.Count -gt 3) { $runningStr += " ve $($runningIPs.Count - 3) daha..." } + + $pct = if ($total -gt 0) { [math]::Round($done / $total * 100) } else { 0 } + Write-Progress ` + -Activity "Switch kesfi - $done/$total tamamlandi" ` + -Status ("Islenen cihazlar: $runningStr") ` + -PercentComplete $pct + + $lastPrint = [datetime]::UtcNow + } + + foreach ($j in $jobs2) { + if ($j.Done) { continue } + if ($j.Handle.IsCompleted) { + $r = $j.PS.EndInvoke($j.Handle) + $j.PS.Dispose() + $j.Done = $true + $done++ + + $rObj = $null + if ($r -and $r.Count -gt 0) { $rObj = $r[0] } + + # Bulunan cihaz bilgisini al + $foundIP = $j.IP + $vendor = if ($rObj -and $rObj.Vendor -and $rObj.Vendor -ne "Bilinmiyor") { $rObj.Vendor } else { "?" } + $model = if ($rObj -and $rObj.Model -and $rObj.Model -ne "Bilinmiyor") { $rObj.Model } else { "" } + $hostname = if ($rObj -and $rObj.Hostname -and $rObj.Hostname -ne "") { $rObj.Hostname } else { "" } + $sshStat = if ($rObj -and $rObj.SSHStatus) { $rObj.SSHStatus } else { "Atlandi" } + $telStat = if ($rObj -and $rObj.TelnetStatus) { $rObj.TelnetStatus } else { "Atlandi" } + $snmpStat = if ($rObj -and $rObj.SNMPStatus) { $rObj.SNMPStatus } else { "Atlandi" } + + if ($rObj) { $allResults.Add($rObj) } + + # --- ETA hesabi + $elapsed = ([datetime]::UtcNow - $startTime).TotalSeconds + $avgPerJob = if ($done -gt 0) { $elapsed / $done } else { 0 } + $remaining = $total - $done + $etaSec = [math]::Round($avgPerJob * $remaining) + $etaStr = if ($etaSec -gt 3600) { "{0}s {1}d {2}sn" -f [math]::Floor($etaSec / 3600), [math]::Floor(($etaSec % 3600) / 60), ($etaSec % 60) } + elseif ($etaSec -gt 60) { "{0}d {1}sn" -f [math]::Floor($etaSec / 60), ($etaSec % 60) } + else { "${etaSec}sn" } + + # --- Renk secimi + $lineColor = if ($sshStat -eq "Basarili" -or $snmpStat -eq "Basarili" -or $telStat -eq "Basarili") { "Green" } else { "DarkGray" } + + # --- Konsola yazdir + $pctDone = [math]::Round($done / $total * 100) + $bar = ("#" * [math]::Floor($pctDone / 5)).PadRight(20) + $hostPart = if ($hostname) { " ($hostname)" } else { "" } + $modPart = if ($model) { " $model" } else { "" } + + Write-Host (" [{0,3}%] [{1}] {2}/{3} {4,-16}{5}{6}{7} | Kalan ~{8}" -f ` + $pctDone, $bar, $done, $total, + $foundIP, $hostPart, " $vendor", $modPart, + $etaStr) -ForegroundColor $lineColor + } + } + if ($done -lt $total) { Start-Sleep -Milliseconds 200 } +} + +$pool2.Close(); $pool2.Dispose() +Write-Progress -Activity "Switch kesfi..." -Completed + +# Ozet satiri +$elapsed = [math]::Round(([datetime]::UtcNow - $startTime).TotalSeconds) +$sshFound = ($allResults | Where-Object { $_.SSHStatus -eq "Basarili" }).Count +$telFound = ($allResults | Where-Object { $_.TelnetStatus -eq "Basarili" }).Count +$snmpFound = ($allResults | Where-Object { $_.SNMPStatus -eq "Basarili" }).Count +Write-Host "" +Write-Host (" Tamamlandi: {0} cihaz taranadi | SSH:{1} Telnet:{2} SNMP:{3} Sure:{4}sn" -f $total, $sshFound, $telFound, $snmpFound, $elapsed) -ForegroundColor Cyan + +$sorted = $allResults | Sort-Object { [System.Version]$_.IP } + +Write-Header "Kesif Sonuclari" +$sorted | Format-Table -AutoSize -Property IP, Hostname, Vendor, Model, FirmwareVer, SSHStatus, TelnetStatus, SNMPStatus + +Write-Header "Disari Aktarma" +$csv = Export-ToCSV $sorted $OutputPath +$html = Export-ToHTML $sorted $OutputPath + +Write-Header "Tamamlandi" +Write-OK "Toplam: $($sorted.Count) cihaz" + +$ans = Read-Host "`n HTML raporu acilsin mi? (E/H)" +if ($ans -match '^[Ee]') { Start-Process $html } diff --git a/README.md b/README.md new file mode 100644 index 0000000..d1a920a --- /dev/null +++ b/README.md @@ -0,0 +1,245 @@ +# 🔍 Network Switch Discovery Tool + +PowerShell tabanlı, SSH + SNMP destekli, çoklu marka ağ switch keşif aracı. +Cisco, HP/Aruba, Ubiquiti/UniFi, Huawei, TP-Link ve diğer markaları otomatik olarak tespit eder. + +--- + +## 📁 Dosya Yapısı + +``` +NetworkSwitchDiscovery\ +├── Start-SwitchDiscovery.ps1 ← İnteraktif menü (buradan başla) +├── Invoke-SwitchDiscovery.ps1 ← Ana keşif motoru +├── discovery_config.json ← Otomatik kaydedilen ayarlar (ilk çalıştırmada oluşur) +├── lib\ +│ └── SharpSnmpLib.dll ← (İsteğe bağlı) Gelişmiş SNMP desteği +└── README.md +``` + +--- + +## ⚙️ Gereksinimler + +| Gereksinim | Açıklama | +|---|---| +| PowerShell 5.1+ | Windows 10/11 ile birlikte gelir | +| [Posh-SSH](https://github.com/darkoperator/Posh-SSH) | SSH bağlantısı için (otomatik kurulum menüde mevcut) | +| .NET Framework 4.7+ | SNMP UDP soketi için | +| SharpSnmpLib.dll | İsteğe bağlı, gelişmiş SNMP v3 desteği için | + +--- + +## 🚀 Hızlı Başlangıç + +### 1. PowerShell'i Yönetici Olarak Aç + +```powershell +# Execution Policy (bir kez gerekli) +Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser +``` + +### 2. Menüyü Başlat + +```powershell +cd C:\Tools\NetworkSwitchDiscovery +.\Start-SwitchDiscovery.ps1 +``` + +### 3. Veya Doğrudan Parametreli Çalıştır + +```powershell +# CIDR aralığı, SSH + SNMP birlikte +.\Invoke-SwitchDiscovery.ps1 -IPRange "192.168.1.0/24" -Username admin -Method Both + +# Sadece SNMP, farklı community +.\Invoke-SwitchDiscovery.ps1 -IPRange "10.0.0.1-10.0.0.50" -Method SNMP -SNMPCommunity private + +# Tek IP, sadece SSH +.\Invoke-SwitchDiscovery.ps1 -IPRange "172.16.0.1" -Username admin -Password "sifre123" -Method SSH +``` + +--- + +## 📋 Parametreler + +| Parametre | Varsayılan | Açıklama | +|---|---|---| +| `-IPRange` | *(zorunlu)* | CIDR, tire veya tekil IP | +| `-Username` | — | SSH kullanıcı adı | +| `-Password` | — | SSH şifre (girilmezse güvenli prompt açılır) | +| `-SNMPCommunity` | `public` | SNMP community string | +| `-SNMPVersion` | `v2c` | v1, v2c veya v3 | +| `-Method` | `Both` | SSH, SNMP veya Both | +| `-OutputPath` | Script dizini | CSV/HTML çıktı klasörü | +| `-MaxThreads` | `20` | Paralel tarama thread sayısı | +| `-SSHPort` | `22` | SSH port numarası | +| `-Timeout` | `5` | Bağlantı zaman aşımı (saniye) | + +--- + +## 🏷️ Desteklenen Markalar ve SSH Komutları + +### Cisco IOS / IOS-XE +``` +terminal length 0 +show version +show running-config | include hostname +``` +Tespit: Banner'da `Cisco` ifadesi veya SNMP sysDescr + +### HP / Aruba ProCurve +``` +no page +show system information +show version +``` +Tespit: `HP`, `ProCurve`, `Aruba` ifadeleri + +### Ubiquiti EdgeSwitch / UniFi +``` +show version +show system +``` +Tespit: `Ubiquiti`, `EdgeOS`, `UniFi` ifadeleri + +### MikroTik RouterOS +``` +/system identity print +/system resource print +/system routerboard print +``` +Tespit: `MikroTik` ifadesi + +### Huawei VRP +``` +screen-length 0 temporary +display version +display sysname +``` +Tespit: `Huawei` ifadesi + +### TP-Link / Diğer +``` +show version +show system +``` +Tespit: `TL-`, model kodu deseni + +--- + +## 📡 SNMP OID Referansı + +| OID | Açıklama | +|---|---| +| `1.3.6.1.2.1.1.1.0` | sysDescr — Cihaz tam açıklaması | +| `1.3.6.1.2.1.1.5.0` | sysName — Hostname | +| `1.3.6.1.2.1.1.4.0` | sysContact — İletişim bilgisi | +| `1.3.6.1.2.1.1.6.0` | sysLocation — Fiziksel konum | +| `1.3.6.1.2.1.1.3.0` | sysUpTime — Çalışma süresi | + +SNMP community string varsayılan olarak `public` kullanılır. +Cihazda SNMP devre dışıysa veya community yanlışsa SNMP sütunu `Başarısız` gösterir. + +--- + +## 📤 Çıktı Dosyaları + +Her tarama sonunda iki dosya oluşturulur: + +### CSV (`SwitchDiscovery_YYYYMMDD_HHmmss.csv`) +Excel veya başka araçlarda açılabilir, UTF-8 kodlamalı. + +| Alan | Açıklama | +|---|---| +| IP | Cihaz IP adresi | +| Hostname | Switch hostname (SNMP/SSH'dan) | +| DNSName | DNS çözümlemesi | +| Vendor | Tespit edilen marka | +| Model | Cihaz modeli | +| FirmwareVer | IOS/Firmware versiyonu | +| SysLocation | SNMP konum bilgisi | +| SysContact | SNMP iletişim bilgisi | +| Uptime | Cihaz çalışma süresi | +| SSHStatus | Başarılı / Başarısız / Atlandı | +| SNMPStatus | Başarılı / Başarısız / Atlandı | +| SysDescr | Ham sysDescr verisi | + +### HTML (`SwitchDiscovery_YYYYMMDD_HHmmss.html`) +Tarayıcıda açılan interaktif rapor: +- Anlık arama/filtreleme +- Marka renkli rozet gösterimi +- SSH/SNMP durum badgeleri +- Özet istatistik kartları + +--- + +## 💡 Pratik Kullanım Örnekleri + +```powershell +# Tüm /24 ağı tara, sonucu masaüstüne kaydet +.\Invoke-SwitchDiscovery.ps1 ` + -IPRange "192.168.10.0/24" ` + -Username netadmin ` + -SNMPCommunity mycompany ` + -Method Both ` + -OutputPath "$env:USERPROFILE\Desktop" ` + -MaxThreads 30 + +# Birden fazla switch IP'si — tire formatıyla +.\Invoke-SwitchDiscovery.ps1 ` + -IPRange "10.1.1.1-10.1.1.20" ` + -Username cisco ` + -Method SSH ` + -SSHPort 2222 + +# Sadece SNMP, hızlı envanter +.\Invoke-SwitchDiscovery.ps1 ` + -IPRange "172.20.0.0/22" ` + -Method SNMP ` + -SNMPCommunity readonly ` + -MaxThreads 50 ` + -Timeout 3 +``` + +--- + +## 🔧 Sorun Giderme + +| Sorun | Çözüm | +|---|---| +| `Posh-SSH bulunamadı` | Menüden [8] seçerek otomatik kurulum yap | +| SSH bağlantı hatası | Firewall port 22'yi açık, cihazda SSH aktif mi kontrol et | +| SNMP yanıt vermiyor | Community string'i doğrula, cihazda SNMP v2c aktif mi kontrol et | +| `execution policy` hatası | `Set-ExecutionPolicy RemoteSigned -Scope CurrentUser` çalıştır | +| Thread hatası | `-MaxThreads` değerini düşür (örn. 5) | +| Şifre prompt açılmıyor | `-Password` parametresini doğrudan ver | + +--- + +## 🔒 Güvenlik Notları + +- Şifreler `discovery_config.json` dosyasına **kaydedilmez**, her oturumda sorulur. +- SSH host anahtarları `Posh-SSH` tarafından otomatik kabul edilir (`-AcceptKey`). + Üretim ortamında host key doğrulama etkinleştirilmesi önerilir. +- SNMP v1/v2c community string düz metin iletilir. Mümkünse SNMP v3 kullan. +- Tarama yalnızca yetkili ağlarda yapılmalıdır. + +--- + +## 📦 İsteğe Bağlı: SharpSnmpLib Kurulumu (Gelişmiş SNMP) + +```powershell +# NuGet ile indir +Install-Package SharpSnmpLib -Destination .\lib + +# Veya dotnet CLI +dotnet add package SharpSnmpLib +# Ardından bin\Debug\net*\SharpSnmpLib.dll dosyasını .\lib\ klasörüne kopyala +``` + +SharpSnmpLib olmadan araç yerleşik UDP SNMP implementasyonu kullanır (v1/v2c destekli). + +--- + +*Mustafa Özkaya — NetworkSwitchDiscovery v1.0* diff --git a/Start-SwitchDiscovery.ps1 b/Start-SwitchDiscovery.ps1 new file mode 100644 index 0000000..a38332c --- /dev/null +++ b/Start-SwitchDiscovery.ps1 @@ -0,0 +1,232 @@ +#Requires -Version 5.1 +Set-StrictMode -Version Latest +$ErrorActionPreference = "SilentlyContinue" +$configFile = Join-Path $PSScriptRoot "discovery_config.json" + +function Write-Banner { + Clear-Host + Write-Host " ======================================================" -ForegroundColor Cyan + Write-Host " Network Switch Discovery Tool v1.1" -ForegroundColor Cyan + Write-Host " SSH + SNMP | Cisco / HP / Ubiquiti / Huawei / TP-Link" -ForegroundColor Cyan + Write-Host " ======================================================" -ForegroundColor Cyan + Write-Host "" +} + +function Write-Menu { + param([hashtable]$c) + Write-Host " Mevcut Ayarlar:" -ForegroundColor DarkGray + Write-Host (" | IP Aralik : " + $c.IPRange) -ForegroundColor Gray + Write-Host (" | Kullanici : " + $c.Username) -ForegroundColor Gray + Write-Host (" | Yontem : " + $c.Method) -ForegroundColor Gray + Write-Host (" | SNMP Comm. : " + $c.SNMPCommunity) -ForegroundColor Gray + Write-Host (" | SSH Port : " + $c.SSHPort) -ForegroundColor Gray + Write-Host (" | Max Thread : " + $c.MaxThreads) -ForegroundColor Gray + Write-Host (" | Timeout (s) : " + $c.Timeout) -ForegroundColor Gray + Write-Host "" + Write-Host " +------------------------------------------+" -ForegroundColor Cyan + Write-Host " | [1] Taramayi Baslat |" -ForegroundColor White + Write-Host " | [2] IP Araligini Degistir |" -ForegroundColor White + Write-Host " | [3] SSH Kimlik Bilgilerini Gir |" -ForegroundColor White + Write-Host " | [4] SNMP Ayarlarini Duzenle |" -ForegroundColor White + Write-Host " | [5] Gelismis Ayarlar |" -ForegroundColor White + Write-Host " | [6] Yontemi Degistir (SSH/SNMP/Both) |" -ForegroundColor White + Write-Host " | [7] Profil Kaydet / Yukle |" -ForegroundColor White + Write-Host " | [8] Bagimlilik Kontrol/Kur |" -ForegroundColor White + Write-Host " | [Q] Cikis |" -ForegroundColor DarkGray + Write-Host " +------------------------------------------+" -ForegroundColor Cyan + Write-Host "" +} + +function rInput { + param([string]$p,[string]$d="") + $disp = if ($d) { "$p [$d]" } else { $p } + Write-Host " $disp : " -ForegroundColor Yellow -NoNewline + $v = Read-Host + if ([string]::IsNullOrWhiteSpace($v)) { return $d } + return $v +} + +function rSecret { + param([string]$p) + Write-Host " $p : " -ForegroundColor Yellow -NoNewline + $s = Read-Host -AsSecureString + return [System.Runtime.InteropServices.Marshal]::PtrToStringAuto( + [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($s)) +} + +function Get-DefaultConfig { + return @{ + IPRange="192.168.1.0/24"; Username="admin"; Password="" + SNMPCommunity="public"; SNMPVersion="v2c"; Method="Both" + OutputPath=$PSScriptRoot; MaxThreads=20; SSHPort=22; Timeout=5 + Profiles=@{} + } +} + +function Load-Config { + if (Test-Path $configFile) { + try { + $j = Get-Content $configFile -Raw | ConvertFrom-Json + $cfg = Get-DefaultConfig + foreach ($k in @("IPRange","Username","SNMPCommunity","SNMPVersion","Method","OutputPath","MaxThreads","SSHPort","Timeout")) { + if ($j.PSObject.Properties.Name -contains $k) { $cfg[$k] = $j.$k } + } + return $cfg + } catch { } + } + return Get-DefaultConfig +} + +function Save-Config { + param([hashtable]$c) + $s = $c.Clone(); $s.Password = "" + $s | ConvertTo-Json -Depth 5 | Out-File $configFile -Encoding UTF8 +} + +function Set-IPRange { + param([hashtable]$c) + Write-Host "`n Format ornekleri:" -ForegroundColor DarkGray + Write-Host " CIDR : 192.168.1.0/24" -ForegroundColor DarkGray + Write-Host " Tire : 10.0.0.1-10.0.0.50" -ForegroundColor DarkGray + Write-Host " Tekil: 172.16.0.1" -ForegroundColor DarkGray + $c.IPRange = rInput "Yeni IP araligi" $c.IPRange +} + +function Set-SSH { + param([hashtable]$c) + $c.Username = rInput "SSH Kullanici adi" $c.Username + $c.Password = rSecret "SSH Sifre (gizli)" + Write-Host " [+] SSH bilgileri guncellendi" -ForegroundColor Green +} + +function Set-SNMP { + param([hashtable]$c) + $c.SNMPCommunity = rInput "Community string" $c.SNMPCommunity + Write-Host " Versiyon: [1] v1 [2] v2c [3] v3" -ForegroundColor Yellow + $v = rInput "Secim" "2" + $c.SNMPVersion = switch ($v) { "1"{"v1"} "3"{"v3"} default{"v2c"} } +} + +function Set-Advanced { + param([hashtable]$c) + $c.MaxThreads = [int](rInput "Thread sayisi (1-100)" $c.MaxThreads) + $c.SSHPort = [int](rInput "SSH port" $c.SSHPort) + $c.Timeout = [int](rInput "Timeout (saniye)" $c.Timeout) + $c.OutputPath = rInput "Cikti dizini" $c.OutputPath +} + +function Set-Method { + param([hashtable]$c) + Write-Host " [1] SSH [2] SNMP [3] Both" -ForegroundColor Gray + $m = rInput "Yontem" "3" + $c.Method = switch ($m) { "1"{"SSH"} "2"{"SNMP"} default{"Both"} } + Write-Host " [+] Yontem: $($c.Method)" -ForegroundColor Green +} + +function Manage-Profiles { + param([hashtable]$c) + Write-Host " [1] Kaydet [2] Yukle [3] Listele" -ForegroundColor Gray + $sel = rInput "Secim" "1" + switch ($sel) { + "1" { + $n = rInput "Profil adi" + if ($n) { + if (-not $c.Profiles) { $c.Profiles = @{} } + $c.Profiles[$n] = @{ + IPRange=$c.IPRange; Username=$c.Username + SNMPCommunity=$c.SNMPCommunity; Method=$c.Method + SNMPVersion=$c.SNMPVersion; SSHPort=$c.SSHPort; MaxThreads=$c.MaxThreads + } + Save-Config $c + Write-Host " [+] Profil '$n' kaydedildi" -ForegroundColor Green + } + } + "2" { + if ($c.Profiles -and $c.Profiles.Count -gt 0) { + $keys = @($c.Profiles.Keys) + for ($i=0;$i -lt $keys.Count;$i++) { Write-Host " [$($i+1)] $($keys[$i])" -ForegroundColor Gray } + $idx = [int](rInput "Profil no") - 1 + if ($idx -ge 0 -and $idx -lt $keys.Count) { + $p = $c.Profiles[$keys[$idx]] + foreach ($k in $p.PSObject.Properties.Name) { $c[$k]=$p.$k } + Write-Host " [+] Yuklendi: $($keys[$idx])" -ForegroundColor Green + } + } else { Write-Host " Kayitli profil yok" -ForegroundColor DarkYellow } + } + "3" { + if ($c.Profiles -and $c.Profiles.Count -gt 0) { + $c.Profiles.Keys | ForEach-Object { Write-Host " - $_" -ForegroundColor Gray } + } else { Write-Host " Profil yok" -ForegroundColor DarkGray } + } + } +} + +function Install-Deps { + Write-Host "`n Kontrol ediliyor..." -ForegroundColor Yellow + if (Get-Module -ListAvailable -Name Posh-SSH) { + Write-Host " [+] Posh-SSH kurulu" -ForegroundColor Green + } else { + Write-Host " [-] Posh-SSH eksik" -ForegroundColor Red + $a = rInput "Kurulsun mu? (E/H)" "E" + if ($a -match '^[Ee]') { + Install-Module Posh-SSH -Scope CurrentUser -Force -AllowClobber + Write-Host " [+] Posh-SSH kuruldu" -ForegroundColor Green + } + } + if (Get-Module -ListAvailable -Name ThreadJob) { + Write-Host " [+] ThreadJob kurulu" -ForegroundColor Green + } else { + Write-Host " [!] ThreadJob eksik, kuruluyor..." -ForegroundColor Yellow + Install-Module ThreadJob -Scope CurrentUser -Force + Write-Host " [+] ThreadJob kuruldu" -ForegroundColor Green + } + $dll = Join-Path $PSScriptRoot "lib\SharpSnmpLib.dll" + if (Test-Path $dll) { Write-Host " [+] SharpSnmpLib.dll mevcut" -ForegroundColor Green } + else { Write-Host " [i] SharpSnmpLib.dll yok - yerlesik SNMP UDP kullanilir" -ForegroundColor Gray } + Read-Host "`n Devam icin Enter" +} + +function Start-Discovery { + param([hashtable]$c) + if (-not $c.Password -and $c.Method -ne "SNMP") { + $c.Password = rSecret "SSH Sifre" + } + $script = Join-Path $PSScriptRoot "Invoke-SwitchDiscovery.ps1" + if (-not (Test-Path $script)) { + Write-Host " [-] Invoke-SwitchDiscovery.ps1 bulunamadi: $script" -ForegroundColor Red + Read-Host " Enter"; return + } + & $script ` + -IPRange $c.IPRange ` + -Username $c.Username ` + -Password $c.Password ` + -SNMPCommunity $c.SNMPCommunity ` + -SNMPVersion $c.SNMPVersion ` + -Method $c.Method ` + -OutputPath $c.OutputPath ` + -MaxThreads $c.MaxThreads ` + -SSHPort $c.SSHPort ` + -Timeout $c.Timeout + Read-Host "`n Menuye donmek icin Enter" +} + +# === ANA DONGU =========================================================== +$cfg = Load-Config +while ($true) { + Write-Banner + Write-Menu -c $cfg + Write-Host " Seciminiz: " -ForegroundColor White -NoNewline + $ch = Read-Host + switch ($ch.Trim().ToUpper()) { + "1" { Start-Discovery $cfg } + "2" { Set-IPRange $cfg; Save-Config $cfg } + "3" { Set-SSH $cfg; Save-Config $cfg } + "4" { Set-SNMP $cfg; Save-Config $cfg } + "5" { Set-Advanced $cfg; Save-Config $cfg } + "6" { Set-Method $cfg; Save-Config $cfg } + "7" { Manage-Profiles $cfg } + "8" { Install-Deps } + "Q" { Write-Host "`n Gule gule!`n" -ForegroundColor Cyan; exit 0 } + default { Write-Host " [!] Gecersiz secim" -ForegroundColor Red; Start-Sleep 1 } + } +} diff --git a/lib/README.txt b/lib/README.txt new file mode 100644 index 0000000..13e4a4a --- /dev/null +++ b/lib/README.txt @@ -0,0 +1 @@ +SharpSnmpLib.dll dosyasini buraya kopyalayin diff --git a/lib/SharpSnmpLib.dll b/lib/SharpSnmpLib.dll new file mode 100644 index 0000000000000000000000000000000000000000..8423afe9f3a30ec26c623557fa48c189390c4ccc GIT binary patch literal 169280 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 QjFriUQ$f3_<0&EjA7X}Vz5oCK literal 0 HcmV?d00001 diff --git a/lib/SharpSnmpLib.xml b/lib/SharpSnmpLib.xml new file mode 100644 index 0000000..abde6ec --- /dev/null +++ b/lib/SharpSnmpLib.xml @@ -0,0 +1,6541 @@ + + + + SharpSnmpLib + + + + + Helper utility that performs data conversions from/to bytes. + + + + + Converts decimal string to bytes. + + The decimal string. + The converted bytes. + " 16 18 " is converted to new byte[] { 0x10, 0x12 }. + + + + Converts the byte string to bytes. + + The HEX string. + The converted bytes. + "80 00" is converted to new byte[] { 0x80, 0x00 }. + + + + Converts bytes to a byte string. + + The bytes. + The formatted string. + new byte[] { 0x80, 0x00 } is converted to "80 00". + + + + Packs parts into a single message body. + + Message length. + Message version. + Header. + Security parameters. + Scope data. + The object that represents the message body. + + + + Counter32 type. + + + + + Creates a instance from raw bytes. + + + + + + Creates a with a specific . + + Value + + + + Initializes a new instance of the class. + + The value. + + + + Creates a instance from stream. + + The length. + The stream. + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Returns a that represents a . + + A uint that represents the current object. + + + + Returns a that represents this . + + A string that represents the current object. + + + + Gets that raw bytes. + + + + + + Indicates whether the current object is equal to another object of the same type. + + An object to compare with this object. + true if the current object is equal to the parameter; otherwise, false. + + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + true if the specified is equal to the current ; otherwise, false. + + + + + Serves as a hash function for a particular type. + + A hash code for the current . + + + + The equality operator. + + Left object + Right object + + Returns true if the values of its operands are equal, false otherwise. + + + + The inequality operator. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + The comparison. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + Counter64 type. + + + + + Creates a instance from raw bytes. + + + + + + Creates a with a specific . + + Value + + + + Initializes a new instance of the class. + + The length. + The stream. + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Returns a that represents a . + + A that represents a . + + + + Returns a that represents this . + + A that represents this . + + + + Gets that raw bytes. + + + + + + Indicates whether the current object is equal to another object of the same type. + + An object to compare with this object. + true if the current object is equal to the parameter; otherwise, false. + + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + true if the specified is equal to the current ; otherwise, false. + + + + + Serves as a hash function for a particular type. + + A hash code for the current . + + + + The equality operator. + + Left object + Right object + + Returns true if the values of its operands are equal, false otherwise. + + + + The inequality operator. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + The comparison. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + Factory that creates instances. + + + + + Creates an instance from buffer. + + Buffer + An instance created from the specified buffer. + + + + Creates an instance from stream. + + Stream. + Type code. + An instance created from the specified stream and type code. + + + + Creates an instance from buffer. + + Buffer + Index + Count + An instance created from the specified buffer, index, and count. + + + + Creates an instance from stream. + + Stream + An instance created from the specified stream. + + + + EndOfMibView exception. + + + + + Initializes a new instance of the class. + + The length data. + The stream. + + + + Initializes a new instance of the class. + + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + true if the specified is equal to the current ; otherwise, false. + + + + + Indicates whether the current object is equal to another object of the same type. + + An object to compare with this object. + true if the current object is equal to the parameter; otherwise, false. + + + + + Serves as a hash function for a particular type. + + A hash code for the current . + + + + The equality operator. + + Left object + Right object + + Returns true if the values of its operands are equal, false otherwise. + + + + The inequality operator. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Returns a that represents this . + + A that represents this . + + + + The comparison. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + Error code for SNMP operations. (0-5 are first defined in SNMP v1, and others are added in v2) + + + + + There was no problem performing the request. + + + + + The response to your request was too big to fit into one response. + + + + + An agent was asked to get or set an OID that it can't find; i.e., the OID doesn't exist. + + + + + A read-write or write-only object was set to an inconsistent value. + + + + + This error is generally not used. The noSuchName error is equivalent to this one. + + + + + This is a catch-all error. If an error occurs for which none of the previous messages is appropriate, a genError is issued. + + + + + A set to an inaccessible variable was attempted. This typically occurs when the variable has an ACCESS type of not-accessible. + + + + + An object was set to a type that is different from its definition. This error will occur if you try to set an object that is of type INTEGER to a string, for example. + + + + + An object's value was set to something other than what it calls for. For instance, a string can be defined to have a maximum character size. This error occurs if you try to set a string object to a value that exceeds its maximum length. + + + + + A set operation was attempted using the wrong encoding for the object being set. + + + + + A variable was set to a value it doesn't understand. This can occur when a read-write is defined as an enumeration, and you try to set it to a value that is not one of the enumerated types. + + + + + You tried to set a nonexistent variable or create a variable that doesn't exist in the MIB. + + + + + A MIB variable is in an inconsistent state, and is not accepting any set requests. + + + + + No system resources are available to perform a set. + + + + + This is a catch-all error for set failures. + + + + + A set failed and the agent was unable to roll back all the previous sets up until the point of failure. + + + + + An SNMP command could not be authenticated; in other words, someone has supplied an incorrect community string. + + + + + A variable will not accept a set, even though it is supposed to. + + + + + You attempted to set a variable, but that attempt failed because the variable was in some kind of inconsistent state. + + + + + Gauge32 type. + + + + + Creates a instance from raw bytes. + + + + + + Creates a with a specific . + + Value + + + + Initializes a new instance of the class. + + The value. + + + + Initializes a new instance of the class. + + The length. + The stream. + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Returns a that represents a . + + A that represents a . + + + + Returns a that represents this . + + A that represents this . + + + + Indicates whether the current object is equal to another object of the same type. + + An object to compare with this object. + true if the current object is equal to the parameter; otherwise, false. + + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + true if the specified is equal to the current ; otherwise, false. + + + + + Serves as a hash function for a particular type. + + A hash code for the current . + + + + The equality operator. + + Left object + Right object + + Returns true if the values of its operands are equal, false otherwise. + + + + The inequality operator. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + The comparison. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + Generic trap code. + + + + + Indicates that the agent has rebooted. All management variables will be reset; specifically, Counters and Gauges will be reset to zero (0). One nice thing about the coldStart trap is that it can be used to determine when new hardware is added to the network. When a device is powered on, it sends this trap to its trap destination. If the trap destination is set correctly (i.e., to the IP address of your NMS) the NMS can receive the trap and determine whether it needs to manage the device. + + + + + Indicates that the agent has reinitialized itself. None of the management variables will be reset. + + + + + Sent when an interface on a device goes down. The first variable binding identifies which interface went down. + + + + + Sent when an interface on a device comes back up. The first variable binding identifies which interface came back up. + + + + + Indicates that someone has tried to query your agent with an incorrect community string; useful in determining if someone is trying to gain unauthorized access to one of your devices. + + + + + Indicates that an Exterior Gateway Protocol (EGP) neighbor has gone down. + + + + + Indicates that the trap is enterprise-specific. SNMP vendors and users define their own traps under the private-enterprise branch of the SMI object tree. To process this trap properly, the NMS has to decode the specific trap number that is part of the SNMP message. + + + + + GETBULK request PDU. + + + + + Creates a with all contents. + + The request id. + Non-repeaters. + Max repetitions. + Variables. + + + + Initializes a new instance of the class. + + The length data. + The stream. + + + + Gets the request ID. + + The request ID. + + + + Gets the error status. + + The error status. + + + + Gets the index of the error. + + The index of the error. + + + + Variables. + + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Returns a that represents this . + + A that represents this . + + + + GETNEXT request PDU. + + + + + Creates a with all contents. + + The request id. + Variables + + + + Initializes a new instance of the class. + + The length data. + The stream. + + + + Gets the request ID. + + The request ID. + + + + Gets the error status. + + The error status. + + + + Gets the index of the error. + + The index of the error. + + + + Variables. + + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Returns a that represents this . + + A that represents this . + + + + GET request PDU. + + + + + Creates a with all contents. + + The request id. + Variables + + + + Initializes a new instance of the class. + + The length data. + The stream. + + + + Gets the request ID. + + The request ID. + + + + Gets the error status. + + The error status. + + + + Gets the index of the error. + + The index of the error. + + + + Variables. + + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Returns a that represents this . + + A that represents this . + + + + Header segment. + + + + + Max message size used in #SNMP. + + + You can use any value for your own application. + Also this value may be changed in #SNMP in future releases. + + + + + Initializes a new instance of the class. + + The message identifier. + + + + Initializes a new instance of the class. + + The data. + + + + Initializes a new instance of the class. + + The message id. + Size of the max message. + The security level. + If you want an empty header, please use . + + + + Empty header. + + + + + Security flags. + + + + + Gets the message ID. + + The message ID. + + + + Converts to object. + + + The object. + + + + + Gets the data. + + The version. + + The object. + + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Gets or sets the size of the max. + + The size of the max. + + + + Class Helper. + + + + + Converts to . + + The object. + The object. + + + + Converts to . + + The object that holds the address. + The object. + length is not equal to 6. + + + + INFORM request PDU. + + + + + Creates a instance with all content. + + The request id. + Enterprise + Time stamp + Variables + + + + Creates a instance for discovery. + + The request id. + + + + Initializes a new instance of the class. + + The length data. + The stream. + + + + Gets the request ID. + + The request ID. + + + + Gets the error status. + + The error status. + + + + Gets the index of the error. + + The index of the error. + + + + Variables. + + + + + Type code. + + + + + Gets the enterprise. + + The enterprise. + + + + Gets the time stamp. + + The time stamp. + + + + Appends the bytes to . + + The stream. + + + + Returns a that represents this . + + A that represents this . + + + + Decorates a list of objects with time and enterprise ID. + + The variables. + Decorated list. + + + + Integer32 type in SMIv2 (or INTEGER in SMIv1). + + + + + Zero. + + + + + Creates an instance. + + Raw bytes + + + + Creates an instance with a specific . + + Value + + + + Initializes a new instance of the class. + + The length. + The stream. + + + + Returns an that represents this . + + + An that represents this . + + + + + Converts to . + + + An that represents this . + + + + + Returns a that represents this . + + + A that represents this . + + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Serves as a hash function for a particular type. + + A hash code for the current . + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + true if the specified is equal to the current ; otherwise, false. + + + + + Indicates whether the current object is equal to another object of the same type. + + An object to compare with this object. + true if the current object is equal to the parameter; otherwise, false. + + + + + The equality operator. + + Left object + Right object + + Returns true if the values of its operands are equal, false otherwise. + + + + The inequality operator. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + The comparison. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + IPAddress type. + + + + + Initializes a new instance of the class. + + The IP bytes. + is null. + + + + Creates a new instance of the class from a specific . + + IP string + + + + Initializes a new instance of the class. + + The length. + The stream. + + + + Gets the raw bytes. + + System.Byte[]. + + + + Returns a that represents this . + + A that represents this . + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + true if the specified is equal to the current ; otherwise, false. + + + + + Indicates whether the current object is equal to another object of the same type. + + An object to compare with this object. + true if the current object is equal to the parameter; otherwise, false. + + + + + Serves as a hash function for a particular type. + + A hash code for the current . + + + + The equality operator. + + Left object + Right object + + Returns true if the values of its operands are equal, false otherwise. + + + + The inequality operator. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + The comparison. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + Segment interface. + + + + + Gets the data. + + The version. + + The data, or null if not available. + + + + Converts to object. + + + A object representing this segment. + + + + SNMP data entity. + + + + + Type code + + + + + Appends the bytes to . + + The stream. + + + + Returns a that represents this object. + + + A that represents this object. + + + + SNMP PDU. + + + + + Gets the request ID. + + The request ID. + + + + Gets the error status. + + The error status. + + + + Gets the index of the error. + + The index of the error. + + + + Variable bindings. + + + + + Security level. + + + + + Authentication flag. + + + + + Privacy flag. + + + + + Reportable flag. + + + + + Malformed PDU class. Many things are not implemented as they are not in use. + + + + + Type code. + + Returns unknown type. + + + + Appends the bytes to . + + The stream. + + + + Gets the request ID. + + The request ID. + + + + Gets the error status. + + The error status. + + + + Gets the index of the error. + + The index of the error. + + + + Variable bindings. + + Returns an empty list. + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Event arguments for agent found event. + + + + + Gets the agent. + + The agent. + + + + Gets the variable. + + The variable. + If the agent is SNMP v3, this is null. + + + + Initializes a new instance of the class. + + The agent. + The variable. + + + + Discoverer class to discover SNMP agents in the same network. + + + Discoverer class to discover SNMP agents in the same network. + + + + + Occurs when an SNMP agent is found. + + + + + Occurs when an exception is raised. + + The exception is typical here. + + + + Discovers agents of the specified version in a specific time interval. + + The version. + The broadcast address. + The community. + The discovering time interval, in milliseconds. + must be configured to a valid multicast address when IPv6 is used. For example, "[ff02::1]:161" + + + + Discovers agents of the specified version in a specific time interval. + + The version. + The broadcast address. + The community. + The discovering time interval, in milliseconds. + must be an IPv4 address. IPv6 is not yet supported here. + + + + Discovers agents of the specified version in a specific time interval. + + The version. + The broadcast address. + The community. + The cancellation token. + must be an IPv4 address. IPv6 is not yet supported here. + + + + Discovers agents of the specified version in a specific time interval. + + The version. + The broadcast address. + The community. + The cancellation token. + must be an IPv4 address. IPv6 is not yet supported here. + + + + Discovery class that participates in SNMP v3 discovery process. + + + Discovery class that participates in SNMP v3 discovery process. + + + + + Initializes a new instance of the class. + + The request id. + The message id. + The max size of message. + + + + Initializes a new instance of the class. + + The request id. + The message id. + The max size of message. + Message type. + + + + Gets the response. + + The time-out value, in milliseconds. The default value is 0, which indicates an infinite time-out period. Specifying -1 also indicates an infinite time-out period. + The receiver. + + + + + Gets the response. + + The receiver. + + + + + Converts to the bytes. + + + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Gets the response. + + The receiver. + The cancellation token. + + + + + Extension methods for . + + + + + Gets the socket. + + The endpoint. + + + + + Error exception of #SNMP. Raised when an error message is received. + + + + + Message body. + + + + + Creates a instance. + + + + + Creates a instance with a specific . + + Message + + + + Creates a instance with a specific and an . + + Message + Inner exception + + + + Creates a instance. + + Info + Context + + + + + + + Details on error. + + + + + Creates a . + + Message. + Agent address. + Error message body. + + + + + Provides data for exception raised event. + + + + + Creates an . + + Exception. + + + + Exception. + + + + + GETBULK request message. + + + + + Creates a with all contents. + + The request ID. + Protocol version. + Community name. + Non-repeaters. + Max repetitions. + Variables. + + + + Creates a with a specific . + + The version. + The message id. + The request id. + Name of the user. + The non repeaters. + The max repetitions. + The variables. + The privacy provider. + The report. + + + + Creates a with a specific . + + The version. + The message id. + The request id. + Name of the user. + Context name. + The non repeaters. + The max repetitions. + The variables. + The privacy provider. + Size of the max message. + The report. + + + + Creates a with a specific . + + The version. + The message id. + The request id. + Name of the user. + The non repeaters. + The max repetitions. + The variables. + The privacy provider. + Size of the max message. + The report. + + + + Gets the header. + + + + + Gets the privacy provider. + + The privacy provider. + + + + Converts to byte format. + + + + + + Gets the parameters. + + The parameters. + + + + Gets the scope. + + The scope. + + + + Gets the version. + + The version. + + + + Returns a that represents this . + + + + + + GETNEXT request message. + + + + + Creates a with all contents. + + The request id. + Protocol version + Community name + Variables + + + + Initializes a new instance of the class. + + The version. + The message id. + The request id. + Name of the user. + The variables. + The privacy provider. + The report. + + + + Initializes a new instance of the class. + + The version. + The message id. + The request id. + Name of the user. + Context name. + The variables. + The privacy provider. + Size of the max message. + The report. + + + + Initializes a new instance of the class. + + The version. + The message id. + The request id. + Name of the user. + The variables. + The privacy provider. + Size of the max message. + The report. + + + + Gets the header. + + + + + Gets the privacy provider. + + The privacy provider. + + + + Converts to byte format. + + + + + + Gets the parameters. + + The parameters. + + + + Gets the scope. + + The scope. + + + + Gets the version. + + The version. + + + + Returns a that represents this . + + + + + + GET request message. + + + + + Creates a with all contents. + + The request id. + Protocol version + Community name + Variables + + + + Initializes a new instance of the class. + + The version. + The message id. + The request id. + Name of the user. + The variables. + The privacy provider. + The report. + + + + Initializes a new instance of the class. + + The version. + The message id. + The request id. + Name of the user. + Context name. + The variables. + The privacy provider. + Size of the max message. + The report. + + + + Initializes a new instance of the class. + + The version. + The message id. + The request id. + Name of the user. + The variables. + The privacy provider. + Size of the max message. + The report. + + + + Gets the header. + + + + + Gets the privacy provider. + + The privacy provider. + + + + Version. + + + + + Converts to byte format. + + + + + + Gets the parameters. + + The parameters. + + + + Gets the scope. + + The scope. + + + + Returns a that represents this . + + + + + + INFORM request message. + + + + + Creates a with all contents. + + The request id. + Protocol version. + Community name. + Enterprise. + Time ticks. + Variables. + + + + Initializes a new instance of the class. + + The version. + The message id. + The request id. + Name of the user. + The enterprise. + The time. + The variables. + The privacy provider. + The report. + + + + Initializes a new instance of the class. + + The version. + The message id. + The request id. + Name of the user. + The enterprise. + The time. + The variables. + The privacy provider. + Size of the max message. + The report. + + + + Initializes a new instance of the class. + + The version. + The message id. + The request id. + Name of the user. + The context name. + The enterprise. + The time. + The variables. + The privacy provider. + Size of the max message. + The report. + + + + Gets the privacy provider. + + The privacy provider. + + + + Gets the version. + + The version. + + + + Gets the time stamp. + + The time stamp. + + + + Enterprise. + + + + + Gets the header. + + + + + Converts to byte format. + + + + + + Gets the parameters. + + The parameters. + + + + Gets the scope. + + The scope. + + + + Returns a that represents this . + + + + + + SNMP message. + + + + + Gets the header. + + + + + Gets the parameters. + + The parameters. + + + + Gets the scope. + + The scope. + + + + Converts to the bytes. + + + + + + Gets the version. + + The version. + + + + Gets the privacy provider. + + The privacy provider. + + + + Malformed message for v3 due to decryption failures or wrong user names. + + + + + Initializes a new instance of the class. + + The message id. + The user. + The data encrypted. + + + + Encrypted scope data. + + The original scope data from packet, which remains encrypted. + + + + Gets the parameters. + + The parameters. + + + + Gets the scope. + + The fake scope, which is used to avoid exceptions in message handling. + + + + Gets the header. + + + + + Converts to the bytes. + + + + + + Gets the version. + + The version. + + + + Gets the privacy provider. + + The privacy provider. + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Factory that creates instances from byte format. + + + + + Creates instances from a string. + + Byte string. + The registry. + + + + + Creates instances from buffer. + + Buffer. + The registry. + + + + + Creates instances from buffer. + + Buffer. + The index. + The length. + The registry. + + + + + Message factory exception. + + + + + Creates a . + + + + + Creates a instance with a specific . + + Message + + + + Creates a instance with a specific and an . + + Message + Inner exception + + + + Creates a instance. + + Info + Context + + + + + + + Gets the bytes. + + + + + Sets the bytes. + + Bytes. + + + + Returns a that represents this . + + + + + + Messenger class contains all static helper methods you need to send out SNMP messages. + Static methods in Manager or Agent class will be removed in the future. + + + SNMP v3 is not supported in many methods of this class. Please use derived classes directly + if you want to do v3 operations. + + + Messenger class contains all static helper methods you need to send out SNMP messages. + Static methods in Manager or Agent class will be removed in the future. + + + SNMP v3 is not supported in many methods of this class. Please use derived classes directly + if you want to do v3 operations. + + + + + RFC 3416 (3.) + + + + + The universal counter for request IDs and other IDs. + + + + + A flag to control request ID range. + + Default is true. + Should be set to false when SNMP devices might not support negative request ID values. + + + + + RFC 3412 (6.) + + + + + Gets a list of variable binds. + + Protocol version. + Endpoint. + Community name. + Variable binds. + + + + + Sets a list of variable binds. + + Protocol version. + Endpoint. + Community name. + Variable binds. + + + + + Walks (based on GET NEXT). + + Protocol version. + Endpoint. + Community name. + OID. + A list to hold the results. + Walk mode. + + Returns row count if the OID is a table. Otherwise this value is meaningless. + + This method only supports SNMP v1 and v2c. + + + + Determines whether the specified seed has next item. + + The version. + The endpoint. + The community. + The seed. + + true if the specified seed has next item; otherwise, false. + + This method only supports SNMP v1 and v2c. + + + + Walks (based on GET BULK). + + Protocol version. + Endpoint. + Community name (v2c) or user name (v3). + Context name. + OID. + A list to hold the results. + The max repetitions. + Walk mode. + The privacy provider. + The report. + Returns row count if the OID is a table. Otherwise this value is meaningless. + This method only supports SNMP v2c and v3. + + + + Sends a TRAP v1 message. + + Receiver. + Agent. + Community name. + Enterprise OID. + Generic code. + Specific code. + Timestamp. + Variable bindings. + This method only supports SNMP v1. + + + + Sends TRAP v2 message. + + Protocol version. + Receiver. + Community name. + Enterprise OID. + Timestamp. + Variable bindings. + Request ID. + This method only supports SNMP v2c. + + + + Sends INFORM message. + + The request ID. + Protocol version. + Receiver. + Community name. + Context name. + Enterprise OID. + Timestamp. + Variable bindings. + The privacy provider. + The report. + This method supports SNMP v2c and v3. + + + + Determines whether the specified seed has next item. + + The version. + The receiver. + The community name (v2c) or user name (v3). + The context name. + The seed. + The max repetitions. + The privacy provider. + The report. + + true if the specified seed has next item; otherwise, false. + + This method supports SNMP v2c and v3. + + + + Gets a list of variable binds. + + Protocol version. + Endpoint. + Community name. + Variable binds. + The time-out value, in milliseconds. The default value is 0, which indicates an infinite time-out period. Specifying -1 also indicates an infinite time-out period. + + This method supports SNMP v1 and v2c. + + + + Sets a list of variable binds. + + Protocol version. + Endpoint. + Community name. + Variable binds. + The time-out value, in milliseconds. The default value is 0, which indicates an infinite time-out period. Specifying -1 also indicates an infinite time-out period. + + This method supports SNMP v1 and v2c. + + + + Walks (based on GET NEXT). + + Protocol version. + Endpoint. + Community name. + OID. + A list to hold the results. + The time-out value, in milliseconds. The default value is 0, which indicates an infinite time-out period. Specifying -1 also indicates an infinite time-out period. + Walk mode. + + Returns row count if the OID is a table. Otherwise this value is meaningless. + + This method supports SNMP v1 and v2c. + + + + Determines whether the specified seed has next item. + + The version. + The endpoint. + The community. + The seed. + The time-out value, in milliseconds. The default value is 0, which indicates an infinite time-out period. Specifying -1 also indicates an infinite time-out period. + The next. + + true if the specified seed has next item; otherwise, false. + + This method supports SNMP v1 and v2c. + + + + Walks (based on GET BULK). + + Protocol version. + Endpoint. + Community name (v2c) or user name (v3). + Context name. + OID. + A list to hold the results. + The time-out value, in milliseconds. The default value is 0, which indicates an infinite time-out period. Specifying -1 also indicates an infinite time-out period. + The max repetitions. + Walk mode. + The privacy provider. + The report. + Returns row count if the OID is a table. Otherwise this value is meaningless. + This method supports SNMP v2c and v3. + + + + Sends a TRAP v1 message. + + Receiver. + Agent. + Community name. + Enterprise OID. + Generic code. + Specific code. + Timestamp. + Variable bindings. + This method supports SNMP v1. + + + + Sends TRAP v2 message. + + Protocol version. + Receiver. + Community name. + Enterprise OID. + Timestamp. + Variable bindings. + Request ID. + This method supports SNMP v2c. + + + + Sends INFORM message. + + The request ID. + Protocol version. + Receiver. + Community name (v2c) or user name (v3). + Context name. + Enterprise OID. + Timestamp. + Variable bindings. + The time-out value, in milliseconds. The default value is 0, which indicates an infinite time-out period. Specifying -1 also indicates an infinite time-out period. + The privacy provider. + The report. + This method supports SNMP v2c and v3. + + + + Determines whether the specified seed has next item. + + The version. + The receiver. + The community name (v2c) or user name (v3). + The context name. + The seed. + The time-out value, in milliseconds. The default value is 0, which indicates an infinite time-out period. Specifying -1 also indicates an infinite time-out period. + The max repetitions. + The next. + The privacy provider. + The report. + + true if the specified seed has next item; otherwise, false. + + This method supports SNMP v2c and v3. + + + + Gets a table of variables. + + Protocol version. + Endpoint. + Community name. + Table OID. + The time-out value, in milliseconds. The default value is 0, which indicates an infinite time-out period. Specifying -1 also indicates an infinite time-out period. + The max repetitions. + + This method supports SNMP v2c and v3. + + + + Gets the request counter. + + The request counter. + + + + Gets the message counter. + + The message counter. + + + + Max message size used in #SNMP. + + + You can use any value for your own application. + Also this value may be changed in #SNMP in future releases. + + + + + If the privacy module returns failure, then the message can + not be processed, so the usmStatsDecryptionErrors counter is + incremented and an error indication (decryptionError) together + with the OID and value of the incremented counter is returned + to the calling module. + + + + + If the authentication module returns failure, then the message + cannot be trusted, so the usmStatsWrongDigests counter is + incremented and an error indication (authenticationFailure) + together with the OID and value of the incremented counter is + returned to the calling module. + + + + + If the value of the msgAuthoritativeEngineID field in the + securityParameters is unknown then + the usmStatsUnknownEngineIDs counter is incremented, and an + error indication (unknownEngineID) together with the OID and + value of the incremented counter is returned to the calling + module. + + + + + Information about the value of the msgUserName and + msgAuthoritativeEngineID fields is extracted from the Local + Configuration Datastore (LCD, usmUserTable). If no information + is available for the user, then the usmStatsUnknownUserNames + counter is incremented and an error indication + (unknownSecurityName) together with the OID and value of the + incremented counter is returned to the calling module. + + + + + If the message is considered to be outside of the Time Window + then the usmStatsNotInTimeWindows counter is incremented and + an error indication (notInTimeWindow) together with the OID, + the value of the incremented counter, and an indication that + the error must be reported with a securityLevel of authNoPriv, + is returned to the calling module + + + + + If the information about the user indicates that it does not + support the securityLevel requested by the caller, then the + usmStatsUnsupportedSecLevels counter is incremented and an error + indication (unsupportedSecurityLevel) together with the OID and + value of the incremented counter is returned to the calling + module. + + + + + Returns a new discovery request. + + Message type. + + + + + Returns error message for the specific . + + The OID. + Error message. + + + + Gets a list of variable binds. + + Protocol version. + Endpoint. + Community name. + Variable binds. + The cancellation token. + + + + + Sets a list of variable binds. + + Protocol version. + Endpoint. + Community name. + Variable binds. + The cancellation token. + + + + + Walks (based on GET NEXT). + + Protocol version. + Endpoint. + Community name. + OID. + A list to hold the results. + Walk mode. + The cancellation token. + + Returns row count if the OID is a table. Otherwise this value is meaningless. + + This method only supports SNMP v1 and v2c. + + + + Determines whether the specified seed has next item. + + The version. + The endpoint. + The community. + The seed. + The cancellation token. + + true if the specified seed has next item; otherwise, false. + + This method only supports SNMP v1 and v2c. + + + + Walks (based on GET BULK). + + Protocol version. + Endpoint. + Community name (v2c) or user name (v3). + Context name. + OID. + A list to hold the results. + The max repetitions. + Walk mode. + The privacy provider. + The report. + The cancellation token. + Returns row count if the OID is a table. Otherwise this value is meaningless. + This method only supports SNMP v2c and v3. + + + + Sends a TRAP v1 message. + + Receiver. + Agent. + Community name. + Enterprise OID. + Generic code. + Specific code. + Timestamp. + Variable bindings. + The cancellation token. + This method only supports SNMP v1. + + + + Sends TRAP v2 message. + + Protocol version. + Receiver. + Community name. + Enterprise OID. + Timestamp. + Variable bindings. + Request ID. + The cancellation token. + This method only supports SNMP v2c. + + + + Sends INFORM message. + + The request ID. + Protocol version. + Receiver. + Community name. + Context name. + Enterprise OID. + Timestamp. + Variable bindings. + The privacy provider. + The report. + The cancellation token. + This method supports SNMP v2c and v3. + + + + Determines whether the specified seed has next item. + + The version. + The receiver. + The community name (v2c) or user name (v3). + The context name. + The seed. + The max repetitions. + The privacy provider. + The report. + The cancellation token. + + true if the specified seed has next item; otherwise, false. + + This method supports SNMP v2c and v3. + + + + Extension methods for . + + + Extension methods for . + + + + + Sends an . + + The . + Manager + The cancellation token. + + + + Sends an . + + The . + Manager + The socket. + The cancellation token. + + + + Sends this and handles the response from agent. + + The . + Port number. + User registry. + The cancellation token. + + + + + Sends this and handles the response from agent. + + The . + Port number. + The cancellation token. + + + + + Sends this and handles the response from agent. + + The . + Agent. + The UDP to use to send/receive. + The cancellation token. + + + + + Sends an and handles the response from agent. + + The . + Agent. + The UDP to use to send/receive. + The user registry. + The cancellation token. + + + + + Gets the . + + The . + + + + + Variables. + + The . + + + + Request ID. + + The . + + + + Gets the message ID. + + The message ID. + The . + For v3, message ID is different from request ID. For v1 and v2c, they are the same. + + + + PDU. + + The . + + + + Community name. + + The . + + + + Sends an . + + The . + Manager + + + + Sends an . + + The . + Manager + The socket. + + + + Sends this and handles the response from agent. + + The . + The time-out value, in milliseconds. The default value is 0, which indicates an infinite time-out period. Specifying -1 also indicates an infinite time-out period. + Port number. + User registry. + + + + + Sends this and handles the response from agent. + + The . + The time-out value, in milliseconds. The default value is 0, which indicates an infinite time-out period. Specifying -1 also indicates an infinite time-out period. + Port number. + + + + + Sends this and handles the response from agent. + + The . + The time-out value, in milliseconds. The default value is 0, which indicates an infinite time-out period. Specifying -1 also indicates an infinite time-out period. + Agent. + The UDP to use to send/receive. + + + + + Sends an and handles the response from agent. + + The . + The time-out value, in milliseconds. The default value is 0, which indicates an infinite time-out period. Specifying -1 also indicates an infinite time-out period. + Agent. + The UDP to use to send/receive. + The user registry. + + + + + Sends an . + + The . + Manager + + + + Sends an . + + The . + Manager + The socket. + + + + Sends this and handles the response from agent. + + The . + Port number. + User registry. + + + + + Sends this and handles the response from agent. + + The . + Port number. + + + + + Sends this and handles the response from agent. + + The . + Agent. + The UDP to use to send/receive. + + + + + Sends an and handles the response from agent. + + The . + Agent. + The UDP to use to send/receive. + The user registry. + + + + + Tests if running on Mono. + + + + + + Gets a value indicating whether it is + running on Windows. + + true if is running on Windows; otherwise, false. + + + + Gets a value indicating whether it is running on macOS. + + true if is running on macOS; otherwise, false. + + + + Gets a value indicating whether it is running on iOS. + + true if is running on iOS; otherwise, false. + + + + Packs up the . + + The . + The length bytes. + + + + + A counter that generates ID. + + The request ID is used to identifier sessions. + + + + Initializes a new instance of the class. + + The min. + The max. + + + + Returns next ID. This method is thread-safe within this instance of NumberGenerator. + + + + + Exception raised when an IP endpoint is already in use. + + + + + Creates a . + + + + + Creates a instance with a specific . + + Message + + + + Creates a instance with a specific and an . + + Message + Inner exception + + + + Creates a instance. + + Info + Context + + + + + + + The endpoint already in use. + + + + + Returns a that represents this . + + + + + + REPORT message. + + + + + Initializes a new instance of the class. + + The version code. + The header. + The security parameters. + The scope. + The privacy provider. + The length bytes. + + + + Gets the header. + + + + + Security parameters. + + + + + Gets the scope. + + The scope. + + + + Gets the version. + + The version. + + + + Converts to byte format. + + + + + + Gets the privacy provider. + + The privacy provider. + + + + Returns a that represents this . + + + + + + Response message. + + + + + Creates a with all contents. + + Request ID. + Protocol version. + Community name. + Error code. + Error index. + Variables. + + + + Initializes a new instance of the class. + + The version. + The header. + The parameters. + The scope. + The privacy provider. + if set to true, authentication is needed. + The length bytes. + + + + Gets the header. + + + + + Gets the privacy provider. + + The privacy provider. + + + + Error status. + + + + + Error index. + + + + + Gets the version. + + The version. + + + + Gets the parameters. + + The parameters. + + + + Gets the scope. + + The scope. + + + + Converts to byte format. + + + + + + Returns a that represents this . + + + + + + SET request message. + + + + + Creates a with all contents. + + The request id. + Protocol version + Community name + Variables + + + + Initializes a new instance of the class. + + The version. + The message id. + The request id. + Name of the user. + The variables. + The privacy provider. + The report. + + + + Initializes a new instance of the class. + + The version. + The message id. + The request id. + Name of the user. + The context name. + The variables. + The privacy provider. + Size of the max message. + The report. + + + + Initializes a new instance of the class. + + The version. + The message id. + The request id. + Name of the user. + The variables. + The privacy provider. + Size of the max message. + The report. + + + + Gets the header. + + + + + Gets the privacy provider. + + The privacy provider. + + + + Returns a that represents this . + + + + + + Converts to byte format. + + + + + + Gets the parameters. + + The parameters. + + + + Gets the scope. + + The scope. + + + + Gets the version. + + The version. + + + + Timeout exception type of #SNMP. + + + + + The time-out value, in milliseconds. The default value is 0, which indicates an infinite time-out period. Specifying -1 also indicates an infinite time-out period. + + + + + Creates a instance. + + + + + Creates a instance with a specific . + + Message + + + + Creates a instance with a specific and an instance. + + Message + Inner exception + + + + Creates a instance. + + Info + Context + + + + + + + Returns a that represents this . + + + + + + Creates a . + + Agent address + Timeout + + + + + Trap message. + + + + + Creates a with all content. + + Protocol version + Agent address + Community name + Enterprise + Generic + Specific + Time + Variables + + + + Creates a instance with a message body. + + Message body + + + + Time stamp. + + + + + Community name. + + + + + Enterprise. + + + + + Agent address. + + + + + Generic type. + + + + + Specific type. + + + + + Protocol version. + + + + + Gets the header. + + + + + Gets the privacy provider. + + + + + To byte format. + + + + + + Gets the parameters. + + The parameters. + returns null here. + + + + Gets the scope. + + The scope. + returns null here. + + + + Returns a that represents the current . + + + + + + Packs the message. + + The version. + The data. + + + + + TRAP v2 message. + + + + + Creates a instance with all content. + + Version code. + Community. + Enterprise. + Time stamp. + Variables. + Request ID. + + + + Initializes a new instance of the class. + + The version. + The message id. + The request id. + Name of the user. + The enterprise. + The time. + The variables. + The privacy. + Size of the max message. + The engine ID. + The engine boots. + The engine time. + + + + Initializes a new instance of the class. + + The version. + The message id. + The request id. + Name of the user. + The enterprise. + The time. + The variables. + The privacy. + Size of the max message. + The engine ID. + The engine boots. + The engine time. + The context engine ID. + The context name. + + + + Gets the header. + + + + + Gets the privacy provider. + + The privacy provider. + + + + Gets the parameters. + + The parameters. + + + + Gets the scope. + + The scope. + + + + Converts to byte format. + + + + + + Enterprise. + + + + + Time stamp. + + + + + Gets the version. + + The version. + + + + Returns a that represents the current . + + + + + + Walk mode. + + + + + Default mode walk to the end of MIB view. + + + + + In this mode, walk within sub-tree. + + + + + NoSuchInstance exception. + + + + + Initializes a new instance of the class. + + The length data. + The stream. + + + + Initializes a new instance of the class. + + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + true if the specified is equal to the current ; otherwise, false. + + + + + Indicates whether the current object is equal to another object of the same type. + + An object to compare with this object. + true if the current object is equal to the parameter; otherwise, false. + + + + + Serves as a hash function for a particular type. + + A hash code for the current . + + + + The equality operator. + + Left object + Right object + + Returns true if the values of its operands are equal, false otherwise. + + + + The inequality operator. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Returns a that represents this . + + A that represents this . + + + + The comparison. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + NoSuchObject exception. + + + + + Initializes a new instance of the class. + + The length data. + The stream. + + + + Initializes a new instance of the class. + + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + true if the specified is equal to the current ; otherwise, false. + + + + + Indicates whether the current object is equal to another object of the same type. + + An object to compare with this object. + true if the current object is equal to the parameter; otherwise, false. + + + + + Serves as a hash function for a particular type. + + A hash code for the current . + + + + The equality operator. + + Left object + Right object + + Returns true if the values of its operands are equal, false otherwise. + + + + The inequality operator. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Returns a that represents this . + + + A that represents this . + + + + The comparison. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + Null type. + + + + + Initializes a new instance of the class. + + The length data. + The stream. + + + + Initializes a new instance of the class. + + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + true if the specified is equal to the current ; otherwise, false. + + + + + Indicates whether the current object is equal to another object of the same type. + + An object to compare with this object. + true if the current object is equal to the parameter; otherwise, false. + + + + + Serves as a hash function for a particular type. + + A hash code for the current . + + + + The equality operator. + + Left object + Right object + + Returns true if the values of its operands are equal, false otherwise. + + + + The inequality operator. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + Returns a that represents this . + + + A that represents this . + + + + The comparison. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + ObjectIdentifier type. + + + + + Creates an instance from textual ID. + + String in this format, "*.*.*.*". + + + + Creates an instance from numerical ID. + + OID array + + + + Creates an instance from raw bytes. + + Raw bytes + + + + Initializes a new instance of the class. + + The length. + The stream. + + + + Converts to numerical ID. + + + + + + Compares the current object with another object of the same type. + + An object to compare with this object. + + A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has the following meanings: + Value + Meaning + Less than zero + This object is less than the parameter. + Zero + This object is equal to . + Greater than zero + This object is greater than . + + + + + Compares the current object with another object of the same type. + + An object to compare with this object. + + A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has the following meanings: + Value + Meaning + Less than zero + This object is less than the parameter. + Zero + This object is equal to . + Greater than zero + This object is greater than . + + + + + Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object. + + An object to compare with this instance. + + A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has these meanings: + Value + Meaning + Less than zero + This instance is less than . + Zero + This instance is equal to . + Greater than zero + This instance is greater than . + + + is not the same type as this instance. + + + + + Returns a that represents this . + + + + + + Converts unsigned integer array to dotted . + + + + + + + Converts dotted to unsigned integer array. + + Dotted string. + Unsigned integer array. + + + + Appends the bytes to . + + The stream. + + + + Type code. + + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + true if the specified is equal to the current ; otherwise, false. + + + + + Indicates whether the current object is equal to another object of the same type. + + An object to compare with this object. + true if the current object is equal to the parameter; otherwise, false. + + + + + Serves as a hash function for a particular type. + + A hash code for the current . + + + + The equality operator. + + Left object + Right object + + Returns true if the values of its operands are equal, false otherwise. + + + + The inequality operator. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + Implements the operator >. + + The left. + The right. + The result of the operator. + + + + Implements the operator >=. + + The left. + The right. + The result of the operator. + + + + Implements the operator <. + + The left. + The right. + The result of the operator. + + + + Implements the operator <=. + + The left. + The right. + The result of the operator. + + + + The comparison. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + Creates a new instance. + + The numerical. + The extra. + + + + + Appends an extra number to the array. + + The original array. + The extra. + + + + + The dedicated for the class. + + + + + Returns whether this converter can convert an object of the given type to the type of this converter. + + + + + + + + Returns whether this converter can convert the object to the specified type. + + + + + + + + Converts the given object to the type of this converter, using the specified context and culture information. + + + + + + + + + Converts the given value object to the specified type, using the arguments. + + + + + + + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + OctetString type. + + + + + Initializes a new instance of the class. + + The length. + The stream. + + + + Creates an from raw bytes. + + Raw bytes + + + + Creates an with a specific . This string is treated in specific . + + String. + Encoding. + + + + Creates an with a specific . This string is treated as UTF-16. + + String. + + + + Creates an with a specific . + + + + + + Encoding of this + + + + + Gets raw bytes. + + + + + + Gets the empty string. + + The empty. + + + + Returns a that represents this . + + + + + + Returns a in a hex form that represents this . + + + + + + Returns a in a specific that represents this . + + + + + + + Returns a in UTF-16 that represents this . + + + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Indicates whether the current object is equal to another object of the same type. + + An object to compare with this object. + true if the current object is equal to the parameter; otherwise, false. + + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + true if the specified is equal to the current ; otherwise, false. + + + + + Serves as a hash function for a particular type. + + A hash code for the current . + + + + The equality operator. + + Left object + Right object + + Returns true if the values of its operands are equal, false otherwise. + + + + The inequality operator. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + Converts octets to physical address. + + + + + + Default encoding of type. + + + + + The comparison. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + Indicates whether the specified object is a null reference (Nothing in Visual Basic) or an string. + + A reference. + true if the parameter is a null reference (Nothing in Visual Basic) or an empty string (""); otherwise, false. + + + + Opaque type. + + This type is obsolete. Use OctetString type instead. + + + + Creates an from raw bytes. + + Raw bytes + + + + Creates a instance from stream. + + The length. + The stream. + + + + Returns a that represents this . + + + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Gets the raw bytes. + + + + + + Indicates whether the current object is equal to another object of the same type. + + An object to compare with this object. + true if the current object is equal to the parameter; otherwise, false. + + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + true if the specified is equal to the current ; otherwise, false. + + + + + Serves as a hash function for a particular type. + + A hash code for the current . + + + + The equality operator. + + Left object + Right object + + Returns true if the values of its operands are equal, false otherwise. + + + + The inequality operator. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + The comparison. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + Operation exception of #SNMP. + + + + + Agent address. + + + + + Creates a instance. + + + + + Creates a instance with a specific . + + + + + + Creates a instance with a specific and an . + + + + + + + Creates a instance. + + Info + Context + + + + + + + Details on operation. + + + + + Creates a with a specific . + + Message + Agent address + + + + Report PDU. + + + + + Creates a with all contents. + + The request id. + Error status + Error index + Variables + + + + Initializes a new instance of the class. + + The length data. + The stream. + + + + Gets the request ID. + + The request ID. + + + + Gets the error status. + + The error status. + + + + Gets the index of the error. + + The index of the error. + + + + Variables. + + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Returns a that represents this . + + + + + + Response PDU. + + + + + Creates a with all contents. + + The request ID. + Error status. + Error index. + Variables. + + + + Initializes a new instance of the class. + + The length data. + The stream. + + + + Gets the request ID. + + The request ID. + + + + Error status. + + + + + Error index. + + + + + Variables. + + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Returns a that represents this / + + + + + + Scope segment. + + + + + Initializes a new instance of the class. + + The data. + + + + Initializes a new instance of the class. + + The context engine ID. + Name of the context. + The PDU. + + + + Initializes a new instance of the class. + + The PDU. + + + + Gets the PDU. + + The PDU. + + + + Gets the data. + + The version. + + + + + Gets or sets the name of the context. + + The name of the context. + + + + Gets or sets the context engine id. + + The context engine id. + + + + Converts to object. + + + + + + Description of SecurityParameters. + + + + + Gets the engine ID. + + The engine ID. + + + + Gets the boot count. + + The boot count. + + + + Gets the engine time. + + The engine time. + + + + Gets the user name. + + The user name. + + + + Gets the authentication parameters. + + The authentication parameters. + + + + Gets the privacy parameters. + + The privacy parameters. + + + + Initializes a new instance of the class. + + The that contains parameters. + + + + Initializes a new instance of the class. + + The engine ID. + The engine boots. + The engine time. + The user name. + The authentication parameters. + The privacy parameters. + Only cannot be null. + + + + Creates an instance of . + + User name. + + + + + Converts to . + + + + + + Gets the data. + + The version. + + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Gets a value that indicates whether the hashes are invalid. + + + + + Privacy provider for AES 192. + + + This is an experimental port from SNMP#NET project. As AES is not part of SNMP RFC, this class is provided as it is. + If you want other AES providers, you can port them from SNMP#NET in a similar manner. + + + + + Initializes a new instance of the class. + + The phrase. + The authentication provider. + + + + Returns a string that represents this object. + + + + + + Privacy provider for AES 256. + + + This is an experimental port from SNMP#NET project. As AES is not part of SNMP RFC, this class is provided as it is. + If you want other AES providers, you can port them from SNMP#NET in a similar manner. + + + + + Initializes a new instance of the class. + + The phrase. + The authentication provider. + + + + Returns a string that represents this object. + + + + + + Privacy provider for AES 128. + + +

This is an experimental port from SNMP#NET project.

+

The algorithm is defined in https://datatracker.ietf.org/doc/html/rfc3826

+
+
+ + + Initializes a new instance of the class. + + The phrase. + The authentication provider. + + + + Returns a string that represents this object. + + + + + + Privacy provider base for AES. + + + This is an experimental port from SNMP#NET project. As AES is not part of SNMP RFC, this class is provided as it is. + If you want other AES providers, you can port them from SNMP#NET in a similar manner. + + + + + Verifies if the provider is supported. + + + + + Flag to force using legacy encryption/decryption code on .NET 6. + + + + + Initializes a new instance of the class. + + Key bytes. + The phrase. + The authentication provider. + + + + Corresponding . + + + + + Engine IDs. + + This is an optional field, and only used by TRAP v2 authentication. + + + + Encrypt scoped PDU using AES encryption protocol + + Unencrypted scoped PDU byte array + Encryption key. Key has to be at least 32 bytes is length + Engine boots. + Engine time. + Privacy parameters out buffer. This field will be filled in with information + required to decrypt the information. Output length of this field is 8 bytes and space has to be reserved + in the USM header to store this information + Encrypted byte array + Thrown when encryption key is null or length of the encryption key is too short. + + + + Decrypt AES encrypted scoped PDU. + + Source data buffer + Engine boots. + Engine time. + Decryption key. Key length has to be 32 bytes in length or longer (bytes beyond 32 bytes are ignored). + Privacy parameters extracted from USM header + Decrypted byte array + Thrown when encrypted data is null or length == 0 + Thrown when encryption key length is less then 32 byte or if privacy parameters + argument is null or length other then 8 bytes + + + + Returns the length of privacyParameters USM header field. For AES, field length is 8. + + + + + Returns minimum encryption/decryption key length. For DES, returned value is 16. + + DES protocol itself requires an 8 byte key. Additional 8 bytes are used for generating the + encryption IV. For encryption itself, first 8 bytes of the key are used. + + + + + Return maximum encryption/decryption key length. For DES, returned value is 16 + + DES protocol itself requires an 8 byte key. Additional 8 bytes are used for generating the + encryption IV. For encryption itself, first 8 bytes of the key are used. + + + + + Decrypts the specified data. + + The data. + The parameters. + + + + + Encrypts the specified scope. + + The scope data. + The parameters. + + + + + Gets the salt. + + The salt. + + + + Gets the key bytes. + + The key bytes. + + + + Passwords to key. + + The secret. + The engine identifier. + + + + + Collection for improving performance. Using hashing of key/value pairs. + Oldest elements will be removed from the Cache when the capacity of the cache is reached. + This class is not thread safe. + + The type of the keys in the dictionary. + The type of the values in the dictionary. + + + + Gets the number of key/value pairs contained in the Cache. + + + + + Caching class for improving performance. Oldest elements are removed as the + cache is filled up + + Capacity of the cache before oldest elements start to get removed + + + + Gets the value associated with the specified key. + + The key of the value to get. + When this method returns, contains the value associated with the specified key, + if the key is found; otherwise, the default value for the type of the value parameter. + This parameter is passed uninitialized. + + true if the Cache contains an element with the specified key; otherwise, false. + + + + Determines whether the Cache contains the specified key. + + The key to locate in the Cache + true if the Cache contains an element with the specified key; otherwise, false. + + + + Gets the value associated with the specified key. + + The key of the value to get + key is null. + The property is retrieved and key does not exist in the collection. + The value associated with the specified key. + If the specified key is not found, a get operation throws a System.Collections.Generic.KeyNotFoundException, + and a set operation creates a new element with the specified key. + + + + Adds the specified key and value to the dictionary. If the cache has reached + its capacity oldest element will be removed automatically + + key is null + An element with the same key already exists in the Cache + The key of the element to add. + The value of the element to add. + + + + Removes oldest element from the cache + + + + + Checks whether cache size has reached the capacity + + True if reached capacity false otherwise + + + + Class for holding computed crypto values which are referenced by password/engineId combination + This class is not thread safe, it does not contain any static parameters. + + + + + Number of elements that Cache will hold before deleting old elements + + + + + Class for holding cached crypto keys computed values, since every password/engine id + combination will produce a different key this class is modeled using + Dictionary of Dictionaries. This class is not thread safe. + + + + + Cache to map engineId to keys + + + + + Default ctor initializes EngineIdCache + + Capacity of the cache + + + + Gets the cached value associated with the specified key. + + The engineId of the cached value to get. + + When this method returns, contains the cachedValue associated with the specified + engineId, if the engineId is found; otherwise, the default value for the type of the + cachedValue parameter. This parameter is passed uninitialized. + + True if the cache contains an element with the specified engineId; otherwise, false. + + + + Adds value to cache + + engine id associated with the value + value to cache + + + + Ctor + + + + + Get the cached value if it exists in the cache + + password associated with cached value + engine id associated with cached value + cached value, if no cache exists for specified password/engine id + combination default value is assigned to cachedValue + True if value exists in cache for specified password/engine id combination, false otherwise + + + + Adds computed value to the cache + + password to associate cached value with + engine id to associate cached value with + value being cached + + + + Converts an array of bytes into a string this way we can use + string.GetHashCode and string.Equals to allow the array of bytes + be the key in a hash table + + + + + + + Decryption exception. + + + + + Initializes a new instance of the class. + + + + + Creates a instance with a specific . + + Message + + + + Creates a instance with a specific and an . + + Message + Inner exception + + + + Creates a instance. + + Info + Context + + + + + + + Gets the bytes. + + + + + Sets the bytes. + + Bytes. + + + + Returns a that represents this . + + + + + + Default authentication provider. + + + + + Gets the instance. + + The instance. + + + + + + + Computes the hash. + + The buffer. + The engine identifier. + + + + + Gets the clean digest. + + The clean digest. + + + + + + + Gets the length of the digest. + + The length of the digest. + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Default privacy provider. + + + + + Default privacy provider with default authentication provider. + + + + + Initializes a new instance of the class. + + Authentication provider. + + + + Corresponding . + + + + + Engine IDs. + + This is an optional field, and only used by TRAP v2 authentication. + + + + Decrypts the specified data. + + The data. + The parameters. + + + + + Encrypts the specified scope. + + The scope data. + The parameters. + + + + + Gets the salt. + + The salt. + + + + Passwords to key. + + The secret. + The engine identifier. + + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Privacy provider for DES. + + Ported from SNMP#NET PrivacyDES class. + + + + Verifies if the provider is supported. + + + + + Flag to force using legacy encryption/decryption code on .NET 6. + + + + + Flag to force using old ECB cipher mode encryption. + + + + + Initializes a new instance of the class. + + The phrase. + The authentication provider. + + + + Corresponding . + + + + + Engine IDs. + + This is an optional field, and only used by TRAP v2 authentication. + + + + Encrypt scoped PDU using DES encryption protocol + + Unencrypted scoped PDU byte array + Encryption key. Key has to be at least 32 bytes is length + Privacy parameters out buffer. This field will be filled in with information + required to decrypt the information. Output length of this field is 8 bytes and space has to be reserved + in the USM header to store this information + Encrypted byte array + Thrown when encryption key is null or length of the encryption key is too short. + + + + Decrypt DES encrypted scoped PDU. + + Source data buffer + Decryption key. Key length has to be 32 bytes in length or longer (bytes beyond 32 bytes are ignored). + Privacy parameters extracted from USM header + Decrypted byte array + Thrown when encrypted data is null or length == 0 + Thrown when encryption key length is less then 32 byte or if privacy parameters + argument is null or length other then 8 bytes + + + + Generate IV from the privacy key and salt value returned by GetSalt method. + + 16 byte privacy key + Salt value returned by GetSalt method + IV value used in the encryption process + + + + Extract and return DES encryption key. + Privacy password is 16 bytes in length. Only the first 8 bytes are used as DES password. Remaining + 8 bytes are used as pre-IV value. + + 16 byte privacy password + 8 byte DES encryption password + + + + Returns the length of privacyParameters USM header field. For DES, field length is 8. + + + + + Returns minimum encryption/decryption key length. For DES, returned value is 16. + + DES protocol itself requires an 8 byte key. Additional 8 bytes are used for generating the + encryption IV. For encryption itself, first 8 bytes of the key are used. + + + + + Return maximum encryption/decryption key length. For DES, returned value is 16. + + DES protocol itself requires an 8 byte key. Additional 8 bytes are used for generating the + encryption IV. For encryption itself, first 8 bytes of the key are used. + + + + + Decrypts the specified data. + + The data. + The parameters. + + + + + Encrypts the specified scope. + + The scope data. + The parameters. + + + + + Gets the salt. + + The salt. + + + + Passwords to key. + + The secret. + The engine identifier. + + + + + Returns a string that represents this object. + + + + + + Authentication provider interface. + + + + + Gets the clean digest. + + The clean digest. + + + + Converts password to key. + + The password. + The engine id. + + + + + Computes the hash. + + The version. + The header. + The parameters. + The scope bytes. + The privacy provider. + The length bytes. + + + + + Gets the length of the digest. + + The length of the digest. + + + + Privacy provider interface. + + + + + Encrypts the specified scope. + + The scope data. + The parameters. + + + + + Gets the salt. + + The salt. + + + + Decrypts the specified data. + + The data. + The parameters. + + + + + Corresponding . + + + + + Engine IDs. + + This is an optional field, and only used by TRAP v2 authentication. + + + + Passwords to key. + + The secret. + The engine identifier. + + + + + Authentication provider using MD5. + + + + + Initializes a new instance of the class. + + The phrase. + + + + Passwords to key. + + The user password. + The engine ID. + + + + + Gets the clean digest. + + The clean digest. + + + + Computes the hash. + + The version. + The header. + The parameters. + The scope data. + The privacy provider. + The length bytes. + + + + + Gets the length of the digest. + + The length of the digest. + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Extension class for . + + + + + Converts to . + + The privacy provider. + Levels. + + + + Gets the scope data. + + The privacy provider. + The header. + The parameters. + The raw scope data. + ISnmpData. + + privacy + or + header + + + + + Computes the hash. + + The version. + The header. + The parameters. + The scope. + The privacy provider. + + + + Verifies the hash. + + The version. + The header. + The parameters. + The scope bytes. + The privacy provider. + The length bytes. + + Returns true if hash matches. Otherwise, returns false. + + + + + Salt generator. + + + + + Get next salt value. Used internally to encrypt data. + + Random value + + + + Gets salt bytes. + + + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Authentication provider using SHA-1. + + + + + Initializes a new instance of the class. + + The phrase. + + + + Passwords to key. + + The user password. + The engine ID. + + + + + Gets the clean digest. + + The clean digest. + + + + Computes the hash. + + The version. + The header. + The parameters. + The scope bytes. + The privacy provider. + The length bytes. + + + + + Gets the length of the digest. + + The length of the digest. + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Authentication provider using SHA-256. + + Defined in https://tools.ietf.org/html/rfc7630#page-3. + + + + Initializes a new instance of the class. + + The phrase. + + + + Passwords to key. + + The user password. + The engine ID. + + + + + Gets the clean digest. + + The clean digest. + + + + Computes the hash. + + The version. + The header. + The parameters. + The scope bytes. + The privacy provider. + The length bytes. + + + + + Length of the digest. + + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Authentication provider using SHA-384. + + Defined in https://tools.ietf.org/html/rfc7630#page-3. + + + + Initializes a new instance of the class. + + The phrase. + + + + Passwords to key. + + The user password. + The engine ID. + + + + + Gets the clean digest. + + The clean digest. + + + + Computes the hash. + + The version. + The header. + The parameters. + The scope bytes. + The privacy provider. + The length bytes. + + + + + Length of the digest. + + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Authentication provider using SHA-512. + + Defined in https://tools.ietf.org/html/rfc7630#page-3. + + + + Initializes a new instance of the class. + + The phrase. + + + + Passwords to key. + + The user password. + The engine ID. + + + + + Gets the clean digest. + + The clean digest. + + + + Computes the hash. + + The version. + The header. + The parameters. + The scope bytes. + The privacy provider. + The length bytes. + + + + + Length of the digest. + + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Privacy provider for 3DES. + + +

Ported from SNMP#NET Privacy3DES class.

+

Originally defined in a draft https://datatracker.ietf.org/doc/html/draft-reeder-snmpv3-usm-3desede-00

+
+
+ + + Flag to force using legacy encryption/decryption code on .NET 6. + + + + + Initializes a new instance of the class. + + The phrase. + The authentication provider. + + + + Corresponding . + + + + + Engine IDs. + + This is an optional field, and only used by TRAP v2 authentication. + + + + Encrypt scoped PDU using DES encryption protocol + + Unencrypted scoped PDU byte array + Encryption key. Key has to be at least 32 bytes is length + Privacy parameters out buffer. This field will be filled in with information + required to decrypt the information. Output length of this field is 8 bytes and space has to be reserved + in the USM header to store this information + Encrypted byte array + Thrown when encryption key is null or length of the encryption key is too short. + + + + Decrypt DES encrypted scoped PDU. + + Source data buffer + Decryption key. Key length has to be 32 bytes in length or longer (bytes beyond 32 bytes are ignored). + Privacy parameters extracted from USM header + Decrypted byte array + Thrown when encrypted data is null or length == 0 + Thrown when encryption key length is less then 32 byte or if privacy parameters + argument is null or length other then 8 bytes + + + + Generate IV from the privacy key and salt value returned by GetSalt method. + + 32 byte privacy key + Salt value returned by GetSalt method + IV value used in the encryption process + + + + Extract and return DES encryption key. + Privacy password is 16 bytes in length. Only the first 8 bytes are used as DES password. Remaining + 8 bytes are used as pre-IV value. + + 16 byte privacy password + 8 byte DES encryption password + + + + Returns the length of privacyParameters USM header field. For 3DES, field length is 8. + + + + + Returns minimum encryption/decryption key length. For 3DES, returned value is 32. + + 3DES protocol itself requires an 24 byte key. Additional 8 bytes are used for generating the + encryption IV. For encryption itself, first 24 bytes of the key are used. + + + + + Return maximum encryption/decryption key length. For 3DES, returned value is 32. + + 3DES protocol itself requires an 24 byte key. Additional 8 bytes are used for generating the + encryption IV. For encryption itself, first 24 bytes of the key are used. + + + + + Decrypts the specified data. + + The data. + The parameters. + + + + + Encrypts the specified scope. + + The scope data. + The parameters. + + + + + Gets the salt. + + The salt. + + + + Passwords to key. + + The secret. + The engine identifier. + + + + + Returns a string that represents this object. + + + + + + User class. + + + + + Initializes a new instance of the class. + + The name. + The privacy provider. + + + + Gets the name. + + The name. + + + + Gets the privacy provider. + + The provider. + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + A repository to store user information for providers. + + + + + Initializes a new instance of the class. + + The users. + + + + Initializes a new instance of the class. + + + + + Returns the user count. + + + + + Adds the specified user name. + + Name of the user. + The privacy provider. + + + + Adds the specified user. + + The user. + + + + Finds the specified user name. + + Name of the user. + + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Array type. + + Represents SMIv1 SEQUENCE. + + + + Gets the enumerator. + + + + + + Creates an instance with varied instances. + + The length bytes. + The items. + + + + Creates an instance with varied instances. + + + + + + Initializes a new instance of the class. + + The length. + The stream. + + + + Item count in this . + + + + + Gets the at the specified index. + + + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Returns a that represents this . + + + + + + Gets the length bytes. + + System.Byte[]. + + + + SET request PDU. + + + + + Creates a instance with all contents. + + The request id. + Variables + + + + Initializes a new instance of the class. + + The length data. + The stream. + + + + Returns a that represents this . + + + + + + Gets the request ID. + + The request ID. + + + + Gets the error status. + + The error status. + + + + Gets the index of the error. + + The index of the error. + + + + Variables. + + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + extension class. + + + + + Converts to a byte array. + + The SNMP data. + + A byte array representing the SNMP data. + + + + Base exception type of #SNMP. + + + + + Creates a . + + + + + Creates a instance with a specific . + + Message + + + + Creates a instance with a specific and an . + + Message + Inner exception + + + + Creates a instance. + + Info + Context + + + + + + + Returns a that represents this . + + + + + + Details on operation. + + + + + SNMP type code. The values are tag values for SNMP types. + + + + + End marker. + + + + + INTEGER type. (SMIv1, SMIv2) + + + + + OCTET STRING type. + + + + + NULL type. (SMIv1) + + + + + OBJECT IDENTIFIER type. (SMIv1) + + + + + RFC1213 sequence for whole SNMP packet beginning + + + + + IpAddress type. (SMIv1) + + + + + Counter32 type. (SMIv1, SMIv2) + + + + + Gauge32 type. (SMIv1, SMIv2) + + + + + TimeTicks type. (SMIv1) + + + + + Opaque type. (SMIv1) + + + + + Network Address. (SMIv1) + + + + + Counter64 type. (SMIv2) + + + + + Unsigned32 type. (Use this code in RFC 1442) + + + + + No such object exception. + + + + + No such instance exception. + + + + + End of MIB view exception. + + + + + Get request PDU. + + + + + Get Next request PDU. + + + + + Response PDU. + + + + + Set request PDU. + + + + + Trap v1 PDU. + + + + + Get Bulk PDU. + + + + + Inform PDU. + + + + + Trap v2 PDU. + + + + + Report PDU. SNMP v3. + + + + + Defined by #SNMP for unknown type. + + + + + Stream extension class. + + + + + TimeTicks type. + + Represents SNMP TimeTicks type. + + + + Creates a instance with a specific count. + + Count + + + + Creates a instance with . + + The time span. + + + + Creates a instance with raw bytes. + + Raw bytes + + + + Initializes a new instance of the class. + + The length. + The stream. + + + + Returns an that represents the current + + + + + + Returns representation. + + + + + + Type code. + + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + true if the specified is equal to the current ; otherwise, false. + + + + + Indicates whether the current object is equal to another object of the same type. + + An object to compare with this object. + true if the current object is equal to the parameter; otherwise, false. + + + + + Serves as a hash function for a particular type. + + A hash code for the current . + + + + Appends the bytes to . + + The stream. + + + + The equality operator. + + Left object + Right object + + Returns true if the values of its operands are equal, false otherwise. + + + + The inequality operator. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + Returns a that represents this . + + + + + + The comparison. + + Left object + Right object + + Returns true if the values of its operands are not equal, false otherwise. + + + + Trap v1 PDU. + + represents the PDU of trap v1 message. + + + + Creates a instance with PDU elements. + + Enterprise + Agent address + Generic trap type + Specific trap type + Time stamp + Variable binds + + + + Creates a instance with PDU elements. + + Enterprise + Agent address + Generic trap type + Specific trap type + Time stamp + Variable binds + + + + Initializes a new instance of the class. + + The length data. + The stream. + + + + Gets the request ID. + + The request ID. + + + + Gets the index of the error. + + The index of the error. + + + + Gets the error status. + + The error status. + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Enterprise. + + + + + Agent address. + + + + + Generic trap type. + + + + + Specific trap type. + + + + + Time stamp. + + + + + Variable binds. + + + + + Returns a that represents this . + + + + + + TRAP v2 PDU. + + + + + Creates a instance with all content. + + Request ID. + Enterprise. + Time stamp. + Variables. + + + + Initializes a new instance of the class. + + The length data. + The stream. + + + + Variables. + + + + + Gets the request ID. + + The request ID. + + + + Gets the error status. + + The error status. + + + + Gets the index of the error. + + The index of the error. + + + + Type code. + + + + + Appends the bytes to . + + The stream. + + + + Enterprise. + + + + + Time stamp. + + + + + Returns a that represents this . + + + + + + Decorates a list of objects with time and enterprise ID. + + The variables. + Decorated list. + + + + Variable bind. + + + Represents SNMP variable bind. + + + + + Creates a instance with a specific object identifier. + + Object identifier + + + + Creates a instance with a specific and . + + Object identifier + Data + If you set null to , you get a instance whose is a instance. + + + + Creates a instance with a specific object identifier and data. + + Object identifier + Data + If you set null to , you get a instance whose is a instance. + + + + Variable object identifier. + + + + + Variable data. + + + + + Converts variable binds section to variable binds list. + + + + + + + Converts variable binds to variable binds section. + + + + + + + Returns a that represents this . + + + + + + Protocol version code. + + + + + SNMP v1. + + + + + SNMP v2 classic. + + + + + SNMP v2u is obsolete. + + + + + SNMP v3. + + +
+