diff --git a/CMakeLists.txt b/CMakeLists.txt
index c847e06a3..6d070c6d3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -802,6 +802,24 @@ if(WITH_SYSTEMD)
endif(NOT POLKIT_FOUND)
endif(WITH_SYSTEMD)
+# Find the path to an arp compatible executable
+if(ZM_PATH_ARP STREQUAL "")
+ find_program(ARP_EXECUTABLE arp)
+ if(ARP_EXECUTABLE)
+ set(ZM_PATH_ARP "${ARP_EXECUTABLE}")
+ mark_as_advanced(ARP_EXECUTABLE)
+ else(ARP_EXECUTABLE)
+ find_program(ARP_EXECUTABLE ip)
+ if(ARP_EXECUTABLE)
+ set(ZM_PATH_ARP "${ARP_EXECUTABLE} neigh")
+ mark_as_advanced(ARP_EXECUTABLE)
+ endif(ARP_EXECUTABLE)
+ endif(ARP_EXECUTABLE)
+ if(ARP_EXECUTABLE-NOTFOUND)
+ message(WARNING "Unable to find a compatible arp binary. Monitor probe will not function." )
+ endif(ARP_EXECUTABLE-NOTFOUND)
+endif(ZM_PATH_ARP STREQUAL "")
+
# Some variables that zm expects
set(ZM_PID "${ZM_RUNDIR}/zm.pid")
set(ZM_CONFIG "${ZM_CONFIG_DIR}/zm.conf")
diff --git a/distros/debian/control b/distros/debian/control
index 9de030e87..29be56e25 100644
--- a/distros/debian/control
+++ b/distros/debian/control
@@ -13,6 +13,7 @@ Build-Depends: debhelper (>= 9), cmake
, libv4l-dev (>= 0.8.3)
, libbz2-dev
, ffmpeg | libav-tools
+ , net-tools
, libnetpbm10-dev
, libvlccore-dev, libvlc-dev
, libcurl4-gnutls-dev | libcurl4-nss-dev | libcurl4-openssl-dev
diff --git a/distros/redhat/zoneminder.spec b/distros/redhat/zoneminder.spec
index e3eb2abab..a9278891e 100644
--- a/distros/redhat/zoneminder.spec
+++ b/distros/redhat/zoneminder.spec
@@ -52,6 +52,7 @@ BuildRequires: pcre-devel
BuildRequires: libjpeg-turbo-devel
BuildRequires: findutils
BuildRequires: coreutils
+BuildRequires: net-tools
BuildRequires: perl
BuildRequires: perl-generators
BuildRequires: perl(Archive::Tar)
diff --git a/distros/ubuntu1604/control b/distros/ubuntu1604/control
index 0b934b7d2..3054a2d55 100644
--- a/distros/ubuntu1604/control
+++ b/distros/ubuntu1604/control
@@ -11,6 +11,8 @@ Build-Depends: debhelper (>= 9), dh-systemd, python-sphinx | python3-sphinx, apa
,libavformat-dev (>= 6:10~)
,libavutil-dev (>= 6:10~)
,libswscale-dev (>= 6:10~)
+ ,ffmpeg | libav-tools
+ ,net-tools
,libbz2-dev
,libgcrypt-dev | libgcrypt11-dev
,libcurl4-gnutls-dev
diff --git a/web/skins/classic/views/monitorprobe.php b/web/skins/classic/views/monitorprobe.php
index 0717d1fca..14be96f48 100644
--- a/web/skins/classic/views/monitorprobe.php
+++ b/web/skins/classic/views/monitorprobe.php
@@ -26,7 +26,7 @@ if ( !canEdit('Monitors') ) {
// Probe Local Cameras
function probeV4L() {
- $cameras = array();
+ $cameras = array();
$command = getZmuCommand(' --query --device');
if ( !empty($_REQUEST['device']) )
@@ -110,6 +110,7 @@ function probeV4L() {
$device['inputs'] = $inputs;
$devices[] = $device;
} # end foreach output line
+ return $cameras;
} # end function probeV4L
// Probe Network Cameras
@@ -206,7 +207,7 @@ function probeVivotek($ip) {
'Width' => 352,
'Height' => 240,
),
- );
+ );t
if ( $lines = @file($url) ) {
foreach ( $lines as $line ) {
$line = rtrim($line);
@@ -242,91 +243,70 @@ function probeWansview($ip) {
}
function probeNetwork() {
- // Calling arp without the full path was reported to fail on some systems
- // Use the builtin unix command "type" to tell us where the command is
- $arp_command = '';
- $result = explode(' ', ZM_PATH_ARP);
- if ( !is_executable($result[0]) ) {
- if ( ZM_PATH_ARP ) {
- Warning("User assigned ARP tool not found. Verify ZM_PATH_ARP points to a valid arp tool and is executable by the web user account.");
- }
- $result = exec('type -p arp', $output, $status);
- if ( $status ) {
- Warning("Unable to determine path for arp command, type -p arp returned '$status' output is: " . implode("\n", $output));
- unset($output);
- $result = exec('which arp', $output, $status);
- if ( $status ) {
- Warning("Unable to determine path for arp command, which arp returned '$status'");
- if ( file_exists('/usr/sbin/arp') ) {
- $arp_command = '/usr/sbin/arp -a';
- }
- } else {
- $arp_command = $output[0].' -a';
- }
- } else {
- $arp_command = $output[0].' -a';
- }
- } else {
- $arp_command = ZM_PATH_ARP;
- }
- // Now that we know where arp is, call it using the full path
- unset($output);
- $result = exec(escapeshellcmd($arp_command), $output, $status);
- if ( $status ) {
- Error("Unable to probe network cameras, status is '$status'");
- return;
- }
+ $cameras = array();
+ $arp_command = ZM_PATH_ARP;
+ $result = explode(' ', $arp_command);
+ if ( !is_executable($result[0]) ) {
+ Error("ARP compatible binary not found or not executable by the web user account. Verify ZM_PATH_ARP points to a valid arp tool.");
+ return;
+ }
- $monitors = array();
- foreach ( dbFetchAll("SELECT Id, Name, Host FROM Monitors WHERE Type = 'Remote' ORDER BY Host") as $monitor ) {
- if ( preg_match('/^(.+)@(.+)$/', $monitor['Host'], $matches) ) {
- //echo "1: ".$matches[2]." = ".gethostbyname($matches[2])."
";
- $monitors[gethostbyname($matches[2])] = $monitor;
- } else {
- //echo "2: ".$monitor['Host']." = ".gethostbyname($monitor['Host'])."
";
- $monitors[gethostbyname($monitor['Host'])] = $monitor;
- }
- }
+ $result = exec(escapeshellcmd($arp_command), $output, $status);
+ if ( $status ) {
+ Error("Unable to probe network cameras, status is '$status'");
+ return;
+ }
- $macBases = array(
- '00:40:8c' => array('type'=>'Axis', 'probeFunc'=>'probeAxis'),
- '00:80:f0' => array('type'=>'Panasonic','probeFunc'=>'probePana'),
- '00:0f:7c' => array('type'=>'ACTi','probeFunc'=>'probeACTi'),
- '00:02:d1' => array('type'=>'Vivotek','probeFunc'=>'probeVivotek'),
- '7c:dd:90' => array('type'=>'Wansview','probeFunc'=>'probeWansview'),
- '78:a5:dd' => array('type'=>'Wansview','probeFunc'=>'probeWansview')
- );
+ $monitors = array();
+ foreach ( dbFetchAll("SELECT Id, Name, Host FROM Monitors WHERE Type = 'Remote' ORDER BY Host") as $monitor ) {
+ if ( preg_match('/^(.+)@(.+)$/', $monitor['Host'], $matches) ) {
+ //echo "1: ".$matches[2]." = ".gethostbyname($matches[2])."
";
+ $monitors[gethostbyname($matches[2])] = $monitor;
+ } else {
+ //echo "2: ".$monitor['Host']." = ".gethostbyname($monitor['Host'])."
";
+ $monitors[gethostbyname($monitor['Host'])] = $monitor;
+ }
+ }
- foreach ( $output as $line ) {
- if ( !preg_match('/(\d+\.\d+\.\d+\.\d+).*(([0-9a-f]{2}:){5})/', $line, $matches) )
- continue;
- $ip = $matches[1];
- $host = $ip;
- $mac = $matches[2];
- //echo "I:$ip, H:$host, M:$mac
";
- $macRoot = substr($mac,0,8);
- if ( isset($macBases[$macRoot]) ) {
- $macBase = $macBases[$macRoot];
- $camera = call_user_func($macBase['probeFunc'], $ip);
- $sourceDesc = htmlspecialchars(serialize($camera['monitor']));
- $sourceString = $camera['model'].' @ '.$host;
- if ( isset($monitors[$ip]) ) {
- $monitor = $monitors[$ip];
- $sourceString .= ' ('.$monitor['Name'].')';
- } else {
- $sourceString .= ' - '.translate('Available');
- }
- $cameras[$sourceDesc] = $sourceString;
- }
- } # end foreach output line
- return $cameras;
+ $macBases = array(
+ '00:40:8c' => array('type'=>'Axis', 'probeFunc'=>'probeAxis'),
+ '00:80:f0' => array('type'=>'Panasonic','probeFunc'=>'probePana'),
+ '00:0f:7c' => array('type'=>'ACTi','probeFunc'=>'probeACTi'),
+ '00:02:d1' => array('type'=>'Vivotek','probeFunc'=>'probeVivotek'),
+ '7c:dd:90' => array('type'=>'Wansview','probeFunc'=>'probeWansview'),
+ '78:a5:dd' => array('type'=>'Wansview','probeFunc'=>'probeWansview')
+ );
+
+ foreach ( $output as $line ) {
+ if ( !preg_match('/(\d+\.\d+\.\d+\.\d+).*(([0-9a-f]{2}:){5})/', $line, $matches) )
+ continue;
+ $ip = $matches[1];
+ $host = $ip;
+ $mac = $matches[2];
+ //echo "I:$ip, H:$host, M:$mac
";
+ $macRoot = substr($mac,0,8);
+ if ( isset($macBases[$macRoot]) ) {
+ $macBase = $macBases[$macRoot];
+ $camera = call_user_func($macBase['probeFunc'], $ip);
+ $sourceDesc = htmlspecialchars(serialize($camera['monitor']));
+ $sourceString = $camera['model'].' @ '.$host;
+ if ( isset($monitors[$ip]) ) {
+ $monitor = $monitors[$ip];
+ $sourceString .= ' ('.$monitor['Name'].')';
+ } else {
+ $sourceString .= ' - '.translate('Available');
+ }
+ $cameras[$sourceDesc] = $sourceString;
+ }
+ } # end foreach output line
+ return $cameras;
} # end function probeNetwork()
$cameras = array();
$cameras[0] = translate('ChooseDetectedCamera');
if ( ZM_HAS_V4L2 )
- $cameras += probeV4L();
+ $cameras += probeV4L();
$cameras += probeNetwork();
if ( count($cameras) <= 1 )