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

master
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},
${misc:Depends},
nmap,
fping,
nymea-plugins-translations,
Replaces: guh-plugin-networkdetector
Description: nymea.io plugin for networkdetector

View File

@ -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<QProcess*>(sender());
p->deleteLater();
}
void DeviceMonitor::log(const QString &message)
{
qCDebug(dcNetworkDetector()).noquote().nospace() << m_name << " (" << m_macAddress << ", " << m_ipAddress << "): " << message;

View File

@ -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;