void tst_QNetworkAddressEntry::prefixAndNetmask() { QFETCH(QHostAddress, ip); QFETCH(QHostAddress, netmask); QFETCH(int, prefix); QNetworkAddressEntry entry; // first, without setting the IP, all must be invalid: entry.setNetmask(netmask); QVERIFY(entry.netmask().isNull()); entry.setPrefixLength(prefix); QCOMPARE(entry.prefixLength(), -1); // set the IP: entry.setIp(ip); // set the netmask: if (!netmask.isNull()) { entry.setNetmask(netmask); // was it a valid one? if (prefix != -1) { QVERIFY(!entry.netmask().isNull()); QCOMPARE(entry.netmask(), netmask); QCOMPARE(entry.prefixLength(), prefix); } else { // not valid QVERIFY(entry.netmask().isNull()); QCOMPARE(entry.prefixLength(), -1); } } entry.setNetmask(QHostAddress()); QVERIFY(entry.netmask().isNull()); QCOMPARE(entry.prefixLength(), -1); // set the prefix if (prefix != -1) { entry.setPrefixLength(prefix); // was it a valid one? if (!netmask.isNull()) { QVERIFY(!entry.netmask().isNull()); QCOMPARE(entry.netmask(), netmask); QCOMPARE(entry.prefixLength(), prefix); } else { // not valid QVERIFY(entry.netmask().isNull()); QCOMPARE(entry.prefixLength(), -1); } } entry.setPrefixLength(-1); QVERIFY(entry.netmask().isNull()); QCOMPARE(entry.prefixLength(), -1); }
static QList<QNetworkInterfacePrivate *> interfaceListingWin2k() { QList<QNetworkInterfacePrivate *> interfaces; IP_ADAPTER_INFO staticBuf[2]; // 2 is arbitrary PIP_ADAPTER_INFO pAdapter = staticBuf; ULONG bufSize = sizeof staticBuf; DWORD retval = ptrGetAdaptersInfo(pAdapter, &bufSize); if (retval == ERROR_BUFFER_OVERFLOW) { // need more memory pAdapter = (IP_ADAPTER_INFO *)malloc(bufSize); if (!pAdapter) return interfaces; // try again if (ptrGetAdaptersInfo(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_INFO ptr = pAdapter; ptr; ptr = ptr->Next) { QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate; interfaces << iface; iface->index = ptr->Index; iface->flags = QNetworkInterface::IsUp | QNetworkInterface::IsRunning; if (ptr->Type == MIB_IF_TYPE_PPP) iface->flags |= QNetworkInterface::IsPointToPoint; else iface->flags |= QNetworkInterface::CanBroadcast; iface->name = QString::fromLocal8Bit(ptr->AdapterName); iface->hardwareAddress = QNetworkInterfacePrivate::makeHwAddress(ptr->AddressLength, ptr->Address); for (PIP_ADDR_STRING addr = &ptr->IpAddressList; addr; addr = addr->Next) { QNetworkAddressEntry entry; entry.setIp(QHostAddress(QLatin1String(addr->IpAddress.String))); entry.setNetmask(QHostAddress(QLatin1String(addr->IpMask.String))); // broadcast address is set on postProcess() iface->addressEntries << entry; } } if (pAdapter != staticBuf) free(pAdapter); return interfaces; }
static QList<QNetworkInterfacePrivate *> interfaceListing() { QList<QNetworkInterfacePrivate *> interfaces; int socket; if ((socket = qt_safe_socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == -1) return interfaces; // error ifaddrs *interfaceListing; if (getifaddrs(&interfaceListing) == -1) { // error ::close(socket); return interfaces; } interfaces = createInterfaces(interfaceListing); for (ifaddrs *ptr = interfaceListing; ptr; ptr = ptr->ifa_next) { // Get the interface index int ifindex = if_nametoindex(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) { // found this interface already iface = *if_it; break; } if (!iface) { // skip all non-IP interfaces continue; } QNetworkAddressEntry entry; entry.setIp(addressFromSockaddr(ptr->ifa_addr)); if (entry.ip().isNull()) // could not parse the address continue; entry.setNetmask(addressFromSockaddr(ptr->ifa_netmask)); if (iface->flags & QNetworkInterface::CanBroadcast) entry.setBroadcast(addressFromSockaddr(ptr->ifa_broadaddr)); iface->addressEntries << entry; } freeifaddrs(interfaceListing); ::close(socket); return interfaces; }
static QList<QNetworkInterfacePrivate *> interfaceListing() { QList<QNetworkInterfacePrivate *> interfaces; int socket; if ((socket = qt_safe_socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == -1) return interfaces; // error QSet<QByteArray> names = interfaceNames(socket); QSet<QByteArray>::ConstIterator it = names.constBegin(); for ( ; it != names.constEnd(); ++it) { ifreq req; memset(&req, 0, sizeof(ifreq)); memcpy(req.ifr_name, *it, qMin<int>(it->length() + 1, sizeof(req.ifr_name) - 1)); QNetworkInterfacePrivate *iface = findInterface(socket, interfaces, req); // Get the interface broadcast address QNetworkAddressEntry entry; if (iface->flags & QNetworkInterface::CanBroadcast) { if (qt_safe_ioctl(socket, SIOCGIFBRDADDR, &req) >= 0) { sockaddr *sa = &req.ifr_addr; if (sa->sa_family == AF_INET) entry.setBroadcast(addressFromSockaddr(sa)); } } // Get the interface netmask if (qt_safe_ioctl(socket, SIOCGIFNETMASK, &req) >= 0) { sockaddr *sa = &req.ifr_addr; entry.setNetmask(addressFromSockaddr(sa)); } // Get the address of the interface if (qt_safe_ioctl(socket, SIOCGIFADDR, &req) >= 0) { sockaddr *sa = &req.ifr_addr; entry.setIp(addressFromSockaddr(sa)); } iface->addressEntries << entry; } ::close(socket); return interfaces; }
static QList<QNetworkInterfacePrivate *> interfaceListing() { QList<QNetworkInterfacePrivate *> interfaces; ifaddrs *interfaceListing; if (getifaddrs(&interfaceListing) == -1) { // error return interfaces; } interfaces = createInterfaces(interfaceListing); for (ifaddrs *ptr = interfaceListing; ptr; ptr = ptr->ifa_next) { // Get the interface index 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)->name == name) { // found this interface already iface = *if_it; break; } if (!iface) { // skip all non-IP interfaces continue; } QNetworkAddressEntry entry; entry.setIp(addressFromSockaddr(ptr->ifa_addr, iface->index, iface->name)); if (entry.ip().isNull()) // could not parse the address continue; entry.setNetmask(addressFromSockaddr(ptr->ifa_netmask, iface->index, iface->name)); if (iface->flags & QNetworkInterface::CanBroadcast) entry.setBroadcast(addressFromSockaddr(ptr->ifa_broadaddr, iface->index, iface->name)); iface->addressEntries << entry; } freeifaddrs(interfaceListing); return interfaces; }
static QList<QNetworkInterfacePrivate *> interfaceListing() { TInt err(KErrNone); QList<QNetworkInterfacePrivate *> interfaces; QList<QHostAddress> addressesWithEstimatedNetmasks; // Open dummy socket for interface queries RSocket socket; err = socket.Open(qt_symbianGetSocketServer(), _L("udp")); if (err) { return interfaces; } // Ask socket to start enumerating interfaces err = socket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl); if (err) { socket.Close(); return interfaces; } int ifindex = 0; TPckgBuf<TSoInetInterfaceInfo> infoPckg; TSoInetInterfaceInfo &info = infoPckg(); while (socket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, infoPckg) == KErrNone) { if (info.iName != KNullDesC) { TName address; QNetworkAddressEntry entry; QNetworkInterfacePrivate *iface = 0; iface = new QNetworkInterfacePrivate; iface->index = ifindex++; interfaces << iface; iface->name = qt_TDesC2QString(info.iName); iface->flags = convertFlags(info); if (/*info.iFeatures&KIfHasHardwareAddr &&*/ info.iHwAddr.Family() != KAFUnspec) { for (TInt i = sizeof(SSockAddr); i < sizeof(SSockAddr) + info.iHwAddr.GetUserLen(); i++) { address.AppendNumFixedWidth(info.iHwAddr[i], EHex, 2); if ((i + 1) < sizeof(SSockAddr) + info.iHwAddr.GetUserLen()) address.Append(_L(":")); } address.UpperCase(); iface->hardwareAddress = qt_TDesC2QString(address); } // Get the address of the interface entry.setIp(qt_QHostAddressFromTInetAddr(info.iAddress)); #if defined(QNETWORKINTERFACE_DEBUG) qDebug() << "address is" << info.iAddress.Family() << entry.ip(); qDebug() << "netmask is" << info.iNetMask.Family() << qt_QHostAddressFromTInetAddr( info.iNetMask ); #endif // Get the interface netmask if (info.iNetMask.IsUnspecified()) { // For some reason netmask is always 0.0.0.0 for IPv4 interfaces // and loopback interfaces (which we statically know) if (info.iAddress.IsV4Mapped()) { if (info.iFeatures & KIfIsLoopback) { entry.setPrefixLength(32); } else { // Workaround: Let Symbian determine netmask based on IP address class (IPv4 only API) TInetAddr netmask; netmask.NetMask(info.iAddress); entry.setNetmask(QHostAddress(netmask.Address())); //binary convert v4 address addressesWithEstimatedNetmasks << entry.ip(); #if defined(QNETWORKINTERFACE_DEBUG) qDebug() << "address class determined netmask" << entry.netmask(); #endif } } else { // For IPv6 interfaces if (info.iFeatures & KIfIsLoopback) { entry.setPrefixLength(128); } else if (info.iNetMask.IsUnspecified()) { //Don't see this error for IPv6, but try to handle it if it happens entry.setPrefixLength(64); //most common #if defined(QNETWORKINTERFACE_DEBUG) qDebug() << "total guess netmask" << entry.netmask(); #endif addressesWithEstimatedNetmasks << entry.ip(); } } } else { //Expected code path for IPv6 non loopback interfaces (IPv4 could come here if symbian is fixed) entry.setNetmask(qt_QHostAddressFromTInetAddr(info.iNetMask)); #if defined(QNETWORKINTERFACE_DEBUG) qDebug() << "reported netmask" << entry.netmask(); #endif } // broadcast address is determined from the netmask in postProcess() // Add new entry to interface address entries iface->addressEntries << entry; #if defined(QNETWORKINTERFACE_DEBUG) qDebug("\n Found network interface %s, interface flags:\n\ IsUp = %d, IsRunning = %d, CanBroadcast = %d,\n\ IsLoopBack = %d, IsPointToPoint = %d, CanMulticast = %d, \n\ ip = %s, netmask = %s, broadcast = %s,\n\ hwaddress = %s", iface->name.toLatin1().constData(), iface->flags & QNetworkInterface::IsUp, iface->flags & QNetworkInterface::IsRunning, iface->flags & QNetworkInterface::CanBroadcast, iface->flags & QNetworkInterface::IsLoopBack, iface->flags & QNetworkInterface::IsPointToPoint, iface->flags & QNetworkInterface::CanMulticast, entry.ip().toString().toLatin1().constData(), entry.netmask().toString().toLatin1().constData(), entry.broadcast().toString().toLatin1().constData(), iface->hardwareAddress.toLatin1().constData()); #endif } }
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; }
static QList<QNetworkInterfacePrivate *> interfaceListing() { TInt err(KErrNone); QList<QNetworkInterfacePrivate *> interfaces; // Connect to Native socket server RSocketServ socketServ; err = socketServ.Connect(); if (err) return interfaces; // Open dummy socket for interface queries RSocket socket; err = socket.Open(socketServ, _L("udp")); if (err) { socketServ.Close(); return interfaces; } // Ask socket to start enumerating interfaces err = socket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl); if (err) { socket.Close(); socketServ.Close(); return interfaces; } int ifindex = 0; TPckgBuf<TSoInetInterfaceInfo> infoPckg; TSoInetInterfaceInfo &info = infoPckg(); while (socket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, infoPckg) == KErrNone) { // Do not include IPv6 addresses because netmask and broadcast address cannot be determined correctly if (info.iName != KNullDesC && info.iAddress.IsV4Mapped()) { TName address; QNetworkAddressEntry entry; QNetworkInterfacePrivate *iface = 0; iface = new QNetworkInterfacePrivate; iface->index = ifindex++; interfaces << iface; iface->name = qt_TDesC2QString(info.iName); iface->flags = convertFlags(info); if (/*info.iFeatures&KIfHasHardwareAddr &&*/ info.iHwAddr.Family() != KAFUnspec) { for (TInt i = sizeof(SSockAddr); i < sizeof(SSockAddr) + info.iHwAddr.GetUserLen(); i++) { address.AppendNumFixedWidth(info.iHwAddr[i], EHex, 2); if ((i + 1) < sizeof(SSockAddr) + info.iHwAddr.GetUserLen()) address.Append(_L(":")); } address.UpperCase(); iface->hardwareAddress = qt_TDesC2QString(address); } // Get the address of the interface info.iAddress.Output(address); entry.setIp(QHostAddress(qt_TDesC2QString(address))); // Get the interface netmask // For some reason netmask is always 0.0.0.0 // info.iNetMask.Output(address); // entry.setNetmask( QHostAddress( qt_TDesC2QString( address ) ) ); // Workaround: Let Symbian determine netmask based on IP address class // TODO: Works only for IPv4 - Task: 259128 Implement IPv6 support TInetAddr netmask; netmask.NetMask(info.iAddress); netmask.Output(address); entry.setNetmask(QHostAddress(qt_TDesC2QString(address))); // Get the interface broadcast address if (iface->flags & QNetworkInterface::CanBroadcast) { // For some reason broadcast address is always 0.0.0.0 // info.iBrdAddr.Output(address); // entry.setBroadcast( QHostAddress( qt_TDesC2QString( address ) ) ); // Workaround: Let Symbian determine broadcast address based on IP address // TODO: Works only for IPv4 - Task: 259128 Implement IPv6 support TInetAddr broadcast; broadcast.NetBroadcast(info.iAddress); broadcast.Output(address); entry.setBroadcast(QHostAddress(qt_TDesC2QString(address))); } // Add new entry to interface address entries iface->addressEntries << entry; #if defined(QNETWORKINTERFACE_DEBUG) printf("\n Found network interface %s, interface flags:\n\ IsUp = %d, IsRunning = %d, CanBroadcast = %d,\n\ IsLoopBack = %d, IsPointToPoint = %d, CanMulticast = %d, \n\ ip = %s, netmask = %s, broadcast = %s,\n\ hwaddress = %s", iface->name.toLatin1().constData(), iface->flags & QNetworkInterface::IsUp, iface->flags & QNetworkInterface::IsRunning, iface->flags & QNetworkInterface::CanBroadcast, iface->flags & QNetworkInterface::IsLoopBack, iface->flags & QNetworkInterface::IsPointToPoint, iface->flags & QNetworkInterface::CanMulticast, entry.ip().toString().toLatin1().constData(), entry.netmask().toString().toLatin1().constData(), entry.broadcast().toString().toLatin1().constData(), iface->hardwareAddress.toLatin1().constData()); #endif } }