From 12773d125b4948245d37fd65a25baaec6d83b410 Mon Sep 17 00:00:00 2001 From: Tony Murray Date: Wed, 13 Nov 2019 02:21:07 +0000 Subject: [PATCH] API: list_arp search by MAC (#10803) * API: Allow search ARP by MAC * reformat mac * Update docs --- doc/API/ARP.md | 11 ++++++----- includes/html/api_functions.inc.php | 17 ++++++++++------- routes/api.php | 2 +- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/doc/API/ARP.md b/doc/API/ARP.md index f4ee0940b9..7b98379cee 100644 --- a/doc/API/ARP.md +++ b/doc/API/ARP.md @@ -5,15 +5,16 @@ path: blob/master/doc/ Retrieve a specific ARP entry or all ARP enties for a device -Route: `/api/v0/resources/ip/arp/:ip` +Route: `/api/v0/resources/ip/arp/:query` -- ip is the specific IP you would like to query, if this is all then - you need to pass ?device=_hostname_ (or device id) -- This may also be a cidr network, for example 192.168.1.0/24 +Query can be: +- An IP address +- A CIDR network (192.168.1.0/24) +- `all` and set ?device=_hostname_ (or device id) Input: -- device if you specify all for the IP then you need to populate this +- device if you specify all for the query then you need to populate this with the hostname or id of the device. Example: diff --git a/includes/html/api_functions.inc.php b/includes/html/api_functions.inc.php index 096c22e49b..068d7f62fc 100644 --- a/includes/html/api_functions.inc.php +++ b/includes/html/api_functions.inc.php @@ -1996,22 +1996,22 @@ function list_ip_networks() function list_arp(\Illuminate\Http\Request $request) { - $ip = $request->route('ip'); + $query = $request->route('query'); $cidr = $request->route('cidr'); $hostname = $request->get('device'); - if (empty($ip)) { - return api_error(400, "No valid IP provided"); - } elseif ($ip === "all" && empty($hostname)) { + if (empty($query)) { + return api_error(400, "No valid IP/MAC provided"); + } elseif ($query === "all" && empty($hostname)) { return api_error(400, "Device argument is required when requesting all entries"); } - if ($ip === "all") { + if ($query === "all") { $device_id = ctype_digit($hostname) ? $hostname : getidbyname($hostname); $arp = dbFetchRows("SELECT `ipv4_mac`.* FROM `ipv4_mac` LEFT JOIN `ports` ON `ipv4_mac`.`port_id` = `ports`.`port_id` WHERE `ports`.`device_id` = ?", [$device_id]); } elseif ($cidr) { try { - $ip = new IPv4("$ip/$cidr"); + $ip = new IPv4("$query/$cidr"); $arp = dbFetchRows( 'SELECT * FROM `ipv4_mac` WHERE (inet_aton(`ipv4_address`) & ?) = ?', [ip2long($ip->getNetmask()), ip2long($ip->getNetworkAddress())] @@ -2019,8 +2019,11 @@ function list_arp(\Illuminate\Http\Request $request) } catch (InvalidIpException $e) { return api_error(400, "Invalid Network Address"); } + } elseif (filter_var($query, FILTER_VALIDATE_MAC)) { + $mac = \LibreNMS\Util\Rewrite::macToHex($query); + $arp = dbFetchRows("SELECT * FROM `ipv4_mac` WHERE `mac_address`=?", [$mac]); } else { - $arp = dbFetchRows("SELECT * FROM `ipv4_mac` WHERE `ipv4_address`=?", [$ip]); + $arp = dbFetchRows("SELECT * FROM `ipv4_mac` WHERE `ipv4_address`=?", [$query]); } return api_success($arp, 'arp'); } diff --git a/routes/api.php b/routes/api.php index 35287f1ec3..7614d2e537 100644 --- a/routes/api.php +++ b/routes/api.php @@ -40,7 +40,7 @@ Route::group(['prefix' => 'v0', 'namespace' => '\App\Api\Controllers'], function Route::get('links/{id}', 'LegacyApiController@get_link')->name('get_link'); Route::get('locations', 'LegacyApiController@list_locations')->name('list_locations'); Route::get('ip/addresses', 'LegacyApiController@list_ip_addresses')->name('list_ip_addresses'); - Route::get('ip/arp/{ip}/{cidr?}', 'LegacyApiController@list_arp')->name('list_arp'); + Route::get('ip/arp/{query}/{cidr?}', 'LegacyApiController@list_arp')->name('list_arp'); Route::get('ip/networks', 'LegacyApiController@list_ip_networks')->name('list_ip_networks'); Route::get('ip/networks/{id}/ip', 'LegacyApiController@get_network_ip_addresses')->name('get_network_ip_addresses'); });