如何检查一个IP地址是否在特定的子网内

46

我有一个子网,格式为10.132.0.0/20,以及来自ASP.Net请求对象的IP地址。

是否有.NET框架函数可以检查IP地址是否在给定的子网内?

如果没有,如何实现?我猜测是通过位操作来完成?


这个回答解决了你的问题吗?如何检查输入的IP是否在特定的IP范围内 - Michael Freidgeim
9个回答

41

请查看MSDN博客上的使用C#进行IP地址计算。它包括一个扩展方法(IsInSameSubnet),可以满足您的需求以及其他有用的内容。

public static class IPAddressExtensions
{
    public static IPAddress GetBroadcastAddress(this IPAddress address, IPAddress subnetMask)
    {
        byte[] ipAdressBytes = address.GetAddressBytes();
        byte[] subnetMaskBytes = subnetMask.GetAddressBytes();

        if (ipAdressBytes.Length != subnetMaskBytes.Length)
            throw new ArgumentException("Lengths of IP address and subnet mask do not match.");

        byte[] broadcastAddress = new byte[ipAdressBytes.Length];
        for (int i = 0; i < broadcastAddress.Length; i++)
        {
            broadcastAddress[i] = (byte)(ipAdressBytes[i] | (subnetMaskBytes[i] ^ 255));
        }
        return new IPAddress(broadcastAddress);
    }

    public static IPAddress GetNetworkAddress(this IPAddress address, IPAddress subnetMask)
    {
        byte[] ipAdressBytes = address.GetAddressBytes();
        byte[] subnetMaskBytes = subnetMask.GetAddressBytes();

        if (ipAdressBytes.Length != subnetMaskBytes.Length)
            throw new ArgumentException("Lengths of IP address and subnet mask do not match.");

        byte[] broadcastAddress = new byte[ipAdressBytes.Length];
        for (int i = 0; i < broadcastAddress.Length; i++)
        {
            broadcastAddress[i] = (byte)(ipAdressBytes[i] & (subnetMaskBytes[i]));
        }
        return new IPAddress(broadcastAddress);
    }

    public static bool IsInSameSubnet(this IPAddress address2, IPAddress address, IPAddress subnetMask)
    {
        IPAddress network1 = address.GetNetworkAddress(subnetMask);
        IPAddress network2 = address2.GetNetworkAddress(subnetMask);

        return network1.Equals(network2);
    }
}

1
IPv6地址怎么样? - ageroh
@ageroh GitHub上似乎有一些能够处理IPv6地址的C#库。例如,IPNetwork https://github.com/lduchosal/ipnetwork。 - Chris Shouts
我在我的回答中添加了一个适用于IPv6和IPv4的实现 - 我很乐意收到一些反馈 ;) - Christoph Sonntag

35

结合ThomasChris的答案以及Cisco子网划分示例,我终于找到了一些代码来处理IPv4和IPv6,如果您使用CIDR符号(IPAddress/PrefixLength)。由于没有UInt128数据类型,我的IPv6实现可能有点简单,无法适应Thomas的解决方案。以下是似乎运行良好的代码:

public static bool IsInSubnet(this IPAddress address, string subnetMask)
{
    var slashIdx = subnetMask.IndexOf("/");
    if (slashIdx == -1)
    { // We only handle netmasks in format "IP/PrefixLength".
        throw new NotSupportedException("Only SubNetMasks with a given prefix length are supported.");
    }

    // First parse the address of the netmask before the prefix length.
    var maskAddress = IPAddress.Parse(subnetMask.Substring(0, slashIdx));

    if (maskAddress.AddressFamily != address.AddressFamily)
    { // We got something like an IPV4-Address for an IPv6-Mask. This is not valid.
        return false;
    }

    // Now find out how long the prefix is.
    int maskLength = int.Parse(subnetMask.Substring(slashIdx + 1));

    if (maskLength == 0)
    {
        return true;
    }

    if (maskLength < 0)
    {
        throw new NotSupportedException("A Subnetmask should not be less than 0.");
    }

    if (maskAddress.AddressFamily == AddressFamily.InterNetwork)
    {
        // Convert the mask address to an unsigned integer.
        var maskAddressBits = BitConverter.ToUInt32(maskAddress.GetAddressBytes().Reverse().ToArray(), 0);

        // And convert the IpAddress to an unsigned integer.
        var ipAddressBits = BitConverter.ToUInt32(address.GetAddressBytes().Reverse().ToArray(), 0);

        // Get the mask/network address as unsigned integer.
        uint mask = uint.MaxValue << (32 - maskLength);

        // https://dev59.com/VXI_5IYBdhLWcg3wK_s6#1499284
        // Bitwise AND mask and MaskAddress, this should be the same as mask and IpAddress
        // as the end of the mask is 0000 which leads to both addresses to end with 0000
        // and to start with the prefix.
        return (maskAddressBits & mask) == (ipAddressBits & mask);
    }

    if (maskAddress.AddressFamily == AddressFamily.InterNetworkV6)
    {
        // Convert the mask address to a BitArray. Reverse the BitArray to compare the bits of each byte in the right order.
        var maskAddressBits = new BitArray(maskAddress.GetAddressBytes().Reverse().ToArray());

        // And convert the IpAddress to a BitArray. Reverse the BitArray to compare the bits of each byte in the right order.
        var ipAddressBits = new BitArray(address.GetAddressBytes().Reverse().ToArray());
        var ipAddressLength = ipAddressBits.Length;

        if (maskAddressBits.Length != ipAddressBits.Length)
        {
            throw new ArgumentException("Length of IP Address and Subnet Mask do not match.");
        }

        // Compare the prefix bits.
        for (var i = ipAddressLength - 1; i >= ipAddressLength - maskLength; i--)
        {
            if (ipAddressBits[i] != maskAddressBits[i])
            {
                return false;
            }
        }

        return true;
    }

    throw new NotSupportedException("Only InterNetworkV6 or InterNetwork address families are supported.");
}

这是我用XUnit测试它的结果:

public class IpAddressExtensionsTests
{
    [Theory]
    [InlineData("192.168.5.85/24", "192.168.5.1")]
    [InlineData("192.168.5.85/24", "192.168.5.254")]
    [InlineData("10.128.240.50/30", "10.128.240.48")]
    [InlineData("10.128.240.50/30", "10.128.240.49")]
    [InlineData("10.128.240.50/30", "10.128.240.50")]
    [InlineData("10.128.240.50/30", "10.128.240.51")]
    [InlineData("192.168.5.85/0", "0.0.0.0")]
    [InlineData("192.168.5.85/0", "255.255.255.255")]
    public void IpV4SubnetMaskMatchesValidIpAddress(string netMask, string ipAddress)
    {
        var ipAddressObj = IPAddress.Parse(ipAddress);
        Assert.True(ipAddressObj.IsInSubnet(netMask));
    }

    [Theory]
    [InlineData("192.168.5.85/24", "192.168.4.254")]
    [InlineData("192.168.5.85/24", "191.168.5.254")]
    [InlineData("10.128.240.50/30", "10.128.240.47")]
    [InlineData("10.128.240.50/30", "10.128.240.52")]
    [InlineData("10.128.240.50/30", "10.128.239.50")]
    [InlineData("10.128.240.50/30", "10.127.240.51")]
    public void IpV4SubnetMaskDoesNotMatchInvalidIpAddress(string netMask, string ipAddress)
    {
        var ipAddressObj = IPAddress.Parse(ipAddress);
        Assert.False(ipAddressObj.IsInSubnet(netMask));
    }

    [Theory]
    [InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0012:0000:0000:0000:0000")]
    [InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0012:FFFF:FFFF:FFFF:FFFF")]
    [InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0012:0001:0000:0000:0000")]
    [InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0012:FFFF:FFFF:FFFF:FFF0")]
    [InlineData("2001:db8:abcd:0012::0/128", "2001:0DB8:ABCD:0012:0000:0000:0000:0000")]
    [InlineData("2001:db8:abcd:5678::0/53", "2001:0db8:abcd:5000:0000:0000:0000:0000")]
    [InlineData("2001:db8:abcd:5678::0/53", "2001:0db8:abcd:57ff:ffff:ffff:ffff:ffff")]
    [InlineData("2001:db8:abcd:0012::0/0", "::")]
    [InlineData("2001:db8:abcd:0012::0/0", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")]
    public void IpV6SubnetMaskMatchesValidIpAddress(string netMask, string ipAddress)
    {
        var ipAddressObj = IPAddress.Parse(ipAddress);
        Assert.True(ipAddressObj.IsInSubnet(netMask));
    }

    [Theory]
    [InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0011:FFFF:FFFF:FFFF:FFFF")]
    [InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0013:0000:0000:0000:0000")]
    [InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0013:0001:0000:0000:0000")]
    [InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0011:FFFF:FFFF:FFFF:FFF0")]
    [InlineData("2001:db8:abcd:0012::0/128", "2001:0DB8:ABCD:0012:0000:0000:0000:0001")]
    [InlineData("2001:db8:abcd:5678::0/53", "2001:0db8:abcd:4999:0000:0000:0000:0000")]
    [InlineData("2001:db8:abcd:5678::0/53", "2001:0db8:abcd:5800:0000:0000:0000:0000")]
    public void IpV6SubnetMaskDoesNotMatchInvalidIpAddress(string netMask, string ipAddress)
    {
        var ipAddressObj = IPAddress.Parse(ipAddress);
        Assert.False(ipAddressObj.IsInSubnet(netMask));
    }
}

作为测试的基础,我使用了思科子网划分示例IBM的IPv6地址示例

希望对某些人有所帮助;)


谢谢。有一件事我想指出来。你的v6比较在掩码长度为0的情况下返回true,而v4比较在掩码长度为0的情况下返回false。在v6的情况下,你应该加入一个0掩码长度检查。 - Ankit Aggarwal
1
注意,IPv6的代码对于不是8的倍数的前缀无法正常工作!构造的BitArray中的字节按正确顺序排列,但其中的位被反转,导致for循环首先比较每个字节的较低位,这是错误的,但当前缀对齐在一个字节上时仍然有效。提供的测试未涵盖此问题! - R. V.
1
正确的方法是在将字节传递给BitArray构造函数之前首先反转它们 - .GetAddressBytes().Reverse().ToArray() 然后向后遍历BitArrayfor 循环,像这样:for (int i = ipAddressBits.Length - 1; i >= ipAddressBits.Length - maskLength; i--) - R. V.
很好的发现@R.V.,非常感谢!我调整了代码和测试来涵盖您描述的情况。我还添加了一个检查掩码长度至少为1,以捕获Ankit所描述的内容。您能否快速看一下现在是否按预期工作?谢谢! - Christoph Sonntag
在更多的思考后,掩码长度为0实际上应该返回true,因为它应该匹配所有IP地址 - 因此我已经更改了它,并且现在如果掩码长度小于0,就会抛出异常 ;) - Christoph Sonntag
显示剩余3条评论

20

位操作是有效的。将IP地址和子网地址都存入32位的无符号整数中,然后使用0xFFFFFFFF << (32-20)进行掩码处理,并进行比较:

unsigned int net = ..., ip = ...;
int network_bits = 20;
unsigned int mask = 0xFFFFFFFF << (32 - network_bits);
if ((net & mask) == (ip & mask)) {
  // ...
}

1
或者,如果像常见的那样,子网以像255.255.240.0这样的数字给出,只需将掩码填入32位整数中,而不是移位。 - erikkallen
4
我发现 System.Net.IPAddress 类在解析和分解 IP 地址为字节方面非常有帮助。 - Ryan Michela
@RyanMichela 一行C#代码总是比一个库更快、更小。 - AaA
1
这是IPv4部分实现的良好基础,我在我的回答中添加了与IPv6和IPv4一起工作的内容 - 如果您能够审查它,那将是很棒的,因为我不太擅长二进制操作 ;) - Christoph Sonntag

4

由于 MSDN 博客代码依赖广播,而 IPv6 没有广播,我不知道它是否支持 IPv6。

最终我采用了以下方法(感谢 nu everest)。你可以从 CIDR 表示法(“1.2.3.4/5”)中获取子网和掩码,并检查地址是否在此网络内。

这适用于 IPv4 和 IPv6:

public static class IpAddresses
{
    public static Tuple<IPAddress, IPAddress> GetSubnetAndMaskFromCidr(string cidr)
    {
        var delimiterIndex = cidr.IndexOf('/');
        string ipSubnet = cidr.Substring(0, delimiterIndex);
        string mask = cidr.Substring(delimiterIndex + 1);

        var subnetAddress = IPAddress.Parse(ipSubnet);

        if (subnetAddress.AddressFamily == AddressFamily.InterNetworkV6)
        {
            // ipv6
            var ip = BigInteger.Parse("00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", NumberStyles.HexNumber) << (128 - int.Parse(mask));

            var maskBytes = new[]
            {
                (byte)((ip & BigInteger.Parse("00FF000000000000000000000000000000", NumberStyles.HexNumber)) >> 120),
                (byte)((ip & BigInteger.Parse("0000FF0000000000000000000000000000", NumberStyles.HexNumber)) >> 112),
                (byte)((ip & BigInteger.Parse("000000FF00000000000000000000000000", NumberStyles.HexNumber)) >> 104),
                (byte)((ip & BigInteger.Parse("00000000FF000000000000000000000000", NumberStyles.HexNumber)) >> 96),
                (byte)((ip & BigInteger.Parse("0000000000FF0000000000000000000000", NumberStyles.HexNumber)) >> 88),
                (byte)((ip & BigInteger.Parse("000000000000FF00000000000000000000", NumberStyles.HexNumber)) >> 80),
                (byte)((ip & BigInteger.Parse("00000000000000FF000000000000000000", NumberStyles.HexNumber)) >> 72),
                (byte)((ip & BigInteger.Parse("0000000000000000FF0000000000000000", NumberStyles.HexNumber)) >> 64),
                (byte)((ip & BigInteger.Parse("000000000000000000FF00000000000000", NumberStyles.HexNumber)) >> 56),
                (byte)((ip & BigInteger.Parse("00000000000000000000FF000000000000", NumberStyles.HexNumber)) >> 48),
                (byte)((ip & BigInteger.Parse("0000000000000000000000FF0000000000", NumberStyles.HexNumber)) >> 40),
                (byte)((ip & BigInteger.Parse("000000000000000000000000FF00000000", NumberStyles.HexNumber)) >> 32),
                (byte)((ip & BigInteger.Parse("00000000000000000000000000FF000000", NumberStyles.HexNumber)) >> 24),
                (byte)((ip & BigInteger.Parse("0000000000000000000000000000FF0000", NumberStyles.HexNumber)) >> 16),
                (byte)((ip & BigInteger.Parse("000000000000000000000000000000FF00", NumberStyles.HexNumber)) >> 8),
                (byte)((ip & BigInteger.Parse("00000000000000000000000000000000FF", NumberStyles.HexNumber)) >> 0),
            };

            return Tuple.Create(subnetAddress, new IPAddress(maskBytes));
        }
        else
        {
            // ipv4
            uint ip = 0xFFFFFFFF << (32 - int.Parse(mask));

            var maskBytes = new[]
            {
                (byte)((ip & 0xFF000000) >> 24),
                (byte)((ip & 0x00FF0000) >> 16),
                (byte)((ip & 0x0000FF00) >> 8),
                (byte)((ip & 0x000000FF) >> 0),
            };

            return Tuple.Create(subnetAddress, new IPAddress(maskBytes));
        }
    }

    public static bool IsAddressOnSubnet(IPAddress address, IPAddress subnet, IPAddress mask)
    {
        byte[] addressOctets = address.GetAddressBytes();
        byte[] subnetOctets = mask.GetAddressBytes();
        byte[] networkOctets = subnet.GetAddressBytes();

        // ensure that IPv4 isn't mixed with IPv6
        if (addressOctets.Length != subnetOctets.Length
            || addressOctets.Length != networkOctets.Length)
        {
            return false;
        }

        for (int i = 0; i < addressOctets.Length; i += 1)
        {
            var addressOctet = addressOctets[i];
            var subnetOctet = subnetOctets[i];
            var networkOctet = networkOctets[i];

            if (networkOctet != (addressOctet & subnetOctet))
            {
                return false;
            }
        }
        return true;
    }
}

示例用法:

var subnetAndMask = IpAddresses.GetSubnetAndMaskFromCidr("10.132.0.0/20");
bool result = IpAddresses.IsAddressOnSubnet(
    IPAddress.Parse("10.132.12.34"),
    subnetAndMask.Item1,
    subnetAndMask.Item2);

我觉得,在你的解决方案中,我发现了一种例外情况。当子网位等于23时,“IsAddressOnSubnet”返回错误的结果。我将 if 行更改为 if ((networkOctet & subnetOctet) != (addressOctet & subnetOctet)),这样它就开始返回正确的结果了。 - Sukru Alatas

2
我来晚了,但有类似的需要,并组合了一个快速的包来做到这一点。

https://www.nuget.org/packages/IpMatcher/

and source:

https://github.com/jchristn/IpMatcher

简单使用:
using IpMatcher;

Matcher matcher = new Matcher();
matcher.Add("192.168.1.0", "255.255.255.0");
matcher.Add("192.168.2.0", "255.255.255.0");
matcher.Remove("192.168.2.0");
matcher.Exists("192.168.1.0", "255.255.255.0");  // true
matcher.Match("192.168.1.34"); // true
matcher.Match("10.10.10.10");  // false

2

解决方案是使用 System.Net.IPAddress 将 IP 地址转换为字节,并对地址、子网和掩码八位进行按位比较。

二进制 AND 运算符 & 如果在两个操作数中都存在,则将一个位复制到结果中。

代码:

using System.Net;   // Used to access IPAddress

bool IsAddressOnSubnet(string address, string subnet, string mask)
{
    try
    {
        IPAddress Address = IPAddress.Parse(address);
        IPAddress Subnet = IPAddress.Parse(subnet);
        IPAddress Mask = IPAddress.Parse(mask);            

        Byte[] addressOctets = Address.GetAddressBytes();
        Byte[] subnetOctets = Mask.GetAddressBytes();
        Byte[] networkOctets = Subnet.GetAddressBytes();

        return
            ((networkOctets[0] & subnetOctets[0]) == (addressOctets[0] & subnetOctets[0])) &&
            ((networkOctets[1] & subnetOctets[1]) == (addressOctets[1] & subnetOctets[1])) &&
            ((networkOctets[2] & subnetOctets[2]) == (addressOctets[2] & subnetOctets[2])) &&
            ((networkOctets[3] & subnetOctets[3]) == (addressOctets[3] & subnetOctets[3]));
    }
    catch (System.Exception ex)
    {
        return false;                
    }
}

特别感谢参考资料


1
请注意,如果遇到IPv6地址,此代码将无法正常运行。 - Fowl

2
如果您正在使用ASP.NET Core,那么有一个新的类IPNetwork可用于测试IP地址是否在特定网络中。请注意保留HTML标签。

0
我还创建了一个类,用于计算网络和广播地址,并检查IP是否既不是广播地址也不是网络地址。
private static IPValidationFailedReason PerformIPRangeValidation(string ipAddress, string subnetMask)
        {
            IPValidationFailedReason ipValidationType = IPValidationFailedReason.None;
            string networkaddress = string.Empty;
            string broadcastAddress = string.Empty;
            string networkAddressBinary = string.Empty;
            string broadcastAddressBinary = string.Empty;
            int zerosCountInSubnetMask = 0;

            Array.ForEach(subnetMask.Split(SplitterChar), (eachOctet) => Array.ForEach(IPInterfaceHelper.GetOctetWithPadding(eachOctet).Where(c => c == CharZero).ToArray(), (k) => zerosCountInSubnetMask++));

            if (zerosCountInSubnetMask == 0)
            {
                return ipValidationType;
            }

            string ipAddressBinary = IPInterfaceHelper.ToBinary(ipAddress);
            networkAddressBinary = GetNetworkAddressInBinaryFormat(zerosCountInSubnetMask, ipAddressBinary);
            broadcastAddressBinary = GetBroadcastAddressInBinaryFormat(zerosCountInSubnetMask, ipAddressBinary);

            networkaddress = ToIPFromBinary(networkAddressBinary);
            broadcastAddress = ToIPFromBinary(broadcastAddressBinary);

            if (ipAddress == networkaddress)
            {
                ipValidationType = IPValidationFailedReason.NetworkAddressZero;
                return ipValidationType;
            }
            if (ipAddress == broadcastAddress)
            {
                ipValidationType = IPValidationFailedReason.BroadcastAddressNotPermiited;
                return ipValidationType;
            }

            return ipValidationType;
        }


private static string GetNetworkAddressInBinaryFormat(int zeroCountInSubnetMask, string ipAddressBinary)
    {
        string networkAddressBinary = string.Empty;
        int countOfOnesInSubnetMask = TotalBitCount - zeroCountInSubnetMask;
        StringBuilder sb = new StringBuilder(ipAddressBinary);
        //When Subnet is like 255.255.255.0
        if (zeroCountInSubnetMask >= 1 && zeroCountInSubnetMask <= 8)
        {
            networkAddressBinary = sb.Replace(CharOne, CharZero, countOfOnesInSubnetMask + 3, zeroCountInSubnetMask).ToString();
        }
        //When Subnet is like 255.255.0.0
        if (zeroCountInSubnetMask > 8 && zeroCountInSubnetMask <= 16)
        {
            networkAddressBinary = sb.Replace(CharOne, CharZero, countOfOnesInSubnetMask + 2, zeroCountInSubnetMask + 1).ToString();
        }
        //When Subnet is like 255.0.0.0
        if (zeroCountInSubnetMask > 16 && zeroCountInSubnetMask <= 24)
        {
            networkAddressBinary = sb.Replace(CharOne, CharZero, countOfOnesInSubnetMask + 1, zeroCountInSubnetMask + 2).ToString();
        }
        //When Subnet is like 128.0.0.0
        if (zeroCountInSubnetMask > 24 && zeroCountInSubnetMask < 32)
        {
            networkAddressBinary = sb.Replace(CharOne, CharZero, countOfOnesInSubnetMask , zeroCountInSubnetMask + 3).ToString();
        }
        return networkAddressBinary;
    }


 private static string GetBroadcastAddressInBinaryFormat(int zeroCountInSubnetMask, string ipAddressBinary)
    {
        string broadcastAddressBinary = string.Empty;
        int countOfOnesInSubnetMask = TotalBitCount - zeroCountInSubnetMask;
        StringBuilder sb = new StringBuilder(ipAddressBinary);
        //When Subnet is like 255.255.255.0
        if (zeroCountInSubnetMask >= 1 && zeroCountInSubnetMask <= 8)
        {
            broadcastAddressBinary = sb.Replace(CharZero, CharOne, countOfOnesInSubnetMask + 3, zeroCountInSubnetMask).ToString();
        }
        //When Subnet is like 255.255.0.0
        if (zeroCountInSubnetMask > 8 && zeroCountInSubnetMask <= 16)
        {
            broadcastAddressBinary = sb.Replace(CharZero, CharOne, countOfOnesInSubnetMask + 2, zeroCountInSubnetMask + 1).ToString();
        }
        //When Subnet is like 255.0.0.0
        if (zeroCountInSubnetMask > 16 && zeroCountInSubnetMask <= 24)
        {
            broadcastAddressBinary = sb.Replace(CharZero, CharOne, countOfOnesInSubnetMask + 1, zeroCountInSubnetMask + 2).ToString();
        }
        //When Subnet is like 128.0.0.0
        if (zeroCountInSubnetMask > 24 && zeroCountInSubnetMask < 32)
        {
            broadcastAddressBinary = sb.Replace(CharZero, CharOne, countOfOnesInSubnetMask , zeroCountInSubnetMask + 3).ToString();
        }
        return broadcastAddressBinary;
    }

private static string ToIPFromBinary(string ipAddressBinary)
        {
            string addrTemp = string.Empty;
            string[] networkAddressBinaryOctets = ipAddressBinary.Split(SplitterChar);
            foreach (var eachOctet in networkAddressBinaryOctets)
            {
                string temp = Convert.ToUInt32(eachOctet, 2).ToString(CultureInfo.InvariantCulture);
                addrTemp += temp + SplitterChar;
            }
            // remove last '.'
            string ipAddress = addrTemp.Substring(0, addrTemp.Length - 1);
            return ipAddress;
        }

0
对于要求支持IPv6的评论,我稍作修正克里斯·肖特的回答。
public static IPAddress GetNetworkAddress(this IPAddress address, IPAddress subnetMask)
        {
            byte[] ipAdressBytes = address.GetAddressBytes();
            byte[] subnetMaskBytes = subnetMask.GetAddressBytes();

            if (ipAdressBytes.Length != subnetMaskBytes.Length)
                subnetMaskBytes = subnetMask.MapToIPv6().GetAddressBytes();

            byte[] broadcastAddress = new byte[ipAdressBytes.Length];
            for (int i = 0; i < broadcastAddress.Length; i++)
            {
                broadcastAddress[i] = (byte)(ipAdressBytes[i] & (subnetMaskBytes[i]));
            }
            return new IPAddress(broadcastAddress);
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接