如何确定私有IP地址?

到目前为止,我有这个代码:

NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface adapter in adapters) { IPInterfaceProperties properties = adapter.GetIPProperties(); foreach (IPAddressInformation uniCast in properties.UnicastAddresses) { // Ignore loop-back addresses & IPv6 if (!IPAddress.IsLoopback(uniCast.Address) && uniCast.Address.AddressFamily!= AddressFamily.InterNetworkV6) Addresses.Add(uniCast.Address); } } 

如何过滤私有IP地址? 我以同样的方式过滤环回IP地址。

更详细的回复如下:

 private bool _IsPrivate(string ipAddress) { int[] ipParts = ipAddress.Split(new String[] { "." }, StringSplitOptions.RemoveEmptyEntries) .Select(s => int.Parse(s)).ToArray(); // in private ip range if (ipParts[0] == 10 || (ipParts[0] == 192 && ipParts[1] == 168) || (ipParts[0] == 172 && (ipParts[1] >= 16 && ipParts[1] <= 31))) { return true; } // IP Address is probably public. // This doesn't catch some VPN ranges like OpenVPN and Hamachi. return false; } 

私有地址范围在RFC1918中定义。 他们是:

  • 10.0.0.0 – 10.255.255.255(10/8前缀)
  • 172.16.0.0 – 172.31.255.255(172.16 / 12前缀)
  • 192.168.0.0 – 192.168.255.255(192.168 / 16前缀)

您可能还希望过滤掉RFC3927中定义的链接本地地址(169.254 / 16)。

最好这样做是IP地址类的扩展方法

  ///  /// An extension method to determine if an IP address is internal, as specified in RFC1918 ///  /// The IP address that will be tested /// Returns true if the IP is internal, false if it is external public static bool IsInternal(this IPAddress toTest) { byte[] bytes = toTest.GetAddressBytes(); switch( bytes[ 0 ] ) { case 10: return true; case 172: return bytes[ 1 ] < 32 && bytes[ 1 ] >= 16; case 192: return bytes[ 1 ] == 168; default: return false; } } 

然后,可以在IP地址类的实例上调用该方法

  bool isIpInternal = ipAddressInformation.Address.IsInternal(); 
 10.0.0.0 - 10.255.255.255 (10/8 prefix) 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) 

使用RFC中定义的范围(由Anders建议); 而使用正则表达式来检测/删除列表中的私有IP地址。

以下是用于检测专用IP地址的示例RegEx。 (未经我测试)

 (^127\.0\.0\.1)| (^10\.)| (^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)| (^192\.168\.) 

添加了IPv6和localhost案例。

  /* An IP should be considered as internal when: ::1 - IPv6 loopback 10.0.0.0 - 10.255.255.255 (10/8 prefix) 127.0.0.0 - 127.255.255.255 (127/8 prefix) 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) */ public bool IsInternal(string testIp) { if(testIp == "::1") return true; byte[] ip = IPAddress.Parse(testIp).GetAddressBytes(); switch (ip[0]) { case 10: case 127: return true; case 172: return ip[1] >= 16 && ip[1] < 32; case 192: return ip[1] == 168; default: return false; } }