Handle duplicate arp cache entries with the same MAC better

This commit is contained in:
Michael Zanetti 2019-01-25 16:59:55 +01:00
parent 765b2c6c75
commit a884d3af85

View File

@ -74,12 +74,15 @@ void DeviceMonitor::arpLookupFinished(int exitCode)
QString data = QString::fromLatin1(m_arpLookupProcess->readAll()); QString data = QString::fromLatin1(m_arpLookupProcess->readAll());
bool found = false; bool found = false;
bool needsPing = true; bool needsPing = true;
QString mostRecentIP = m_host->address();
qlonglong secsSinceLastSeen = -1;
foreach (QString line, data.split('\n')) { foreach (QString line, data.split('\n')) {
line.replace(QRegExp("[ ]{1,}"), " "); line.replace(QRegExp("[ ]{1,}"), " ");
QStringList parts = line.split(" "); QStringList parts = line.split(" ");
int lladdrIndex = parts.indexOf("lladdr"); int lladdrIndex = parts.indexOf("lladdr");
if (lladdrIndex >= 0 && parts.count() > lladdrIndex && parts.at(lladdrIndex+1).toLower() == m_host->macAddress().toLower()) { if (lladdrIndex >= 0 && parts.count() > lladdrIndex + 1 && parts.at(lladdrIndex+1).toLower() == m_host->macAddress().toLower()) {
found = true; found = true;
QString entryIP = parts.first();
if (parts.last() == "REACHABLE") { if (parts.last() == "REACHABLE") {
qCDebug(dcNetworkDetector()) << "Device" << m_host->macAddress() << "found in ARP cache and claims to be REACHABLE"; qCDebug(dcNetworkDetector()) << "Device" << m_host->macAddress() << "found in ARP cache and claims to be REACHABLE";
if (!m_host->reachable()) { if (!m_host->reachable()) {
@ -89,19 +92,33 @@ void DeviceMonitor::arpLookupFinished(int exitCode)
m_host->seen(); m_host->seen();
emit seen(); emit seen();
// Verify if IP address is still the same // Verify if IP address is still the same
if (parts.first() != m_host->address()) { if (entryIP != mostRecentIP) {
m_host->setAddress(parts.first()); mostRecentIP = entryIP;
emit addressChanged(parts.first());
} }
// If we have a reachable entry, stop processing here // If we have a reachable entry, stop processing here
needsPing = false; needsPing = false;
break; break;
} else { } else {
// ARP claims the device to be stale... Flagging device to require a ping. // ARP claims the device to be stale... Flagging device to require a ping.
qCDebug(dcNetworkDetector()) << "Device" << m_host->macAddress() << "found in ARP cache but is marked as" << parts.last(); qCDebug(dcNetworkDetector()) << "Device" << m_host->macAddress() << "found in ARP cache with IP" << entryIP << "but is marked as" << parts.last();
int usedIndex = parts.indexOf("used");
if (usedIndex >= 0 && parts.count() > usedIndex + 1) {
QString usedFields = parts.at(usedIndex + 1);
qlonglong newSecsSinceLastSeen = usedFields.split("/").first().toInt();
if (secsSinceLastSeen == -1 || newSecsSinceLastSeen < secsSinceLastSeen) {
secsSinceLastSeen = newSecsSinceLastSeen;
mostRecentIP = entryIP;
}
}
} }
} }
} }
if (mostRecentIP != m_host->address()) {
qCDebug(dcNetworkDetector()) << "IP seems to have changed IP:" << m_host->address() << "->" << mostRecentIP;
m_host->setAddress(mostRecentIP);
emit addressChanged(mostRecentIP);
}
if (!found) { if (!found) {
qCDebug(dcNetworkDetector()) << "Device" << m_host->macAddress() << "not found in ARP cache."; qCDebug(dcNetworkDetector()) << "Device" << m_host->macAddress() << "not found in ARP cache.";
ping(); ping();