vak*_*kas 25 c# asp.net network-programming
到目前为止,我有这个代码:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
如何过滤私有IP地址?我以同样的方式过滤环回IP地址.
Gab*_*ves 43
更详细的回复如下:
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;
}
Run Code Online (Sandbox Code Playgroud)
ang*_*sen 12
此实施+测试涵盖:
\n在 .NET Core 3.1 和 .NET 6 上测试。
\nhttps://gist.github.com/angularsen/f77b53ee9966fcd914025e25a2b3a085
\n执行
\nusing System;\nusing System.Net;\nusing System.Net.Sockets;\n\nnamespace MyNamespace\n{\n /// <summary>\n /// Extension methods on <see cref="System.Net.IPAddress"/>.\n /// </summary>\n public static class IPAddressExtensions\n {\n /// <summary>\n /// Returns true if the IP address is in a private range.<br/>\n /// IPv4: Loopback, link local ("169.254.x.x"), class A ("10.x.x.x"), class B ("172.16.x.x" to "172.31.x.x") and class C ("192.168.x.x").<br/>\n /// IPv6: Loopback, link local, site local, unique local and private IPv4 mapped to IPv6.<br/>\n /// </summary>\n /// <param name="ip">The IP address.</param>\n /// <returns>True if the IP address was in a private range.</returns>\n /// <example><code>bool isPrivate = IPAddress.Parse("127.0.0.1").IsPrivate();</code></example>\n public static bool IsPrivate(this IPAddress ip)\n {\n // Map back to IPv4 if mapped to IPv6, for example "::ffff:1.2.3.4" to "1.2.3.4".\n if (ip.IsIPv4MappedToIPv6)\n ip = ip.MapToIPv4();\n\n // Checks loopback ranges for both IPv4 and IPv6.\n if (IPAddress.IsLoopback(ip)) return true;\n\n // IPv4\n if (ip.AddressFamily == AddressFamily.InterNetwork)\n return IsPrivateIPv4(ip.GetAddressBytes());\n\n // IPv6\n if (ip.AddressFamily == AddressFamily.InterNetworkV6)\n {\n return ip.IsIPv6LinkLocal ||\n#if NET6_0\n ip.IsIPv6UniqueLocal ||\n#endif\n ip.IsIPv6SiteLocal;\n }\n\n throw new NotSupportedException(\n $"IP address family {ip.AddressFamily} is not supported, expected only IPv4 (InterNetwork) or IPv6 (InterNetworkV6).");\n }\n\n private static bool IsPrivateIPv4(byte[] ipv4Bytes)\n {\n // Link local (no IP assigned by DHCP): 169.254.0.0 to 169.254.255.255 (169.254.0.0/16)\n bool IsLinkLocal() => ipv4Bytes[0] == 169 && ipv4Bytes[1] == 254;\n\n // Class A private range: 10.0.0.0 \xe2\x80\x93 10.255.255.255 (10.0.0.0/8)\n bool IsClassA() => ipv4Bytes[0] == 10;\n\n // Class B private range: 172.16.0.0 \xe2\x80\x93 172.31.255.255 (172.16.0.0/12)\n bool IsClassB() => ipv4Bytes[0] == 172 && ipv4Bytes[1] >= 16 && ipv4Bytes[1] <= 31;\n\n // Class C private range: 192.168.0.0 \xe2\x80\x93 192.168.255.255 (192.168.0.0/16)\n bool IsClassC() => ipv4Bytes[0] == 192 && ipv4Bytes[1] == 168;\n\n return IsLinkLocal() || IsClassA() || IsClassC() || IsClassB();\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n测试
\nusing System.Diagnostics.CodeAnalysis;\nusing System.Net;\nusing MyNamespace;\nusing FluentAssertions;\nusing Xunit;\n\nnamespace MyNamespace.Tests\n{\n [SuppressMessage("ReSharper", "InvokeAsExtensionMethod")]\n public class IPAddressExtensionsTests\n {\n [Theory]\n [InlineData("1.1.1.1" )] // Cloudflare DNS\n [InlineData("8.8.8.8" )] // Google DNS\n [InlineData("20.112.52.29")] // microsoft.com\n public void IsPrivate_ReturnsFalse_PublicIPv4(string ip)\n {\n var ipAddress = IPAddress.Parse(ip);\n IPAddressExtensions.IsPrivate(ipAddress).Should().BeFalse();\n }\n\n [Theory]\n [InlineData("::ffff:1.1.1.1" )] // Cloudflare DNS\n [InlineData("::ffff:8.8.8.8" )] // Google DNS\n [InlineData("::ffff:20.112.52.29")] // microsoft.com\n public void IsPrivate_ReturnsFalse_PublicIPv4MappedToIPv6(string ip)\n {\n var ipAddress = IPAddress.Parse(ip);\n IPAddressExtensions.IsPrivate(ipAddress).Should().BeFalse();\n }\n\n [Theory]\n [InlineData("127.0.0.1" )] // Loopback IPv4 127.0.0.1 - 127.255.255.255 (127.0.0.0/8)\n [InlineData("127.10.20.30" )]\n [InlineData("127.255.255.255")]\n [InlineData("10.0.0.0" )] // Class A private IP 10.0.0.0 \xe2\x80\x93 10.255.255.255 (10.0.0.0/8)\n [InlineData("10.20.30.40" )]\n [InlineData("10.255.255.255" )]\n [InlineData("172.16.0.0" )] // Class B private IP 172.16.0.0 \xe2\x80\x93 172.31.255.255 (172.16.0.0/12)\n [InlineData("172.20.30.40" )]\n [InlineData("172.31.255.255" )]\n [InlineData("192.168.0.0" )] // Class C private IP 192.168.0.0 \xe2\x80\x93 192.168.255.255 (192.168.0.0/16)\n [InlineData("192.168.30.40" )]\n [InlineData("192.168.255.255")]\n [InlineData("169.254.0.0" )] // Link local (169.254.x.x)\n [InlineData("169.254.30.40" )]\n [InlineData("169.254.255.255")]\n public void IsPrivate_ReturnsTrue_PrivateIPv4(string ip)\n {\n var ipAddress = IPAddress.Parse(ip);\n IPAddressExtensions.IsPrivate(ipAddress).Should().BeTrue();\n }\n\n [Theory]\n [InlineData("::ffff:127.0.0.1" )] // Loopback IPv4 127.0.0.1 - 127.255.255.254 (127.0.0.0/8)\n [InlineData("::ffff:127.10.20.30" )]\n [InlineData("::ffff:127.255.255.254")]\n [InlineData("::ffff:10.0.0.0" )] // Class A private IP 10.0.0.0 \xe2\x80\x93 10.255.255.255 (10.0.0.0/8)\n [InlineData("::ffff:10.20.30.40" )]\n [InlineData("::ffff:10.255.255.255" )]\n [InlineData("::ffff:172.16.0.0" )] // Class B private IP 172.16.0.0 \xe2\x80\x93 172.31.255.255 (172.16.0.0/12)\n [InlineData("::ffff:172.20.30.40" )]\n [InlineData("::ffff:172.31.255.255" )]\n [InlineData("::ffff:192.168.0.0" )] // Class C private IP 192.168.0.0 \xe2\x80\x93 192.168.255.255 (192.168.0.0/16)\n [InlineData("::ffff:192.168.30.40" )]\n [InlineData("::ffff:192.168.255.255")]\n [InlineData("::ffff:169.254.0.0" )] // Link local (169.254.x.x)\n [InlineData("::ffff:169.254.30.40" )]\n [InlineData("::ffff:169.254.255.255")]\n public void IsPrivate_ReturnsTrue_PrivateIPv4MappedToIPv6(string ip)\n {\n var ipAddress = IPAddress.Parse(ip);\n IPAddressExtensions.IsPrivate(ipAddress).Should().BeTrue();\n }\n\n [Theory]\n [InlineData("::1" )] // Loopback\n [InlineData("fe80::" )] // Link local\n [InlineData("fe80:1234:5678::1")] // Link local\n [InlineData("fc00::" )] // Unique local, globally assigned.\n [InlineData("fc00:1234:5678::1")] // Unique local, globally assigned.\n [InlineData("fd00::" )] // Unique local, locally assigned.\n [InlineData("fd12:3456:789a::1")] // Unique local, locally assigned.\n public void IsPrivate_ReturnsTrue_PrivateIPv6(string ip)\n {\n var ipAddress = IPAddress.Parse(ip);\n IPAddressExtensions.IsPrivate(ipAddress).Should().BeTrue();\n }\n\n [Theory]\n [InlineData("2606:4700:4700::64" )] // Cloudflare DNS\n [InlineData("2001:4860:4860::8888" )] // Google DNS\n [InlineData("2001:0db8:85a3:0000:0000:8a2e:0370:7334")] // Commonly used example.\n public void IsPrivate_ReturnsFalse_PublicIPv6(string ip)\n {\n var ipAddress = IPAddress.Parse(ip);\n IPAddressExtensions.IsPrivate(ipAddress).Should().BeFalse();\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
执行此操作的最佳方法是IP地址类的扩展方法
/// <summary>
/// An extension method to determine if an IP address is internal, as specified in RFC1918
/// </summary>
/// <param name="toTest">The IP address that will be tested</param>
/// <returns>Returns true if the IP is internal, false if it is external</returns>
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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,可以在IP地址类的实例上调用该方法
bool isIpInternal = ipAddressInformation.Address.IsInternal();
Run Code Online (Sandbox Code Playgroud)
添加了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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16391 次 |
| 最近记录: |