& SELF:matches &>
* Advanced Searches can be slow to load. <%args> $node => '' $dates => 1 $archive => 0 $showoui => 1 $expandoui => 0 @vendors => () @oui => () $specific => '' $sort => 'mac' %args> <%shared> my $matches = []; my $Node_IP_Seen = {}; my $domain = $netdisco::CONFIG{domain}; my ($arg_showdate, $arg_showoui, @arg_vendors, @arg_oui, $arg_archive, $arg_dates, $arg_node,$arg_sort); my $odd=1; my $ran_query = 0; my @search = (); my $ouis = undef; my @cols = (); my $vendors = { 'Cisco' => qr/cisco/i, '3Com' => qr/3 ?com/i, 'Compaq' => qr/compaq/i, 'Intel' => qr/intel/i, 'Apple' => qr/apple/i, 'Sun' => qr/sun\s+/i, 'HP' => qr/(hp|hewlett.*packard)/i, 'Linksys' => qr/linksys/i, 'SGI' => qr/silicon.*graphics/i, 'D-Link' => qr/d-link/i, 'IBM' => qr/ibm/i, 'Dell' => qr/dell/i, 'Bay' => qr/bay.*networks/i, 'APC' => qr/american.*power.*conversion/i, 'Lexmark' => qr/lexmark/i, 'Kingston' => qr/kingston/i, 'GW2000' => qr/gateway.*2000/i, 'VMWare' => qr/vmware/i, '[No OUI]' => qr/\[NA\]/, 'Avaya' => qr/avaya/i, }; my %sort_type = ('mac' => 'MAC Address', 'dev' => 'Device Name', 'oui' => 'Vendor', ); # Cheers to the makers of Kismet for their extensive AP list # which is added to here. my $wireless = { '00:00:94:CB' => 'Asante', '00:01:03:7C' => '3Com', '00:01:24:24' => 'SMC SMC7004AWBR', '00:01:24:F0' => 'Acer', '00:01:24:F1' => 'Acer', '00:01:f4' => 'Enterasys Networks', '00:02:2d' => 'Agere / Lucent Systems', '00:02:a5:6e:46' => 'Compaq Computer Corporation', '00:02:a5:6e:47' => 'Compaq Computer Corporation', '00:02:a5:6f' => 'Compaq Computer Corporation', '00:02:b3:65' => 'Intel Corporation', '00:02:b3:86' => 'Intel Corporation', '00:02:b3:92' => 'Intel Corporation', '00:02:b3:94' => 'Intel Corporation', '00:02:b3:B1' => 'Intel Corporation', '00:02:6F' => 'Senao', '00:03:2f' => 'Global Sun Technology, Inc.', '00:04:3A:3A' => 'Avaya ad-01444', '00:04:5a:0c' => 'The Linksys Group, Inc.', '00:04:5A:0E' => 'Linksys WAP11', '00:04:5a:0f' => 'The Linksys Group, Inc.', '00:04:5a:23' => 'The Linksys Group, Inc.', '00:04:5a:26' => 'The Linksys Group, Inc.', '00:04:5A:2E' => 'Linksys BEFW11S4', '00:04:5a:2f' => 'The Linksys Group, Inc.', '00:04:5A:5A' => 'Linksys BEFW11S4', '00:04:5a:cc' => 'The Linksys Group, Inc.', '00:04:5a:cd' => 'The Linksys Group, Inc.', '00:04:5a:ce' => 'The Linksys Group, Inc.', '00:04:5a:cf' => 'The Linksys Group, Inc.', '00:04:5a:d0' => 'The Linksys Group, Inc.', '00:04:5a:d1' => 'The Linksys Group, Inc.', '00:04:5a:d2' => 'The Linksys Group, Inc.', '00:04:5a:d8' => 'The Linksys Group, Inc.', '00:04:5a:da' => 'The Linksys Group, Inc.', '00:04:5a:db' => 'The Linksys Group, Inc.', '00:04:5a:dd' => 'The Linksys Group, Inc.', '00:04:5a:e4' => 'The Linksys Group, Inc.', '00:04:5a:e8' => 'The Linksys Group, Inc.', '00:04:5a:eb' => 'The Linksys Group, Inc.', '00:04:5a:ee' => 'The Linksys Group, Inc.', '00:04:5a:f6' => 'The Linksys Group, Inc.', '00:04:5a:f9' => 'The Linksys Group, Inc.', '00:04:5a:fa' => 'The Linksys Group, Inc.', '00:04:5a:fc' => 'The Linksys Group, Inc.', '00:04:5a:fd' => 'The Linksys Group, Inc.', '00:04:75:62' => '3 Com Corporation', '00:04:75:75' => '3Com 3CRWE20096A AP2000 Version 1', '00:04:76:a5' => '3 Com Corporation', '00:04:8a' => 'Temia Vertriebs GmbH', '00:04:db' => 'Tellus Group Corp.', '00:04:e2' => 'SMC Networks, Inc.', '00:04:E2:E2' => 'SMC 7004AWBR', '00:05:5d:25' => 'D-Link Systems, Inc.', '00:05:5D:5D' => 'D-Link DWL-1000AP', '00:05:5d:ea' => 'D-Link Systems, Inc.', '00:05:5d:ec' => 'D-Link Systems, Inc.', '00:05:5d:ed' => 'D-Link Systems, Inc.', '00:05:5d:ee' => 'D-Link Systems, Inc.', '00:05:5d:f1' => 'D-Link Systems, Inc.', '00:05:5d:f2' => 'D-Link Systems, Inc.', '00:05:5f' => 'Cisco Systems, Inc.', '00:06:25' => 'The Linksys Group, Inc.', '00:06:25:25' => 'Linksys BEFW11S4 v2', '00:06:25:50' => 'The Linksys Group, Inc.', '00:06:25:51' => 'The Linksys Group, Inc.', '00:06:25:53' => 'The Linksys Group, Inc.', '00:06:25:54' => 'The Linksys Group, Inc.', '00:06:25:59' => 'The Linksys Group, Inc.', '00:06:25:5d' => 'The Linksys Group, Inc.', '00:06:25:61' => 'The Linksys Group, Inc.', '00:06:25:64' => 'The Linksys Group, Inc.', '00:06:25:66' => 'The Linksys Group, Inc.', '00:06:25:6d' => 'The Linksys Group, Inc.', '00:06:25:75' => 'The Linksys Group, Inc.', '00:06:25:76' => 'The Linksys Group, Inc.', '00:07:0E' => 'Cisco', '00:07:50' => 'Cisco Systems, Inc.', '00:08:21' => 'Cisco', '00:09:43' => 'Cisco', '00:09:5b' => 'Netgear, Inc.', '00:09:7C' => 'Cisco', '00:09:92:92' => 'Sweex LC000010', '00:09:E8' => 'Cisco', '00:0A:41' => 'Cisco', '00:0A:8A:8A' => 'Cisco AIR-AP1200', '00:0C:41' => 'Linksys', '00:0D:88' => 'D-Link', '00:10:e7' => 'BreezeCom', '00:20:d8' => 'Nortel Networks', '00:30:65:03' => 'Apple', '00:30:65:04' => 'Apple', '00:30:65:05' => 'Apple', '00:30:65:13' => 'Apple', '00:30:65:15' => 'Apple', '00:30:65:1B' => 'Apple', '00:30:65:1C' => 'Apple', '00:30:65:1D' => 'Apple', '00:30:65:1E' => 'Apple', '00:30:65:1F' => 'Apple', '00:30:65:2D' => 'Apple', '00:30:65:65' => 'Apple Snow Base Station', '00:30:ab:07' => 'Netgear', '00:30:ab:0a' => 'Netgear', '00:30:ab:0c' => 'Netgear', '00:30:ab:0d' => 'Netgear', '00:30:ab:16' => 'Netgear', '00:30:AB:AB' => 'Netgear MR314NA', '00:30:BD' => 'Belkin', '00:30:BD:BD' => 'Belkin F5D6230-3', '00:30:f1:10' => 'Accton Technology Corp.', '00:30:f1:26' => 'Accton Technology Corp.', '00:40:05' => 'ANI', '00:40:05:05' => 'D-Link DI-614+', '00:40:05:ac' => 'ANI COMMUNICATIONS INC.', '00:40:05:de' => 'ANI COMMUNICATIONS INC.', '00:40:05:df' => 'ANI COMMUNICATIONS INC.', '00:40:26:26' => 'Buffalo WLAR-L11G-L', '00:40:96' => 'Aironet Wireless Communication', '00:40:96:96' => 'Cisco AIR-AP342E2R', '00:50:18' => 'ADVANCED MULTIMEDIA INTERNET TECHNOLOGY INC.', '00:50:8B:8B' => 'Compaq WL400 - ETSI region', '00:50:8b:99' => 'COMPAQ COMPUTER CORPORATION', '00:50:da:97' => '3COM CORPORATION', '00:50:DA:DA' => '3Com 3CRWE747A', '00:50:F2:F2' => 'Microsoft MN-500', '00:60:1d' => 'LUCENT TECHNOLOGIES', '00:60:1D:1D' => 'Orinoco RG1000', '00:60:b3' => 'Z-COM, INC.', '00:80:37:37' => 'Ericsson A11 (AP-4121-105M-ER-EU)', '00:80:c6:e3' => 'SOHOWare', '00:80:C6:C6' => 'SOHOware NetBlaster II', '00:80:C8' => 'D-Link', '00:90:4B:4B' => 'Linksys BEFW11S4', '00:90:D1:D1' => 'SMC SMC2652W', '00:A0:04:04' => '3Com 3CRWE51196', '00:a0:f8' => 'SYMBOL TECHNOLOGIES, INC.', '00:e0:03' => 'NOKIA WIRELESS BUSINESS COMMUN', '00:E0:29' => 'OEM', '00:e0:63' => 'CABLETRON - YAGO SYSTEMS, INC.', }; my %MatchMAP = ('ip' => 'MAC -> IP', 'port' => 'Switch Port', 'host_ip' => 'IP -> MAC', 'dev' => 'IP -> Device', 'devmac' => 'MAC -> Device', 'swport' => 'Switch Port', 'alias' => 'Device IP w/out MAC', 'nbname' => 'NetBIOS', ); my $hex = "[0-9a-fA-F]"; %shared> <%init> # remove other search criteria if specific search if ($specific) { @oui = (); $node=''; @vendors = (); $showoui=0; } # Pass the form argument to the global for <%methods> $arg_dates = $dates; @arg_vendors = @vendors; @arg_oui = @oui; $arg_archive = $archive; $arg_showoui = $showoui; $arg_node = $node; $arg_sort = $sort; # ----------------- Node Search ------------------------- if ($node){ # Choose columns to show and order to show them in matches() @cols = (['mac','MAC']); push (@cols,['oui','Vendor']) if $arg_showoui; push (@cols,['match','Match'],['type','Device or Node']); push (@cols,['time_first','First Seen']) if $arg_dates; push (@cols,['time_last','Last Seen']) if $arg_dates; $m->flush_buffer; $node =~ s/^\s+//; $node =~ s/\s+$//; # Translate space separated octets into colon separated. if ($node =~ /^${hex}{2} ${hex}{2} ${hex}{2} ${hex}{2} ${hex}{2} ${hex}{2}$/){ $node =~ s/\s+/:/g; } my $is_mac = &is_mac($node); my $wildhex = "[0-9a-fA-F?]"; my $is_partial_mac = ($node =~ /^([?*]+)?(${wildhex}{2}:)+(${wildhex}{2})([?*]+)?$/); # Search by MAC Address if ($is_mac or $is_partial_mac) { my $where = { 'mac' => $is_mac ? $node : sql_match($node,0) }; $where->{'active'} = 1 unless $arg_archive; # Lookup IPs associated with this MAC $m->comp('SELF:add_node_ips','where'=>$where); # Lookup what switch ports this MAC was seen at. my $ports = sql_rows('node', ['mac','switch','port','active','oui','extract(epoch from time_first) as time_first', 'extract(epoch from time_last) as time_last'], $where ); foreach my $port (@$ports) { $port->{type} = 'port'; $port->{switchname} = sql_scalar('device',['dns'],{'ip'=>$port->{switch}}) || ''; $port->{switchname} =~ s/\Q$domain\E//; push (@$matches,$port); } # Lookup NetBIOS names. my $nbnames = sql_rows('node_nbt', ['ip','mac','nbname','domain','nbuser','active','extract(epoch from time_first) as time_first', 'extract(epoch from time_last) as time_last'], $where ); foreach my $node_nbt (@$nbnames) { $node_nbt->{type} = 'nbname'; $node_nbt->{oui} = substr($node_nbt->{mac},0,8); push (@$matches,$node_nbt); } # Check the posibilty that this could be a switch port's MAC my $switch_ports = sql_rows('device_port', ['ip','port','mac','extract(epoch from creation) as time_first', 'extract(epoch from creation) as time_last'], {'mac' => $node}); foreach my $sp (@$switch_ports){ $sp->{type} = 'swport'; $sp->{switch} = $sp->{ip}; $sp->{active} = 1; $sp->{oui} = substr($sp->{mac},0,8); $sp->{switchname} = sql_scalar('device',['dns'],{'ip' => $sp->{ip}}); $sp->{switchname} =~ s/\Q$domain\E//; push (@$matches,$sp); } if (@$switch_ports == 0) { # It could also be a device's base address my $device = sql_rows('device', ['ip','mac','dns','extract(epoch from creation) as time_first', 'extract(epoch from creation) as time_last'], {'mac' => $node}); foreach my $dev (@$device) { $dev->{type} = 'devmac'; $dev->{active} = 1; $dev->{oui} = substr($dev->{mac},0,8); $dev->{dev} = $dev->{ip}; $dev->{host} = $dev->{dns}; $dev->{host} =~ s/\Q$domain\E//; push (@$matches,$dev); } } # If there are no matches, at least return the vendor info. if (!@$matches) { my $oui = lc(substr($node, 0, 8)); unless ( defined $ouis->{$oui} ){ $ouis->{$oui} = sql_scalar('oui',['company'],{'oui' => $oui}); } } } my $realip = &getip($node); # Search by HOST if (!$is_mac and defined $realip) { my $hostname = &hostname($node); $hostname =~ s/\Q$domain\E//; # see if this is a listed device or one of its aliases. my $device = root_device($realip); # Find MACs associated with this IP my $where = { 'ip'=>$realip}; $where->{'active'} = 1 unless $archive; my $macs = sql_rows('node_ip', ['mac','ip','active','extract(epoch from time_first) as time_first', 'extract(epoch from time_last) as time_last'], $where ); my @foundmacs = (); # Add info to each entry foreach my $node_ip (@$macs){ $node_ip->{host} = $hostname; $node_ip->{type} = $device ? 'dev' : 'host_ip'; $node_ip->{dev} = $device; $node_ip->{oui} = substr($node_ip->{mac},0,8); push (@$matches,$node_ip); push (@foundmacs, $node_ip->{mac}); push(@{$Node_IP_Seen->{$node_ip->{mac}}},$realip); } # Get details for each MAC associated with this IP foreach my $mac (@foundmacs){ $where = { 'mac' => $mac }; $where->{'active'} = 1 unless $archive; my $ports = sql_rows('node', ['mac','switch','port','active','oui','extract(epoch from time_first) as time_first', 'extract(epoch from time_last) as time_last'], $where ); foreach my $port (@$ports) { $port->{type} = 'port'; $port->{switchname} = sql_scalar('device',['dns'],{'ip'=>$port->{switch}}); $port->{switchname} =~ s/\Q$domain\E//; push(@$matches,$port); } # Get additional/other IPs for each MAC $m->comp('SELF:add_node_ips','where'=>$where); # Lookup NetBIOS names. my $nbnames = sql_rows('node_nbt', ['ip','mac','nbname','domain','nbuser','active','extract(epoch from time_first) as time_first', 'extract(epoch from time_last) as time_last'], $where ); foreach my $node_nbt (@$nbnames) { $node_nbt->{type} = 'nbname'; $node_nbt->{oui} = substr($node_nbt->{mac},0,8); push (@$matches,$node_nbt); } } # If the IP belongs to a device, but we have no info, must be a VLAN or unused ALIAS if (!scalar @$matches and $device) { my $entry = {}; $entry->{type} = 'alias'; $entry->{mac} = $realip; $entry->{active} = 1; $entry->{dev} = $device; $entry->{dns} = sql_scalar('device',['dns'],{'ip'=>$device}); $entry->{dns} =~ s/\Q$domain\E//; $entry->{ip} = $realip; push (@$matches,$entry); } } # Search by NetBIOS Name unless ($is_mac) { # Find MACs associated with this NetBIOS Name my $where = { 'nbname'=>sql_match($node)}; $where->{'active'} = 1 unless $archive; my $macs = sql_rows('node_nbt', ['ip','mac','nbname','domain','nbuser','active','extract(epoch from time_first) as time_first', 'extract(epoch from time_last) as time_last'], $where ); my @foundmacs = (); my %macseen = (); # Add info to each entry foreach my $node_nbt (@$macs){ $node_nbt->{type} = 'nbname'; $node_nbt->{oui} = substr($node_nbt->{mac},0,8); push (@$matches,$node_nbt); push (@foundmacs, $node_nbt->{mac}) unless $macseen{$node_nbt->{mac}}++; } # Get details for each MAC associated with this NetBIOS Name foreach my $mac (@foundmacs){ $where = { 'mac' => $mac }; $where->{'active'} = 1 unless $archive; my $ports = sql_rows('node', ['mac','switch','port','active','oui','extract(epoch from time_first) as time_first', 'extract(epoch from time_last) as time_last'], $where ); foreach my $port (@$ports) { $port->{type} = 'port'; $port->{switchname} = sql_scalar('device',['dns'],{'ip'=>$port->{switch}}); $port->{switchname} =~ s/\Q$domain\E//; push(@$matches,$port); } # Get additional/other IPs for each MAC $m->comp('SELF:add_node_ips','where'=>$where); } } $ran_query++; } # ----------------- Advanced Searches ------------------------- # Search for wireless access points if ($specific =~ /wireless/i) { push (@search,keys %$wireless); } # Search for multiple IP per node if ($specific =~ /ip/i) { @cols = (['mac','MAC'],['oui','Vendor'],['location','Location']); # select n.mac,n.switch,n.port,count(distinct(i.ip)),d.dns # from node_ip i, node n left join device d on d.ip = n.switch # where n.mac = i.mac and i.active = true and n.active = true # group by n.mac, n.switch, n.port,d.dns # having count(distinct(i.ip)) > 1 # order by count desc; $matches = sql_rows('node_ip i, node n left join device d on d.ip = n.switch', ['n.mac','n.switch','n.port','d.dns','true as active','count(distinct(i.ip))'], {'n.mac' => \'i.mac', 'i.active' => 1, 'n.active' => 1}, undef, 'group by n.mac, n.switch, n.port, d.dns having count(distinct(i.ip)) > 1' ); $ran_query++; } # OUI Search push(@search,@oui); # Vendor Search foreach my $vendor_search (@vendors){ $m->comp('SELF:init_ouis'); next unless defined $vendors->{$vendor_search}; my $regex = $vendors->{$vendor_search}; # Look for OUIs that match our regex foreach my $oui (keys %$ouis){ my $company = $ouis->{$oui}; if ($company =~ m/$regex/){ push(@search,$oui) } } } if (scalar @search){ @cols = (['mac','MAC'],['oui','Vendor'],['location','Location']); # These are taking a while, so we put this here # to let em know we're still working... $m->flush_buffer; # Sort search by length my %search_length; foreach my $search (@search){ my $length = length($search); # add to queue matching length push @{$search_length{$length}},lc($search); } # New method using substr() and IN (list) for speed foreach my $length (keys %search_length){ next unless defined $length and scalar @{$search_length{$length}}; next unless $length > 0; my $where = {"substr(text(n.mac),1,$length)" => [$search_length{$length}]}; $where->{'n.active'} = 1 unless $archive; my $submatch = sql_rows('node n left join device d on d.ip = n.switch', ['n.mac','d.dns','n.switch','n.port','n.active','n.oui'], $where); push @$matches, @$submatch; } # don't list OUI matches for wireless if (defined $specific and $specific =~ /wireless/i){ @search = (); } $ran_query++; } # Lookup OUI for matches foreach my $match (@$matches){ my $oui = $match->{oui}; # only look each up once. unless ( defined $ouis->{$oui} ){ $ouis->{$oui} = sql_scalar('oui',['company'],{'oui' => $oui}); } $match->{oui} = $ouis->{$oui}; } %init> %# %# matches() - Outputs each match depending on type %# <%method matches> % return unless $ran_query;
<%$c->[1]%> | % }
---|
\ % if ($col eq 'mac' and $last_match->{mac} ne $match->{mac}) { <%$match->{mac}%>\ <% $active ? '' : '*' %>\ % } elsif ($col eq 'oui' and ($last_match->{mac} ne $match->{mac})){ <%$match->{oui}|h%>\ % } elsif ($col eq 'match') { <%$MatchMAP{$type} || 'Bad Match'%>\ % } elsif ($col eq 'type') { <& SELF:type_map, type=>$type, match =>$match &>\ % } elsif ($col eq 'time_first') { <& SELF:format_date, date=>$match->{time_first} &>\ % } elsif ($col eq 'time_last') { <& SELF:format_date, date=>$match->{time_last} &>\ % } elsif ($col eq 'location') { % my $loc = $match->{dns} || $match->{switch}; % $loc =~ s/\Q$domain\E//; <% $loc %> (<% $match->{port}%>)\ % } else { \ % } | % } % $last_match=$match;
OUI | Count | Company |
---|---|---|
<%$search%> | (<%$count%>) | <% $ouis->{$oui} || '' %> |