Created
February 7, 2017 09:20
-
-
Save illarionov/fbb4d5d1a09feb77eb9cb7836c6f3dd2 to your computer and use it in GitHub Desktop.
ports set converter for D-link switches
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use strict; | |
use warnings; | |
use utf8; | |
use Getopt::Long; | |
use Pod::Usage; | |
my $VERSION="0.01"; | |
#Ф-я преобразует бинарную битовую маску списка портов | |
#(тип PortList в D-Link'овских MIB'ах) | |
#в строку - список портов (напр. "1, 5-10, 20") | |
sub portlist2str { | |
my $portlist = shift; | |
my @res; | |
my ($seq_start, $lastval) = (0, 0); | |
my $port_num; | |
return if (!$portlist); | |
$port_num = 0; | |
my @ports = split(//, unpack("B*", $portlist)); | |
foreach (@ports) { | |
$port_num++; | |
if ($_ == 1) { | |
$seq_start = $port_num | |
if ($seq_start == 0); | |
}else { | |
if ($lastval == 1) { | |
my $seq_end = $port_num-1; | |
push (@res, $seq_start == $seq_end ? $seq_start : | |
"$seq_start-$seq_end"); | |
$seq_start=0; | |
} | |
} | |
$lastval = $_; | |
} | |
if ($lastval == 1) { | |
my $seq_end = $port_num-1; | |
push (@res, $seq_start == $seq_end ? $seq_start : | |
"$seq_start-$seq_end"); | |
$seq_start=0; | |
} | |
return join(",", @res); | |
} | |
#Ф-я преобразует строку - список портов (напр. "1, 5-10, 20") | |
#в битовую маску для SNMP | |
#$str - преобразуемая строка, | |
#$sw_num_ports - кол-во портов на коммутаторе. Если ее не указать, или указать | |
#неправильно, будет сформирована битовая маска неправильной длины (ее не | |
#примет коммутатор) | |
#Возвращает undef в случае ошибки, или если не было портов | |
sub str2portlist { | |
my ($str, $sw_num_ports) = @_; | |
my @ports = str2portset($str, $sw_num_ports); | |
return if (scalar(@ports) == 0); | |
return pack("B*", join("", @ports)); | |
} | |
#Ф-я преобразует строку - список портов (напр. "1, 5-10, 20") | |
#в множество в виде массива 0 и 1. | |
#Напр. "1,5,7" вернет (1,0,0,0,1,0,1). | |
#sw_num_ports - кол-во портов на коммутаторе. 0 - без ограничений | |
sub str2portset { | |
my ($str, $sw_num_ports) = @_; | |
$sw_num_ports += 0; | |
my @bmask = (); | |
return if (!$str); | |
my @ranges = split(/\s*\,\s*/, $str); | |
return if (scalar(@ranges) == 0); | |
foreach my $r (@ranges) { | |
if ( $r =~ /^([0-9]+)$/) { | |
my $port_num = $1 + 0; | |
return if ($port_num < 1 || ($sw_num_ports && ($port_num > | |
$sw_num_ports))); | |
$bmask[$1-1] = 1; | |
}elsif ( $r =~ /^([0-9]+)\s?-\s?([0-9]+)$/) { | |
my ($seq_start, $seq_end) = ( $1+0, $2+0); | |
if ($sw_num_ports) { | |
return if ($seq_start < 1 || $seq_start > $sw_num_ports | |
|| $seq_end < 1 || $seq_end > $sw_num_ports | |
|| $seq_start > $seq_end); | |
}else { | |
return if ($seq_start < 1 | |
|| $seq_end < 1 | |
|| $seq_start > $seq_end); | |
} | |
for (my $i=$seq_start; $i <= $seq_end; $i++) { | |
$bmask[$i-1]=1; | |
} | |
}else { | |
return; | |
} | |
} | |
for (my $i=0; $i < ($sw_num_ports || $#bmask); $i++) {$bmask[$i] ||= 0;} | |
return @bmask; | |
} | |
my $help; | |
my $ports; | |
my $portlist; | |
my $numports=28; | |
GetOptions( | |
'help|?' => \$help, | |
'ports=s' => \$ports, | |
'snmp=s' => \$portlist, | |
'numports=i' => \$numports | |
) or pod2usage(2); | |
pod2usage(1) if $help; | |
pod2usage(2) if ((!$ports && !$portlist) || ($ports && $portlist)); | |
pod2usage(2) if ($numports < 0 || $numports >= 64); | |
if ($ports) { | |
#Преобразование из списка портов в значение для snmpset | |
my $mask = str2portlist($ports, $numports); | |
die("wrong portlist or numports") if !$mask; | |
print unpack("H*", $mask),"\n"; | |
}else { | |
die ("wrong snmp portlist") if ($portlist !~ /^[0-9a-fA-F]+$/); | |
my $mask = pack("H*", $portlist); | |
my $ports = portlist2str($mask); | |
die("wrong snmp port mask") if !$ports; | |
print $ports, "\n"; | |
} | |
1; | |
=head1 dlink_ports.pl | |
dlink_ports.pl - ports set converter for D-link switches | |
=head1 SYNOPSIS | |
dlink_ports.pl -ports <ports> | |
dlink_ports.pl -snmp <snmp portlist> [options] | |
examples: | |
dlink_ports.pl -ports 1,5,7-9 | |
dlink_ports.pl -snmp 8b800000 | |
=head1 OPTIONS | |
-help help message | |
-ports ports (ex.: '1,3,4-5,7') | |
-snmp snmp portlist value (ex.: 0f2) | |
-numports Switch ports count | |
=head1 AUTHOR | |
Alexey Illarionov <littlesavage@rambler.ru> | |
=head1 LICENSE | |
Public Domain |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment