better discovery of default IP address via ZeroConf

This commit is contained in:
walker0643 2018-07-02 00:32:09 -04:00
parent 2ddc81d927
commit 2d7818fe49
1 changed files with 66 additions and 20 deletions

View File

@ -30,16 +30,12 @@
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <wlanapi.h>
#pragma comment(lib, "wlanapi.lib")
#else #else
#include <stdlib.h> #include <stdlib.h>
#endif #endif
static const QStringList preferedIPAddress(
QStringList() <<
"192.168." <<
"10." <<
"172.");
const char* ZeroconfService:: m_ServerServiceName = "_barrierServerZeroconf._tcp"; const char* ZeroconfService:: m_ServerServiceName = "_barrierServerZeroconf._tcp";
const char* ZeroconfService:: m_ClientServiceName = "_barrierClientZeroconf._tcp"; const char* ZeroconfService:: m_ClientServiceName = "_barrierClientZeroconf._tcp";
@ -124,25 +120,75 @@ void ZeroconfService::errorHandle(DNSServiceErrorType errorCode)
tr("Error code: %1.").arg(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<QString> wireless_mac_strings()
{
QList<QString> 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<QString> wireless_mac_strings()
{
// TODO
return QList<QString>();
}
#endif
QString ZeroconfService::getLocalIPAddresses() QString ZeroconfService::getLocalIPAddresses()
{ {
QStringList addresses; const QString NonEthernetMAC = "00:00:00:00:00:00";
foreach (const QHostAddress& address, QNetworkInterface::allAddresses()) { const auto wlanMAC = wireless_mac_strings();
if (address.protocol() == QAbstractSocket::IPv4Protocol && QString wirelessIP = "";
address != QHostAddress(QHostAddress::LocalHost)) { foreach(const auto qni, QNetworkInterface::allInterfaces()) {
addresses.append(address.toString()); // weed out loopback, inactive, and non-ethernet interfaces
} if (!qni.flags().testFlag(QNetworkInterface::IsLoopBack) &&
} qni.flags().testFlag(QNetworkInterface::IsUp) &&
qni.hardwareAddress() != NonEthernetMAC) {
foreach (const QString& preferedIP, preferedIPAddress) { bool isWireless = wlanMAC.contains(qni.hardwareAddress().toUpper());
foreach (const QString& address, addresses) { foreach(const auto address, qni.allAddresses()) {
if (address.startsWith(preferedIP)) { if (address.protocol() == QAbstractSocket::IPv4Protocol) {
return address; // 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) bool ZeroconfService::registerService(bool server)