diff options
Diffstat (limited to 'src/network/kernel/qnetworkinterface_unix.cpp')
-rw-r--r-- | src/network/kernel/qnetworkinterface_unix.cpp | 58 |
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; |