From 944731c17186cea6cb165ff3ecfa21b7893f2507 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Fri, 1 Mar 2019 19:58:32 +0100 Subject: [PATCH] fire broadcast pings if a device doesn't respond to the remembered ip --- debian/control | 1 + networkdetector/devicemonitor.cpp | 44 +++++++++++++++++++++++++++++-- networkdetector/devicemonitor.h | 2 ++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/debian/control b/debian/control index 3adf6421..aea80a21 100644 --- a/debian/control +++ b/debian/control @@ -374,6 +374,7 @@ Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, nmap, + fping, nymea-plugins-translations, Replaces: guh-plugin-networkdetector Description: nymea.io plugin for networkdetector diff --git a/networkdetector/devicemonitor.cpp b/networkdetector/devicemonitor.cpp index 91b29a13..18c3a9f8 100644 --- a/networkdetector/devicemonitor.cpp +++ b/networkdetector/devicemonitor.cpp @@ -111,7 +111,6 @@ void DeviceMonitor::arpLookupFinished(int exitCode) void DeviceMonitor::arping() { - log("Sending ARP Ping..."); QNetworkInterface targetInterface; foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) { foreach (const QNetworkAddressEntry &addressEntry, interface.addressEntries()) { @@ -131,6 +130,7 @@ void DeviceMonitor::arping() return; } + log("Sending ARP Ping to " + m_ipAddress + "..."); m_arpingProcess->start("arping", {"-I", targetInterface.name(), "-f", "-w", "30", m_ipAddress}); } @@ -157,11 +157,12 @@ void DeviceMonitor::arpingFinished(int exitCode) void DeviceMonitor::ping() { - log("Sending ICMP Ping..."); + log("Sending ICMP Ping to " + m_ipAddress + "..."); m_pingProcess->start("ping", {"-c", "30", m_ipAddress}); } void DeviceMonitor::pingFinished(int exitCode) + { if (exitCode == 0) { // we were able to ping the device @@ -175,6 +176,10 @@ void DeviceMonitor::pingFinished(int exitCode) } else { m_failedPings++; log("ICMP Ping failed for " + QString::number(m_failedPings) + " times. (Grace Period: " + QString::number(m_gracePeriod) + ")"); + if (m_failedPings > m_gracePeriod - 1) { + // Regular ping fails too... Fire a broadcast ping in case the device has changed IP. After that, our ARP table should be up to date again. + broadcastPing(); + } if (m_failedPings > m_gracePeriod && m_reachable) { log("Marking device as offline."); m_reachable = false; @@ -187,6 +192,41 @@ void DeviceMonitor::pingFinished(int exitCode) // qCDebug(dcNetworkDetector()) << "have ping data" << data; } +void DeviceMonitor::broadcastPing() +{ + QNetworkAddressEntry targetAddressEntry; + foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) { + foreach (const QNetworkAddressEntry &addressEntry, interface.addressEntries()) { + QHostAddress clientAddress(m_ipAddress); + if (clientAddress.isInSubnet(addressEntry.ip(), addressEntry.prefixLength())) { + targetAddressEntry = addressEntry; + break; + } + } + } + if (targetAddressEntry.broadcast().isNull()) { + warn("Could not find a suitable broadcast address Ping."); + if (m_reachable) { + m_reachable = false; + emit reachableChanged(false); + } + return; + } + + QProcess *p = new QProcess(this); + log("Sending Broadcast Ping on " + targetAddressEntry.ip().toString() + '/' + QString::number(targetAddressEntry.prefixLength()) + "..."); + p->start("fping", {"-a", "-c", "5", "-g", targetAddressEntry.broadcast().toString() + "/" + QString::number(targetAddressEntry.prefixLength())}); + connect(p, SIGNAL(finished(int)), this, SLOT(broadcastPingFinished(int))); +} + +void DeviceMonitor::broadcastPingFinished(int exitCode) +{ + Q_UNUSED(exitCode); + log("Broadcast ping finished"); + QProcess *p = static_cast(sender()); + p->deleteLater(); +} + void DeviceMonitor::log(const QString &message) { qCDebug(dcNetworkDetector()).noquote().nospace() << m_name << " (" << m_macAddress << ", " << m_ipAddress << "): " << message; diff --git a/networkdetector/devicemonitor.h b/networkdetector/devicemonitor.h index f8c3d937..822900e4 100644 --- a/networkdetector/devicemonitor.h +++ b/networkdetector/devicemonitor.h @@ -25,6 +25,7 @@ private: void lookupArpCache(); void arping(); void ping(); + void broadcastPing(); void log(const QString &message); void warn(const QString &message); @@ -33,6 +34,7 @@ private slots: void arpLookupFinished(int exitCode); void arpingFinished(int exitCode); void pingFinished(int exitCode); + void broadcastPingFinished(int exitCode); private: QString m_name;