NetworkDeviceDiscovery: Skip duplicated discovery if there are multiple network interfaces connected to the same network
This commit is contained in:
parent
da6d7b8efe
commit
285abcdd36
@ -29,10 +29,11 @@
|
|||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
#include "networkdevicediscoveryimpl.h"
|
#include "networkdevicediscoveryimpl.h"
|
||||||
|
|
||||||
#include "nymeasettings.h"
|
#include "nymeasettings.h"
|
||||||
#include "loggingcategories.h"
|
#include "loggingcategories.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include <network/ping.h>
|
#include <network/ping.h>
|
||||||
#include <network/arpsocket.h>
|
#include <network/arpsocket.h>
|
||||||
#include <network/networkutils.h>
|
#include <network/networkutils.h>
|
||||||
@ -339,6 +340,9 @@ void NetworkDeviceDiscoveryImpl::setEnabled(bool enabled)
|
|||||||
|
|
||||||
void NetworkDeviceDiscoveryImpl::pingAllNetworkDevices()
|
void NetworkDeviceDiscoveryImpl::pingAllNetworkDevices()
|
||||||
{
|
{
|
||||||
|
QList<QHostAddress> ownAddresses;
|
||||||
|
QList<TargetNetwork> targetNetworks;
|
||||||
|
|
||||||
qCDebug(dcNetworkDeviceDiscovery()) << "Starting ping for all network devices...";
|
qCDebug(dcNetworkDeviceDiscovery()) << "Starting ping for all network devices...";
|
||||||
foreach (const QNetworkInterface &networkInterface, QNetworkInterface::allInterfaces()) {
|
foreach (const QNetworkInterface &networkInterface, QNetworkInterface::allInterfaces()) {
|
||||||
if (networkInterface.flags().testFlag(QNetworkInterface::IsLoopBack))
|
if (networkInterface.flags().testFlag(QNetworkInterface::IsLoopBack))
|
||||||
@ -352,31 +356,64 @@ void NetworkDeviceDiscoveryImpl::pingAllNetworkDevices()
|
|||||||
|
|
||||||
qCDebug(dcNetworkDeviceDiscovery()) << "Verifying network interface" << networkInterface.name() << networkInterface.hardwareAddress() << "...";
|
qCDebug(dcNetworkDeviceDiscovery()) << "Verifying network interface" << networkInterface.name() << networkInterface.hardwareAddress() << "...";
|
||||||
foreach (const QNetworkAddressEntry &entry, networkInterface.addressEntries()) {
|
foreach (const QNetworkAddressEntry &entry, networkInterface.addressEntries()) {
|
||||||
qCDebug(dcNetworkDeviceDiscovery()) << " Checking entry" << entry.ip().toString();
|
|
||||||
|
|
||||||
// Only IPv4
|
// Only IPv4
|
||||||
if (entry.ip().protocol() != QAbstractSocket::IPv4Protocol)
|
if (entry.ip().protocol() != QAbstractSocket::IPv4Protocol)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Store the own address of this network interface in any case,
|
||||||
|
// since we don't want to ping our self
|
||||||
|
ownAddresses.append(entry.ip());
|
||||||
|
|
||||||
|
TargetNetwork targetNetwork;
|
||||||
|
targetNetwork.networkInterface = networkInterface;
|
||||||
|
targetNetwork.addressEntry = entry;
|
||||||
|
targetNetwork.address = QHostAddress(entry.ip().toIPv4Address() & entry.netmask().toIPv4Address());
|
||||||
|
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << " Checking entry" << entry.ip().toString();
|
||||||
qCDebug(dcNetworkDeviceDiscovery()) << " Host address:" << entry.ip().toString();
|
qCDebug(dcNetworkDeviceDiscovery()) << " Host address:" << entry.ip().toString();
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << " Network address:" << targetNetwork.address.toString();
|
||||||
qCDebug(dcNetworkDeviceDiscovery()) << " Broadcast address:" << entry.broadcast().toString();
|
qCDebug(dcNetworkDeviceDiscovery()) << " Broadcast address:" << entry.broadcast().toString();
|
||||||
qCDebug(dcNetworkDeviceDiscovery()) << " Netmask:" << entry.netmask().toString();
|
qCDebug(dcNetworkDeviceDiscovery()) << " Netmask:" << entry.netmask().toString();
|
||||||
quint32 addressRangeStart = entry.ip().toIPv4Address() & entry.netmask().toIPv4Address();
|
qCDebug(dcNetworkDeviceDiscovery()) << " Address rang from" << targetNetwork.address.toString() << "-->" << targetNetwork.addressEntry.broadcast().toString();
|
||||||
quint32 addressRangeStop = entry.broadcast().toIPv4Address() | addressRangeStart;
|
|
||||||
quint32 range = addressRangeStop - addressRangeStart;
|
|
||||||
|
|
||||||
// Let's scan only 255.255.255.0 networks for now
|
// Let's scan only 255.255.255.0 networks for now
|
||||||
if (range > 255)
|
if (entry.prefixLength() < 24) {
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << "Skipping network interface" << networkInterface.name() << "because there are to many hosts to contact. The network detector was designed for /24 networks.";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter out duplicated networks (for example connected using wifi and ethernet to the same network) ...
|
||||||
|
|
||||||
|
bool duplicatedNetwork = false;
|
||||||
|
foreach (const TargetNetwork &tn, targetNetworks) {
|
||||||
|
if (tn.address == targetNetwork.address && tn.addressEntry.netmask() == targetNetwork.addressEntry.netmask()) {
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << "Skipping network interface" << targetNetwork.networkInterface.name() << targetNetwork.address.toString() << "as ping target network because it seems to be the same network as" << tn.networkInterface.name() << tn.address.toString();
|
||||||
|
duplicatedNetwork = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (duplicatedNetwork)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
qCDebug(dcNetworkDeviceDiscovery()) << " Address range" << range << " | from" << QHostAddress(addressRangeStart).toString() << "-->" << QHostAddress(addressRangeStop).toString();
|
targetNetworks.append(targetNetwork);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (const TargetNetwork &targetNetwork, targetNetworks) {
|
||||||
|
|
||||||
// Send ping request to each address within the range
|
// Send ping request to each address within the range
|
||||||
for (quint32 i = 1; i < range; i++) {
|
quint32 targetHostsCount = pow(2, 32 - targetNetwork.addressEntry.prefixLength()) - 1;
|
||||||
quint32 address = addressRangeStart + i;
|
for (quint32 i = 1; i < targetHostsCount; i++) {
|
||||||
QHostAddress targetAddress(address);
|
QHostAddress targetAddress(targetNetwork.address.toIPv4Address() + i);
|
||||||
|
|
||||||
|
// Skip the broadcast
|
||||||
|
if (targetAddress == targetNetwork.addressEntry.broadcast())
|
||||||
|
continue;
|
||||||
|
|
||||||
// Skip our self
|
// Skip our self
|
||||||
if (targetAddress == entry.ip())
|
if (ownAddresses.contains(targetAddress))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Retry only once to ping a device and lookup the hostname on success
|
// Retry only once to ping a device and lookup the hostname on success
|
||||||
@ -404,7 +441,6 @@ void NetworkDeviceDiscoveryImpl::pingAllNetworkDevices()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkDeviceDiscoveryImpl::processMonitorPingResult(PingReply *reply, NetworkDeviceMonitorImpl *monitor)
|
void NetworkDeviceDiscoveryImpl::processMonitorPingResult(PingReply *reply, NetworkDeviceMonitorImpl *monitor)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -85,6 +85,12 @@ protected:
|
|||||||
void setEnabled(bool enabled) override;
|
void setEnabled(bool enabled) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef struct TargetNetwork {
|
||||||
|
QNetworkInterface networkInterface;
|
||||||
|
QNetworkAddressEntry addressEntry;
|
||||||
|
QHostAddress address;
|
||||||
|
} TargetNetwork;
|
||||||
|
|
||||||
MacAddressDatabase *m_macAddressDatabase = nullptr;
|
MacAddressDatabase *m_macAddressDatabase = nullptr;
|
||||||
ArpSocket *m_arpSocket = nullptr;
|
ArpSocket *m_arpSocket = nullptr;
|
||||||
Ping *m_ping = nullptr;
|
Ping *m_ping = nullptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user