QT_BEGIN_INCLUDE_NAMESPACE # include <features.h> QT_END_INCLUDE_NAMESPACE # endif # if defined(Q_OS_LINUX) && __GLIBC__ - 0 >= 2 && __GLIBC_MINOR__ - 0 >= 1 # include <netpacket/packet.h> static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList) { QList<QNetworkInterfacePrivate *> interfaces; 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); // 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; QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate; interfaces << iface; iface->index = ifindex; iface->name = QString::fromLatin1(ptr->ifa_name); iface->flags = convertFlags(ptr->ifa_flags); 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); } } return interfaces; }
QT_BEGIN_INCLUDE_NAMESPACE # include <features.h> QT_END_INCLUDE_NAMESPACE # endif # if defined(Q_OS_LINUX) && __GLIBC__ - 0 >= 2 && __GLIBC_MINOR__ - 0 >= 1 && !defined(QT_LINUXBASE) # include <netpacket/packet.h> 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 && 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); seenInterfaces.insert(iface->name); } } // 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; QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate; interfaces << iface; iface->name = name; iface->flags = convertFlags(ptr->ifa_flags); iface->index = if_nametoindex(ptr->ifa_name); } } return interfaces; }
QT_BEGIN_INCLUDE_NAMESPACE # include <net/if_dl.h> QT_END_INCLUDE_NAMESPACE static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList) { QList<QNetworkInterfacePrivate *> interfaces; // on NetBSD we use AF_LINK and sockaddr_dl // scan the list for that family for (ifaddrs *ptr = rawList; ptr; ptr = ptr->ifa_next) if (ptr->ifa_addr && ptr->ifa_addr->sa_family == AF_LINK) { QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate; interfaces << iface; sockaddr_dl *sdl = (sockaddr_dl *)ptr->ifa_addr; iface->index = sdl->sdl_index; iface->name = QString::fromLatin1(ptr->ifa_name); iface->flags = convertFlags(ptr->ifa_flags); iface->hardwareAddress = iface->makeHwAddress(sdl->sdl_alen, (uchar*)LLADDR(sdl)); } return interfaces; }
static QNetworkInterfacePrivate *findInterface(int socket, QList<QNetworkInterfacePrivate *> &interfaces, struct ifreq &req) { QNetworkInterfacePrivate *iface = 0; int ifindex = 0; #ifndef QT_NO_IPV6IFNAME // Get the interface index ifindex = if_nametoindex(req.ifr_name); // find the interface data QList<QNetworkInterfacePrivate *>::Iterator if_it = interfaces.begin(); for ( ; if_it != interfaces.end(); ++if_it) if ((*if_it)->index == ifindex) { // existing interface iface = *if_it; break; } #else // Search by name QList<QNetworkInterfacePrivate *>::Iterator if_it = interfaces.begin(); for ( ; if_it != interfaces.end(); ++if_it) if ((*if_it)->name == QLatin1String(req.ifr_name)) { // existing interface iface = *if_it; break; } #endif if (!iface) { // new interface, create data: iface = new QNetworkInterfacePrivate; iface->index = ifindex; interfaces << iface; #ifdef SIOCGIFNAME // Get the canonical name QByteArray oldName = req.ifr_name; if (qt_safe_ioctl(socket, SIOCGIFNAME, &req) >= 0) { iface->name = QString::fromLatin1(req.ifr_name); // reset the name: memcpy(req.ifr_name, oldName, qMin<int>(oldName.length() + 1, sizeof(req.ifr_name) - 1)); } else #endif { // use this name anyways iface->name = QString::fromLatin1(req.ifr_name); } // Get interface flags if (qt_safe_ioctl(socket, SIOCGIFFLAGS, &req) >= 0) { iface->flags = convertFlags(req.ifr_flags); } #ifdef SIOCGIFHWADDR // Get the HW address if (qt_safe_ioctl(socket, SIOCGIFHWADDR, &req) >= 0) { uchar *addr = (uchar *)req.ifr_addr.sa_data; iface->hardwareAddress = iface->makeHwAddress(6, addr); } #endif } return iface; }
static QList<QNetworkInterfacePrivate *> interfaceListingWinXP() { QList<QNetworkInterfacePrivate *> interfaces; IP_ADAPTER_ADDRESSES staticBuf[2]; // 2 is arbitrary PIP_ADAPTER_ADDRESSES pAdapter = staticBuf; ULONG bufSize = sizeof staticBuf; const QHash<QHostAddress, QHostAddress> &ipv4netmasks = ipv4Netmasks(); ULONG flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_MULTICAST; ULONG retval = ptrGetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapter, &bufSize); if (retval == ERROR_BUFFER_OVERFLOW) { // need more memory pAdapter = (IP_ADAPTER_ADDRESSES *)malloc(bufSize); if (!pAdapter) return interfaces; // try again if (ptrGetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapter, &bufSize) != ERROR_SUCCESS) { free(pAdapter); return interfaces; } } else if (retval != ERROR_SUCCESS) { // error return interfaces; } // iterate over the list and add the entries to our listing for (PIP_ADAPTER_ADDRESSES ptr = pAdapter; ptr; ptr = ptr->Next) { QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate; interfaces << iface; iface->index = 0; if (ptr->Length >= offsetof(IP_ADAPTER_ADDRESSES, Ipv6IfIndex) && ptr->Ipv6IfIndex != 0) iface->index = ptr->Ipv6IfIndex; else if (ptr->IfIndex != 0) iface->index = ptr->IfIndex; iface->flags = QNetworkInterface::CanBroadcast; if (ptr->OperStatus == IfOperStatusUp) iface->flags |= QNetworkInterface::IsUp | QNetworkInterface::IsRunning; if ((ptr->Flags & IP_ADAPTER_NO_MULTICAST) == 0) iface->flags |= QNetworkInterface::CanMulticast; if (ptr->IfType == IF_TYPE_PPP) iface->flags |= QNetworkInterface::IsPointToPoint; iface->name = QString::fromLocal8Bit(ptr->AdapterName); iface->friendlyName = QString::fromWCharArray(ptr->FriendlyName); if (ptr->PhysicalAddressLength) iface->hardwareAddress = iface->makeHwAddress(ptr->PhysicalAddressLength, ptr->PhysicalAddress); else // loopback if it has no address iface->flags |= QNetworkInterface::IsLoopBack; // The GetAdaptersAddresses call has an interesting semantic: // It can return a number N of addresses and a number M of prefixes. // But if you have IPv6 addresses, generally N > M. // I cannot find a way to relate the Address to the Prefix, aside from stopping // the iteration at the last Prefix entry and assume that it applies to all addresses // from that point on. PIP_ADAPTER_PREFIX pprefix = 0; if (ptr->Length >= offsetof(IP_ADAPTER_ADDRESSES, FirstPrefix)) pprefix = ptr->FirstPrefix; for (PIP_ADAPTER_UNICAST_ADDRESS addr = ptr->FirstUnicastAddress; addr; addr = addr->Next) { QNetworkAddressEntry entry; entry.setIp(addressFromSockaddr(addr->Address.lpSockaddr)); if (pprefix) { if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) { entry.setNetmask(ipv4netmasks[entry.ip()]); // broadcast address is set on postProcess() } else { //IPV6 entry.setPrefixLength(pprefix->PrefixLength); } pprefix = pprefix->Next ? pprefix->Next : pprefix; } iface->addressEntries << entry; } } if (pAdapter != staticBuf) free(pAdapter); return interfaces; }