summaryrefslogtreecommitdiffstats
path: root/src/network/kernel/qnetworkinterface_unix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/kernel/qnetworkinterface_unix.cpp')
-rw-r--r--src/network/kernel/qnetworkinterface_unix.cpp58
1 files changed, 29 insertions, 29 deletions
diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp
index b090213861..01c082059f 100644
--- a/src/network/kernel/qnetworkinterface_unix.cpp
+++ b/src/network/kernel/qnetworkinterface_unix.cpp
@@ -312,38 +312,38 @@ QT_END_INCLUDE_NAMESPACE
static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList)
{
QList<QNetworkInterfacePrivate *> interfaces;
+ QSet<QString> seenInterfaces;
+ // on Linux, AF_PACKET addresses carry the hardware address and interface index;
+ // scan for them first (they're usually first, but we have no guarantee this
+ // will be the case forever)
for (ifaddrs *ptr = rawList; ptr; ptr = ptr->ifa_next) {
- if ( !ptr->ifa_addr )
- continue;
-
- // Get the interface index
- int ifindex = if_nametoindex(ptr->ifa_name);
+ if (ptr->ifa_addr && ptr->ifa_addr->sa_family == AF_PACKET) {
+ sockaddr_ll *sll = (sockaddr_ll *)ptr->ifa_addr;
+ QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate;
+ interfaces << iface;
+ iface->index = sll->sll_ifindex;
+ iface->name = QString::fromLatin1(ptr->ifa_name);
+ iface->flags = convertFlags(ptr->ifa_flags);
+ iface->hardwareAddress = iface->makeHwAddress(sll->sll_halen, (uchar*)sll->sll_addr);
- // on Linux we use AF_PACKET and sockaddr_ll to obtain hHwAddress
- QList<QNetworkInterfacePrivate *>::Iterator if_it = interfaces.begin();
- for ( ; if_it != interfaces.end(); ++if_it)
- if ((*if_it)->index == ifindex) {
- // this one has been added already
- if ( ptr->ifa_addr->sa_family == AF_PACKET
- && (*if_it)->hardwareAddress.isEmpty()) {
- sockaddr_ll *sll = (sockaddr_ll *)ptr->ifa_addr;
- (*if_it)->hardwareAddress = (*if_it)->makeHwAddress(sll->sll_halen, (uchar*)sll->sll_addr);
- }
- break;
- }
- if ( if_it != interfaces.end() )
- continue;
+ seenInterfaces.insert(iface->name);
+ }
+ }
- QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate;
- interfaces << iface;
- iface->index = ifindex;
- iface->name = QString::fromLatin1(ptr->ifa_name);
- iface->flags = convertFlags(ptr->ifa_flags);
+ // see if we missed anything:
+ // virtual interfaces with no HW address have no AF_PACKET
+ for (ifaddrs *ptr = rawList; ptr; ptr = ptr->ifa_next) {
+ if (ptr->ifa_addr && ptr->ifa_addr->sa_family != AF_PACKET) {
+ QString name = QString::fromLatin1(ptr->ifa_name);
+ if (seenInterfaces.contains(name))
+ continue;
- if ( ptr->ifa_addr->sa_family == AF_PACKET ) {
- sockaddr_ll *sll = (sockaddr_ll *)ptr->ifa_addr;
- iface->hardwareAddress = iface->makeHwAddress(sll->sll_halen, (uchar*)sll->sll_addr);
+ QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate;
+ interfaces << iface;
+ iface->name = name;
+ iface->flags = convertFlags(ptr->ifa_flags);
+ iface->index = if_nametoindex(ptr->ifa_name);
}
}
@@ -423,11 +423,11 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
interfaces = createInterfaces(interfaceListing);
for (ifaddrs *ptr = interfaceListing; ptr; ptr = ptr->ifa_next) {
// Get the interface index
- int ifindex = if_nametoindex(ptr->ifa_name);
+ QString name = QString::fromLatin1(ptr->ifa_name);
QNetworkInterfacePrivate *iface = 0;
QList<QNetworkInterfacePrivate *>::Iterator if_it = interfaces.begin();
for ( ; if_it != interfaces.end(); ++if_it)
- if ((*if_it)->index == ifindex) {
+ if ((*if_it)->name == name) {
// found this interface already
iface = *if_it;
break;