summary refs log tree commit diff
path: root/Crypto/src/util/net/IPAddress.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Crypto/src/util/net/IPAddress.cs')
-rw-r--r--Crypto/src/util/net/IPAddress.cs197
1 files changed, 197 insertions, 0 deletions
diff --git a/Crypto/src/util/net/IPAddress.cs b/Crypto/src/util/net/IPAddress.cs
new file mode 100644
index 000000000..2a30a15f0
--- /dev/null
+++ b/Crypto/src/util/net/IPAddress.cs
@@ -0,0 +1,197 @@
+using System;
+using System.Globalization;
+
+using Org.BouncyCastle.Math;
+
+namespace 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;
+		}
+	}
+}