Browse Source

Added IPv6 support to the IPAddress class

tags/2021-05-28
ed 8 years ago
parent
commit
e09c2b65a1
5 changed files with 378 additions and 103 deletions
  1. +0
    -4
      modules/juce_core/juce_core.cpp
  2. +3
    -0
      modules/juce_core/native/juce_BasicNativeHeaders.h
  3. +111
    -25
      modules/juce_core/native/juce_win32_Network.cpp
  4. +212
    -57
      modules/juce_core/network/juce_IPAddress.cpp
  5. +52
    -17
      modules/juce_core/network/juce_IPAddress.h

+ 0
- 4
modules/juce_core/juce_core.cpp View File

@@ -55,10 +55,6 @@
#if JUCE_WINDOWS #if JUCE_WINDOWS
#include <ctime> #include <ctime>
#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
#include <winsock2.h>
#include <ws2tcpip.h>
#if ! JUCE_MINGW #if ! JUCE_MINGW
#pragma warning (push) #pragma warning (push)
#pragma warning (disable: 4091) #pragma warning (disable: 4091)


+ 3
- 0
modules/juce_core/native/juce_BasicNativeHeaders.h View File

@@ -121,6 +121,7 @@
#define NOMINMAX #define NOMINMAX
#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
#define STRICT 1 #define STRICT 1
#define WIN32_LEAN_AND_MEAN 1 #define WIN32_LEAN_AND_MEAN 1
#if JUCE_MINGW #if JUCE_MINGW
@@ -141,6 +142,8 @@
#include <ctime> #include <ctime>
#include <wininet.h> #include <wininet.h>
#include <nb30.h> #include <nb30.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h> #include <iphlpapi.h>
#include <mapi.h> #include <mapi.h>
#include <float.h> #include <float.h>


+ 111
- 25
modules/juce_core/native/juce_win32_Network.cpp View File

@@ -400,26 +400,26 @@ private:
//============================================================================== //==============================================================================
struct GetAdaptersInfoHelper
struct GetAdaptersAddressesHelper
{ {
bool callGetAdaptersInfo()
bool callGetAdaptersAddresses()
{ {
DynamicLibrary dll ("iphlpapi.dll"); 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; 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 namespace MACAddressHelpers
@@ -430,15 +430,17 @@ namespace MACAddressHelpers
result.addIfNotAlreadyThere (ma); 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) void MACAddress::findAllAddresses (Array<MACAddress>& result)
{ {
MACAddressHelpers::getViaGetAdaptersInfo (result);
MACAddressHelpers::getViaGetAdaptersAddresses (result);
MACAddressHelpers::getViaNetBios (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;
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];
if (ip != IPAddress::any())
result.addIfNotAlreadyThere (ip);
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);
}
}
} }
} }
} }


+ 212
- 57
modules/juce_core/network/juce_IPAddress.cpp View File

@@ -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[0] = a0; address[1] = a1;
address[2] = a2; address[3] = a3; 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[0] = (n >> 24);
address[1] = (n >> 16) & 255; address[1] = (n >> 16) & 255;
address[2] = (n >> 8) & 255;
address[2] = (n >> 8) & 255;
address[3] = (n & 255); address[3] = (n & 255);
zeroUnusedBytes();
} }
IPAddress::IPAddress (const String& adr) IPAddress::IPAddress (const String& adr)
{ {
StringArray tokens;
tokens.addTokens (adr, ".", String());
isIPv6 = adr.contains (":");
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());
for (int i = 0; i < 4; ++i)
address[i] = (uint8) tokens[i].getIntValue();
address[i * 2] = temp.split[0];
address[i * 2 + 1] = temp.split[1];
}
}
} }
String IPAddress::toString() const 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];
return s;
}
for (int i = 1; i < 4; ++i)
s << '.' << (int) address[i];
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];
return s;
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 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 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))); 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);
cfg.ifc_len = bufferSize;
cfg.ifc_buf = buffer;
uint16 combined;
uint8 split[2];
} ByteUnion;
if (ioctl (sock, SIOCGIFCONF, &cfg) < 0 && errno != EINVAL)
return;
ByteUnion temp;
uint16 arr[8];
} 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 (getifaddrs (&ifaddr) == -1)
return;
if (sock >= 0)
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 #endif

+ 52
- 17
modules/juce_core/network/juce_IPAddress.h View File

@@ -33,48 +33,83 @@
//============================================================================== //==============================================================================
/** /**
An IPV4 address.
Represents an IP address.
*/ */
class JUCE_API IPAddress class JUCE_API IPAddress
{ {
public: public:
//============================================================================== //==============================================================================
/** Populates a list of all the IP addresses that this machine is using. */ /** 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 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. */
explicit IPAddress (const uint8 bytes[4]) noexcept;
/** Creates an IPv6 address from an array of 8 16-bit integers */
explicit IPAddress (const uint16 bytes[8]) noexcept;
/** Creates an address from 4 bytes. */
/** Creates an IPv4 address from 4 bytes. */
IPAddress (uint8 address1, uint8 address2, uint8 address3, uint8 address4) noexcept; 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; 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); 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; 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; 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;
bool operator!= (const IPAddress& other) const noexcept; bool operator!= (const IPAddress& other) const noexcept;
/** The elements of the IP address. */ /** 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…
Cancel
Save