Node search by NetBIOS name. Update documentation.
This commit is contained in:
@@ -5,8 +5,9 @@
|
|||||||
* [#86] Use Vendor abbrevs to enhance node display in device port view
|
* [#86] Use Vendor abbrevs to enhance node display in device port view
|
||||||
* [#74] Device Name / DNS mismatches report
|
* [#74] Device Name / DNS mismatches report
|
||||||
* [#71] Node search by date (but not time)
|
* [#71] Node search by date (but not time)
|
||||||
* [#73] NetBIOS Poller (nbtstat and nbtwalk), NetBIOS Node Report,
|
* [#73] NetBIOS Poller (nbtstat and nbtwalk), Node search by NetBIOS name,
|
||||||
and provide information when available in Node and Port views
|
NetBIOS Node Report, and provide information when available in Node
|
||||||
|
and Port views
|
||||||
* [#56] Support API call to /login
|
* [#56] Support API call to /login
|
||||||
|
|
||||||
[ENHANCEMENTS]
|
[ENHANCEMENTS]
|
||||||
|
|||||||
@@ -312,17 +312,13 @@ See L<App::Netdisco::Web::Plugin> for further information.
|
|||||||
Lots of information about the architecture of this application is contained
|
Lots of information about the architecture of this application is contained
|
||||||
within the L<Developer|App::Netdisco::Manual::Developing> documentation.
|
within the L<Developer|App::Netdisco::Manual::Developing> documentation.
|
||||||
|
|
||||||
=head1 Caveats
|
|
||||||
|
|
||||||
NetBIOS Node properies are not yet shown.
|
|
||||||
|
|
||||||
=head1 AUTHOR
|
=head1 AUTHOR
|
||||||
|
|
||||||
Oliver Gorwits <oliver@cpan.org>
|
Oliver Gorwits <oliver@cpan.org>
|
||||||
|
|
||||||
=head1 COPYRIGHT AND LICENSE
|
=head1 COPYRIGHT AND LICENSE
|
||||||
|
|
||||||
This software is copyright (c) 2012, 2013 by The Netdisco Developer Team.
|
This software is copyright (c) 2012, 2013, 2014 by The Netdisco Developer Team.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -98,6 +98,17 @@ See also the C<node_sightings> helper routine, below.
|
|||||||
__PACKAGE__->has_many( nodes => 'App::Netdisco::DB::Result::Node',
|
__PACKAGE__->has_many( nodes => 'App::Netdisco::DB::Result::Node',
|
||||||
{ 'foreign.mac' => 'self.mac' } );
|
{ 'foreign.mac' => 'self.mac' } );
|
||||||
|
|
||||||
|
=head2 netbios
|
||||||
|
|
||||||
|
Returns the set of C<node_nbt> entries associated with the MAC of this IP.
|
||||||
|
That is, all the NetBIOS entries recorded which shared the same MAC with this
|
||||||
|
IP Address.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
__PACKAGE__->has_many( netbios => 'App::Netdisco::DB::Result::NodeNbt',
|
||||||
|
{ 'foreign.mac' => 'self.mac' } );
|
||||||
|
|
||||||
my $search_attr = {
|
my $search_attr = {
|
||||||
order_by => {'-desc' => 'time_last'},
|
order_by => {'-desc' => 'time_last'},
|
||||||
'+columns' => {
|
'+columns' => {
|
||||||
|
|||||||
@@ -45,6 +45,141 @@ __PACKAGE__->set_primary_key("mac");
|
|||||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:XFpxaGAWE13iizQIuVOP3g
|
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:XFpxaGAWE13iizQIuVOP3g
|
||||||
|
|
||||||
|
=head1 RELATIONSHIPS
|
||||||
|
|
||||||
|
=head2 oui
|
||||||
|
|
||||||
|
Returns the C<oui> table entry matching this Node. You can then join on this
|
||||||
|
relation and retrieve the Company name from the related table.
|
||||||
|
|
||||||
|
The JOIN is of type LEFT, in case the OUI table has not been populated.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
__PACKAGE__->belongs_to( oui => 'App::Netdisco::DB::Result::Oui',
|
||||||
|
sub {
|
||||||
|
my $args = shift;
|
||||||
|
return {
|
||||||
|
"$args->{foreign_alias}.oui" =>
|
||||||
|
{ '=' => \"substring(cast($args->{self_alias}.mac as varchar) for 8)" }
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{ join_type => 'LEFT' }
|
||||||
|
);
|
||||||
|
|
||||||
|
=head2 nodes
|
||||||
|
|
||||||
|
Returns the set of C<node> entries associated with this IP. That is, all the
|
||||||
|
MAC addresses recorded which have ever hosted this IP Address.
|
||||||
|
|
||||||
|
Remember you can pass a filter to this method to find only active or inactive
|
||||||
|
nodes, but do take into account that both the C<node> and C<node_nbt> tables
|
||||||
|
include independent C<active> fields.
|
||||||
|
|
||||||
|
See also the C<node_sightings> helper routine, below.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
__PACKAGE__->has_many( nodes => 'App::Netdisco::DB::Result::Node',
|
||||||
|
{ 'foreign.mac' => 'self.mac' } );
|
||||||
|
|
||||||
|
|
||||||
|
=head2 nodeips
|
||||||
|
|
||||||
|
Returns the set of C<node_ip> entries associated with this NetBIOS entry.
|
||||||
|
That is, the IP addresses which the same MAC address at the time of discovery.
|
||||||
|
|
||||||
|
Note that the Active status of the returned IP entries will all be the same
|
||||||
|
as the current NetBIOS entry.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
__PACKAGE__->has_many( nodeips => 'App::Netdisco::DB::Result::NodeIp',
|
||||||
|
{ 'foreign.mac' => 'self.mac', 'foreign.active' => 'self.active' } );
|
||||||
|
|
||||||
|
|
||||||
|
my $search_attr = {
|
||||||
|
order_by => {'-desc' => 'time_last'},
|
||||||
|
'+columns' => {
|
||||||
|
time_first_stamp => \"to_char(time_first, 'YYYY-MM-DD HH24:MI')",
|
||||||
|
time_last_stamp => \"to_char(time_last, 'YYYY-MM-DD HH24:MI')",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
=head2 node_sightings( \%cond, \%attrs? )
|
||||||
|
|
||||||
|
Returns the set of C<node> entries associated with this IP. That is, all the
|
||||||
|
MAC addresses recorded which have ever hosted this IP Address.
|
||||||
|
|
||||||
|
Remember you can pass a filter to this method to find only active or inactive
|
||||||
|
nodes, but do take into account that both the C<node> and C<node_ip> tables
|
||||||
|
include independent C<active> fields.
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
Results are ordered by time last seen.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
Additional columns C<time_first_stamp> and C<time_last_stamp> provide
|
||||||
|
preformatted timestamps of the C<time_first> and C<time_last> fields.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
A JOIN is performed on the Device table and the Device DNS column prefetched.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub node_sightings {
|
||||||
|
my ($row, $cond, $attrs) = @_;
|
||||||
|
|
||||||
|
return $row
|
||||||
|
->nodes({}, {
|
||||||
|
'+columns' => [qw/ device.dns /],
|
||||||
|
join => 'device',
|
||||||
|
})
|
||||||
|
->search_rs({}, $search_attr)
|
||||||
|
->search($cond, $attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
=head1 ADDITIONAL COLUMNS
|
||||||
|
|
||||||
|
=head2 time_first_stamp
|
||||||
|
|
||||||
|
Formatted version of the C<time_first> field, accurate to the minute.
|
||||||
|
|
||||||
|
The format is somewhat like ISO 8601 or RFC3339 but without the middle C<T>
|
||||||
|
between the date stamp and time stamp. That is:
|
||||||
|
|
||||||
|
2012-02-06 12:49
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub time_first_stamp { return (shift)->get_column('time_first_stamp') }
|
||||||
|
|
||||||
|
=head2 time_last_stamp
|
||||||
|
|
||||||
|
Formatted version of the C<time_last> field, accurate to the minute.
|
||||||
|
|
||||||
|
The format is somewhat like ISO 8601 or RFC3339 but without the middle C<T>
|
||||||
|
between the date stamp and time stamp. That is:
|
||||||
|
|
||||||
|
2012-02-06 12:49
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub time_last_stamp { return (shift)->get_column('time_last_stamp') }
|
||||||
|
|
||||||
|
=head2 net_mac
|
||||||
|
|
||||||
|
Returns the C<mac> column instantiated into a L<Net::MAC> object.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub net_mac { return Net::MAC->new(mac => (shift)->mac) }
|
||||||
|
|
||||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
|
||||||
1;
|
1;
|
||||||
|
|||||||
189
Netdisco/lib/App/Netdisco/DB/ResultSet/NodeNbt.pm
Normal file
189
Netdisco/lib/App/Netdisco/DB/ResultSet/NodeNbt.pm
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
package App::Netdisco::DB::ResultSet::NodeNbt;
|
||||||
|
use base 'App::Netdisco::DB::ResultSet';
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings FATAL => 'all';
|
||||||
|
|
||||||
|
__PACKAGE__->load_components(qw/
|
||||||
|
+App::Netdisco::DB::ExplicitLocking
|
||||||
|
/);
|
||||||
|
|
||||||
|
my $search_attr = {
|
||||||
|
order_by => {'-desc' => 'time_last'},
|
||||||
|
'+columns' => [
|
||||||
|
'oui.company',
|
||||||
|
{ time_first_stamp => \"to_char(time_first, 'YYYY-MM-DD HH24:MI')" },
|
||||||
|
{ time_last_stamp => \"to_char(time_last, 'YYYY-MM-DD HH24:MI')" },
|
||||||
|
],
|
||||||
|
join => 'oui'
|
||||||
|
};
|
||||||
|
|
||||||
|
=head1 with_times
|
||||||
|
|
||||||
|
This is a modifier for any C<search()> (including the helpers below) which
|
||||||
|
will add the following additional synthesized columns to the result set:
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item time_first_stamp
|
||||||
|
|
||||||
|
=item time_last_stamp
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub with_times {
|
||||||
|
my ($rs, $cond, $attrs) = @_;
|
||||||
|
|
||||||
|
return $rs
|
||||||
|
->search_rs({}, $search_attr)
|
||||||
|
->search($cond, $attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
=head1 search_by_ip( \%cond, \%attrs? )
|
||||||
|
|
||||||
|
my $set = $rs->search_by_ip({ip => '192.0.2.1', active => 1});
|
||||||
|
|
||||||
|
Like C<search()>, this returns a ResultSet of matching rows from the
|
||||||
|
NodeNbt table.
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
The C<cond> parameter must be a hashref containing a key C<ip> with the value
|
||||||
|
to search for. Value can either be a simple string of IPv4 or IPv6, or a
|
||||||
|
L<NetAddr::IP::Lite> object in which case all results within the CIDR/Prefix
|
||||||
|
will be retrieved.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
Results are ordered by time last seen.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
Additional columns C<time_first_stamp> and C<time_last_stamp> provide
|
||||||
|
preformatted timestamps of the C<time_first> and C<time_last> fields.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
A JOIN is performed on the OUI table and the OUI C<company> column prefetched.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
To limit results only to active IPs, set C<< {active => 1} >> in C<cond>.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub search_by_ip {
|
||||||
|
my ($rs, $cond, $attrs) = @_;
|
||||||
|
|
||||||
|
die "ip address required for search_by_ip\n"
|
||||||
|
if ref {} ne ref $cond or !exists $cond->{ip};
|
||||||
|
|
||||||
|
# handle either plain text IP or NetAddr::IP (/32 or CIDR)
|
||||||
|
my ($op, $ip) = ('=', delete $cond->{ip});
|
||||||
|
|
||||||
|
if ('NetAddr::IP::Lite' eq ref $ip and $ip->num > 1) {
|
||||||
|
$op = '<<=';
|
||||||
|
$ip = $ip->cidr;
|
||||||
|
}
|
||||||
|
$cond->{ip} = { $op => $ip };
|
||||||
|
|
||||||
|
return $rs
|
||||||
|
->search_rs({}, $search_attr)
|
||||||
|
->search($cond, $attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
=head1 search_by_name( \%cond, \%attrs? )
|
||||||
|
|
||||||
|
my $set = $rs->search_by_name({nbname => 'MYNAME', active => 1});
|
||||||
|
|
||||||
|
Like C<search()>, this returns a ResultSet of matching rows from the
|
||||||
|
NodeNbt table.
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
The C<cond> parameter must be a hashref containing a key C<nbname> with the
|
||||||
|
value to search for. The value may optionally include SQL wildcard characters.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
Results are ordered by time last seen.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
Additional columns C<time_first_stamp> and C<time_last_stamp> provide
|
||||||
|
preformatted timestamps of the C<time_first> and C<time_last> fields.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
A JOIN is performed on the OUI table and the OUI C<company> column prefetched.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
To limit results only to active IPs, set C<< {active => 1} >> in C<cond>.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub search_by_name {
|
||||||
|
my ($rs, $cond, $attrs) = @_;
|
||||||
|
|
||||||
|
die "nbname field required for search_by_name\n"
|
||||||
|
if ref {} ne ref $cond or !exists $cond->{nbname};
|
||||||
|
|
||||||
|
$cond->{nbname} = { '-ilike' => delete $cond->{nbname} };
|
||||||
|
|
||||||
|
return $rs
|
||||||
|
->search_rs({}, $search_attr)
|
||||||
|
->search($cond, $attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
=head1 search_by_mac( \%cond, \%attrs? )
|
||||||
|
|
||||||
|
my $set = $rs->search_by_mac({mac => '00:11:22:33:44:55', active => 1});
|
||||||
|
|
||||||
|
Like C<search()>, this returns a ResultSet of matching rows from the
|
||||||
|
NodeNbt table.
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
The C<cond> parameter must be a hashref containing a key C<mac> with the value
|
||||||
|
to search for.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
Results are ordered by time last seen.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
Additional columns C<time_first_stamp> and C<time_last_stamp> provide
|
||||||
|
preformatted timestamps of the C<time_first> and C<time_last> fields.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
A JOIN is performed on the OUI table and the OUI C<company> column prefetched.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
To limit results only to active IPs, set C<< {active => 1} >> in C<cond>.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub search_by_mac {
|
||||||
|
my ($rs, $cond, $attrs) = @_;
|
||||||
|
|
||||||
|
die "mac address required for search_by_mac\n"
|
||||||
|
if ref {} ne ref $cond or !exists $cond->{mac};
|
||||||
|
|
||||||
|
return $rs
|
||||||
|
->search_rs({}, $search_attr)
|
||||||
|
->search($cond, $attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
@@ -49,6 +49,9 @@ ajax '/ajax/content/search/node' => require_login sub {
|
|||||||
my $ips = schema('netdisco')->resultset('NodeIp')
|
my $ips = schema('netdisco')->resultset('NodeIp')
|
||||||
->search_by_mac({mac => $mac->as_IEEE, @active, @times});
|
->search_by_mac({mac => $mac->as_IEEE, @active, @times});
|
||||||
|
|
||||||
|
my $netbios = schema('netdisco')->resultset('NodeNbt')
|
||||||
|
->search_by_mac({mac => $mac->as_IEEE, @active, @times});
|
||||||
|
|
||||||
my $ports = schema('netdisco')->resultset('DevicePort')
|
my $ports = schema('netdisco')->resultset('DevicePort')
|
||||||
->search({mac => $mac->as_IEEE});
|
->search({mac => $mac->as_IEEE});
|
||||||
|
|
||||||
@@ -62,17 +65,6 @@ ajax '/ajax/content/search/node' => require_login sub {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
my $netbios = schema('netdisco')->resultset('NodeNbt')->search(
|
|
||||||
{ mac => $mac->as_IEEE },
|
|
||||||
{ order_by => { '-desc' => 'time_last' },
|
|
||||||
'+columns' => [
|
|
||||||
{
|
|
||||||
time_first_stamp => \"to_char(time_first, 'YYYY-MM-DD HH24:MI')",
|
|
||||||
time_last_stamp => \"to_char(time_last, 'YYYY-MM-DD HH24:MI')"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return unless $sightings->has_rows
|
return unless $sightings->has_rows
|
||||||
or $ips->has_rows
|
or $ips->has_rows
|
||||||
or $ports->has_rows
|
or $ports->has_rows
|
||||||
@@ -89,25 +81,33 @@ ajax '/ajax/content/search/node' => require_login sub {
|
|||||||
else {
|
else {
|
||||||
my $set;
|
my $set;
|
||||||
|
|
||||||
|
my $name = $node;
|
||||||
|
|
||||||
|
if (param('partial')) {
|
||||||
|
$name = "\%$name\%" if $name !~ m/%/;
|
||||||
|
}
|
||||||
|
|
||||||
|
$set = schema('netdisco')->resultset('NodeNbt')
|
||||||
|
->search_by_name({nbname => $name, @active, @times});
|
||||||
|
|
||||||
|
unless ( $set->has_rows ) {
|
||||||
if (my $ip = NetAddr::IP::Lite->new($node)) {
|
if (my $ip = NetAddr::IP::Lite->new($node)) {
|
||||||
# search_by_ip() will extract cidr notation if necessary
|
# search_by_ip() will extract cidr notation if necessary
|
||||||
$set = schema('netdisco')->resultset('NodeIp')
|
$set = schema('netdisco')->resultset('NodeIp')
|
||||||
->search_by_ip({ip => $ip, @active, @times});
|
->search_by_ip({ip => $ip, @active, @times});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (param('partial')) {
|
|
||||||
$node = "\%$node\%" if $node !~ m/%/;
|
if ($name !~ m/%/ and setting('domain_suffix')) {
|
||||||
}
|
$name .= setting('domain_suffix')
|
||||||
elsif (setting('domain_suffix')) {
|
if index($name, setting('domain_suffix')) == -1;
|
||||||
$node .= setting('domain_suffix')
|
|
||||||
if index($node, setting('domain_suffix')) == -1;
|
|
||||||
}
|
}
|
||||||
$set = schema('netdisco')->resultset('NodeIp')
|
$set = schema('netdisco')->resultset('NodeIp')
|
||||||
->search_by_dns({dns => $node, @active, @times});
|
->search_by_dns({dns => $node, @active, @times});
|
||||||
|
|
||||||
# if the user selects Vendor search opt, then
|
# if the user selects Vendor search opt, then
|
||||||
# we'll try the OUI company name as a fallback
|
# we'll try the OUI company name as a fallback
|
||||||
if (not $set->count and param('show_vendor')) {
|
if (not $set->has_rows and param('show_vendor')) {
|
||||||
$node = param('q');
|
$node = param('q');
|
||||||
$set = schema('netdisco')->resultset('NodeIp')
|
$set = schema('netdisco')->resultset('NodeIp')
|
||||||
->with_times
|
->with_times
|
||||||
@@ -117,7 +117,8 @@ ajax '/ajax/content/search/node' => require_login sub {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return unless $set and $set->count;
|
return unless $set and $set->has_rows;
|
||||||
|
}
|
||||||
$set = $set->search_rs({}, { order_by => 'me.mac' });
|
$set = $set->search_rs({}, { order_by => 'me.mac' });
|
||||||
|
|
||||||
template 'ajax/search/node_by_ip.tt', {
|
template 'ajax/search/node_by_ip.tt', {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
[% USE date(format = '%Y-%m-%d %H:%M') %]
|
[% USE date(format = '%Y-%m-%d %H:%M') %]
|
||||||
|
[% USE Number.Format %]
|
||||||
<table class="table table-bordered table-hover nd_floatinghead">
|
<table class="table table-bordered table-hover nd_floatinghead">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -16,6 +17,24 @@
|
|||||||
</thead>
|
</thead>
|
||||||
</tbody>
|
</tbody>
|
||||||
[% WHILE (row = macs.next) %]
|
[% WHILE (row = macs.next) %]
|
||||||
|
[% IF row.nbname %]
|
||||||
|
<tr>
|
||||||
|
<td><a class="nd_linkcell"
|
||||||
|
href="[% search_node %]&q=[% row.net_mac.$mac_format_call | uri %]">
|
||||||
|
[% row.net_mac.$mac_format_call | html_entity %]</a></td>
|
||||||
|
[% IF params.show_vendor %]
|
||||||
|
<td>[% row.oui.company | html_entity %]</td>
|
||||||
|
[% END %]
|
||||||
|
<td>NetBIOS</td>
|
||||||
|
<td class="nd_linkcell">\\<a href="[% uri_for('report/netbios') %]?domain=[% row.domain | uri %]" title="Devices in this Domain">[% row.domain | html %]</a>\<a href="[% search_node %]&q=[% row.nbname | uri %]">[% row.nbname | html_entity %]</a>
|
||||||
|
<br>[% row.nbuser || '[No User]' | html %]@<a href="[% search_node %]&q=[% row.ip | uri %]">[% row.ip | html_entity %]</a>
|
||||||
|
</td>
|
||||||
|
[% IF params.stamps %]
|
||||||
|
<td>[% row.time_first_stamp | html_entity %]</td>
|
||||||
|
<td>[% row.time_last_stamp | html_entity %]</td>
|
||||||
|
[% END %]
|
||||||
|
</tr>
|
||||||
|
[% ELSE %]
|
||||||
<tr>
|
<tr>
|
||||||
<td><a class="nd_linkcell"
|
<td><a class="nd_linkcell"
|
||||||
href="[% search_node %]&q=[% row.net_mac.$mac_format_call | uri %]">
|
href="[% search_node %]&q=[% row.net_mac.$mac_format_call | uri %]">
|
||||||
@@ -33,6 +52,40 @@
|
|||||||
<td>[% row.time_last_stamp | html_entity %]</td>
|
<td>[% row.time_last_stamp | html_entity %]</td>
|
||||||
[% END %]
|
[% END %]
|
||||||
</tr>
|
</tr>
|
||||||
|
[% END %]
|
||||||
|
[% FOREACH nbt IN row.netbios %]
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
[% IF params.show_vendor %]
|
||||||
|
<td> </td>
|
||||||
|
[% END %]
|
||||||
|
<td>NetBIOS</td>
|
||||||
|
<td class="nd_linkcell">\\<a href="[% uri_for('report/netbios') %]?domain=[% nbt.domain | uri %]" title="Devices in this Domain">[% nbt.domain | html %]</a>\<a href="[% search_node %]&q=[% nbt.nbname | uri %]">[% nbt.nbname | html_entity %]</a>
|
||||||
|
<br>[% nbt.nbuser || '[No User]' | html %]@<a href="[% search_node %]&q=[% nbt.ip | uri %]">[% nbt.ip | html_entity %]</a>
|
||||||
|
</td>
|
||||||
|
[% IF params.stamps %]
|
||||||
|
<td>[% date.format(nbt.time_first) | html_entity %]</td>
|
||||||
|
<td>[% date.format(nbt.time_last) | html_entity %]</td>
|
||||||
|
[% END %]
|
||||||
|
</tr>
|
||||||
|
[% END %]
|
||||||
|
[% FOREACH ni IN row.nodeips %]
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
[% IF params.show_vendor %]
|
||||||
|
<td> </td>
|
||||||
|
[% END %]
|
||||||
|
<td>IP → MAC</td>
|
||||||
|
<td><a href="[% search_node %]&q=[% ni.ip | uri %]">[% ni.ip | html_entity %]</a>
|
||||||
|
[% ' <i class="icon-book text-warning"></i> ' IF NOT ni.active %]
|
||||||
|
[% ' (' _ ni.dns.remove(settings.domain_suffix) _ ')' IF ni.dns %]
|
||||||
|
</td>
|
||||||
|
[% IF params.stamps %]
|
||||||
|
<td>[% date.format(ni.time_first) | html_entity %]</td>
|
||||||
|
<td>[% date.format(ni.time_last) | html_entity %]</td>
|
||||||
|
[% END %]
|
||||||
|
</tr>
|
||||||
|
[% END %]
|
||||||
[% FOREACH node IN row.node_sightings(archive_filter) %]
|
[% FOREACH node IN row.node_sightings(archive_filter) %]
|
||||||
<tr>
|
<tr>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
@@ -53,22 +106,6 @@
|
|||||||
<td>[% node.time_last_stamp | html_entity %]</td>
|
<td>[% node.time_last_stamp | html_entity %]</td>
|
||||||
[% END %]
|
[% END %]
|
||||||
</tr>
|
</tr>
|
||||||
[% FOREACH nbt IN node.netbios %]
|
|
||||||
<tr>
|
|
||||||
<td> </td>
|
|
||||||
[% IF params.show_vendor %]
|
|
||||||
<td> </td>
|
|
||||||
[% END %]
|
|
||||||
<td>NetBIOS</td>
|
|
||||||
<td class="nd_linkcell">\\<a href="[% uri_for('report/netbios') %]?domain=[% nbt.domain | uri %]" title="Devices in this Domain">[% nbt.domain | html %]</a>\<a href="[% search_node %]&q=[% nbt.nbname | uri %]">[% nbt.nbname | html_entity %]</a>
|
|
||||||
<br>[% nbt.nbuser || '[No User]' | html %]@<a href="[% search_node %]&q=[% nbt.ip | uri %]">[% nbt.ip | html_entity %]</a>
|
|
||||||
</td>
|
|
||||||
[% IF params.stamps %]
|
|
||||||
<td>[% date.format(nbt.time_first) | html_entity %]</td>
|
|
||||||
<td>[% date.format(nbt.time_last) | html_entity %]</td>
|
|
||||||
[% END %]
|
|
||||||
</tr>
|
|
||||||
[% END %]
|
|
||||||
[% FOREACH wlan IN node.wireless %]
|
[% FOREACH wlan IN node.wireless %]
|
||||||
<tr>
|
<tr>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
|
|||||||
@@ -138,8 +138,8 @@
|
|||||||
<br>[% nbt.nbuser || '[No User]' | html %]@<a href="[% search_node %]&q=[% nbt.ip | uri %]">[% nbt.ip | html_entity %]</a>
|
<br>[% nbt.nbuser || '[No User]' | html %]@<a href="[% search_node %]&q=[% nbt.ip | uri %]">[% nbt.ip | html_entity %]</a>
|
||||||
</td>
|
</td>
|
||||||
[% IF params.stamps %]
|
[% IF params.stamps %]
|
||||||
<td>[% nbt.get_column('time_first_stamp') | html_entity %]</td>
|
<td>[% nbt.time_first_stamp | html_entity %]</td>
|
||||||
<td>[% nbt.get_column('time_last_stamp') | html_entity %]</td>
|
<td>[% nbt.time_last_stamp | html_entity %]</td>
|
||||||
[% END %]
|
[% END %]
|
||||||
</tr>
|
</tr>
|
||||||
[% SET first_row = 0 %]
|
[% SET first_row = 0 %]
|
||||||
|
|||||||
Reference in New Issue
Block a user