Line 53... |
Line 53... |
53 |
# also set it up so it is a little more concise by combining redundant code into one routine, parseSNMPQuery, which
|
53 |
# also set it up so it is a little more concise by combining redundant code into one routine, parseSNMPQuery, which
|
54 |
# reads an snmp walk and returns the results as a hash
|
54 |
# reads an snmp walk and returns the results as a hash
|
55 |
# 20200301 RWR v2.1.0
|
55 |
# 20200301 RWR v2.1.0
|
56 |
# added some error checking in snmpwalk when a value is not returned, and also when the MAC address of the switch in
|
56 |
# added some error checking in snmpwalk when a value is not returned, and also when the MAC address of the switch in
|
57 |
# question show up as bridge 0, which has no port (or, actually, all ports). Also, fixed the ignoreports
|
57 |
# question show up as bridge 0, which has no port (or, actually, all ports). Also, fixed the ignoreports
|
- |
|
58 |
# 20200302 RWR v2.2.0
|
- |
|
59 |
# Added the ability to override or supplement arp and dns searches for mac addresses
|
58 |
|
60 |
|
59 |
use strict;
|
61 |
use strict;
|
60 |
use warnings;
|
62 |
use warnings;
|
61 |
use Data::Dumper; # only used for debugging
|
63 |
use Data::Dumper; # only used for debugging
|
62 |
use Socket; # for reverse dns entries
|
64 |
use Socket; # for reverse dns entries
|
Line 67... |
Line 69... |
67 |
my $DEBUG = 0;
|
69 |
my $DEBUG = 0;
|
68 |
|
70 |
|
69 |
# define the version number
|
71 |
# define the version number
|
70 |
# see https://metacpan.org/pod/release/JPEACOCK/version-0.97/lib/version.pod
|
72 |
# see https://metacpan.org/pod/release/JPEACOCK/version-0.97/lib/version.pod
|
71 |
use version;
|
73 |
use version;
|
72 |
our $VERSION = version->declare("v2.1.0");
|
74 |
our $VERSION = version->declare("v2.2.0");
|
73 |
|
75 |
|
74 |
# see https://perldoc.perl.org/Getopt/Long.html
|
76 |
# see https://perldoc.perl.org/Getopt/Long.html
|
75 |
use Getopt::Long;
|
77 |
use Getopt::Long;
|
76 |
# allow -vvn (ie, --verbose --verbose --dryrun)
|
78 |
# allow -vvn (ie, --verbose --verbose --dryrun)
|
77 |
Getopt::Long::Configure ("bundling");
|
79 |
Getopt::Long::Configure ("bundling");
|
Line 137... |
Line 139... |
137 |
# ensures a hash has $name with every value in @keys
|
139 |
# ensures a hash has $name with every value in @keys
|
138 |
# call with &initialize( \%hash, 'somename', 'key1','key2');
|
140 |
# call with &initialize( \%hash, 'somename', 'key1','key2');
|
139 |
# will ensure $hash->{somename}->{key1} and $hash->{somename}->{key2} exist
|
141 |
# will ensure $hash->{somename}->{key1} and $hash->{somename}->{key2} exist
|
140 |
sub initialize {
|
142 |
sub initialize {
|
141 |
my ( $hash, $name, @keys ) = @_;
|
143 |
my ( $hash, $name, @keys ) = @_;
|
- |
|
144 |
print "In initialize, name is $name and hash is\n" . Dumper( $hash ) if $DEBUG > 3;
|
142 |
foreach my $key ( @keys ) {
|
145 |
foreach my $key ( @keys ) {
|
143 |
$hash->{$name}->{$key} = '' unless $hash->{$name}->{$key};
|
146 |
$hash->{$name}->{$key} = '' unless $hash->{$name}->{$key};
|
144 |
}
|
147 |
}
|
145 |
}
|
148 |
}
|
146 |
|
149 |
|
Line 295... |
Line 298... |
295 |
|
298 |
|
296 |
|
299 |
|
297 |
# Now, try to match up the MAC address. Read the ARP table from the router(s)
|
300 |
# Now, try to match up the MAC address. Read the ARP table from the router(s)
|
298 |
foreach my $router ( keys %{$config{'routers'}} ) {
|
301 |
foreach my $router ( keys %{$config{'routers'}} ) {
|
299 |
print "Working on $router\n" if $DEBUG;
|
302 |
print "Working on $router\n" if $DEBUG;
|
- |
|
303 |
print "snmpwalk -v1 -c $config{routers}{$router}{community} $router $ROUTERIPMACMIB\n" if $DEBUG > 1;
|
300 |
my $values = `snmpwalk -v1 -c $config{routers}{$router}{community} $router $ROUTERIPMACMIB`;
|
304 |
my $values = `snmpwalk -v1 -c $config{routers}{$router}{community} $router $ROUTERIPMACMIB`;
|
301 |
my @lines = split( "\n", $values );
|
305 |
my @lines = split( "\n", $values );
|
302 |
foreach my $line ( @lines ) {
|
306 |
foreach my $line ( @lines ) {
|
303 |
$line =~ m/$ROUTERIPMACMIB\.([0-9]+)\.([0-9.]+)\s=\sHex-STRING:\s([0-9a-z ]+)/i;
|
307 |
$line =~ m/$ROUTERIPMACMIB\.([0-9]+)\.([0-9.]+)\s=\sHex-STRING:\s([0-9a-z ]+)/i;
|
304 |
my $interface = $1;
|
308 |
my $interface = $1;
|
Line 307... |
Line 311... |
307 |
$mac =~ s/ //g;
|
311 |
$mac =~ s/ //g;
|
308 |
&updateIP( \%switchports, $ip, $mac );
|
312 |
&updateIP( \%switchports, $ip, $mac );
|
309 |
}
|
313 |
}
|
310 |
}
|
314 |
}
|
311 |
|
315 |
|
- |
|
316 |
# now, process any static maps we might have
|
- |
|
317 |
if ( defined( $config{'staticmaps'} ) ) {
|
- |
|
318 |
# let's make sure there is an entry for each one
|
- |
|
319 |
foreach my $entry ( keys %{$config{'staticmaps'}} ) {
|
- |
|
320 |
&initialize( \%{$config{'staticmaps'}}, $entry, 'ip','hostname','override' );
|
- |
|
321 |
}
|
- |
|
322 |
# this seems counter productive to make a pass through the whole switchport hash when there may only be one staticmap
|
- |
|
323 |
# but this way, we only make one pass whereas if we were to go through each static map, we would make one pass for
|
- |
|
324 |
# each mapping.
|
- |
|
325 |
foreach my $switch ( keys %switchports ) {
|
- |
|
326 |
foreach my $portnum (keys %{ $switchports{$switch}{'ports'} } ) {
|
- |
|
327 |
foreach my $connection ( keys %{ $switchports{$switch}{'ports'}{$portnum} } ) {
|
- |
|
328 |
next if $connection eq 'description' or $connection eq 'alias';
|
- |
|
329 |
my $mac = $switchports{$switch}{'ports'}{$portnum}{$connection}{'mac'};
|
- |
|
330 |
if ( defined ( $config{'staticmaps'}{$mac} ) ) {
|
- |
|
331 |
if ( $config{'staticmaps'}{$mac}{'ip'} && ( $config{'staticmaps'}{$mac}{'override'} || ! $switchports{$switch}{'ports'}{$portnum}{$connection}{'ip'} ) ) {
|
- |
|
332 |
$switchports{$switch}{'ports'}{$portnum}{$connection}{'ip'} = $config{'staticmaps'}{$mac}{'ip'};
|
- |
|
333 |
}
|
- |
|
334 |
if ( $config{'staticmaps'}{$mac}{'hostname'} && ( $config{'staticmaps'}{$mac}{'override'} || ! $switchports{$switch}{'ports'}{$portnum}{$connection}{'hostname'} ) ) {
|
- |
|
335 |
$switchports{$switch}{'ports'}{$portnum}{$connection}{'hostname'} = $config{'staticmaps'}{$mac}{'hostname'};
|
- |
|
336 |
}
|
- |
|
337 |
} # if there is an entry
|
- |
|
338 |
} # checking each connection
|
- |
|
339 |
} # checking each port number
|
- |
|
340 |
} # checking each switch
|
- |
|
341 |
} # if defined
|
- |
|
342 |
|
312 |
#die Dumper( \%switchports );
|
343 |
#die Dumper( \%switchports );
|
313 |
|
344 |
|
314 |
# save the state file for later, so we can find things which disappear from the network
|
345 |
# save the state file for later, so we can find things which disappear from the network
|
315 |
my $yaml = YAML::Tiny->new( \%switchports );
|
346 |
my $yaml = YAML::Tiny->new( \%switchports );
|
316 |
$yaml->write( $STATEFILE );
|
347 |
$yaml->write( $STATEFILE );
|