fire broadcast pings if a device doesn't respond to the remembered ip

This commit is contained in:
Michael Zanetti 2019-03-01 19:58:32 +01:00
parent 29a8fae0da
commit 944731c171
3 changed files with 45 additions and 2 deletions

1
debian/control vendored
View File

@ -374,6 +374,7 @@ Architecture: any
Depends: ${shlibs:Depends}, Depends: ${shlibs:Depends},
${misc:Depends}, ${misc:Depends},
nmap, nmap,
fping,
nymea-plugins-translations, nymea-plugins-translations,
Replaces: guh-plugin-networkdetector Replaces: guh-plugin-networkdetector
Description: nymea.io plugin for networkdetector Description: nymea.io plugin for networkdetector

View File

@ -111,7 +111,6 @@ void DeviceMonitor::arpLookupFinished(int exitCode)
void DeviceMonitor::arping() void DeviceMonitor::arping()
{ {
log("Sending ARP Ping...");
QNetworkInterface targetInterface; QNetworkInterface targetInterface;
foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) { foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) {
foreach (const QNetworkAddressEntry &addressEntry, interface.addressEntries()) { foreach (const QNetworkAddressEntry &addressEntry, interface.addressEntries()) {
@ -131,6 +130,7 @@ void DeviceMonitor::arping()
return; return;
} }
log("Sending ARP Ping to " + m_ipAddress + "...");
m_arpingProcess->start("arping", {"-I", targetInterface.name(), "-f", "-w", "30", 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() void DeviceMonitor::ping()
{ {
log("Sending ICMP Ping..."); log("Sending ICMP Ping to " + m_ipAddress + "...");
m_pingProcess->start("ping", {"-c", "30", m_ipAddress}); m_pingProcess->start("ping", {"-c", "30", m_ipAddress});
} }
void DeviceMonitor::pingFinished(int exitCode) void DeviceMonitor::pingFinished(int exitCode)
{ {
if (exitCode == 0) { if (exitCode == 0) {
// we were able to ping the device // we were able to ping the device
@ -175,6 +176,10 @@ void DeviceMonitor::pingFinished(int exitCode)
} else { } else {
m_failedPings++; m_failedPings++;
log("ICMP Ping failed for " + QString::number(m_failedPings) + " times. (Grace Period: " + QString::number(m_gracePeriod) + ")"); 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) { if (m_failedPings > m_gracePeriod && m_reachable) {
log("Marking device as offline."); log("Marking device as offline.");
m_reachable = false; m_reachable = false;
@ -187,6 +192,41 @@ void DeviceMonitor::pingFinished(int exitCode)
// qCDebug(dcNetworkDetector()) << "have ping data" << data; // 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<QProcess*>(sender());
p->deleteLater();
}
void DeviceMonitor::log(const QString &message) void DeviceMonitor::log(const QString &message)
{ {
qCDebug(dcNetworkDetector()).noquote().nospace() << m_name << " (" << m_macAddress << ", " << m_ipAddress << "): " << message; qCDebug(dcNetworkDetector()).noquote().nospace() << m_name << " (" << m_macAddress << ", " << m_ipAddress << "): " << message;

View File

@ -25,6 +25,7 @@ private:
void lookupArpCache(); void lookupArpCache();
void arping(); void arping();
void ping(); void ping();
void broadcastPing();
void log(const QString &message); void log(const QString &message);
void warn(const QString &message); void warn(const QString &message);
@ -33,6 +34,7 @@ private slots:
void arpLookupFinished(int exitCode); void arpLookupFinished(int exitCode);
void arpingFinished(int exitCode); void arpingFinished(int exitCode);
void pingFinished(int exitCode); void pingFinished(int exitCode);
void broadcastPingFinished(int exitCode);
private: private:
QString m_name; QString m_name;