diff --git a/LibreNMS/Util/Rewrite.php b/LibreNMS/Util/Rewrite.php index 450e882ad4..fefdab958a 100644 --- a/LibreNMS/Util/Rewrite.php +++ b/LibreNMS/Util/Rewrite.php @@ -27,6 +27,7 @@ namespace LibreNMS\Util; use App\Models\Device; use Illuminate\Support\Arr; +use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; use LibreNMS\Config; @@ -158,10 +159,12 @@ class Rewrite { $oui = substr($mac, 0, 6); - $results = DB::table('vendor_ouis') - ->where('oui', 'like', "$oui%") // possible matches - ->orderBy('oui', 'desc') // so we can check longer ones first if we have them - ->pluck('vendor', 'oui'); + $results = Cache::remember($oui, 21600, function () use ($oui) { + return DB::table('vendor_ouis') + ->where('oui', 'like', "$oui%") // possible matches + ->orderBy('oui', 'desc') // so we can check longer ones first if we have them + ->pluck('vendor', 'oui'); + }); if (count($results) == 1) { return Arr::first($results); diff --git a/app/Http/Controllers/Table/FdbTablesController.php b/app/Http/Controllers/Table/FdbTablesController.php index c7fdd74ad4..10b807c7b4 100755 --- a/app/Http/Controllers/Table/FdbTablesController.php +++ b/app/Http/Controllers/Table/FdbTablesController.php @@ -31,6 +31,7 @@ use App\Models\PortsFdb; use App\Models\Vlan; use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\Request; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; use LibreNMS\Util\IP; use LibreNMS\Util\Rewrite; @@ -39,7 +40,6 @@ use LibreNMS\Util\Url; class FdbTablesController extends TableController { protected $macCountCache = []; - protected $ipCache = []; protected function rules() { @@ -67,7 +67,8 @@ class FdbTablesController extends TableController */ protected function baseQuery($request) { - return PortsFdb::hasAccess($request->user())->with(['device', 'port', 'vlan'])->select('ports_fdb.*'); + return PortsFdb::hasAccess($request->user()) + ->with(['device', 'port', 'vlan', 'ipv4Addresses']); } /** @@ -158,17 +159,15 @@ class FdbTablesController extends TableController */ public function formatItem($fdb_entry) { - $ip_info = $this->findIps($fdb_entry->mac_address); - $item = [ 'device' => $fdb_entry->device ? Url::deviceLink($fdb_entry->device) : '', 'mac_address' => Rewrite::readableMac($fdb_entry->mac_address), 'mac_oui' => Rewrite::readableOUI($fdb_entry->mac_address), - 'ipv4_address' => $ip_info['ips']->implode(', '), + 'ipv4_address' => $fdb_entry->ipv4Addresses->implode(', '), 'interface' => '', 'vlan' => $fdb_entry->vlan ? $fdb_entry->vlan->vlan_vlan : '', 'description' => '', - 'dnsname' => $ip_info['dns'], + 'dnsname' => $this->resolveDns($fdb_entry->ipv4Addresses), 'first_seen' => 'unknown', 'last_seen' => 'unknown', ]; @@ -198,9 +197,9 @@ class FdbTablesController extends TableController /** * @param string $ip - * @return \Illuminate\Support\Collection + * @return Collection */ - protected function findMacs($ip): \Illuminate\Support\Collection + protected function findMacs($ip): Collection { $port_id = \Request::get('port_id'); $device_id = \Request::get('device_id'); @@ -217,9 +216,9 @@ class FdbTablesController extends TableController /** * @param string $vlan - * @return \Illuminate\Support\Collection + * @return Collection */ - protected function findVlans($vlan): \Illuminate\Support\Collection + protected function findVlans($vlan): Collection { $port_id = \Request::get('port_id'); $device_id = \Request::get('device_id'); @@ -238,9 +237,9 @@ class FdbTablesController extends TableController /** * @param string $ifAlias - * @return \Illuminate\Support\Collection + * @return Collection */ - protected function findPorts($ifAlias): \Illuminate\Support\Collection + protected function findPorts($ifAlias): Collection { $port_id = \Request::get('port_id'); $device_id = \Request::get('device_id'); @@ -255,38 +254,22 @@ class FdbTablesController extends TableController ->pluck('port_id'); } - /** - * @param string $mac_address - * @return array - */ - protected function findIps($mac_address): array + private function resolveDns(Collection $ips): string { - if (! isset($this->ipCache[$mac_address])) { - $ips = Ipv4Mac::where('mac_address', $mac_address) - ->groupBy('ipv4_address') - ->pluck('ipv4_address'); + $dns = 'N/A'; - $dns = 'N/A'; - - // only fetch DNS if the column is visible - if (\Request::get('dns') == 'true') { - // don't try too many dns queries, this is the slowest part - foreach ($ips->take(3) as $ip) { - $hostname = gethostbyaddr($ip); - if (! IP::isValid($hostname)) { - $dns = $hostname; - break; - } + // only fetch DNS if the column is visible + if (\Request::get('dns') == 'true') { + // don't try too many dns queries, this is the slowest part + foreach ($ips->take(3) as $ip) { + $hostname = gethostbyaddr($ip); + if (! IP::isValid($hostname)) { + return $hostname; } } - - $this->ipCache[$mac_address] = [ - 'ips' => $ips, - 'dns' => $dns, - ]; } - return $this->ipCache[$mac_address]; + return $dns; } /** @@ -308,31 +291,24 @@ class FdbTablesController extends TableController * @param string $vendor * @return array */ - protected function ouisFromVendor($vendor) + protected function ouisFromVendor(string $vendor): array { - $matching_ouis = DB::table('vendor_ouis') + return DB::table('vendor_ouis') ->where('vendor', 'LIKE', '%' . $vendor . '%') ->pluck('oui') ->toArray(); - - return $matching_ouis; } /** * Get all port ids from vendor OUIs - * - * @param array $vendor_ouis - * @return Builder */ - protected function findPortsByOui($vendor_ouis, $query) + protected function findPortsByOui(array $vendor_ouis, Builder $query): Builder { - $condition = ''; - foreach ($vendor_ouis as $oui) { - $clean_oui = str_replace(':', '', $oui); - $condition .= " ports_fdb.mac_address LIKE '$clean_oui%' OR"; - } - $condition = rtrim($condition, ' OR'); - $query->whereRaw($condition); + $query->where(function (Builder $query) use ($vendor_ouis) { + foreach ($vendor_ouis as $oui) { + $query->orWhere('ports_fdb.mac_address', 'LIKE', "$oui%"); + } + }); return $query; // Return the query builder instance } diff --git a/app/Models/PortsFdb.php b/app/Models/PortsFdb.php index 5f0f859585..81e8902456 100644 --- a/app/Models/PortsFdb.php +++ b/app/Models/PortsFdb.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasMany; class PortsFdb extends PortRelatedModel { @@ -21,4 +22,9 @@ class PortsFdb extends PortRelatedModel { return $this->belongsTo(\App\Models\Vlan::class, 'vlan_id', 'vlan_id'); } + + public function ipv4Addresses(): HasMany + { + return $this->hasMany(\App\Models\Ipv4Mac::class, 'mac_address', 'mac_address'); + } }