Скрипт для сбора MAC-адресов коммутаторов и занесение их в NetK
Скрипт для сбора MAC-адресов коммутаторов и занесение их в NetK
Столкнулась со следующей ситуацией - необходимо собрать MAC-адреса порядка 4-х тысяч коммутаторов Zyxel и D-link и занести в программу NetK - визуализатор сети.
На всех коммутаторах настроен SNMP. Всё оборудование занесено в программу NetK, поэтому список IP-адресов коммутаторов формировала sql запросом к базе данных.
Для реализации данной задачи требуется скрипт, который будет обходить каждый коммутатор по SNMP и собирать MAC таблицу. Список IP-адресов коммутаторов поместим в файл ip.txt в формате одна строка - один IP-адрес:
10.35.1.30 10.35.4.242 10.35.2.248 ...
Для сбора данных с интерфейсов будем использовать утилиту snmpwalk из пакета Net-SNMP:
/usr/local/bin/snmpwalk -Osf -c COMMUNITY -v1 10.35.1.30 .1.3.6.1.2.1.2.2.1.6
где Osf - формат вывода:
f: print full OIDs on output
s: print only last symbolic element of OID
v - версия SNMP
OID .1.3.6.1.2.1.2.2.1.6 определяет физический адрес интерфейса.
Пример вывода команды snmpwalk:
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifPhysAddress.1 = STRING: 0:1c:f0:1d:1f:0
Итак, скрипт сбора MAC-адресов я решила писать на perl, обновление же NetK реализовала на php.
#!/usr/bin/perl use strict; use File::Copy; my $storepath = './'; my $routers_list = $storepath.'ip.txt'; my $H1; my $i; my $dumplog = './dump_mac.log'; my @array; sub trim($) { $_[0]=~s/(^\s+)|(\s+$)|(\n$)//gs; return $_[0]; }; open (RL, $routers_list) or die "can't open routers list: $!"; $i=0; undef @array; while(<RL>){ my $ip= $_; trim($ip); if ($ip =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { $H1=""; open DATA,"/usr/local/bin/snmpwalk -Osf -c COMMUNITY -v 1 $ip .1.3.6.1.2.1.2.2.1.6|"; while (<DATA>){ $H1=(split(/[.\s]/), $_)[11,14]; trim($_); if (!(grep $_ eq $H1, @array ) && ($H1 ne '0:0:0:0:0:0')){ $i = $i + 1; print "$i - $ip - $H1\n"; open (RW," >>$dumplog") or die "can't open dumplog: $!"; print(RW "$ip;$H1\n"); push @array, $H1; } } } } close(RL);
Результат работы скрипта сохраняется в файл dump_mac.log в формате:
10.32.151.149;0:19:cb:4c:2b:10 10.32.2.76;0:13:49:f2:ae:5 10.32.2.76;0:13:49:f2:ae:3 10.32.2.76;0:13:49:f2:ae:3
Скрипт обновления базы данных NetK - update_mac.php:
<?php include("./config.php"); $filename ="./dump_mac.log"; $fp =fopen($filename, "r"); $pub = fread($fp, filesize($filename)); fclose($fp); $arr = array(); $arr = preg_split('/\n/', $pub,-1, PREG_SPLIT_NO_EMPTY); //В файле dump_mac.log могут присутствовать строки с пустыми MAC-адресами. Запишем данный факт в лог dump_mac_err.log $filename_err ="./dump_mac_err.log"; $fperr =fopen($filename_err, "a"); $count_mac=0; foreach ($arr as $idx=> $val) { $knot_par = explode(";", $arr[$idx]); $knot_ip=trim($knot_par[0]); $knot_mac=trim($knot_par[1]); if($knot_mac==""){ fwrite($fperr, $knot_ip."\n"); }else{ $knot_mac_exp = explode(":", $knot_mac); $knot_mac = sprintf("%02s:%02s:%02s:%02s:%02s:%02s", $knot_mac_exp[0], $knot_mac_exp[1], $knot_mac_exp[2], $knot_mac_exp[3], $knot_mac_exp[4], $knot_mac_exp[5]); } $query = "select k.id FROM knot k LEFT JOIN net as n ON k.id=n.id_knot where n.ip_for=INET_ATON('$knot_ip')"; $param=mysql_query($query); if($param){ while($rows_id_knot=mysql_fetch_array($param)){ $db_id_knot=$rows_id_knot['id']; $db_id_mac=""; $query_mac = "select m.id as id_mac FROM knot k,mac as m where k.id=m.id_knot and k.id=$db_id_knot and m.name='$knot_mac'"; $param_mac=mysql_query($query_mac); if($param_mac){ while($rows_mac=mysql_fetch_array($param_mac)){ $db_id_mac=$rows_mac['id_mac']; } if(($db_id_mac=="") and ($knot_mac<>"")){ $count_mac++; echo"$knot_ip ; $knot_mac <br>"; $query_up = "insert into `mac` values(NULL,'$knot_mac',0,$db_id_knot)"; if(!mysql_query($query_up)){ echo"error insert"; } } } } } } echo"Count mac: $count_mac"; fclose($fp_err); ?>
Нажимая кнопку «Сохранить», я подтверждаю свою дееспособность, согласие на получение информации от NetK, согласие на обработку персональных данных в соответствии с Политикой конфиденциальности и Пользовательским соглашением.