Squashed commit of the following: commita43c98962aAuthor: Oliver Gorwits <oliver@cpan.org> Date: Mon Jun 3 20:37:39 2013 +0100 Missing mibdirs causes all MIBs to be loaded (with a warning) commit09829a25b8Author: Oliver Gorwits <oliver@cpan.org> Date: Mon Jun 3 20:07:31 2013 +0100 local plugins site_plugins dir commitb0e804e558Author: Oliver Gorwits <oliver@cpan.org> Date: Mon Jun 3 19:59:04 2013 +0100 use send_error and redirect from Dancer commit3d1185261aAuthor: Oliver Gorwits <oliver@cpan.org> Date: Mon Jun 3 19:13:40 2013 +0100 support path config option commit31ca119f84Merge:9a798554d2b3a5Author: Oliver Gorwits <oliver@cpan.org> Date: Mon Jun 3 00:06:17 2013 +0100 Merge remote-tracking branch 'origin/og-work' into og-work g-work" This reverts commit9a79855361, reversing changes made to6fd6118354. Conflicts: Netdisco/share/views/plugin/device_port_column/c_observiumsparklines.tt commit9a79855361Merge:6fd6118c8c3b82Author: Oliver Gorwits <oliver@cpan.org> Date: Mon Jun 3 00:03:32 2013 +0100 Merge remote-tracking branch 'origin/master' into og-work commit6fd6118354Author: Oliver Gorwits <oliver@cpan.org> Date: Sun Jun 2 15:47:45 2013 +0100 extra note about behind proxy commit798086ca29Author: Oliver Gorwits <oliver@cpan.org> Date: Sun Jun 2 15:30:26 2013 +0100 complete the observium plugin commit66b3ced179Author: Oliver Gorwits <oliver@cpan.org> Date: Sun Jun 2 12:48:06 2013 +0100 Plugins can have CSS and Javascript loaded within <head> commit4d2b3a5307Author: Oliver Gorwits <oliver@cpan.org> Date: Thu May 30 08:50:16 2013 +0100 get device dns to port template commited1bfa1ae7Author: Oliver Gorwits <oliver@cpan.org> Date: Thu May 30 08:17:02 2013 +0100 observium sparklines plugin; support X:: namespace commit76b7636c74Author: Oliver Gorwits <oliver@cpan.org> Date: Thu May 30 06:30:06 2013 +0100 rename private settings keys commitfdac8f6c33Author: Oliver Gorwits <oliver@cpan.org> Date: Thu May 30 05:59:53 2013 +0100 add macwalk and arpnip buttons to device details commit3d688c7d83Author: Oliver Gorwits <oliver@cpan.org> Date: Thu May 30 05:57:20 2013 +0100 Revert "reduce refresh to 5sec" This reverts commit8ea9ec7dd9. commitdc62382112Author: Oliver Gorwits <oliver@cpan.org> Date: Thu May 30 05:50:34 2013 +0100 support for arpwalk and macwalk and all jobs via web commit8bc7d83c98Author: Oliver Gorwits <oliver@cpan.org> Date: Thu May 30 05:35:41 2013 +0100 simplify discover options to only discoverall and discover commit8ea9ec7dd9Author: Oliver Gorwits <oliver@cpan.org> Date: Wed May 29 20:23:08 2013 +0100 reduce refresh to 5sec commit8c54e6c58bAuthor: Oliver Gorwits <oliver@cpan.org> Date: Wed May 29 20:11:06 2013 +0100 show undiscovered neighbor properly commite0ee25628fAuthor: Oliver Gorwits <oliver@cpan.org> Date: Wed May 29 19:54:09 2013 +0100 avoid unecessary log for queueing commitd5565423f2Author: Oliver Gorwits <oliver@cpan.org> Date: Wed May 29 19:51:37 2013 +0100 avoid warning on undefined remote type commit5d9b58a6b2Author: Oliver Gorwits <oliver@cpan.org> Date: Wed May 29 19:48:22 2013 +0100 avoid explosion when not admin commit377bb942e0Author: Oliver Gorwits <oliver@cpan.org> Date: Wed May 29 19:46:52 2013 +0100 avoid undefined warning commit08806dcfa2Author: Oliver Gorwits <oliver@cpan.org> Date: Wed May 29 19:46:42 2013 +0100 get_db_version will be 0 at first deploy commit9511c17056Author: Oliver Gorwits <oliver@cpan.org> Date: Wed May 29 19:15:55 2013 +0100 fix name of Template module commiteb0288de35Author: Oliver Gorwits <oliver@cpan.org> Date: Tue May 28 07:17:07 2013 +0100 initial config settings documentation commit7f2ea7f8dcAuthor: Oliver Gorwits <oliver@cpan.org> Date: Mon May 27 15:18:15 2013 +0100 remove check_mac to own module, use in macsuck too commitb995cf6398Author: Oliver Gorwits <oliver@cpan.org> Date: Mon May 27 15:01:29 2013 +0100 show probable but undiscovered neighbor is ports display commitdd8d461188Author: Oliver Gorwits <oliver@cpan.org> Date: Mon May 27 14:52:41 2013 +0100 new schema version for is_uplink and is_uplink_admin commit3f6a7b5aa2Author: Oliver Gorwits <oliver@cpan.org> Date: Mon May 27 14:47:59 2013 +0100 make sure device_port is updated when manual_topo is set commit33bf9a6599Author: Oliver Gorwits <oliver@cpan.org> Date: Sun May 26 19:51:49 2013 +0100 export store_arp and store_node commit0ed356d560Author: Oliver Gorwits <oliver@cpan.org> Date: Sat May 25 17:12:31 2013 +0100 use row lock not table lock commitf830bc3a3bAuthor: Oliver Gorwits <oliver@cpan.org> Date: Sat May 25 16:38:33 2013 +0100 move macsuck/arpnip/discover to ::Core namespace commitbe40788987Author: Oliver Gorwits <oliver@cpan.org> Date: Fri May 24 21:10:34 2013 +0100 add maybe_uplink to device_port; more macsuck implementation commit88371026d5Author: Oliver Gorwits <oliver@cpan.org> Date: Fri May 24 14:34:58 2013 +0100 start on macsuck; tweak update locking commit6f7c87ac07Author: Oliver Gorwits <oliver@cpan.org> Date: Fri May 24 13:10:58 2013 +0100 ORDER BY ... FOR UPDATE will allow us to avoid table lock commit7c438e01fcAuthor: Oliver Gorwits <oliver@cpan.org> Date: Fri May 24 12:12:46 2013 +0100 yet more efficient arpnip commitc74c56dc02Author: Oliver Gorwits <oliver@cpan.org> Date: Fri May 24 11:34:23 2013 +0100 guard against race with *_or_* DBIC methods commitd50c54972eAuthor: Oliver Gorwits <oliver@cpan.org> Date: Mon May 20 23:42:41 2013 +0100 more efficient arpnip commit73c8979130Author: Oliver Gorwits <oliver@cpan.org> Date: Sun May 19 22:52:15 2013 +0100 fix confusing name commitbf78e82411Author: Oliver Gorwits <oliver@cpan.org> Date: Sun May 19 22:37:22 2013 +0100 fix mistake in DBIx::Class schema commit6a5af95836Author: Oliver Gorwits <oliver@cpan.org> Date: Sun May 19 22:06:27 2013 +0100 arpnip implementation commit594abd3f82Author: Oliver Gorwits <oliver@cpan.org> Date: Thu May 16 00:00:50 2013 +0100 PostgreSQL explicit locking support. Squashed commit of the following: commit76e1539102Author: Oliver Gorwits <oliver@cpan.org> Date: Wed May 15 23:54:25 2013 +0100 finished explicit locking module commit369387258bAuthor: Oliver Gorwits <oliver@cpan.org> Date: Tue May 14 23:50:42 2013 +0100 initial implementation of locking from schema object commit55c6d4fe63Author: Oliver Gorwits <oliver@cpan.org> Date: Tue May 14 21:05:01 2013 +0100 add discover button to device details page commit11fd8bf964Author: Oliver Gorwits <oliver@cpan.org> Date: Tue May 14 20:43:43 2013 +0100 fix typo and clear port box on autocomplete dropdown commita00f9b5c2eAuthor: Oliver Gorwits <oliver@cpan.org> Date: Tue May 14 20:38:54 2013 +0100 move admin tasks and remove JobControl package commit74bc0023dfAuthor: Oliver Gorwits <oliver@cpan.org> Date: Sat May 11 18:25:04 2013 +0100 complete job queue delete and kill running timers properly when reloading page commitdd6947f38dAuthor: Oliver Gorwits <oliver@cpan.org> Date: Sat May 11 16:51:28 2013 +0100 fix improper use of bootstrap table class commitcd5b83f71eAuthor: Oliver Gorwits <oliver@cpan.org> Date: Sat May 11 15:55:45 2013 +0100 fix update view icon in sidebar commite9349f325dAuthor: Oliver Gorwits <oliver@cpan.org> Date: Sat May 11 11:57:19 2013 +0100 css audit commit201470275dAuthor: Oliver Gorwits <oliver@cpan.org> Date: Thu May 9 23:48:05 2013 +0100 add job queue to standard plugins list commita18a3c72a3Author: Oliver Gorwits <oliver@cpan.org> Date: Thu May 9 23:37:43 2013 +0100 fix table headings and improve Action display in Job Queue commit70f5da8bb6Author: Oliver Gorwits <oliver@cpan.org> Date: Thu May 9 23:30:32 2013 +0100 implement "no devices" prompt for admin users to do first discover commit2e8ac83173Author: Oliver Gorwits <oliver@cpan.org> Date: Thu May 9 21:53:39 2013 +0100 more js refactoring for report and search commit479ac0e55dAuthor: Oliver Gorwits <oliver@cpan.org> Date: Thu May 9 21:50:29 2013 +0100 refactor js for device tabs commit6a17fe5d6cAuthor: Oliver Gorwits <oliver@cpan.org> Date: Thu May 9 21:05:42 2013 +0100 fix crazy races with javasacript by using global delegations commite94e3cef3bAuthor: Oliver Gorwits <oliver@cpan.org> Date: Wed May 8 23:06:41 2013 +0100 remove Try::Tiny from web runtime commitc746e68b9bAuthor: Oliver Gorwits <oliver@cpan.org> Date: Tue May 7 21:54:11 2013 +0100 make topo autocomplete more responsive commit24c511786fAuthor: Oliver Gorwits <oliver@cpan.org> Date: Tue May 7 21:52:17 2013 +0100 display name and IP for device typeahead commit52ab7d1266Author: Oliver Gorwits <oliver@cpan.org> Date: Tue May 7 21:47:05 2013 +0100 add drop-down control for the topo form fields commit5744b6845fAuthor: Oliver Gorwits <oliver@cpan.org> Date: Tue May 7 21:25:30 2013 +0100 complete the topology editor (add/delete) commitb510fbe8c5Author: Oliver Gorwits <oliver@cpan.org> Date: Tue May 7 00:59:11 2013 +0100 add new admin tasks to default plugins list commit11d55e0129Author: Oliver Gorwits <oliver@cpan.org> Date: Tue May 7 00:56:19 2013 +0100 Manual Device Topology Needed to add the 'autocomplete' jQuery UI component because it can do minLength=0 properly. Used the smoothness UI theme. Added typeahead AJAX calls to support the topology searching. Added new plugin and template for the topology editing page. commitbf7a419d08Author: Oliver Gorwits <oliver@cpan.org> Date: Mon May 6 22:16:24 2013 +0100 add a little colour to lone tab titles commit9690a31f19Author: Oliver Gorwits <oliver@cpan.org> Date: Mon May 6 22:01:13 2013 +0100 complete Manage Pseudo Devices commit024f4d9a83Author: Oliver Gorwits <oliver@cpan.org> Date: Mon May 6 00:49:47 2013 +0100 use bootstrap font colour instead of css commitf75f1e5cbfAuthor: Oliver Gorwits <oliver@cpan.org> Date: Mon May 6 00:45:18 2013 +0100 add frontend update/del forms, and display port count commitf0899e16b3Author: Oliver Gorwits <oliver@cpan.org> Date: Sun May 5 23:53:20 2013 +0100 add frontend pseudo device add form commit3271c01931Author: Oliver Gorwits <oliver@cpan.org> Date: Sun May 5 21:45:17 2013 +0100 complete the code for admin tasks page loading commit38f70624f3Author: Oliver Gorwits <oliver@cpan.org> Date: Sun May 5 17:04:30 2013 +0100 set up file paths consistently in all scripts commitc761ca839bAuthor: Oliver Gorwits <oliver@cpan.org> Date: Sun May 5 17:00:30 2013 +0100 Helper script to import the Netdisco 1.x Topology file to the database commitf468b48049Author: Oliver Gorwits <oliver@cpan.org> Date: Sun May 5 16:20:39 2013 +0100 Handle whitespace ahead of OUI data commit5c8a5754f6Author: Oliver Gorwits <oliver@cpan.org> Date: Sun May 5 16:16:20 2013 +0100 also set neighbor info when discovering device interfaces commitacb988b6afAuthor: Oliver Gorwits <oliver@cpan.org> Date: Sun May 5 15:34:20 2013 +0100 try to avoid duplicate execution of scheduled jobs commitc6bcaf66c5Author: Oliver Gorwits <oliver@cpan.org> Date: Sun May 5 14:16:25 2013 +0100 do not clobber manual topo when discovering neighbors commitd9a6a1882aAuthor: Oliver Gorwits <oliver@cpan.org> Date: Sun May 5 13:02:45 2013 +0100 User icon color indicates port_control/admin ability commit2cdcb9db7eAuthor: Oliver Gorwits <oliver@cpan.org> Date: Mon Apr 29 23:34:27 2013 +0100 add support for admin tasks as plugins commit075a770c9aAuthor: Oliver Gorwits <oliver@cpan.org> Date: Mon Apr 29 22:23:20 2013 +0100 skip pseudo devices (vendor netdisco) commit045c022d42Author: Oliver Gorwits <oliver@cpan.org> Date: Mon Apr 29 21:58:33 2013 +0100 incorporate manual topo info from the topology db table commit09285d42b4Author: Oliver Gorwits <oliver@cpan.org> Date: Sat Apr 27 18:39:12 2013 +0100 add unique constraints to topology table commit2780b72e49Author: Oliver Gorwits <oliver@cpan.org> Date: Sat Apr 27 15:38:05 2013 +0100 muted help text in sidebar commit733d4f83fbAuthor: Oliver Gorwits <oliver@cpan.org> Date: Sat Apr 27 14:39:54 2013 +0100 sorry, testing hook changes commit71e366e352Author: Oliver Gorwits <oliver@cpan.org> Date: Sat Apr 27 14:34:36 2013 +0100 sorry, testing hook changes commit7f9eaa99f5Author: Oliver Gorwits <oliver@cpan.org> Date: Sat Apr 27 14:33:44 2013 +0100 sorry, testing hook changes commit5215fd632dAuthor: Oliver Gorwits <oliver@cpan.org> Date: Sat Apr 27 14:30:07 2013 +0100 sorry, testing hook changes commitbe817d60c2Author: Oliver Gorwits <oliver@cpan.org> Date: Sat Apr 27 14:21:45 2013 +0100 sorry, testing hook changes commit1fd3695358Author: Oliver Gorwits <oliver@cpan.org> Date: Sat Apr 27 14:18:57 2013 +0100 sorry, testing hook changes commitac448c4a91Author: Oliver Gorwits <oliver@cpan.org> Date: Sat Apr 27 14:13:03 2013 +0100 sorry, testing hook changes commitc563b8d9afAuthor: Oliver Gorwits <oliver@cpan.org> Date: Sat Apr 27 14:08:54 2013 +0100 sorry, testing hook changes commit3abcfb01d5Author: Oliver Gorwits <oliver@cpan.org> Date: Sat Apr 27 14:06:25 2013 +0100 sorry, testing hook changes commit877a81facfAuthor: Oliver Gorwits <oliver@cpan.org> Date: Sat Apr 27 14:05:25 2013 +0100 sorry, testing hook changes
458 lines
13 KiB
Perl
458 lines
13 KiB
Perl
package App::Netdisco::Core::Macsuck;
|
|
|
|
use Dancer qw/:syntax :script/;
|
|
use Dancer::Plugin::DBIC 'schema';
|
|
|
|
use App::Netdisco::Util::PortMAC 'get_port_macs';
|
|
use App::Netdisco::Util::SanityCheck 'check_mac';
|
|
use App::Netdisco::Util::SNMP 'snmp_comm_reindex';
|
|
use Time::HiRes 'gettimeofday';
|
|
|
|
use base 'Exporter';
|
|
our @EXPORT = ();
|
|
our @EXPORT_OK = qw/
|
|
do_macsuck
|
|
store_node
|
|
store_wireless_client_info
|
|
/;
|
|
our %EXPORT_TAGS = (all => \@EXPORT_OK);
|
|
|
|
=head1 NAME
|
|
|
|
App::Netdisco::Core::Macsuck
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
Helper subroutines to support parts of the Netdisco application.
|
|
|
|
There are no default exports, however the C<:all> tag will export all
|
|
subroutines.
|
|
|
|
=head1 EXPORT_OK
|
|
|
|
=head2 do_macsuck( $device, $snmp )
|
|
|
|
Given a Device database object, and a working SNMP connection, connect to a
|
|
device and discover the MAC addresses listed against each physical port
|
|
without a neighbor.
|
|
|
|
If the device has VLANs, C<do_macsuck> will walk each VALN to get the MAC
|
|
addresses from there.
|
|
|
|
It will also gather wireless client information if C<store_wireless_client>
|
|
configuration setting is enabled.
|
|
|
|
=cut
|
|
|
|
sub do_macsuck {
|
|
my ($device, $snmp) = @_;
|
|
|
|
unless ($device->in_storage) {
|
|
debug sprintf
|
|
' [%s] macsuck - skipping device not yet discovered',
|
|
$device->ip;
|
|
return;
|
|
}
|
|
|
|
# would be possible just to use now() on updated records, but by using this
|
|
# same value for them all, we _can_ if we want add a job at the end to
|
|
# select and do something with the updated set (no reason to yet, though)
|
|
my $now = 'to_timestamp('. (join '.', gettimeofday) .')';
|
|
my $total_nodes = 0;
|
|
|
|
# do this before we start messing with the snmp community string
|
|
store_wireless_client_info($device, $snmp, $now);
|
|
|
|
# cache the device ports to save hitting the database for many single rows
|
|
my $device_ports = {map {($_->port => $_)} $device->ports->all};
|
|
my $port_macs = get_port_macs($device);
|
|
|
|
# get forwarding table data via basic snmp connection
|
|
my $fwtable = { 0 => _walk_fwtable($device, $snmp, $port_macs, $device_ports) };
|
|
|
|
# ...then per-vlan if supported
|
|
my @vlan_list = _get_vlan_list($device, $snmp);
|
|
foreach my $vlan (@vlan_list) {
|
|
snmp_comm_reindex($snmp, $vlan);
|
|
$fwtable->{$vlan} = _walk_fwtable($device, $snmp, $port_macs, $device_ports);
|
|
}
|
|
|
|
# now it's time to call store_node for every node discovered
|
|
# on every port on every vlan on this device.
|
|
|
|
# reverse sort allows vlan 0 entries to be included only as fallback
|
|
foreach my $vlan (reverse sort keys %$fwtable) {
|
|
foreach my $port (keys %{ $fwtable->{$vlan} }) {
|
|
if ($device_ports->{$port}->is_uplink) {
|
|
debug sprintf
|
|
' [%s] macsuck - port %s is uplink, topo broken - skipping.',
|
|
$device->ip, $port;
|
|
next;
|
|
}
|
|
|
|
debug sprintf ' [%s] macsuck - port %s vlan %s : %s nodes',
|
|
$device->ip, $port, $vlan, scalar keys %{ $fwtable->{$vlan}->{$port} };
|
|
|
|
foreach my $mac (keys %{ $fwtable->{$vlan}->{$port} }) {
|
|
# remove vlan 0 entry for this MAC addr
|
|
delete $fwtable->{0}->{$_}->{$mac}
|
|
for keys %{ $fwtable->{0} };
|
|
|
|
++$total_nodes;
|
|
store_node($device->ip, $vlan, $port, $mac, $now);
|
|
}
|
|
}
|
|
}
|
|
|
|
debug sprintf ' [%s] macsuck - %s forwarding table entries',
|
|
$device->ip, $total_nodes;
|
|
$device->update({last_macsuck => \$now});
|
|
}
|
|
|
|
=head2 store_node( $ip, $vlan, $port, $mac, $now? )
|
|
|
|
Writes a fresh entry to the Netdisco C<node> database table. Will mark old
|
|
entries for this data as no longer C<active>.
|
|
|
|
All four fields in the tuple are required. If you don't know the VLAN ID,
|
|
Netdisco supports using ID "0".
|
|
|
|
Optionally, a fifth argument can be the literal string passed to the time_last
|
|
field of the database record. If not provided, it defauls to C<now()>.
|
|
|
|
=cut
|
|
|
|
sub store_node {
|
|
my ($ip, $vlan, $port, $mac, $now) = @_;
|
|
$now ||= 'now()';
|
|
|
|
schema('netdisco')->txn_do(sub {
|
|
my $nodes = schema('netdisco')->resultset('Node');
|
|
|
|
# TODO: probably needs changing if we're to support VTP domains
|
|
my $old = $nodes->search(
|
|
{
|
|
mac => $mac,
|
|
vlan => $vlan,
|
|
-bool => 'active',
|
|
-not => {
|
|
switch => $ip,
|
|
port => $port,
|
|
},
|
|
});
|
|
|
|
# lock rows,
|
|
# and get the count so we know whether to set time_recent
|
|
my $old_count = scalar $old->search(undef,
|
|
{
|
|
columns => [qw/switch vlan port mac/],
|
|
order_by => [qw/switch vlan port mac/],
|
|
for => 'update',
|
|
})->all;
|
|
|
|
$old->update({ active => \'false' });
|
|
|
|
my $new = $nodes->search(
|
|
{
|
|
'me.switch' => $ip,
|
|
'me.port' => $port,
|
|
'me.mac' => $mac,
|
|
},
|
|
{
|
|
order_by => [qw/switch vlan port mac/],
|
|
for => 'update',
|
|
});
|
|
|
|
# lock rows
|
|
$new->search({vlan => [$vlan, 0, undef]})->first;
|
|
|
|
# upgrade old schema
|
|
$new->search({vlan => [$vlan, 0, undef]})
|
|
->update({vlan => $vlan});
|
|
|
|
$new->update_or_create({
|
|
vlan => $vlan,
|
|
active => \'true',
|
|
oui => substr($mac,0,8),
|
|
time_last => \$now,
|
|
($old_count ? (time_recent => \$now) : ()),
|
|
});
|
|
});
|
|
}
|
|
|
|
# return a list of vlan numbers which are OK to macsuck on this device
|
|
sub _get_vlan_list {
|
|
my ($device, $snmp) = @_;
|
|
|
|
return () unless $snmp->cisco_comm_indexing;
|
|
|
|
my (%vlans, %vlan_names);
|
|
my $i_vlan = $snmp->i_vlan || {};
|
|
|
|
# get list of vlans in use
|
|
while (my ($idx, $vlan) = each %$i_vlan) {
|
|
# hack: if vlan id comes as 1.142 instead of 142
|
|
$vlan =~ s/^\d+\.//;
|
|
|
|
++$vlans{$vlan};
|
|
}
|
|
|
|
unless (scalar keys %vlans) {
|
|
debug sprintf ' [%s] macsuck - no VLANs found.', $device->ip;
|
|
return ();
|
|
}
|
|
|
|
my $v_name = $snmp->v_name || {};
|
|
|
|
# get vlan names (required for config which filters by name)
|
|
while (my ($idx, $name) = each %$v_name) {
|
|
# hack: if vlan id comes as 1.142 instead of 142
|
|
(my $vlan = $idx) =~ s/^\d+\.//;
|
|
|
|
# just in case i_vlan is different to v_name set
|
|
++$vlans{$vlan};
|
|
|
|
$vlan_names{$vlan} = $name;
|
|
}
|
|
|
|
debug sprintf ' [%s] macsuck - VLANs: %s', $device->ip,
|
|
(join ',', sort keys %vlans);
|
|
|
|
my @ok_vlans = ();
|
|
foreach my $vlan (sort keys %vlans) {
|
|
my $name = $vlan_names{$vlan} || '(unnamed)';
|
|
|
|
# FIXME: macsuck_no_vlan
|
|
# FIXME: macsuck_no_devicevlan
|
|
|
|
if (setting('macsuck_no_unnamed') and $name eq '(unnamed)') {
|
|
debug sprintf
|
|
' [%s] macsuck VLAN %s - skipped by macsuck_no_unnamed config',
|
|
$device->ip, $vlan;
|
|
next;
|
|
}
|
|
|
|
if ($vlan == 0 or $vlan > 4094) {
|
|
debug sprintf ' [%s] macsuck - invalid VLAN number %s',
|
|
$device->ip, $vlan;
|
|
next;
|
|
}
|
|
|
|
# check in use by a port on this device
|
|
if (scalar keys %$i_vlan and not exists $vlans{$vlan}
|
|
and not setting('macsuck_all_vlans')) {
|
|
|
|
debug sprintf
|
|
' [%s] macsuck VLAN %s/%s - not in use by any port - skipping.',
|
|
$device->ip, $vlan, $name;
|
|
next;
|
|
}
|
|
|
|
push @ok_vlans, $vlan;
|
|
}
|
|
|
|
return @ok_vlans;
|
|
}
|
|
|
|
# walks the forwarding table (BRIDGE-MIB) for the device and returns a
|
|
# table of node entries.
|
|
sub _walk_fwtable {
|
|
my ($device, $snmp, $port_macs, $device_ports) = @_;
|
|
my $cache = {};
|
|
|
|
my $fw_mac = $snmp->fw_mac;
|
|
my $fw_port = $snmp->fw_port;
|
|
my $fw_vlan = $snmp->qb_fw_vlan;
|
|
my $bp_index = $snmp->bp_index;
|
|
my $interfaces = $snmp->interfaces;
|
|
|
|
# to map forwarding table port to device port we have
|
|
# fw_port -> bp_index -> interfaces
|
|
|
|
while (my ($idx, $mac) = each %$fw_mac) {
|
|
my $bp_id = $fw_port->{$idx};
|
|
next unless check_mac($device, $mac, $port_macs);
|
|
|
|
unless (defined $bp_id) {
|
|
debug sprintf
|
|
' [%s] macsuck %s - %s has no fw_port mapping - skipping.',
|
|
$device->ip, $mac, $idx;
|
|
next;
|
|
}
|
|
|
|
my $iid = $bp_index->{$bp_id};
|
|
|
|
unless (defined $iid) {
|
|
debug sprintf
|
|
' [%s] macsuck %s - port %s has no bp_index mapping - skipping.',
|
|
$device->ip, $mac, $bp_id;
|
|
next;
|
|
}
|
|
|
|
my $port = $interfaces->{$iid};
|
|
|
|
unless (defined $port) {
|
|
debug sprintf
|
|
' [%s] macsuck %s - iid %s has no port mapping - skipping.',
|
|
$device->ip, $mac, $iid;
|
|
next;
|
|
}
|
|
|
|
# TODO: add proper port channel support!
|
|
if ($port =~ m/port.channel/i) {
|
|
debug sprintf
|
|
' [%s] macsuck %s - port %s is LAG member - skipping.',
|
|
$device->ip, $mac, $port;
|
|
next;
|
|
}
|
|
|
|
# this uses the cached $ports resultset to limit hits on the db
|
|
my $device_port = $device_ports->{$port};
|
|
|
|
unless (defined $device_port) {
|
|
debug sprintf
|
|
' [%s] macsuck %s - port %s is not in database - skipping.',
|
|
$device->ip, $mac, $port;
|
|
next;
|
|
}
|
|
|
|
# check to see if the port is connected to another device
|
|
# and if we have that device in the database.
|
|
|
|
# we have several ways to detect "uplink" port status:
|
|
# * a neighbor was discovered using CDP/LLDP
|
|
# * a mac addr is seen which belongs to any device port/interface
|
|
# * (TODO) admin sets is_uplink_admin on the device_port
|
|
|
|
if ($device_port->is_uplink) {
|
|
if (my $neighbor = $device_port->neighbor) {
|
|
debug sprintf
|
|
' [%s] macsuck %s - port %s has neighbor %s - skipping.',
|
|
$device->ip, $mac, $port, $neighbor->ip;
|
|
next;
|
|
}
|
|
elsif (my $remote = $device_port->remote_ip) {
|
|
debug sprintf
|
|
' [%s] macsuck %s - port %s has undiscovered neighbor %s',
|
|
$device->ip, $mac, $port, $remote;
|
|
# continue!!
|
|
}
|
|
else {
|
|
debug sprintf
|
|
' [%s] macsuck %s - port %s is detected uplink - skipping.',
|
|
$device->ip, $mac, $port;
|
|
next;
|
|
}
|
|
}
|
|
|
|
if (exists $port_macs->{$mac}) {
|
|
my $switch_ip = $port_macs->{$mac};
|
|
if ($device->ip eq $switch_ip) {
|
|
debug sprintf
|
|
' [%s] macsuck %s - port %s connects to self - skipping.',
|
|
$device->ip, $mac, $port;
|
|
next;
|
|
}
|
|
|
|
debug sprintf ' [%s] macsuck %s - port %s is probably an uplink',
|
|
$device->ip, $mac, $port;
|
|
$device_port->update({is_uplink => \'true'});
|
|
|
|
# when there's no CDP/LLDP, we only want to gather macs at the
|
|
# topology edge, hence skip ports with known device macs.
|
|
next unless setting('macsuck_bleed');
|
|
}
|
|
|
|
++$cache->{$port}->{$mac};
|
|
}
|
|
|
|
return $cache;
|
|
}
|
|
|
|
=head2 store_wireless_client_info( $device, $snmp, $now? )
|
|
|
|
Given a Device database object, and a working SNMP connection, connect to a
|
|
device and discover 802.11 related information for all connected wireless
|
|
clients.
|
|
|
|
If the device doesn't support the 802.11 MIBs, then this will silently return.
|
|
|
|
If the device does support the 802.11 MIBs but Netdisco's configuration
|
|
does not permit polling (C<store_wireless_client> must be true) then a debug
|
|
message is logged and the subroutine returns.
|
|
|
|
Otherwise, client information is gathered and stored to the database.
|
|
|
|
Optionally, a third argument can be the literal string passed to the time_last
|
|
field of the database record. If not provided, it defauls to C<now()>.
|
|
|
|
=cut
|
|
|
|
sub store_wireless_client_info {
|
|
my ($device, $snmp, $now) = @_;
|
|
$now ||= 'now()';
|
|
|
|
my $cd11_txrate = $snmp->cd11_txrate;
|
|
return unless $cd11_txrate and scalar keys %$cd11_txrate;
|
|
|
|
if (setting('store_wireless_client')) {
|
|
debug sprintf ' [%s] macsuck - gathering wireless client info',
|
|
$device->ip;
|
|
}
|
|
else {
|
|
debug sprintf ' [%s] macsuck - dot11 info available but skipped due to config',
|
|
$device->ip;
|
|
return;
|
|
}
|
|
|
|
my $cd11_rateset = $snmp->cd11_rateset();
|
|
my $cd11_uptime = $snmp->cd11_uptime();
|
|
my $cd11_sigstrength = $snmp->cd11_sigstrength();
|
|
my $cd11_sigqual = $snmp->cd11_sigqual();
|
|
my $cd11_mac = $snmp->cd11_mac();
|
|
my $cd11_port = $snmp->cd11_port();
|
|
my $cd11_rxpkt = $snmp->cd11_rxpkt();
|
|
my $cd11_txpkt = $snmp->cd11_txpkt();
|
|
my $cd11_rxbyte = $snmp->cd11_rxbyte();
|
|
my $cd11_txbyte = $snmp->cd11_txbyte();
|
|
my $cd11_ssid = $snmp->cd11_ssid();
|
|
|
|
while (my ($idx, $txrates) = each %$cd11_txrate) {
|
|
my $rates = $cd11_rateset->{$idx};
|
|
my $mac = $cd11_mac->{$idx};
|
|
next unless defined $mac; # avoid null entries
|
|
# there can be more rows in txrate than other tables
|
|
|
|
my $txrate = defined $txrates->[$#$txrates]
|
|
? int($txrates->[$#$txrates])
|
|
: undef;
|
|
|
|
my $maxrate = defined $rates->[$#$rates]
|
|
? int($rates->[$#$rates])
|
|
: undef;
|
|
|
|
schema('netdisco')->txn_do(sub {
|
|
schema('netdisco')->resultset('NodeWireless')
|
|
->search({ 'me.mac' => $mac })
|
|
->update_or_create({
|
|
txrate => $txrate,
|
|
maxrate => $maxrate,
|
|
uptime => $cd11_uptime->{$idx},
|
|
rxpkt => $cd11_rxpkt->{$idx},
|
|
txpkt => $cd11_txpkt->{$idx},
|
|
rxbyte => $cd11_rxbyte->{$idx},
|
|
txbyte => $cd11_txbyte->{$idx},
|
|
sigqual => $cd11_sigqual->{$idx},
|
|
sigstrength => $cd11_sigstrength->{$idx},
|
|
ssid => ($cd11_ssid->{$idx} || 'unknown'),
|
|
time_last => \$now,
|
|
}, {
|
|
order_by => [qw/mac ssid/],
|
|
for => 'update',
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
1;
|