You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
202 lines
4.1 KiB
202 lines
4.1 KiB
1 year ago
|
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||
|
#pragma warning disable
|
||
|
using System;
|
||
|
using System.Globalization;
|
||
|
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||
|
|
||
|
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Net
|
||
|
{
|
||
|
public class IPAddress
|
||
|
{
|
||
|
/**
|
||
|
* Validate the given IPv4 or IPv6 address.
|
||
|
*
|
||
|
* @param address the IP address as a string.
|
||
|
*
|
||
|
* @return true if a valid address, false otherwise
|
||
|
*/
|
||
|
public static bool IsValid(
|
||
|
string address)
|
||
|
{
|
||
|
return IsValidIPv4(address) || IsValidIPv6(address);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Validate the given IPv4 or IPv6 address and netmask.
|
||
|
*
|
||
|
* @param address the IP address as a string.
|
||
|
*
|
||
|
* @return true if a valid address with netmask, false otherwise
|
||
|
*/
|
||
|
public static bool IsValidWithNetMask(
|
||
|
string address)
|
||
|
{
|
||
|
return IsValidIPv4WithNetmask(address) || IsValidIPv6WithNetmask(address);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Validate the given IPv4 address.
|
||
|
*
|
||
|
* @param address the IP address as a string.
|
||
|
*
|
||
|
* @return true if a valid IPv4 address, false otherwise
|
||
|
*/
|
||
|
public static bool IsValidIPv4(
|
||
|
string address)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
return unsafeIsValidIPv4(address);
|
||
|
}
|
||
|
catch (FormatException) {}
|
||
|
catch (OverflowException) {}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
private static bool unsafeIsValidIPv4(
|
||
|
string address)
|
||
|
{
|
||
|
if (address.Length == 0)
|
||
|
return false;
|
||
|
|
||
|
int octets = 0;
|
||
|
string temp = address + ".";
|
||
|
|
||
|
int pos;
|
||
|
int start = 0;
|
||
|
while (start < temp.Length
|
||
|
&& (pos = temp.IndexOf('.', start)) > start)
|
||
|
{
|
||
|
if (octets == 4)
|
||
|
return false;
|
||
|
|
||
|
string octetStr = temp.Substring(start, pos - start);
|
||
|
int octet = Int32.Parse(octetStr);
|
||
|
|
||
|
if (octet < 0 || octet > 255)
|
||
|
return false;
|
||
|
|
||
|
start = pos + 1;
|
||
|
octets++;
|
||
|
}
|
||
|
|
||
|
return octets == 4;
|
||
|
}
|
||
|
|
||
|
public static bool IsValidIPv4WithNetmask(
|
||
|
string address)
|
||
|
{
|
||
|
int index = address.IndexOf('/');
|
||
|
string mask = address.Substring(index + 1);
|
||
|
|
||
|
return (index > 0) && IsValidIPv4(address.Substring(0, index))
|
||
|
&& (IsValidIPv4(mask) || IsMaskValue(mask, 32));
|
||
|
}
|
||
|
|
||
|
public static bool IsValidIPv6WithNetmask(
|
||
|
string address)
|
||
|
{
|
||
|
int index = address.IndexOf('/');
|
||
|
string mask = address.Substring(index + 1);
|
||
|
|
||
|
return (index > 0) && (IsValidIPv6(address.Substring(0, index))
|
||
|
&& (IsValidIPv6(mask) || IsMaskValue(mask, 128)));
|
||
|
}
|
||
|
|
||
|
private static bool IsMaskValue(
|
||
|
string component,
|
||
|
int size)
|
||
|
{
|
||
|
int val = Int32.Parse(component);
|
||
|
try
|
||
|
{
|
||
|
return val >= 0 && val <= size;
|
||
|
}
|
||
|
catch (FormatException) {}
|
||
|
catch (OverflowException) {}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Validate the given IPv6 address.
|
||
|
*
|
||
|
* @param address the IP address as a string.
|
||
|
*
|
||
|
* @return true if a valid IPv4 address, false otherwise
|
||
|
*/
|
||
|
public static bool IsValidIPv6(
|
||
|
string address)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
return unsafeIsValidIPv6(address);
|
||
|
}
|
||
|
catch (FormatException) {}
|
||
|
catch (OverflowException) {}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
private static bool unsafeIsValidIPv6(
|
||
|
string address)
|
||
|
{
|
||
|
if (address.Length == 0)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
int octets = 0;
|
||
|
|
||
|
string temp = address + ":";
|
||
|
bool doubleColonFound = false;
|
||
|
int pos;
|
||
|
int start = 0;
|
||
|
while (start < temp.Length
|
||
|
&& (pos = temp.IndexOf(':', start)) >= start)
|
||
|
{
|
||
|
if (octets == 8)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (start != pos)
|
||
|
{
|
||
|
string value = temp.Substring(start, pos - start);
|
||
|
|
||
|
if (pos == (temp.Length - 1) && value.IndexOf('.') > 0)
|
||
|
{
|
||
|
if (!IsValidIPv4(value))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
octets++; // add an extra one as address covers 2 words.
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
string octetStr = temp.Substring(start, pos - start);
|
||
|
int octet = Int32.Parse(octetStr, NumberStyles.AllowHexSpecifier);
|
||
|
|
||
|
if (octet < 0 || octet > 0xffff)
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (pos != 1 && pos != temp.Length - 1 && doubleColonFound)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
doubleColonFound = true;
|
||
|
}
|
||
|
start = pos + 1;
|
||
|
octets++;
|
||
|
}
|
||
|
|
||
|
return octets == 8 || doubleColonFound;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#pragma warning restore
|
||
|
#endif
|