Skip to content

Commit

Permalink
feat: add IPv4 and IPv6 address recovery to the ParseArgument class
Browse files Browse the repository at this point in the history
  • Loading branch information
MasterLaplace committed Dec 9, 2024
1 parent d95a612 commit 5566f23
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 1 deletion.
149 changes: 148 additions & 1 deletion Flakkari/ParseArgument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ ParseArgument::ParseArgument(int ac, const char *av[])
if (_gameDir.empty())
GetGameDirEnv();

if (_ip.empty())
if (_ip.empty() && (!GetIPv4Addresses() && !GetIPv6Addresses()))
_ip = "localhost";

if (_port == 0)
Expand All @@ -67,6 +67,153 @@ const std::string &ParseArgument::getIp() const { return _ip; }

unsigned short ParseArgument::getPort() const { return _port; }

bool ParseArgument::GetIPv4Addresses()
{
#if defined(FLAKKARI_SYSTEM_WINDOWS)
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
throw std::runtime_error("WSAStartup failed!");

IP_ADAPTER_ADDRESSES *pAdapterAddresses = nullptr;
ULONG bufferSize = 0;
DWORD dwRetVal =
GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_ALL_INTERFACES, nullptr, pAdapterAddresses, &bufferSize);

if (dwRetVal == ERROR_BUFFER_OVERFLOW)
{
pAdapterAddresses = (IP_ADAPTER_ADDRESSES *) malloc(bufferSize);
dwRetVal =
GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_ALL_INTERFACES, nullptr, pAdapterAddresses, &bufferSize);
}

if (dwRetVal != NO_ERROR)
{
free(pAdapterAddresses);
WSACleanup();
throw std::runtime_error("GetAdaptersAddresses failed with error: " + std::to_string(dwRetVal));
}

IP_ADAPTER_ADDRESSES *pAdapter = pAdapterAddresses;
while (pAdapter)
{
IP_ADAPTER_UNICAST_ADDRESS *pUnicast = pAdapter->FirstUnicastAddress;
while (pUnicast)
{
sockaddr_in *sa_in = (sockaddr_in *) pUnicast->Address.lpSockaddr;
pUnicast = pUnicast->Next;

if (sa_in->sin_family != AF_INET)
continue;

char ipStr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(sa_in->sin_addr), ipStr, INET_ADDRSTRLEN);
FLAKKARI_LOG_INFO("Adresse IPv4 de l'interface " + std::string(pAdapter->AdapterName) + ": " + ipStr);
_ip = ipStr;
}
pAdapter = pAdapter->Next;
}

free(pAdapterAddresses);
WSACleanup();
#else
struct ifaddrs *ifAddrStruct = nullptr;
struct ifaddrs *ifa = nullptr;

if (getifaddrs(&ifAddrStruct) == -1)
throw std::runtime_error("getifaddrs failed!");

for (ifa = ifAddrStruct; ifa != nullptr; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr->sa_family != AF_INET)
continue;

void *tmpAddrPtr = &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr;
char addressBuffer[INET_ADDRSTRLEN];
inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);

if (strcmp(addressBuffer, "127.0.0.1") != 0)
FLAKKARI_LOG_INFO("Interface " + ifa->ifa_name + " a l'adresse IPv4 : " + addressBuffer);
}

freeifaddrs(ifAddrStruct);
#endif
}

bool ParseArgument::GetIPv6Addresses()
{
#if defined(FLAKKARI_SYSTEM_WINDOWS)
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
throw std::runtime_error("WSAStartup failed!");

IP_ADAPTER_ADDRESSES *pAdapterAddresses = nullptr;
ULONG bufferSize = 0;
DWORD dwRetVal =
GetAdaptersAddresses(AF_INET6, GAA_FLAG_INCLUDE_ALL_INTERFACES, nullptr, pAdapterAddresses, &bufferSize);

if (dwRetVal == ERROR_BUFFER_OVERFLOW)
{
pAdapterAddresses = (IP_ADAPTER_ADDRESSES *) malloc(bufferSize);
dwRetVal =
GetAdaptersAddresses(AF_INET6, GAA_FLAG_INCLUDE_ALL_INTERFACES, nullptr, pAdapterAddresses, &bufferSize);
}

if (dwRetVal != NO_ERROR)
{
free(pAdapterAddresses);
WSACleanup();
throw std::runtime_error("GetAdaptersAddresses failed with error: " + std::to_string(dwRetVal));
}

IP_ADAPTER_ADDRESSES *pAdapter = pAdapterAddresses;
while (pAdapter)
{
IP_ADAPTER_UNICAST_ADDRESS *pUnicast = pAdapter->FirstUnicastAddress;
while (pUnicast)
{
sockaddr_in6 *sa_in6 = (sockaddr_in6 *) pUnicast->Address.lpSockaddr;
pUnicast = pUnicast->Next;

if (sa_in6->sin6_family != AF_INET6)
continue;

char ipStr[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &(sa_in6->sin6_addr), ipStr, INET6_ADDRSTRLEN);
if (strcmp(ipStr, "::1") != 0)
{
FLAKKARI_LOG_INFO("IPv6 address of interface " + std::string(pAdapter->AdapterName) + ": " + ipStr);
_ip = ipStr;
}
}
pAdapter = pAdapter->Next;
}

free(pAdapterAddresses);
WSACleanup();
#else
struct ifaddrs *ifAddrStruct = nullptr;
struct ifaddrs *ifa = nullptr;

if (getifaddrs(&ifAddrStruct) == -1)
throw std::runtime_error("getifaddrs failed!");

for (ifa = ifAddrStruct; ifa != nullptr; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;

void *tmpAddrPtr = &((struct sockaddr_in6 *) ifa->ifa_addr)->sin6_addr;
char addressBuffer[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN);

if (strcmp(addressBuffer, "::1") != 0)
FLAKKARI_LOG_INFO("Interface " + ifa->ifa_name + " a l'adresse IPv6 : " + addressBuffer);
}

freeifaddrs(ifAddrStruct);
#endif
}

void ParseArgument::GetGameDirEnv()
{
const char *dir = std::getenv("FLAKKARI_GAME_DIR");
Expand Down
18 changes: 18 additions & 0 deletions Flakkari/ParseArgument.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@

#include "Server/UDPServer.hpp"

#if defined(FLAKKARI_SYSTEM_WINDOWS)
# include <iphlpapi.h>
#else
# include <ifaddrs.h>
#endif

/**
* @namespace Flakkari
* The Flakkari namespace contains classes and functions related to the Flakkari project.
Expand Down Expand Up @@ -65,6 +71,18 @@ class ParseArgument {
unsigned short getPort() const;

private:
/**
* @brief Retrieves IPv4 addresses.
* @return True if successful, false otherwise.
*/
bool GetIPv4Addresses();

/**
* @brief Retrieves IPv6 addresses.
* @return True if successful, false otherwise.
*/
bool GetIPv6Addresses();

/**
* @brief Retrieves the game directory from the environment.
*/
Expand Down

0 comments on commit 5566f23

Please sign in to comment.