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);
}
Beispiel #2
0
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
        }
    }
Beispiel #7
0
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
        }
    }