Subversion Repositories sysadmin_scripts

Rev

Rev 3 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3 Rev 5
Line 15... Line 15...
15
# As new entries become available, they are added. A time stamp
15
# As new entries become available, they are added. A time stamp
16
# records the last time an entry was "seen"
16
# records the last time an entry was "seen"
17
 
17
 
18
# Data is stored in the hash %switchports with the following structure
18
# Data is stored in the hash %switchports with the following structure
19
# %switchports =
19
# %switchports =
20
#     {switch} (from %switches key)
20
#     {switch} (from $config{'switches'} key)
21
#        {name} (scalar, from snmp)
21
#        {name} (scalar, from snmp)
22
#        {location} (scalar, from snmp)
22
#        {location} (scalar, from snmp)
23
#        {'ports'} (constant key for sub hash)
23
#        {'ports'} (constant key for sub hash)
24
#           {port number} (from snmp)
24
#           {port number} (from snmp)
25
#              {connection} (uniqe id from snmp, basically the MAC)
25
#              {connection} (uniqe id from snmp, basically the MAC)
26
#                 {mac} (from snmp walk of switch)
26
#                 {mac} (from snmp walk of switch)
27
#                 {ip}  (from snmp walk of router)
27
#                 {ip}  (from snmp walk of router)
28
#                 {hostname} (from reverse dns query)
28
#                 {hostname} (from reverse dns query)
29
#                 {lastseen} (last time this was active as unix timestamp)
29
#                 {lastseen} (last time this was active as unix timestamp)
30
 
30
 
-
 
31
# 20190407 RWR
-
 
32
# converted to use external config file in YAML format
-
 
33
# added the ability to ignore ports on the switches
-
 
34
 
31
use strict;
35
use strict;
32
use warnings;
36
use warnings;
33
#use Data::Dumper; # only used for debugging
37
use Data::Dumper; # only used for debugging
34
use Socket; # for reverse dns entries
38
use Socket; # for reverse dns entries
35
use YAML::Tiny; # apt-get libyaml-tiny-perl under debian
39
use YAML::Tiny; # apt-get libyaml-tiny-perl under debian
36
use File::Spec; # find location of script so we can put storage in same directory
40
use File::Spec; # find location of script so we can put storage in same directory
37
use File::Basename;
41
use File::Basename;
38
 
42
 
39
# one or more switches and their corresponding
-
 
40
# community name. Use v1 snmp only
-
 
41
my %switches = (
-
 
42
                   'dns name or ip' => 'snmp v1 community name',
-
 
43
                   #'dns name or ip' => 'snmp v1 community name'
-
 
44
               );
-
 
45
 
-
 
46
# You must include at least one router.
-
 
47
# this will be queried to resolve IP's to MAC 
-
 
48
# using its arp table
-
 
49
# put IP and community name into the hash
-
 
50
my %routers = (
43
my %config;
51
                   'dns name or ip' => 'snmp v1 read/only community name',
-
 
52
                   #'dns name or ip' => 'snmp v1 read/only community name',
-
 
53
              );
-
 
54
 
44
 
55
# where the script is located
45
# where the script is located
56
my $scriptDir = dirname( File::Spec->rel2abs( __FILE__ ) );
46
my $scriptDir = dirname( File::Spec->rel2abs( __FILE__ ) );
57
# put the statefile in there
47
# put the statefile in there
58
my $STATEFILE = $scriptDir . '/mapSwitches.yaml';
48
my $STATEFILE = $scriptDir . '/mapSwitches.yaml';
-
 
49
my $CONFIGFILE = $scriptDir . '/mapSwitches.config.yaml';
59
# main hash that holds the data we collect
50
# main hash that holds the data we collect
60
my %switchports;
51
my %switchports;
61
# some OIDS we need for the program
52
# some OIDS we need for the program
62
my $SWITCHPORTMIB  = 'iso.3.6.1.2.1.17.4.3.1.2';
53
my $SWITCHPORTMIB  = 'iso.3.6.1.2.1.17.4.3.1.2';
63
my $SWITCHMACMIB   = 'iso.3.6.1.2.1.17.4.3.1.1';
54
my $SWITCHMACMIB   = 'iso.3.6.1.2.1.17.4.3.1.1';
Line 115... Line 106...
115
         } # for connection
106
         } # for connection
116
      } # for port
107
      } # for port
117
   } # for switch
108
   } # for switch
118
} # updateIP
109
} # updateIP
119
 
110
 
-
 
111
if ( -e $CONFIGFILE ) {
-
 
112
   my $yaml = YAML::Tiny->read( $CONFIGFILE );
-
 
113
   %config = %{ $yaml->[0] };
-
 
114
} else {
-
 
115
   die "could not locate config file $CONFIGFILE\n";
-
 
116
}
-
 
117
 
120
# read the saved state into memory if it exists
118
# read the saved state into memory if it exists
121
if ( -e $STATEFILE ) {
119
if ( -e $STATEFILE ) {
122
   my $yaml = YAML::Tiny->read( $STATEFILE );
120
   my $yaml = YAML::Tiny->read( $STATEFILE );
123
   %switchports = %{ $yaml->[0] };
121
   %switchports = %{ $yaml->[0] };
124
}
122
}
125
 
123
 
126
# first, get all of the MAC/Port assignments from the switches
124
# first, get all of the MAC/Port assignments from the switches
127
foreach my $switch ( keys %switches ) {
125
foreach my $switch ( keys %{$config{'switches'}} ) {
128
   &initialize( \%switchports, $switch, 'name','location' );
126
   &initialize( \%switchports, $switch, 'name','location' );
129
   &updateValue(
127
   &updateValue(
130
      \$switchports{$switch}{'name'},
128
      \$switchports{$switch}{'name'},
131
      &getOneSNMPValue( $DEVICENAMEMIB,$switches{$switch},$switch, '= STRING: "?([^"]*)"?' )
129
      &getOneSNMPValue( $DEVICENAMEMIB,$config{'switches'}{$switch}{'community'},$switch, '= STRING: "?([^"]*)"?' )
132
      );
130
      );
133
 
131
 
134
   &updateValue(
132
   &updateValue(
135
      \$switchports{$switch}{'location'},
133
      \$switchports{$switch}{'location'},
136
      &getOneSNMPValue( $DEVICELOCMIB,$switches{$switch},$switch, '= STRING: "?([^"]*)"?' )
134
      &getOneSNMPValue( $DEVICELOCMIB,$config{'switches'}{$switch}{'community'},$switch, '= STRING: "?([^"]*)"?' )
137
      );
135
      );
138
 
136
 
139
   my $values = `snmpwalk -v1 -c $switches{$switch} $switch $SWITCHPORTMIB`;
137
   my $values = `snmpwalk -v1 -c $config{switches}{$switch}{'community'} $switch $SWITCHPORTMIB`;
140
   my @lines = split( "\n", $values );
138
   my @lines = split( "\n", $values );
141
   foreach my $line ( @lines ) {
139
   foreach my $line ( @lines ) {
142
      $line =~ m/$SWITCHPORTMIB\.([0-9.]+)\s=\sINTEGER:\s+(\d+)/;
140
      $line =~ m/$SWITCHPORTMIB\.([0-9.]+)\s=\sINTEGER:\s+(\d+)/;
-
 
141
      my $uuid = $1; # this is the ID string of this MAC; normally the MAC itself in decimal form
-
 
142
      my $port = $2; # this is the port number
143
      next unless $2; # skip port 0, or any port which has nothing
143
      next unless $port; # skip port 0, or any port which has nothing
-
 
144
      next if $config{'switches'}{$switch}{'portsToIgnore'} && grep( /^$port$/, @{$config{'switches'}{$switch}{'portsToIgnore'}} );
144
      $switchports{$switch}{'ports'}{$2}{$1}{'mac'} = &makeMAC( $1 );
145
      $switchports{$switch}{'ports'}{$port}{$uuid}{'mac'} = &makeMAC( $1 );
145
   }
146
   }
146
}
147
}
147
 
148
 
148
# die Dumper( \%switchports );
149
# die Dumper( \%switchports );
149
 
150
 
150
 
151
 
151
# Now, try to match up the MAC address. Read the ARP table from the router(s)
152
# Now, try to match up the MAC address. Read the ARP table from the router(s)
152
foreach my $router ( keys %routers ) {
153
foreach my $router ( keys %{$config{'routers'}} ) {
153
   my $values = `snmpwalk -v1 -c $routers{$router} $router $ROUTERIPMACMIB`;
154
   my $values = `snmpwalk -v1 -c $config{routers}{$router}{community} $router $ROUTERIPMACMIB`;
154
   my @lines = split( "\n", $values );
155
   my @lines = split( "\n", $values );
155
   foreach my $line ( @lines ) {
156
   foreach my $line ( @lines ) {
156
      $line =~ m/$ROUTERIPMACMIB\.([0-9]+)\.([0-9.]+)\s=\sHex-STRING:\s([0-9a-z ]+)/i;
157
      $line =~ m/$ROUTERIPMACMIB\.([0-9]+)\.([0-9.]+)\s=\sHex-STRING:\s([0-9a-z ]+)/i;
157
      my $interface = $1;
158
      my $interface = $1;
158
      my $ip = $2;
159
      my $ip = $2;