diff --git a/src/gui/src/ZeroconfService.cpp b/src/gui/src/ZeroconfService.cpp index 02902ee5..9f263984 100644 --- a/src/gui/src/ZeroconfService.cpp +++ b/src/gui/src/ZeroconfService.cpp @@ -30,16 +30,12 @@ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include +#include +#pragma comment(lib, "wlanapi.lib") #else #include #endif -static const QStringList preferedIPAddress( - QStringList() << - "192.168." << - "10." << - "172."); - const char* ZeroconfService:: m_ServerServiceName = "_barrierServerZeroconf._tcp"; const char* ZeroconfService:: m_ClientServiceName = "_barrierClientZeroconf._tcp"; @@ -124,25 +120,75 @@ void ZeroconfService::errorHandle(DNSServiceErrorType errorCode) tr("Error code: %1.").arg(errorCode)); } +#ifdef _WIN32 +static QString mac_to_string(DOT11_MAC_ADDRESS mac) +{ + char str[18]; + snprintf(str, 18, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return str; +} + +static QList wireless_mac_strings() +{ + QList wlanMAC; + DWORD version; + HANDLE client; + if (WlanOpenHandle(2, NULL, &version, &client) == 0) { + WLAN_INTERFACE_INFO_LIST * list; + if (WlanEnumInterfaces(client, NULL, &list) == 0) { + for (DWORD idx = 0; idx < list->dwNumberOfItems; ++idx) { + const GUID * PGuid = &(list->InterfaceInfo[0].InterfaceGuid); + const WLAN_INTF_OPCODE OpCode = wlan_intf_opcode_current_connection; + WLAN_CONNECTION_ATTRIBUTES * attrs; + DWORD attrsSz; + if (WlanQueryInterface(client, PGuid, OpCode, NULL, &attrsSz, + (void**)&attrs, NULL) == 0) { + wlanMAC.append(mac_to_string( + attrs->wlanAssociationAttributes.dot11Bssid)); + WlanFreeMemory(attrs); + } + } + WlanFreeMemory(list); + } + WlanCloseHandle(client, NULL); + } + return wlanMAC; +} +#else +static QList wireless_mac_strings() +{ + // TODO + return QList(); +} +#endif + QString ZeroconfService::getLocalIPAddresses() { - QStringList addresses; - foreach (const QHostAddress& address, QNetworkInterface::allAddresses()) { - if (address.protocol() == QAbstractSocket::IPv4Protocol && - address != QHostAddress(QHostAddress::LocalHost)) { - addresses.append(address.toString()); - } - } - - foreach (const QString& preferedIP, preferedIPAddress) { - foreach (const QString& address, addresses) { - if (address.startsWith(preferedIP)) { - return address; + const QString NonEthernetMAC = "00:00:00:00:00:00"; + const auto wlanMAC = wireless_mac_strings(); + QString wirelessIP = ""; + foreach(const auto qni, QNetworkInterface::allInterfaces()) { + // weed out loopback, inactive, and non-ethernet interfaces + if (!qni.flags().testFlag(QNetworkInterface::IsLoopBack) && + qni.flags().testFlag(QNetworkInterface::IsUp) && + qni.hardwareAddress() != NonEthernetMAC) { + bool isWireless = wlanMAC.contains(qni.hardwareAddress().toUpper()); + foreach(const auto address, qni.allAddresses()) { + if (address.protocol() == QAbstractSocket::IPv4Protocol) { + // use the first non-wireless address we find + if (!isWireless) + return address.toString(); + // save the first wireless address we find + if (wirelessIP.isEmpty()) + wirelessIP = address.toString(); + } } } } - - return ""; + // if no non-wireless address could be found use a wireless one + // if one was found. otherwise return an empty string + return wirelessIP; } bool ZeroconfService::registerService(bool server)