Skip to Content
 Русский Русский    English English   

 

Скрипт для сбора портов подключения коммутаторов D-link, Zyxel и занесение их в NetK

Скрипт для сбора портов подключения коммутаторов D-link, Zyxel и занесение их в NetK

Скажу сразу, всё оборудование уже занесено в NetK - визуализатор сети, поэтому задача построения топологии сети не ставилась. Однако данные скрипты могут послужить основой для автоматической генерации топологии сети.

Итак, необходимо получить информацию по портам подключения коммутаторов:

1) порт вышестоящего коммутатора, к которому подключен текущий коммутатор;

2) порт (uplink) текущего коммутатора, к которому подключен вышестоящий коммутатор.

Пример портов подключения из NetK - коммутатор с IP-адресом 10.32.198.234 (назовем его текущий коммутатор) подключен к 26 порту вышестоящего коммутатора с IP-адресом 10.32.198.249.  Порт подключения на текущем коммутаторе - 28.

Схема подключения коммутаторов. Порты подключения коммутаторов

Для реализации данной задачи буду перебирать MAC-адреса, полученные из таблицы коммутации оборудования. Предварительно необходимо пропинговать коммутатор (в случае, если к нему давно не было обращений), MAC-адрес которого необходимо найти, чтобы данный мак появился в arp таблице.

IP и MAC-адреса формировала sql запросом к базе данных NetK в следующем формате.

1. Для получения порта вышестоящего коммутатора, на который подключен текущий коммутатор:

10.32.198.249;00 1e 58 a0 dc 62; 10.32.198.234;1

где 10.32.198.249 - IP-адрес вышестоящего коммутатора, на котором необходимо найти MAC-адрес 00:1e:58:a0:dc:62 текущего коммутатора 10.32.198.134. Флаг 1 указывает, что производитель коммутатора 10.32.198.249 -D-link (флаг 0 - для коммутаторов Zyxel).

2. Для получения порта (uplink) текущего коммутатора, к которому подключен вышестоящий коммутатор:

10.32.198.234;00 1e 58 a8 56 2d; 10.32.198.249;1

где 10.32.198.234 - IP-адрес текущего коммутатора, на котором необходимо найти MAC-адрес 00:1e:58:a8:56:2d вышестоящего коммутатора 10.32.198.249. Флаг 1 указывает, что производитель коммутатора 10.32.198.234 -D-link (флаг 0 - для коммутаторов Zyxel).

 IP-адреса коммутаторов D-link и Zyxel формировала отдельными списками ввиду большого количества оборудования - порядка 4-х тысяч.

 

Алгоритм сбора портов подключения коммутаторов:

1. Заходим по telnet на коммутатор, IP-адрес которого указан первым в строке.

2. Пингуем коммутатор, IP-адрес которого указан вторым в строке.

На коммутаторах D-link:

# ping  $ip  times 1
# logo

На коммутаторах Zyxel:

# ping $ip
# exit

3. Выполняем команду snmpwalk из пакета Net-SNMP.

На коммутаторах D-link:

/usr/local/bin/snmpwalk -Osfn -c COMMUNITY -v2c $ip .1.3.6.1.2.1.17.7.1.2.2.1.2

Пример возвращаемого значения:

.1.3.6.1.2.1.17.7.1.2.2.1.2.2.0.28.240.40.57.191 = INTEGER: 21

где 0.28.240.40.57.191 - MAC-адрес в десятичной системе;

21 - номер порта.

На коммутаторах Zyxel:

/usr/local/bin/snmpwalk -Osfn -c COMMUNITY -v2c $ip .1.3.6.1.2.1.17.4.3.1.2

Пример возвращаемого значения:

.1.3.6.1.2.1.17.4.3.1.2.0.1.108.25.235.110 = INTEGER: 11

где 0.1.108.25.235.120 - MAC-адрес в десятичной системе;

11 - номер порта.

4. Сравниваем мак-адреса из таблицы коммутации с мак-адресом из строки и находим необходимый порт.

 

Скрипт сбора портов подключения коммутаторов - port.pl:

#!/usr/bin/perl

use strict;
use File::Copy;
use Net::Telnet;
my $storepath = './';
my $source_list = $storepath.'ip-mac.txt';
my $macaddr;
my $result;
my $oid_mac;
my $oid_port;
my $i_count=0;
my $dumplog = './dump_port.log';

sub trim($) {
        $_[0]=~s/(^\s+)|(\s+$)|(\n$)//gs;
        return $_[0];
};

open (RW," >>$dumplog") or die "can't open dumplog: $!";

open (RL, $source_list) or die "can't open source list: $!";
while(<RL>){
        my $ip= (split(/[;]/), $_)[0];
        trim($ip);
        my $mac=(split(/[;]/), $_)[1];
        trim($mac);
        my $ip_to= (split(/[;]/), $_)[2];
        trim($ip_to);
        my $flag=(split(/[;]/), $_)[3];
        trim($flag);
        print "-----------------------------------------\n";
        print "start $ip-$ip_to-$mac\n";
        my $username = 'LOGIN';
        my $password =  'PASS';
        my $dumplog_telnet = 'dump_telnet.log';
        if ($ip =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
                #Zyxel
                if($flag == 0){
                        print "telnet...start\n";
                        my $command_ping= 'ping '.$ip_to;
                        my $command_ex='exit';
                        my $telnet = new Net::Telnet ( Timeout=>20, Errmode=> 'return', Dump_Log => $dumplog_telnet);
                        if($telnet->open($ip)){
                                if($telnet->print($username)){
                                        sleep(1);
                                        if($telnet->print($password)){
                                                if($telnet->print($command_ping)){
                                                        sleep(1);
                                                        if($telnet->print($command_ex)){
                                                                sleep(1);
                                                        }
                                                }else{
                                                        print "error ping";
                                                }
                                        }else{
                                                print "error pass";
                                        }
                                }else{
                                        print "error username";
                                }
                                if($telnet->close){
                                        print "telnet...end\n";
                                }
                        }else{
                                print "error open";
                        }
                        sleep(3);
                       open DATA,"/usr/local/bin/snmpwalk -Osfn -c COMMUNITY -v 2c $ip .1.3.6.1.2.1.17.4.3.1.2|";
                        $oid_mac="";
                        $macaddr="";
                        $oid_port="";
                        while (<DATA>){
                                $oid_mac=(split(/[=]/), $_)[0];
                                trim($oid_mac);
                                $oid_port=(split(/[ ]/), $_)[3];
                                trim($oid_port);
                                if  ($oid_mac =~ /^\.1\.3\.6\.1\.2\.1\.17\.4\.3\.1\.2\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/) {
                                        my $mac1=sprintf "%02lx",$1;
                                        my $mac2=sprintf "%02lx",$2;
                                        my $mac3=sprintf "%02lx",$3;
                                        my $mac4=sprintf "%02lx",$4;
                                        my $mac5=sprintf "%02lx",$5;
                                        my $mac6=sprintf "%02lx",$6;
                                        $macaddr=$mac1.' '.$mac2.' '.$mac3.' '.$mac4.' '.$mac5.' '.$mac6;
                                        trim($macaddr);
                                }

                                if ($macaddr =~ /$mac/) {
                                        $i_count=$i_count + 1;
                                        print "$i_count: $ip - $oid_port - $mac - $ip_to - $flag\n";
                                        print RW "$ip;$oid_port;$mac;$ip_to;$flag\n";
                                }
                        }
                }elsif($flag == 1){
                        #D-link
                        print "telnet...start\n";
                        my $command_ping= 'ping '.$ip_to.' times 1';
                        my $command_ex='logo';
                        my $telnet = new Net::Telnet ( Timeout=>20, Errmode=> 'return', Dump_Log => $dumplog_telnet);
                        if($telnet->open($ip)){
                                if($telnet->print($username)){
                                        sleep(1);
                                        if($telnet->print($password)){
                                                if($telnet->print($command_ping)){
                                                        sleep(1);
                                                        if($telnet->print($command_ex)){
                                                                sleep(1);
                                                        }
                                                }else{
                                                        print "error ping";
                                                }
                                        }else{
                                                print "error pass";
                                        }
                                }else{
                                        print "error username";
                                }
                                if($telnet->close){
                                        print "telnet...end\n";
                                }
                        }else{
                                print "error open";
                        }
                        sleep(3);
                        open DATA,"/usr/local/bin/snmpwalk -Osfn -c COMMUNITY  -v 2c $ip .1.3.6.1.2.1.17.7.1.2.2.1.2|";
                        $oid_mac="";
                        $macaddr="";
                        $oid_port="";
                        while (<DATA>){
                                $oid_mac=(split(/[=]/), $_)[0];
                                trim($oid_mac);
                                $oid_port=(split(/[ ]/), $_)[3];
                                trim($oid_port);
                                if  ($oid_mac =~ /^\.1\.3\.6\.1\.2\.1\.17\.7\.1\.2\.2\.1\.2\.\d{1,3}\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/) {
                                        my $mac1=sprintf "%02lx",$1;
                                        my $mac2=sprintf "%02lx",$2;
                                        my $mac3=sprintf "%02lx",$3;
                                        my $mac4=sprintf "%02lx",$4;
                                        my $mac5=sprintf "%02lx",$5;
                                        my $mac6=sprintf "%02lx",$6;
                                        $macaddr=$mac1.' '.$mac2.' '.$mac3.' '.$mac4.' '.$mac5.' '.$mac6;
                                        trim($macaddr);

                                        if ($macaddr =~ /$mac/) {
                                                $flag=1;
                                                $i_count=$i_count + 1;
                                                print "$i_count: $ip - $oid_port - $mac - $ip_to - $flag\n";
                                                print RW "$ip;$oid_port;$mac;$ip_to;$flag\n";
                                        }
                                }
                        }
                }
        }
}
close(RW);
close(RL);

Результат можно наблюдать в файле dump_port.log. Формат записей:

10.32.198.249;26;00 1e 58 a0 dc 62; 10.32.198.234;1

где 26 - искомый порт.

 

Скрипт обновления порта подключения текущего коммутатора к вышестоящему в базе данных NetK

В примере выше для узла с IP-адресом 10.32.198.234 номер порта - 26. Пример входных данных:

10.32.198.249;26;00 1e 58 a0 dc 62; 10.32.198.234;1

update_port_to.php:

<?php
include("./config.php");
$filename ="./dump_port.log";
$fp =fopen($filename, "r");
$pub = fread($fp, filesize($filename));
fclose($fp);
$arr = array();
$arr = preg_split('/\n/', $pub,-1, PREG_SPLIT_NO_EMPTY);
$count_port=0;

foreach ($arr as $idx=> $val) {
	$count_port++;
	$knot_par = explode(";", $arr[$idx]); 
	$knot_ip=trim($knot_par[3]);	
	$knot_port=trim($knot_par[1]);

	mysql_query("LOCK TABLES `net` WRITE;");
	$query_up = "UPDATE net SET port_to='$knot_port' where INET_NTOA(ip_for)='$knot_ip'";
       	if(!mysql_query($query_up))
       	{
       		echo "error update";
       	}
	mysql_query("UNLOCK TABLES");
}
echo"port  $count_port";
?>

 

Скрипт обновления порта подключения вышестоящего коммутатора к текущему в базе данных NetK

В примере выше для узла с IP-адресом 10.32.198.234 номер порта - 28. Пример входных данных:

10.32.198.234;28;00 1e 58 a8 56 2d; 10.32.198.249;1

update_port_for.php:

<?php
include("./config.php");
$filename ="./dump_port.log";
$fp =fopen($filename, "r");
$pub = fread($fp, filesize($filename));
fclose($fp);
$arr = array();
$arr = preg_split('/\n/', $pub,-1, PREG_SPLIT_NO_EMPTY);
$count_port=0;

foreach ($arr as $idx=> $val) {
	$count_port++;
	$knot_par = explode(";", $arr[$idx]); 
	$knot_ip=trim($knot_par[0]);	
	$knot_port=trim($knot_par[1]);
	mysql_query("LOCK TABLES `net` WRITE;");
	$query_up = "UPDATE net SET port_for='$knot_port' where INET_NTOA(ip_for)='$knot_ip'";
	if(!mysql_query($query_up))
	{
		echo "error update";
	}
	mysql_query("UNLOCK TABLES");
}
echo"port  $count_port";
?>

 

port.pl

update_port_to.php

update_port_for.php

 

 

Ваша оценка: Нет Средняя: 4.8 (30 голосов)

Нажимая кнопку «Сохранить», я подтверждаю свою дееспособность, согласие на получение информации от NetK, согласие на обработку персональных данных в соответствии с Политикой конфиденциальности и Пользовательским соглашением.