mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Added IPv6 support to the IPAddress class
This commit is contained in:
parent
242b934163
commit
e09c2b65a1
5 changed files with 378 additions and 103 deletions
|
|
@ -55,10 +55,6 @@
|
|||
#if JUCE_WINDOWS
|
||||
#include <ctime>
|
||||
|
||||
#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#if ! JUCE_MINGW
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4091)
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@
|
|||
|
||||
#define NOMINMAX
|
||||
|
||||
#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
|
||||
#define STRICT 1
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#if JUCE_MINGW
|
||||
|
|
@ -141,6 +142,8 @@
|
|||
#include <ctime>
|
||||
#include <wininet.h>
|
||||
#include <nb30.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <mapi.h>
|
||||
#include <float.h>
|
||||
|
|
|
|||
|
|
@ -400,26 +400,26 @@ private:
|
|||
|
||||
|
||||
//==============================================================================
|
||||
struct GetAdaptersInfoHelper
|
||||
struct GetAdaptersAddressesHelper
|
||||
{
|
||||
bool callGetAdaptersInfo()
|
||||
bool callGetAdaptersAddresses()
|
||||
{
|
||||
DynamicLibrary dll ("iphlpapi.dll");
|
||||
JUCE_LOAD_WINAPI_FUNCTION (dll, GetAdaptersInfo, getAdaptersInfo, DWORD, (PIP_ADAPTER_INFO, PULONG))
|
||||
JUCE_LOAD_WINAPI_FUNCTION (dll, GetAdaptersAddresses, getAdaptersAddresses, DWORD, (ULONG, ULONG, PVOID, PIP_ADAPTER_ADDRESSES, PULONG))
|
||||
|
||||
if (getAdaptersInfo == nullptr)
|
||||
if (getAdaptersAddresses == nullptr)
|
||||
return false;
|
||||
|
||||
adapterInfo.malloc (1);
|
||||
ULONG len = sizeof (IP_ADAPTER_INFO);
|
||||
adaptersAddresses.malloc (1);
|
||||
ULONG len = sizeof (IP_ADAPTER_ADDRESSES);
|
||||
|
||||
if (getAdaptersInfo (adapterInfo, &len) == ERROR_BUFFER_OVERFLOW)
|
||||
adapterInfo.malloc (len, 1);
|
||||
if (getAdaptersAddresses (AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, adaptersAddresses, &len) == ERROR_BUFFER_OVERFLOW)
|
||||
adaptersAddresses.malloc (len, 1);
|
||||
|
||||
return getAdaptersInfo (adapterInfo, &len) == NO_ERROR;
|
||||
return getAdaptersAddresses (AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, adaptersAddresses, &len) == NO_ERROR;
|
||||
}
|
||||
|
||||
HeapBlock<IP_ADAPTER_INFO> adapterInfo;
|
||||
HeapBlock<IP_ADAPTER_ADDRESSES> adaptersAddresses;
|
||||
};
|
||||
|
||||
namespace MACAddressHelpers
|
||||
|
|
@ -430,15 +430,17 @@ namespace MACAddressHelpers
|
|||
result.addIfNotAlreadyThere (ma);
|
||||
}
|
||||
|
||||
static void getViaGetAdaptersInfo (Array<MACAddress>& result)
|
||||
static void getViaGetAdaptersAddresses (Array<MACAddress>& result)
|
||||
{
|
||||
GetAdaptersInfoHelper gah;
|
||||
GetAdaptersAddressesHelper addressesHelper;
|
||||
|
||||
if (gah.callGetAdaptersInfo())
|
||||
if (addressesHelper.callGetAdaptersAddresses())
|
||||
{
|
||||
for (PIP_ADAPTER_INFO adapter = gah.adapterInfo; adapter != nullptr; adapter = adapter->Next)
|
||||
if (adapter->AddressLength >= 6)
|
||||
addAddress (result, MACAddress (adapter->Address));
|
||||
for (PIP_ADAPTER_ADDRESSES adapter = addressesHelper.adaptersAddresses; adapter != nullptr; adapter = adapter->Next)
|
||||
{
|
||||
if (adapter->PhysicalAddressLength >= 6)
|
||||
addAddress (result, MACAddress (adapter->PhysicalAddress));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -493,24 +495,108 @@ namespace MACAddressHelpers
|
|||
|
||||
void MACAddress::findAllAddresses (Array<MACAddress>& result)
|
||||
{
|
||||
MACAddressHelpers::getViaGetAdaptersInfo (result);
|
||||
MACAddressHelpers::getViaGetAdaptersAddresses (result);
|
||||
MACAddressHelpers::getViaNetBios (result);
|
||||
}
|
||||
|
||||
void IPAddress::findAllAddresses (Array<IPAddress>& result)
|
||||
void IPAddress::findAllAddresses (Array<IPAddress>& result, bool includeIPv6)
|
||||
{
|
||||
result.addIfNotAlreadyThere (IPAddress::local());
|
||||
result.addIfNotAlreadyThere (IPAddress::local ());
|
||||
|
||||
GetAdaptersInfoHelper gah;
|
||||
if (includeIPv6)
|
||||
result.addIfNotAlreadyThere (IPAddress::local (true));
|
||||
|
||||
if (gah.callGetAdaptersInfo())
|
||||
GetAdaptersAddressesHelper addressesHelper;
|
||||
if (addressesHelper.callGetAdaptersAddresses())
|
||||
{
|
||||
for (PIP_ADAPTER_INFO adapter = gah.adapterInfo; adapter != nullptr; adapter = adapter->Next)
|
||||
for (PIP_ADAPTER_ADDRESSES adapter = addressesHelper.adaptersAddresses; adapter != nullptr; adapter = adapter->Next)
|
||||
{
|
||||
IPAddress ip (adapter->IpAddressList.IpAddress.String);
|
||||
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = nullptr;
|
||||
for (pUnicast = adapter->FirstUnicastAddress; pUnicast != nullptr; pUnicast = pUnicast->Next)
|
||||
{
|
||||
if (pUnicast->Address.lpSockaddr->sa_family == AF_INET)
|
||||
{
|
||||
const sockaddr_in* sa_in = (sockaddr_in*)pUnicast->Address.lpSockaddr;
|
||||
IPAddress ip ((uint8*)&sa_in->sin_addr.s_addr, false);
|
||||
result.addIfNotAlreadyThere (ip);
|
||||
}
|
||||
else if (pUnicast->Address.lpSockaddr->sa_family == AF_INET6 && includeIPv6)
|
||||
{
|
||||
const sockaddr_in6* sa_in6 = (sockaddr_in6*)pUnicast->Address.lpSockaddr;
|
||||
|
||||
if (ip != IPAddress::any())
|
||||
result.addIfNotAlreadyThere (ip);
|
||||
ByteUnion temp;
|
||||
uint16 arr[8];
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
temp.split[0] = sa_in6->sin6_addr.u.Byte[i * 2 + 1];
|
||||
temp.split[1] = sa_in6->sin6_addr.u.Byte[i * 2];
|
||||
|
||||
arr[i] = temp.combined;
|
||||
}
|
||||
|
||||
IPAddress ip (arr);
|
||||
result.addIfNotAlreadyThere (ip);
|
||||
}
|
||||
}
|
||||
|
||||
PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = nullptr;
|
||||
for (pAnycast = adapter->FirstAnycastAddress; pAnycast != nullptr; pAnycast = pAnycast->Next)
|
||||
{
|
||||
if (pAnycast->Address.lpSockaddr->sa_family == AF_INET)
|
||||
{
|
||||
const sockaddr_in* sa_in = (sockaddr_in*)pAnycast->Address.lpSockaddr;
|
||||
IPAddress ip ((uint8*)&sa_in->sin_addr.s_addr, false);
|
||||
result.addIfNotAlreadyThere (ip);
|
||||
}
|
||||
else if (pAnycast->Address.lpSockaddr->sa_family == AF_INET6 && includeIPv6)
|
||||
{
|
||||
const sockaddr_in6* sa_in6 = (sockaddr_in6*)pAnycast->Address.lpSockaddr;
|
||||
|
||||
ByteUnion temp;
|
||||
uint16 arr[8];
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
temp.split[0] = sa_in6->sin6_addr.u.Byte[i * 2 + 1];
|
||||
temp.split[1] = sa_in6->sin6_addr.u.Byte[i * 2];
|
||||
|
||||
arr[i] = temp.combined;
|
||||
}
|
||||
|
||||
IPAddress ip (arr);
|
||||
result.addIfNotAlreadyThere (ip);
|
||||
}
|
||||
}
|
||||
|
||||
PIP_ADAPTER_MULTICAST_ADDRESS pMulticast = nullptr;
|
||||
for (pMulticast = adapter->FirstMulticastAddress; pMulticast != nullptr; pMulticast = pMulticast->Next)
|
||||
{
|
||||
if (pMulticast->Address.lpSockaddr->sa_family == AF_INET)
|
||||
{
|
||||
const sockaddr_in* sa_in = (sockaddr_in*)pMulticast->Address.lpSockaddr;
|
||||
IPAddress ip ((uint8*)&sa_in->sin_addr.s_addr, false);
|
||||
result.addIfNotAlreadyThere (ip);
|
||||
}
|
||||
else if (pMulticast->Address.lpSockaddr->sa_family == AF_INET6 && includeIPv6)
|
||||
{
|
||||
const sockaddr_in6* sa_in6 = (sockaddr_in6*)pMulticast->Address.lpSockaddr;
|
||||
|
||||
ByteUnion temp;
|
||||
uint16 arr[8];
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
temp.split[0] = sa_in6->sin6_addr.u.Byte[i * 2 + 1];
|
||||
temp.split[1] = sa_in6->sin6_addr.u.Byte[i * 2];
|
||||
|
||||
arr[i] = temp.combined;
|
||||
}
|
||||
|
||||
IPAddress ip (arr);
|
||||
result.addIfNotAlreadyThere (ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,61 +28,222 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
IPAddress::IPAddress() noexcept
|
||||
IPAddress::IPAddress (bool IPv6) noexcept : isIPv6 (IPv6)
|
||||
{
|
||||
address[0] = 0; address[1] = 0;
|
||||
address[2] = 0; address[3] = 0;
|
||||
for (int i = 0; i < 16; ++i)
|
||||
address[i] = 0;
|
||||
}
|
||||
|
||||
IPAddress::IPAddress (const uint8 bytes[4]) noexcept
|
||||
IPAddress::IPAddress (const uint8 bytes[], bool IPv6) noexcept : isIPv6 (IPv6)
|
||||
{
|
||||
address[0] = bytes[0]; address[1] = bytes[1];
|
||||
address[2] = bytes[2]; address[3] = bytes[3];
|
||||
for (int i = 0; i < (isIPv6 ? 16 : 4); ++i)
|
||||
address[i] = bytes[i];
|
||||
|
||||
if (! isIPv6)
|
||||
zeroUnusedBytes();
|
||||
}
|
||||
|
||||
IPAddress::IPAddress (uint8 a0, uint8 a1, uint8 a2, uint8 a3) noexcept
|
||||
IPAddress::IPAddress (const uint16 bytes[8]) noexcept : isIPv6 (true)
|
||||
{
|
||||
ByteUnion temp;
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
temp.combined = bytes[i];
|
||||
|
||||
address[i * 2] = temp.split[0];
|
||||
address[i * 2 + 1] = temp.split[1];
|
||||
}
|
||||
}
|
||||
|
||||
IPAddress::IPAddress (uint8 a0, uint8 a1, uint8 a2, uint8 a3) noexcept : isIPv6 (false)
|
||||
{
|
||||
address[0] = a0; address[1] = a1;
|
||||
address[2] = a2; address[3] = a3;
|
||||
|
||||
zeroUnusedBytes();
|
||||
}
|
||||
|
||||
IPAddress::IPAddress (uint32 n) noexcept
|
||||
IPAddress::IPAddress (uint16 a1, uint16 a2, uint16 a3, uint16 a4,
|
||||
uint16 a5, uint16 a6, uint16 a7, uint16 a8) noexcept : isIPv6 (true)
|
||||
|
||||
{
|
||||
uint16 array[8] = { a1, a2, a3, a4, a5, a6, a7, a8 };
|
||||
|
||||
ByteUnion temp;
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
temp.combined = array[i];
|
||||
address[i * 2] = temp.split[0];
|
||||
address[i * 2 + 1] = temp.split[1];
|
||||
}
|
||||
}
|
||||
|
||||
IPAddress::IPAddress (uint32 n) noexcept : isIPv6 (false)
|
||||
{
|
||||
address[0] = (n >> 24);
|
||||
address[1] = (n >> 16) & 255;
|
||||
address[2] = (n >> 8) & 255;
|
||||
address[2] = (n >> 8) & 255;
|
||||
address[3] = (n & 255);
|
||||
|
||||
zeroUnusedBytes();
|
||||
}
|
||||
|
||||
IPAddress::IPAddress (const String& adr)
|
||||
{
|
||||
StringArray tokens;
|
||||
tokens.addTokens (adr, ".", String());
|
||||
isIPv6 = adr.contains (":");
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
address[i] = (uint8) tokens[i].getIntValue();
|
||||
if (! isIPv6)
|
||||
{
|
||||
StringArray tokens;
|
||||
tokens.addTokens (adr, ".", String());
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
address[i] = (uint8) tokens[i].getIntValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
StringArray tokens;
|
||||
tokens.addTokens (adr.removeCharacters ("[]"), ":", String());
|
||||
|
||||
if (tokens.contains (StringRef())) // if :: shorthand has been used
|
||||
{
|
||||
int idx = tokens.indexOf (StringRef());
|
||||
tokens.set (idx, "0");
|
||||
|
||||
while (tokens.size() < 8)
|
||||
tokens.insert (idx, "0");
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
ByteUnion temp;
|
||||
temp.combined = (uint16) CharacterFunctions::HexParser<int>::parse (tokens[i].getCharPointer());
|
||||
|
||||
address[i * 2] = temp.split[0];
|
||||
address[i * 2 + 1] = temp.split[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String IPAddress::toString() const
|
||||
{
|
||||
String s ((int) address[0]);
|
||||
if (! isIPv6)
|
||||
{
|
||||
String s ((int) address[0]);
|
||||
|
||||
for (int i = 1; i < 4; ++i)
|
||||
s << '.' << (int) address[i];
|
||||
for (int i = 1; i < 4; ++i)
|
||||
s << '.' << (int) address[i];
|
||||
|
||||
return s;
|
||||
return s;
|
||||
}
|
||||
|
||||
String addressString;
|
||||
ByteUnion temp;
|
||||
|
||||
temp.split[0] = address[0];
|
||||
temp.split[1] = address[1];
|
||||
|
||||
addressString = String (String::toHexString (temp.combined));
|
||||
|
||||
for (int i = 1; i < 8; ++i)
|
||||
{
|
||||
temp.split[0] = address[i * 2];
|
||||
temp.split[1] = address[i * 2 + 1];
|
||||
|
||||
addressString << ':' << String (String::toHexString (temp.combined));
|
||||
}
|
||||
|
||||
return getFormattedAddress (addressString);
|
||||
}
|
||||
|
||||
IPAddress IPAddress::any() noexcept { return IPAddress(); }
|
||||
IPAddress IPAddress::broadcast() noexcept { return IPAddress (255, 255, 255, 255); }
|
||||
IPAddress IPAddress::local() noexcept { return IPAddress (127, 0, 0, 1); }
|
||||
IPAddress IPAddress::any (bool IPv6) noexcept { return IPAddress (IPv6); }
|
||||
IPAddress IPAddress::broadcast() noexcept { return IPAddress (255, 255, 255, 255); }
|
||||
IPAddress IPAddress::local (bool IPv6) noexcept { return IPv6 ? IPAddress (0, 0, 0, 0, 0, 0, 0, 1)
|
||||
: IPAddress (127, 0, 0, 1); }
|
||||
|
||||
String IPAddress::getFormattedAddress (const String& unformattedAddress)
|
||||
{
|
||||
jassert (unformattedAddress.contains (":") && ! unformattedAddress.contains ("::")); // needs to be an unformatted IPv6 address!
|
||||
|
||||
String portString = unformattedAddress.fromFirstOccurrenceOf ("]", false, true);
|
||||
String addressString = unformattedAddress.dropLastCharacters (portString.length()).removeCharacters ("[]");
|
||||
|
||||
StringArray tokens;
|
||||
tokens.addTokens (addressString, ":", String());
|
||||
|
||||
int numZeros = 0;
|
||||
int numZerosTemp = 0;
|
||||
bool isFirst = false;
|
||||
bool isLast = false;
|
||||
|
||||
for (int i = 0; i < tokens.size(); ++i)
|
||||
{
|
||||
String t = tokens.getReference (i);
|
||||
|
||||
if (t.getHexValue32() == 0x0000)
|
||||
{
|
||||
++numZeros;
|
||||
|
||||
if (i == 0)
|
||||
isFirst = true;
|
||||
else if (i == tokens.size() - 1 && numZeros > numZerosTemp)
|
||||
isLast = true;
|
||||
|
||||
if (t.length() > 1)
|
||||
addressString = addressString.replace (String::repeatedString ("0", t.length()), "0");
|
||||
|
||||
if (isFirst && numZerosTemp != 0 && numZeros > numZerosTemp)
|
||||
isFirst = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
addressString = addressString.replace (t, t.trimCharactersAtStart ("0").toLowerCase());
|
||||
|
||||
if (numZeros > 0)
|
||||
{
|
||||
if (numZeros > numZerosTemp)
|
||||
numZerosTemp = numZeros;
|
||||
|
||||
numZeros = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (numZerosTemp > numZeros)
|
||||
numZeros = numZerosTemp;
|
||||
|
||||
if (numZeros > 1)
|
||||
{
|
||||
if (numZeros == tokens.size())
|
||||
addressString = "::,";
|
||||
else
|
||||
{
|
||||
String zeroString = isFirst ? String ("0") + String::repeatedString (":0", numZeros - 1)
|
||||
: String::repeatedString (":0", numZeros);
|
||||
|
||||
addressString = addressString.replaceFirstOccurrenceOf (zeroString, ":");
|
||||
|
||||
if (isLast)
|
||||
addressString += String (":");
|
||||
}
|
||||
}
|
||||
|
||||
if (portString.isNotEmpty())
|
||||
addressString = String ("[") + addressString + String ("]") + portString;
|
||||
|
||||
return addressString;
|
||||
}
|
||||
|
||||
bool IPAddress::operator== (const IPAddress& other) const noexcept
|
||||
{
|
||||
return address[0] == other.address[0]
|
||||
&& address[1] == other.address[1]
|
||||
&& address[2] == other.address[2]
|
||||
&& address[3] == other.address[3];
|
||||
for (int i = 0; i < (isIPv6 ? 16 : 4); ++i)
|
||||
if (address[i] != other.address[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool IPAddress::operator!= (const IPAddress& other) const noexcept
|
||||
|
|
@ -99,53 +260,47 @@ static void addAddress (const sockaddr_in* addr_in, Array<IPAddress>& result)
|
|||
result.addIfNotAlreadyThere (IPAddress (ntohl (addr)));
|
||||
}
|
||||
|
||||
static void findIPAddresses (int sock, Array<IPAddress>& result)
|
||||
static void addAddress (const sockaddr_in6* addr_in, Array<IPAddress>& result)
|
||||
{
|
||||
ifconf cfg;
|
||||
HeapBlock<char> buffer;
|
||||
int bufferSize = 1024;
|
||||
in6_addr addr = addr_in->sin6_addr;
|
||||
|
||||
do
|
||||
typedef union
|
||||
{
|
||||
bufferSize *= 2;
|
||||
buffer.calloc ((size_t) bufferSize);
|
||||
uint16 combined;
|
||||
uint8 split[2];
|
||||
} ByteUnion;
|
||||
|
||||
cfg.ifc_len = bufferSize;
|
||||
cfg.ifc_buf = buffer;
|
||||
ByteUnion temp;
|
||||
uint16 arr[8];
|
||||
|
||||
if (ioctl (sock, SIOCGIFCONF, &cfg) < 0 && errno != EINVAL)
|
||||
return;
|
||||
|
||||
} while (bufferSize < cfg.ifc_len + 2 * (int) (IFNAMSIZ + sizeof (struct sockaddr_in6)));
|
||||
|
||||
#if JUCE_MAC || JUCE_IOS
|
||||
while (cfg.ifc_len >= (int) (IFNAMSIZ + sizeof (struct sockaddr_in)))
|
||||
for (int i = 0; i < 8; ++i) // Swap bytes from network to host order
|
||||
{
|
||||
if (cfg.ifc_req->ifr_addr.sa_family == AF_INET) // Skip non-internet addresses
|
||||
addAddress ((const sockaddr_in*) &cfg.ifc_req->ifr_addr, result);
|
||||
temp.split[0] = addr.s6_addr[i * 2 + 1];
|
||||
temp.split[1] = addr.s6_addr[i * 2];
|
||||
|
||||
cfg.ifc_len -= IFNAMSIZ + cfg.ifc_req->ifr_addr.sa_len;
|
||||
cfg.ifc_buf += IFNAMSIZ + cfg.ifc_req->ifr_addr.sa_len;
|
||||
arr[i] = temp.combined;
|
||||
}
|
||||
#else
|
||||
for (size_t i = 0; i < (size_t) cfg.ifc_len / (size_t) sizeof (struct ifreq); ++i)
|
||||
{
|
||||
const ifreq& item = cfg.ifc_req[i];
|
||||
|
||||
if (item.ifr_addr.sa_family == AF_INET)
|
||||
addAddress ((const sockaddr_in*) &item.ifr_addr, result);
|
||||
}
|
||||
#endif
|
||||
IPAddress ip (arr);
|
||||
result.addIfNotAlreadyThere (ip);
|
||||
}
|
||||
|
||||
void IPAddress::findAllAddresses (Array<IPAddress>& result)
|
||||
void IPAddress::findAllAddresses (Array<IPAddress>& result, bool includeIPv6)
|
||||
{
|
||||
const int sock = socket (AF_INET, SOCK_DGRAM, 0); // a dummy socket to execute the IO control
|
||||
struct ifaddrs *ifaddr, *ifa;
|
||||
|
||||
if (sock >= 0)
|
||||
if (getifaddrs (&ifaddr) == -1)
|
||||
return;
|
||||
|
||||
for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next)
|
||||
{
|
||||
findIPAddresses (sock, result);
|
||||
::close (sock);
|
||||
if (ifa->ifa_addr == nullptr)
|
||||
continue;
|
||||
|
||||
if (ifa->ifa_addr->sa_family == AF_INET) addAddress ((const sockaddr_in*) ifa->ifa_addr, result);
|
||||
else if (ifa->ifa_addr->sa_family == AF_INET6 && includeIPv6) addAddress ((const sockaddr_in6*) ifa->ifa_addr, result);
|
||||
}
|
||||
|
||||
freeifaddrs (ifaddr);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -33,48 +33,83 @@
|
|||
|
||||
//==============================================================================
|
||||
/**
|
||||
An IPV4 address.
|
||||
Represents an IP address.
|
||||
*/
|
||||
class JUCE_API IPAddress
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Populates a list of all the IP addresses that this machine is using. */
|
||||
static void findAllAddresses (Array<IPAddress>& results);
|
||||
static void findAllAddresses (Array<IPAddress>& results, bool includeIPv6 = false);
|
||||
|
||||
//==============================================================================
|
||||
/** Creates a null address (0.0.0.0). */
|
||||
IPAddress() noexcept;
|
||||
/** Creates a null address - 0.0.0.0 (IPv4) or ::, (IPv6)
|
||||
@param IPv6 if true indicates that this is an IPv6 address
|
||||
*/
|
||||
IPAddress (bool IPv6 = false) noexcept;
|
||||
|
||||
/** Creates an address from 4 bytes. */
|
||||
explicit IPAddress (const uint8 bytes[4]) noexcept;
|
||||
/** Creates an IPv4 or IPv6 address by reading 4 or 16 bytes from an array.
|
||||
@param IPv6 if true indicates that 16 bytes should be read instead of 4.
|
||||
*/
|
||||
explicit IPAddress (const uint8 bytes[], bool IPv6 = false) noexcept;
|
||||
|
||||
/** Creates an address from 4 bytes. */
|
||||
/** Creates an IPv6 address from an array of 8 16-bit integers */
|
||||
explicit IPAddress (const uint16 bytes[8]) noexcept;
|
||||
|
||||
/** Creates an IPv4 address from 4 bytes. */
|
||||
IPAddress (uint8 address1, uint8 address2, uint8 address3, uint8 address4) noexcept;
|
||||
|
||||
/** Creates an address from a packed 32-bit integer, where the MSB is
|
||||
the first number in the address, and the LSB is the last.
|
||||
/** Creates an IPv6 address from 8 16-bit integers */
|
||||
IPAddress (uint16 address1, uint16 address2, uint16 address3, uint16 address4,
|
||||
uint16 address5, uint16 address6, uint16 address7, uint16 address8) noexcept;
|
||||
|
||||
/** Creates an IPv4 address from a packed 32-bit integer, where the
|
||||
MSB is the first number in the address, and the LSB is the last.
|
||||
*/
|
||||
explicit IPAddress (uint32 asNativeEndian32Bit) noexcept;
|
||||
|
||||
/** Parses a string IP address of the form "a.b.c.d". */
|
||||
/** Parses a string IP address of the form "1.2.3.4" (IPv4) or "1:2:3:4:5:6:7:8" (IPv6). */
|
||||
explicit IPAddress (const String& address);
|
||||
|
||||
/** Returns a dot-separated string in the form "1.2.3.4" */
|
||||
/** Returns a dot- or colon-separated string in the form "1.2.3.4" (IPv4) or "1:2:3:4:5:6:7:8" (IPv6). */
|
||||
String toString() const;
|
||||
|
||||
/** Returns an address meaning "any" (0.0.0.0) */
|
||||
static IPAddress any() noexcept;
|
||||
/** Returns an IPv4 or IPv6 address meaning "any", equivalent to 0.0.0.0 (IPv4) or ::, (IPv6) */
|
||||
static IPAddress any (bool IPv6 = false) noexcept;
|
||||
|
||||
/** Returns an address meaning "broadcast" (255.255.255.255) */
|
||||
/** Returns an IPv4 address meaning "broadcast" (255.255.255.255) */
|
||||
static IPAddress broadcast() noexcept;
|
||||
|
||||
/** Returns an address meaning "localhost" (127.0.0.1) */
|
||||
static IPAddress local() noexcept;
|
||||
/** Returns an IPv4 or IPv6 address meaning "localhost", equivalent to 127.0.0.1 (IPv4) or ::1 (IPv6) */
|
||||
static IPAddress local (bool IPv6 = false) noexcept;
|
||||
|
||||
/** Returns a formatted version of the provided IPv6 address conforming to RFC 5952 with leading zeros suppressed,
|
||||
lower case characters, and double-colon notation used to represent contiguous 16-bit fields of zeros.
|
||||
|
||||
@param unformattedAddress the IPv6 address to be formatted
|
||||
*/
|
||||
static String getFormattedAddress (const String& unformattedAddress);
|
||||
|
||||
bool operator== (const IPAddress& other) const noexcept;
|
||||
bool operator!= (const IPAddress& other) const noexcept;
|
||||
|
||||
/** The elements of the IP address. */
|
||||
uint8 address[4];
|
||||
uint8 address[16];
|
||||
|
||||
bool isIPv6;
|
||||
|
||||
private:
|
||||
/** Union used to split a 16-bit unsigned integer into 2 8-bit unsigned integers or vice-versa */
|
||||
typedef union
|
||||
{
|
||||
uint16 combined;
|
||||
uint8 split[2];
|
||||
} ByteUnion;
|
||||
|
||||
/** Method used to zero the remaining bytes of the address array when creating IPv4 addresses */
|
||||
void zeroUnusedBytes()
|
||||
{
|
||||
for (int i = 4; i < 16; ++i)
|
||||
address[i] = 0;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue