IPAddress.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Globalization;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
  6. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Net
  7. {
  8. public class IPAddress
  9. {
  10. /**
  11. * Validate the given IPv4 or IPv6 address.
  12. *
  13. * @param address the IP address as a string.
  14. *
  15. * @return true if a valid address, false otherwise
  16. */
  17. public static bool IsValid(
  18. string address)
  19. {
  20. return IsValidIPv4(address) || IsValidIPv6(address);
  21. }
  22. /**
  23. * Validate the given IPv4 or IPv6 address and netmask.
  24. *
  25. * @param address the IP address as a string.
  26. *
  27. * @return true if a valid address with netmask, false otherwise
  28. */
  29. public static bool IsValidWithNetMask(
  30. string address)
  31. {
  32. return IsValidIPv4WithNetmask(address) || IsValidIPv6WithNetmask(address);
  33. }
  34. /**
  35. * Validate the given IPv4 address.
  36. *
  37. * @param address the IP address as a string.
  38. *
  39. * @return true if a valid IPv4 address, false otherwise
  40. */
  41. public static bool IsValidIPv4(
  42. string address)
  43. {
  44. try
  45. {
  46. return unsafeIsValidIPv4(address);
  47. }
  48. catch (FormatException) {}
  49. catch (OverflowException) {}
  50. return false;
  51. }
  52. private static bool unsafeIsValidIPv4(
  53. string address)
  54. {
  55. if (address.Length == 0)
  56. return false;
  57. int octets = 0;
  58. string temp = address + ".";
  59. int pos;
  60. int start = 0;
  61. while (start < temp.Length
  62. && (pos = temp.IndexOf('.', start)) > start)
  63. {
  64. if (octets == 4)
  65. return false;
  66. string octetStr = temp.Substring(start, pos - start);
  67. int octet = Int32.Parse(octetStr);
  68. if (octet < 0 || octet > 255)
  69. return false;
  70. start = pos + 1;
  71. octets++;
  72. }
  73. return octets == 4;
  74. }
  75. public static bool IsValidIPv4WithNetmask(
  76. string address)
  77. {
  78. int index = address.IndexOf('/');
  79. string mask = address.Substring(index + 1);
  80. return (index > 0) && IsValidIPv4(address.Substring(0, index))
  81. && (IsValidIPv4(mask) || IsMaskValue(mask, 32));
  82. }
  83. public static bool IsValidIPv6WithNetmask(
  84. string address)
  85. {
  86. int index = address.IndexOf('/');
  87. string mask = address.Substring(index + 1);
  88. return (index > 0) && (IsValidIPv6(address.Substring(0, index))
  89. && (IsValidIPv6(mask) || IsMaskValue(mask, 128)));
  90. }
  91. private static bool IsMaskValue(
  92. string component,
  93. int size)
  94. {
  95. int val = Int32.Parse(component);
  96. try
  97. {
  98. return val >= 0 && val <= size;
  99. }
  100. catch (FormatException) {}
  101. catch (OverflowException) {}
  102. return false;
  103. }
  104. /**
  105. * Validate the given IPv6 address.
  106. *
  107. * @param address the IP address as a string.
  108. *
  109. * @return true if a valid IPv4 address, false otherwise
  110. */
  111. public static bool IsValidIPv6(
  112. string address)
  113. {
  114. try
  115. {
  116. return unsafeIsValidIPv6(address);
  117. }
  118. catch (FormatException) {}
  119. catch (OverflowException) {}
  120. return false;
  121. }
  122. private static bool unsafeIsValidIPv6(
  123. string address)
  124. {
  125. if (address.Length == 0)
  126. {
  127. return false;
  128. }
  129. int octets = 0;
  130. string temp = address + ":";
  131. bool doubleColonFound = false;
  132. int pos;
  133. int start = 0;
  134. while (start < temp.Length
  135. && (pos = temp.IndexOf(':', start)) >= start)
  136. {
  137. if (octets == 8)
  138. {
  139. return false;
  140. }
  141. if (start != pos)
  142. {
  143. string value = temp.Substring(start, pos - start);
  144. if (pos == (temp.Length - 1) && value.IndexOf('.') > 0)
  145. {
  146. if (!IsValidIPv4(value))
  147. {
  148. return false;
  149. }
  150. octets++; // add an extra one as address covers 2 words.
  151. }
  152. else
  153. {
  154. string octetStr = temp.Substring(start, pos - start);
  155. int octet = Int32.Parse(octetStr, NumberStyles.AllowHexSpecifier);
  156. if (octet < 0 || octet > 0xffff)
  157. return false;
  158. }
  159. }
  160. else
  161. {
  162. if (pos != 1 && pos != temp.Length - 1 && doubleColonFound)
  163. {
  164. return false;
  165. }
  166. doubleColonFound = true;
  167. }
  168. start = pos + 1;
  169. octets++;
  170. }
  171. return octets == 8 || doubleColonFound;
  172. }
  173. }
  174. }
  175. #pragma warning restore
  176. #endif