#721 redux - better MAC address support in searching

This commit is contained in:
Oliver Gorwits
2020-06-30 09:46:19 +01:00
parent 88ce0d7f9a
commit f882f98319
3 changed files with 39 additions and 3 deletions

View File

@@ -2,6 +2,7 @@
[ENHANCEMENTS] [ENHANCEMENTS]
* #721 redux - better MAC address support in searching
* #728 store SNMP Engine ID * #728 store SNMP Engine ID
[BUG FIXES] [BUG FIXES]

View File

@@ -7,6 +7,7 @@ use warnings;
use Try::Tiny; use Try::Tiny;
use Regexp::Common 'net'; use Regexp::Common 'net';
use NetAddr::IP::Lite ':lower'; use NetAddr::IP::Lite ':lower';
use NetAddr::MAC ();
require Dancer::Logger; require Dancer::Logger;
@@ -181,6 +182,10 @@ Can match the C<location> field as a substring.
Can match the C<description> field as a substring (usually this field contains Can match the C<description> field as a substring (usually this field contains
a description of the vendor operating system). a description of the vendor operating system).
=item mac
Will match exactly the C<mac> field of the Device or any of its Interfaces.
=item model =item model
Will match exactly the C<model> field. Will match exactly the C<model> field.
@@ -245,6 +250,13 @@ sub search_by_field {
\[ 'substring(me.layers,9-?, 1)::int = 1', $layers ]; \[ 'substring(me.layers,9-?, 1)::int = 1', $layers ];
} }
# get IEEE MAC format
my $mac = NetAddr::MAC->new($p->{mac});
undef $mac if
($mac and $mac->as_ieee
and (($mac->as_ieee eq '00:00:00:00:00:00')
or ($mac->as_ieee !~ m/$RE{net}{MAC}/)));
return $rs return $rs
->search_rs({}, $attrs) ->search_rs({}, $attrs)
->search({ ->search({
@@ -256,6 +268,12 @@ sub search_by_field {
($p->{description} ? ('me.description' => ($p->{description} ? ('me.description' =>
{ '-ilike' => "\%$p->{description}\%" }) : ()), { '-ilike' => "\%$p->{description}\%" }) : ()),
($mac ? (
-or => [
'me.mac' => $mac->as_ieee,
'ports.mac' => $mac->as_ieee,
]) : ()),
($p->{model} ? ('me.model' => ($p->{model} ? ('me.model' =>
{ '-in' => $p->{model} }) : ()), { '-in' => $p->{model} }) : ()),
($p->{os} ? ('me.os' => ($p->{os} ? ('me.os' =>
@@ -283,7 +301,7 @@ sub search_by_field {
{ {
order_by => [qw/ me.dns me.ip /], order_by => [qw/ me.dns me.ip /],
(($p->{dns} or $p->{ip}) ? ( (($p->{dns} or $p->{ip}) ? (
join => 'device_ips', join => [qw/device_ips ports/],
distinct => 1, distinct => 1,
) : ()), ) : ()),
} }
@@ -309,6 +327,8 @@ The following fields are inspected for a match:
=item name =item name
=item mac (including port addresses)
=item description =item description
=item dns =item dns
@@ -341,6 +361,14 @@ sub search_fuzzy {
]; ];
} }
# get IEEE MAC format
my $mac = NetAddr::MAC->new($q);
undef $mac if
($mac and $mac->as_ieee
and (($mac->as_ieee eq '00:00:00:00:00:00')
or ($mac->as_ieee !~ m/$RE{net}{MAC}/)));
$mac = ($mac ? $mac->as_ieee : $q);
return $rs->search( return $rs->search(
{ {
-or => [ -or => [
@@ -353,6 +381,10 @@ sub search_fuzzy {
$rs->search({ 'modules.serial' => $qc }, $rs->search({ 'modules.serial' => $qc },
{ join => 'modules', columns => 'ip' })->as_query() { join => 'modules', columns => 'ip' })->as_query()
}, },
-or => [
'me.mac::text' => { '-ilike' => $mac},
'ports.mac::text' => { '-ilike' => $mac},
],
-or => [ -or => [
'me.dns' => { '-ilike' => $q }, 'me.dns' => { '-ilike' => $q },
'device_ips.dns' => { '-ilike' => $q }, 'device_ips.dns' => { '-ilike' => $q },
@@ -362,7 +394,7 @@ sub search_fuzzy {
}, },
{ {
order_by => [qw/ me.dns me.ip /], order_by => [qw/ me.dns me.ip /],
join => 'device_ips', join => [qw/device_ips ports/],
distinct => 1, distinct => 1,
} }
); );

View File

@@ -32,6 +32,9 @@ register_search_tab({
description => { description => {
description => 'Partial match of the Device description', description => 'Partial match of the Device description',
}, },
mac => {
description => 'MAC Address of the Device or any of its Interfaces',
},
model => { model => {
description => 'Exact match of the Device model', description => 'Exact match of the Device model',
}, },
@@ -58,7 +61,7 @@ register_search_tab({
# device with various properties or a default match-all # device with various properties or a default match-all
get '/ajax/content/search/device' => require_login sub { get '/ajax/content/search/device' => require_login sub {
my $has_opt = List::MoreUtils::any { param($_) } my $has_opt = List::MoreUtils::any { param($_) }
qw/name location dns ip description model os os_ver vendor layers/; qw/name location dns ip description model os os_ver vendor layers mac/;
my $rs; my $rs;
if ($has_opt) { if ($has_opt) {