From 4ab358501dc21d9714ae0deaea690a86d794837c Mon Sep 17 00:00:00 2001 From: Tony Murray Date: Fri, 7 Apr 2017 15:05:46 -0500 Subject: [PATCH] api: API allow cidr network searches of the ARP table (#6378) * api: API allow cidr network searches of the ARP table * Allow non-encoded / in request I also noticed that all is allowed to be called without device, which the sql query does not support. --- doc/API/API-Docs.md | 4 +++- html/api_v0.php | 2 +- html/includes/api_functions.inc.php | 15 ++++++++++++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/doc/API/API-Docs.md b/doc/API/API-Docs.md index 005dab3578..285d2bd287 100644 --- a/doc/API/API-Docs.md +++ b/doc/API/API-Docs.md @@ -1826,6 +1826,7 @@ Retrieve a specific ARP entry or all ARP enties for a device Route: /api/v0/resources/ip/arp/:ip - 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 Input: @@ -1834,7 +1835,8 @@ Input: Example: ```curl curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/ip/arp/1.1.1.1 -curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/ip/arp/1.1.1.1?device=localhost +curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/ip/arp/192.168.1.0/24 +curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/ip/arp/all?device=localhost ``` Output: diff --git a/html/api_v0.php b/html/api_v0.php index f2b499bb2f..4d423e1cbc 100644 --- a/html/api_v0.php +++ b/html/api_v0.php @@ -153,7 +153,7 @@ $app->group( $app->group( '/ip', function () use ($app) { - $app->get('/arp/:ip', 'authToken', 'list_arp')->name('list_arp'); + $app->get('/arp/:ip', 'authToken', 'list_arp')->name('list_arp')->conditions(array('ip' => '[^?]+')); } ); } diff --git a/html/includes/api_functions.inc.php b/html/includes/api_functions.inc.php index 1832e155e5..532a34db82 100644 --- a/html/includes/api_functions.inc.php +++ b/html/includes/api_functions.inc.php @@ -1465,26 +1465,35 @@ function list_arp() $code = 404; $message = ''; $ip = $router['ip']; + $hostname = mres($_GET['device']); $total = 0; if (empty($ip)) { $message = "No valid IP provided"; + } elseif ($ip === "all" && empty($hostname)) { + $message = "Device argument is required when requesting all entries"; } else { $code = 200; $status = 'ok'; if ($ip === "all") { - $hostname = mres($_GET['device']); $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` = ?", array($device_id)); + } elseif (str_contains($ip, '/')) { + $ipv4 = new Net_IPv4(); + $net = $ipv4->parseAddress($ip); + $arp = dbFetchRows( + 'SELECT * FROM `ipv4_mac` WHERE (inet_aton(`ipv4_address`) & ?) = ?', + array(ip2long($net->netmask), ip2long($net->network)) + ); } else { $arp = dbFetchRows("SELECT * FROM `ipv4_mac` WHERE `ipv4_address`=?", array($ip)); } - $total = count($arp); + $total = count($arp); } $output = array( 'status' => $status, 'err-msg' => $message, 'count' => $total, - 'arp' => $arp, + 'arp' => $arp, ); $app->response->setStatus($code); $app->response->headers->set('Content-Type', 'application/json');