@@ -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; | |||
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); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
@@ -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 (":"); | |||
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 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 | |||
{ | |||
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); | |||
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 |
@@ -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 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; | |||
/** 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; | |||
} | |||
}; |