From 88a24a9f85d3aa23e2f3d9c117c1ed27f2b268b6 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Sat, 7 Mar 2015 16:33:19 +0000 Subject: [PATCH] [#110] rules for IP Phone and Wireless AP identification now configurable --- Netdisco/Changes | 11 +-- Netdisco/lib/App/Netdisco/Core/Discover.pm | 31 +++++-- Netdisco/lib/App/Netdisco/DB/Result/Device.pm | 8 ++ .../lib/App/Netdisco/Manual/Configuration.pod | 86 +++++++++++++++++++ Netdisco/lib/App/Netdisco/Util/Device.pm | 1 + Netdisco/share/config.yml | 12 +++ Netdisco/share/views/ajax/device/ports.tt | 6 +- 7 files changed, 140 insertions(+), 15 deletions(-) diff --git a/Netdisco/Changes b/Netdisco/Changes index 51c42cf8..ee4e3647 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -4,17 +4,18 @@ * macsuck_unsupported setting to allow node gathering on delinquent switches * netdisco-do -d accepts IP prefixes (subnet in CIDR format) + * [#110] rules for IP Phone and Wireless AP identification now configurable [ENHANCEMENTS] - * Show page and total records number on DataTables tables - * Be more strict about Node Search matching ports/wifi within date range - * Allow filtering out of Device Ports on Node (MAC) search + * show page and total records number on DataTables tables + * be more strict about Node Search matching ports/wifi within date range + * allow filtering out of Device Ports on Node (MAC) search [BUG FIXES] - * Only exclude discover_no on Undiscovered Neighbors report when few (<50) results - * Mention expire in netdisco-do docs + * only exclude discover_no on Undiscovered Neighbors report when few (<50) results + * mention expire in netdisco-do docs 2.031012 - 2015-02-28 diff --git a/Netdisco/lib/App/Netdisco/Core/Discover.pm b/Netdisco/lib/App/Netdisco/Core/Discover.pm index e506a33f..c398fadc 100644 --- a/Netdisco/lib/App/Netdisco/Core/Discover.pm +++ b/Netdisco/lib/App/Netdisco/Core/Discover.pm @@ -3,11 +3,13 @@ package App::Netdisco::Core::Discover; use Dancer qw/:syntax :script/; use Dancer::Plugin::DBIC 'schema'; -use App::Netdisco::Util::Device qw/get_device is_discoverable/; +use App::Netdisco::Util::Device + qw/get_device match_devicetype is_discoverable/; use App::Netdisco::Util::DNS ':all'; use App::Netdisco::JobQueue qw/jq_queued jq_insert/; use NetAddr::IP::Lite ':lower'; use List::MoreUtils (); +use Scalar::Util 'blessed'; use Encode; use Try::Tiny; use NetAddr::MAC; @@ -723,14 +725,16 @@ sub store_neighbors { # IP Phone and WAP detection type fixup if (scalar @$remote_cap or $remote_type) { - my $phone_flag = grep {/phone/i} @$remote_cap; - my $ap_flag = grep {/wlanAccessPoint/} @$remote_cap; + my $phone_flag = grep {match_devicetype($_, 'phone_capabilities')} + @$remote_cap; + my $ap_flag = grep {match_devicetype($_, 'wap_capabilities')} + @$remote_cap; - if ($phone_flag or $remote_type =~ m/mitel.5\d{3}/i) { + if ($phone_flag or match_devicetype($remote_type, 'phone_platforms')) { $remote_type = 'IP Phone: '. $remote_type - if $remote_type !~ /ip phone/i; + if $remote_type !~ /ip.phone/i; } - elsif ($ap_flag or $remote_type =~ m/\bw?ap\b/i) { + elsif ($ap_flag or match_devicetype($remote_type, 'wap_platforms')) { $remote_type = 'AP: '. $remote_type; } @@ -831,8 +835,21 @@ sub store_neighbors { push @to_discover, [$remote_ip, $remote_type]; } - $remote_port = $c_port->{$entry}; + # further device type discovery using MAC OUI + # only works once device is fully discovered (so we have a MAC addr) + my $neigh = get_device($remote_ip); + if (blessed $neigh and $neigh->in_storage and $neigh->mac) { + if (match_devicetype($neigh->mac, 'phone_ouis')) { + $remote_type = 'IP Phone: '. $remote_type + if $remote_type !~ /ip.phone/i; + } + elsif (match_devicetype($neigh->mac, 'wap_ouis')) { + $remote_type = 'AP: '. $remote_type + if $remote_type !~ /^AP: /; + } + } + $remote_port = $c_port->{$entry}; if (defined $remote_port) { # clean weird characters $remote_port =~ s/[^\d\/\.,()\w:-]+//gi; diff --git a/Netdisco/lib/App/Netdisco/DB/Result/Device.pm b/Netdisco/lib/App/Netdisco/DB/Result/Device.pm index 62ae78d0..0195b9d4 100644 --- a/Netdisco/lib/App/Netdisco/DB/Result/Device.pm +++ b/Netdisco/lib/App/Netdisco/DB/Result/Device.pm @@ -252,6 +252,14 @@ sub renumber { =head1 ADDITIONAL COLUMNS +=head2 oui + +Returns the first half of the device MAC address. + +=cut + +sub oui { return substr( ((shift)->mac || ''), 0, 8 ) } + =head2 port_count Returns the number of ports on this device. Enable this diff --git a/Netdisco/lib/App/Netdisco/Manual/Configuration.pod b/Netdisco/lib/App/Netdisco/Manual/Configuration.pod index a2189232..a4213453 100644 --- a/Netdisco/lib/App/Netdisco/Manual/Configuration.pod +++ b/Netdisco/lib/App/Netdisco/Manual/Configuration.pod @@ -961,6 +961,92 @@ Value: Boolean. Default: C. Turn this on to have Netdisco do a reverse lookup of the device C field to use as the management IP address for a device. +=head3 C + +Value: List of Strings. Default: + + phone_capabilities: + - '(?i:phone)' + +Regular expressions to match the Capability field received within neighbor +discovery protocols such as CDP/FDP/LLDP. Netdisco uses this to display a +"phone" icon alongside devices or nodes in the Device Ports table. + +To find the received Capabilities on an upstream device, run this command: + + ~netdisco/bin/netdisco-do show -d -e c_cap + +=head3 C + +Value: List of Strings. Default: + + phone_platforms: + - '(?i:mitel.5\d{3})' + +Regular expressions to match the Platform field received within neighbor +discovery protocols such as CDP/FDP/LLDP. Netdisco uses this to display a +"phone" icon alongside devices or nodes in the Device Ports table. + +To find the received Platforms on an upstream device, run this command: + + ~netdisco/bin/netdisco-do show -d -e c_platform + +=head3 C + +Value: List of Strings. Default: Empty List. + +If you can't get C or C to match, as a +last ditch attempt you can match on the MAC address of the device (if it has +one). This is a set of regular expressions matched against the whole MAC +address (not only the OUI portion) in IEEE format. For example: + + phone_ouis: + - '^a4:0c:c3' + +=head3 C + +Value: List of Strings. Default: + + wap_capabilities: + - 'wlanAccessPoint' + +Regular expressions to match the Capability field received within neighbor +discovery protocols such as CDP/FDP/LLDP. Netdisco uses this to display a +"wireless signal" icon alongside devices or nodes in the Device Ports table. + +To find the received Capabilities on an upstream device, run this command: + + ~netdisco/bin/netdisco-do show -d -e c_cap + +=head3 C + +Value: List of Strings. Default: + + wap_platforms: + - '(?i:\bw?ap\b)' + - 'cisco\s+AIR-[L|C]?AP' + - '-K9W8-' + +Regular expressions to match the Platform field received within neighbor +discovery protocols such as CDP/FDP/LLDP. Netdisco uses this to display a +"wireless signal" icon alongside devices or nodes in the Device Ports table. + +To find the received Platforms on an upstream device, run this command: + + ~netdisco/bin/netdisco-do show -d -e c_platform + +=head3 C + +Value: List of Strings. Default: Empty List. + +If you can't get C or C to match, as a last +ditch attempt you can match on the MAC address of the device (if it has one). +This is a set of regular expressions matched against the whole MAC address +(not only the OUI portion) in IEEE format. For example: + + wap_ouis: + - '^a4:0c:c3' + =head2 Backend Daemon =head3 C diff --git a/Netdisco/lib/App/Netdisco/Util/Device.pm b/Netdisco/lib/App/Netdisco/Util/Device.pm index 30e98c62..943c9135 100644 --- a/Netdisco/lib/App/Netdisco/Util/Device.pm +++ b/Netdisco/lib/App/Netdisco/Util/Device.pm @@ -48,6 +48,7 @@ stored to the database. sub get_device { my $ip = shift; + return unless $ip; # naive check for existing DBIC object return $ip if ref $ip; diff --git a/Netdisco/share/config.yml b/Netdisco/share/config.yml index 536e02ef..0b093cad 100644 --- a/Netdisco/share/config.yml +++ b/Netdisco/share/config.yml @@ -177,6 +177,18 @@ ignore_interfaces: - '(E|T)\d \d\/\d\/\d' ignore_private_nets: false reverse_sysname: false +phone_capabilities: + - '(?i:phone)' +phone_platforms: + - '(?i:mitel.5\d{3})' +phone_ouis: [] +wap_capabilities: + - 'wlanAccessPoint' +wap_platforms: + - '(?i:\bw?ap\b)' + - 'cisco\s+AIR-[L|C]?AP' + - '-K9W8-' +wap_ouis: [] # -------------- # BACKEND DAEMON diff --git a/Netdisco/share/views/ajax/device/ports.tt b/Netdisco/share/views/ajax/device/ports.tt index b5e4ffcc..01dafa6a 100644 --- a/Netdisco/share/views/ajax/device/ports.tt +++ b/Netdisco/share/views/ajax/device/ports.tt @@ -265,7 +265,7 @@ [% IF row.remote_type AND row.remote_type.match('(?i)ip.phone') %]   - [% ELSIF row.remote_type AND row.remote_type.match('(cisco\s+AIR-[L|C]?AP|-K9W8-|^AP:\s)') %] + [% ELSIF row.remote_type AND row.remote_type.match('^AP:\s') %]   [% END %] @@ -284,7 +284,7 @@   [% IF row.remote_type AND row.remote_type.match('(?i)ip.phone') %]   - [% ELSIF row.remote_type AND row.remote_type.match('(cisco\s+AIR-[L|C]?AP|-K9W8-|^AP:\s)') %] + [% ELSIF row.remote_type AND row.remote_type.match('^AP:\s') %]   [% END %] @@ -305,7 +305,7 @@ [% IF row.remote_type AND row.remote_type.match('(?i)ip.phone') %]   [% ELSIF node.wireless.defined - OR (row.remote_type AND row.remote_type.match('(cisco\s+AIR-[L|c]?AP|-K9W8-|^AP:\s)')) %] + OR (row.remote_type AND row.remote_type.match('^AP:\s')) %]   [% END %]