Скрипт для выявления порта свитча по маку. Опрос по SNMP

Posted by map[name:devi1 uri:https://www.blogger.com/profile/05777499482649623616] on Friday, February 27, 2015

Допилил предыдущий скрипт . Необходимо знать аплинки каждого из свитчей. В моем случае, все они подключены к одному корневому (RootSwitch). Скрипт вытягивает по SNMP FDB таблицу корневого свитча, ищет в ней заданный MAC, сверяет его по заранее заданной таблице аплинков до свитчей доступа, переходит на следующий свитч и с него так же забирает FDB таблицу, а в ней уже ищет необходимый MAC. Информация выводится следующим образом “MAC, vlan, port корневого свитча; MAC, vlan, port конечного свитча”.Для работы с SNMP необходимо подключить модуль SharpSNMP.Из неожиданностей в OID  MAC адреса хранятся в десятичном формате, пришлось их переводить в шестнадцатеричный. Простым способом вернуть несколько значений из функции невозможно. Пришлось городить хэш-таблицу, в которой хранились бы три массива (MAC, vlan, port)В OID информация хранится следующим образом:OID                                                                                   Data—                                                                                       —-.1.3.6.1.2.1.17.7.1.2.1.1.2.1                                               223.1.3.6.1.2.1.17.7.1.2.1.1.2.41                                              63.1.3.6.1.2.1.17.7.1.2.1.1.2.4026                                         222.1.3.6.1.2.1.17.7.1.2.2.1.2.1.144.2.166.50.206.43                3.1.3.6.1.2.1.17.7.1.2.2.1.2.1.144.2.166.50.206.63                6.1.3.6.1.2.1.17.7.1.2.2.1.2.1.144.2.166.50.206.126              4.1.3.6.1.2.1.17.7.1.2.2.1.2.41.0.21.100.59.187.78                26.1.3.6.1.2.1.17.7.1.2.2.1.2.4026.0.9.136.173.129.150          26.1.3.6.1.2.1.17.7.1.2.2.1.3.4026.232.64.241.24.239.215      3.1.3.6.1.2.1.17.7.1.2.2.1.3.4026.232.64.241.24.242.213      3Первые три строки (может быть больше или меньше, в зависиомсти от количества vlan’ов): последняя цифра - номер vlan’а, data - количество MAC-адресов в этом влане в FDB-таблице.Далее следуют строки с перечислением MAC-адресов, сгруппированные по vlan’ам: после символов .1.3.6.1.2.1.17.7.1.2.2.1.2. идет номер vlan (1, 41, 4026 в нашем случае), а за ним MAC адрес в десятичном формате. В поле Data - порт с найденным MAC-ом.Далее следуют строки, начинающиеся на .1.3.6.1.2.1.17.7.1.2.2.1.3. Они содержат информацию, о способе получения MAC-адреса. Если параметр 3 - MAC получен методом learning (опрос порта), 4 - MAC коммутатора, с которого взяли FDB.Мы будем обрабатывать строки из второго блока. Сначала отсекаем ненужную нам часть OID, затем разбиваем на подстроки и запоминаем данные. Полученные данные выводим по порядку в 3 массива - MAC, port, vlan.Собственно скрипт:function findonswitch ([string]$ip) {$oid=".1.3.6.1.2.1.17.7.1.2.2.1.2."$mas = Invoke-SnmpWalk $ip “.1.3.6.1.2.1.17.7.1.2” #vlans$i=0$vlan=@()$mac=@()$port=@()foreach ($pt in $mas){ if ($pt.OID -like “$oid”) { $pt.OID = $pt.OID.remove(0,28) $vlan += $pt.OID.Substring(0, $pt.OID.IndexOf(".")) $temp = $pt.OID.Substring($pt.OID.IndexOf(".") + 1, $pt.OID.Length - $pt.OID.IndexOf(".")-1) ###перевод из Dec в Hex $mas=$temp.split(".") $nmac=@() foreach ($sdec in $mas) { $dec = [int]$sdec $nmac += ‘{0:X2}’ -f $dec } $str=$nmac -join “-" ### $mac += $str $port += $pt.Data } }$return= @{}$return.vlan=$vlan$return.mac=$mac$return.port=$portreturn $return}####################################################################$rootIP = “192.168.0.21”$sport = (“1”, “2”, “5”, “12”, “13”, “14”, “43”, “44”, “65”, “66”, “74”, “107”)$swDB = (“192.168.0.42”, “192.168.0.44”, “192.168.0.61”, “192.168.0.52”, “192.168.0.51”, “192.168.0.12”, “192.168.0.33”, “192.168.0.32”, “192.168.0.41”, “192.168.0.43”, “192.168.0.11”, “192.168.0.34”)function findinarr ($array, $value) {    for ($i=0; $i -lt $array.count;$i++) {         if($array[$i] -eq $value){$i}    }}$res=findonswitch $rootIP$dataMACRoot = $res.mac$dataPortRoot = $res.port$dataVlanRoot = $res.vlan$mac = Read-Host “Enter MAC”if ($mac.indexof(”:") -ne 0){ $mac=$mac.replace(":", “-”)}$i=0$flag=0foreach ($S in $dataMACRoot){ if ($mac -eq $s) { $portRoot = $dataPortRoot[$i] $vlanRoot = $dataVlanRoot[$i] Write-Host $mac on $portRoot ‘in vlan’ $vlanRoot on RootSwitch if ($flag -eq 0) { $portRoot1 = $dataPortRoot[$i] } $flag++ } $i++}$A = findinarr $sport $portRoot1$res=findonswitch $swDB[$A]$dataMAC = $res.mac$dataPort = $res.port$dataVlan = $res.vlan$i=0foreach ($S in $dataMAC){ if ($mac -eq $s) { $port = $dataPort[$i] $vlan = $dataVlan[$i] Write-Host $mac on $port ‘in vlan’ $vlan on ‘switch’ $swDB[$A] } $i++}Работа второй части скрипта (после ###########) описана в предыдущем посте. Тут она претерпела некоторые изменения, в связи с входящей информацией из массива, а не из csv-файла, но логика не изменилась.


comments powered by Disqus