add unix implementation for DefaultInterfaceIP

This commit is contained in:
walker0643 2018-07-03 22:28:32 -04:00
parent 33224a1f97
commit a2b365815a
6 changed files with 130 additions and 36 deletions

View File

@ -20,6 +20,7 @@
#include "MainWindow.h" #include "MainWindow.h"
#include "ZeroconfRegister.h" #include "ZeroconfRegister.h"
#include "ZeroconfBrowser.h" #include "ZeroconfBrowser.h"
#include "DefaultInterfaceIP.h"
#include <QtNetwork> #include <QtNetwork>
#include <QMessageBox> #include <QMessageBox>
@ -30,7 +31,6 @@
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include "win32/DefaultInterfaceIP.h"
#else #else
#include <stdlib.h> #include <stdlib.h>
#endif #endif
@ -119,29 +119,6 @@ void ZeroconfService::errorHandle(DNSServiceErrorType errorCode)
tr("Error code: %1.").arg(errorCode)); tr("Error code: %1.").arg(errorCode));
} }
QString ZeroconfService::getLocalIPAddresses()
{
#ifdef _WIN32
return QString::fromStdString(Debauchee::default_interface_ip());
#else
const QString NonEthernetMAC = "00:00:00:00:00:00";
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) {
foreach(const auto address, qni.allAddresses()) {
if (address.protocol() == QAbstractSocket::IPv4Protocol) {
// use the first address we find
return address.toString();
}
}
}
}
return "";
#endif
}
bool ZeroconfService::registerService(bool server) bool ZeroconfService::registerService(bool server)
{ {
bool result = true; bool result = true;
@ -156,7 +133,7 @@ bool ZeroconfService::registerService(bool server)
else { else {
m_pZeroconfRegister = new ZeroconfRegister(this); m_pZeroconfRegister = new ZeroconfRegister(this);
if (server) { if (server) {
QString localIP = getLocalIPAddresses(); QString localIP = QString::fromStdString(Debauchee::default_interface_ip());
if (localIP.isEmpty()) { if (localIP.isEmpty()) {
QMessageBox::warning(m_pMainWindow, tr("Barrier"), QMessageBox::warning(m_pMainWindow, tr("Barrier"),
tr("Failed to get local IP address. " tr("Failed to get local IP address. "

View File

@ -42,7 +42,6 @@ private slots:
void errorHandle(DNSServiceErrorType errorCode); void errorHandle(DNSServiceErrorType errorCode);
private: private:
QString getLocalIPAddresses();
bool registerService(bool server); bool registerService(bool server);
private: private:

View File

@ -0,0 +1,55 @@
#include <string>
#include <cstring>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/wireless.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "SocketResource.h"
#include "IfAddrsResource.h"
namespace Debauchee
{
static bool is_wireless(const char * ifname)
{
if (ifname) {
SocketResource fd(AF_INET, SOCK_STREAM, 0);
if (fd.is_valid()) {
struct iwreq req { 0 };
::strncpy(req.ifr_name, ifname, IFNAMSIZ - 1);
return ioctl(fd, SIOCGIWMODE, req) >= 0;
}
}
return false;
}
std::string default_interface_ip()
{
std::string wirelessAddress;
IfAddrsResource ifa;
if (ifa.is_valid()) {
for (struct ifaddrs * next = ifa; next; next = next->ifa_next) {
auto sain = (struct sockaddr_in *)next->ifa_addr;
if (!sain || sain->sin_family != AF_INET ||
!(next->ifa_flags & IFF_RUNNING) ||
(next->ifa_flags & IFF_LOOPBACK)
) {
continue;
}
std::string address = inet_ntoa(sain->sin_addr);
// take first wired address right away
if (!is_wireless(next->ifa_name)) {
return address;
}
// save first wireless address to be used if we don't find a wired one
if (wirelessAddress.empty()) {
wirelessAddress = address;
}
}
}
return wirelessAddress;
}
}

View File

@ -0,0 +1,32 @@
#include <sys/types.h>
#include <ifaddrs.h>
namespace Debauchee
{
class IfAddrsResource
{
public:
explicit IfAddrsResource() :
_valid(getifaddrs(&_ifa) == 0)
{
}
~IfAddrsResource()
{
if (_valid) {
freeifaddrs(_ifa);
}
}
bool is_valid() const { return _valid; }
operator struct ifaddrs * () const { return _ifa; }
private:
bool _valid;
struct ifaddrs * _ifa;
};
}

View File

@ -0,0 +1,31 @@
#include <sys/types.h>
#include <sys/socket.h>
namespace Debauchee
{
class SocketResource
{
public:
explicit SocketResource(int domain, int type, int protocol) :
_fd(socket(domain, type, protocol))
{
}
~SocketResource()
{
if (is_valid()) {
close(_fd);
}
}
bool is_valid() const { return _fd >= 0; }
operator int() const { return _fd; }
private:
int _fd;
};
}