|
|
|
@@ -85,24 +85,34 @@ IPAddress::IPAddress (uint32 n) noexcept : isIPv6 (false) |
|
|
|
zeroUnusedBytes();
|
|
|
|
}
|
|
|
|
|
|
|
|
static String removePort (const String& adr)
|
|
|
|
{
|
|
|
|
if (adr.containsAnyOf ("[]"))
|
|
|
|
return adr.fromFirstOccurrenceOf ("[", false, true).upToLastOccurrenceOf ("]", false, true);
|
|
|
|
else if (adr.indexOf (":") == adr.lastIndexOf (":"))
|
|
|
|
return adr.upToLastOccurrenceOf (":", false, true);
|
|
|
|
|
|
|
|
return adr;
|
|
|
|
}
|
|
|
|
|
|
|
|
IPAddress::IPAddress (const String& adr)
|
|
|
|
{
|
|
|
|
isIPv6 = adr.contains (":");
|
|
|
|
auto ipAddress = removePort (adr);
|
|
|
|
|
|
|
|
isIPv6 = ipAddress.contains (":");
|
|
|
|
|
|
|
|
if (! isIPv6)
|
|
|
|
{
|
|
|
|
StringArray tokens;
|
|
|
|
tokens.addTokens (adr, ".", String());
|
|
|
|
auto tokens = StringArray::fromTokens (ipAddress, ".", {});
|
|
|
|
|
|
|
|
for (int i = 0; i < 4; ++i)
|
|
|
|
address[i] = (uint8) tokens[i].getIntValue();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
StringArray tokens;
|
|
|
|
tokens.addTokens (adr.removeCharacters ("[]"), ":", String());
|
|
|
|
auto tokens = StringArray::fromTokens (ipAddress, ":", {});
|
|
|
|
|
|
|
|
if (tokens.contains (StringRef())) // if :: shorthand has been used
|
|
|
|
if (tokens.contains ({})) // if :: shorthand has been used
|
|
|
|
{
|
|
|
|
int idx = tokens.indexOf (StringRef());
|
|
|
|
tokens.set (idx, "0");
|
|
|
|
@@ -111,8 +121,22 @@ IPAddress::IPAddress (const String& adr) |
|
|
|
tokens.insert (idx, "0");
|
|
|
|
}
|
|
|
|
|
|
|
|
tokens.removeEmptyStrings();
|
|
|
|
|
|
|
|
for (int i = 0; i < 8; ++i)
|
|
|
|
{
|
|
|
|
if (i == 6 && isIPv4MappedAddress (IPAddress (address, true)))
|
|
|
|
{
|
|
|
|
IPAddress v4Address (tokens[i]);
|
|
|
|
|
|
|
|
address[12] = v4Address.address[0];
|
|
|
|
address[13] = v4Address.address[1];
|
|
|
|
address[14] = v4Address.address[2];
|
|
|
|
address[15] = v4Address.address[3];
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ByteUnion temp;
|
|
|
|
temp.combined = (uint16) CharacterFunctions::HexParser<int>::parse (tokens[i].getCharPointer());
|
|
|
|
|
|
|
|
@@ -134,25 +158,62 @@ String IPAddress::toString() const |
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
String addressString;
|
|
|
|
ByteUnion temp;
|
|
|
|
|
|
|
|
temp.split[0] = address[0];
|
|
|
|
temp.split[1] = address[1];
|
|
|
|
|
|
|
|
addressString = String (String::toHexString (temp.combined));
|
|
|
|
auto addressString = 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));
|
|
|
|
addressString << ':' << String::toHexString (temp.combined);
|
|
|
|
}
|
|
|
|
|
|
|
|
return getFormattedAddress (addressString);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IPAddress::operator== (const IPAddress& other) const noexcept { return compare (other) == 0; }
|
|
|
|
bool IPAddress::operator!= (const IPAddress& other) const noexcept { return compare (other) != 0; }
|
|
|
|
bool IPAddress::operator< (const IPAddress& other) const noexcept { return compare (other) < 0; }
|
|
|
|
bool IPAddress::operator<= (const IPAddress& other) const noexcept { return compare (other) <= 0; }
|
|
|
|
bool IPAddress::operator> (const IPAddress& other) const noexcept { return compare (other) > 0; }
|
|
|
|
bool IPAddress::operator>= (const IPAddress& other) const noexcept { return compare (other) >= 0; }
|
|
|
|
|
|
|
|
int IPAddress::compare (const IPAddress& other) const noexcept
|
|
|
|
{
|
|
|
|
if (isIPv6 != other.isIPv6)
|
|
|
|
{
|
|
|
|
if (isIPv6)
|
|
|
|
{
|
|
|
|
if (isIPv4MappedAddress (*this))
|
|
|
|
return convertIPv4MappedAddressToIPv4 (*this).compare (other);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (isIPv4MappedAddress (other))
|
|
|
|
return compare (convertIPv4MappedAddressToIPv4 (other));
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < (isIPv6 ? 16 : 4); ++i)
|
|
|
|
{
|
|
|
|
if (address[i] > other.address[i])
|
|
|
|
return 1;
|
|
|
|
else if (address[i] < other.address[i])
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
IPAddress IPAddress::any() noexcept { return IPAddress(); }
|
|
|
|
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)
|
|
|
|
@@ -174,7 +235,7 @@ String IPAddress::getFormattedAddress (const String& unformattedAddress) |
|
|
|
|
|
|
|
for (int i = 0; i < tokens.size(); ++i)
|
|
|
|
{
|
|
|
|
const auto& t = tokens.getReference (i);
|
|
|
|
auto& t = tokens.getReference (i);
|
|
|
|
|
|
|
|
if (t.getHexValue32() == 0x0000)
|
|
|
|
{
|
|
|
|
@@ -232,21 +293,46 @@ String IPAddress::getFormattedAddress (const String& unformattedAddress) |
|
|
|
return addressString;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IPAddress::operator== (const IPAddress& other) const noexcept
|
|
|
|
bool IPAddress::isIPv4MappedAddress (const IPAddress& mappedAddress)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < (isIPv6 ? 16 : 4); ++i)
|
|
|
|
if (address[i] != other.address[i])
|
|
|
|
if (! mappedAddress.isIPv6)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for (int i = 0; i < 10; ++i)
|
|
|
|
{
|
|
|
|
if (mappedAddress.address[i] != 0)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mappedAddress.address[10] != 255 || mappedAddress.address[11] != 255)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
IPAddress IPAddress::convertIPv4MappedAddressToIPv4 (const IPAddress& mappedAddress)
|
|
|
|
{
|
|
|
|
// The address that you're converting needs to be IPv6!
|
|
|
|
jassert (mappedAddress.isIPv6);
|
|
|
|
|
|
|
|
if (isIPv4MappedAddress (mappedAddress))
|
|
|
|
return { mappedAddress.address[12], mappedAddress.address[13],
|
|
|
|
mappedAddress.address[14], mappedAddress.address[15] };
|
|
|
|
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IPAddress::operator!= (const IPAddress& other) const noexcept
|
|
|
|
IPAddress IPAddress::convertIPv4AddressToIPv4Mapped (const IPAddress& addressToMap)
|
|
|
|
{
|
|
|
|
return ! operator== (other);
|
|
|
|
// The address that you're converting needs to be IPv4!
|
|
|
|
jassert (! addressToMap.isIPv6);
|
|
|
|
|
|
|
|
return { 0x0, 0x0, 0x0, 0x0, 0x0, 0xffff,
|
|
|
|
static_cast<uint16> ((addressToMap.address[0] << 8) | addressToMap.address[1]),
|
|
|
|
static_cast<uint16> ((addressToMap.address[2] << 8) | addressToMap.address[3]) };
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#if (! JUCE_WINDOWS) && (! JUCE_ANDROID)
|
|
|
|
static void addAddress (const sockaddr_in* addr_in, Array<IPAddress>& result)
|
|
|
|
{
|
|
|
|
@@ -277,8 +363,7 @@ static void addAddress (const sockaddr_in6* addr_in, Array<IPAddress>& result) |
|
|
|
arr[i] = temp.combined;
|
|
|
|
}
|
|
|
|
|
|
|
|
IPAddress ip (arr);
|
|
|
|
result.addIfNotAlreadyThere (ip);
|
|
|
|
result.addIfNotAlreadyThere (IPAddress (arr));
|
|
|
|
}
|
|
|
|
|
|
|
|
void IPAddress::findAllAddresses (Array<IPAddress>& result, bool includeIPv6)
|
|
|
|
|