Скрипт для сбора портов подключения коммутаторов 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:

1
2

# ping  $ip  times 1
# logo

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

1
2

# 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157

#!/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(){
        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 (){
                                $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 (){
                                $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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26


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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25


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

Запись опубликована в рубрике *Lan&Wan, *Unix,*Linux, *Сети. Добавьте в закладки постоянную ссылку.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Я не спамер This plugin created by Alexei91