/// <summary> /// Creates a range from a base address and mask bits. /// This can also be used with <see cref="SubnetMaskLength"/> to create a /// range based on a subnet mask. /// </summary> /// <param name="baseAddress"></param> /// <param name="maskLength"></param> public IPAddressRange(IPAddress baseAddress, int maskLength) { if (baseAddress == null) { throw new ArgumentNullException(nameof(baseAddress)); } var baseAdrBytes = baseAddress.GetAddressBytes(); if (baseAdrBytes.Length * 8 < maskLength) { throw new FormatException(); } var maskBytes = Bits.GetBitMask(baseAdrBytes.Length, maskLength); baseAdrBytes = Bits.And(baseAdrBytes, maskBytes); Begin = new IPAddress(baseAdrBytes); End = new IPAddress(Bits.Or(baseAdrBytes, Bits.Not(maskBytes))); }
public static IPAddressRange Parse(string ipRangeString) { if (ipRangeString == null) { throw new ArgumentNullException(nameof(ipRangeString)); } // trim white spaces. ipRangeString = ipRangeString.Trim(); // define local funtion to strip scope id in ip address string. string stripScopeId(string ipaddressString) => ipaddressString.Split('%')[0]; // Pattern 1. CIDR range: "192.168.0.0/24", "fe80::/10%eth0" var m1 = m1_regex.Match(ipRangeString); if (m1.Success) { var baseAdrBytes = IPAddress.Parse(stripScopeId(m1.Groups["adr"].Value)).GetAddressBytes(); var maskLen = int.Parse(m1.Groups["maskLen"].Value); if (baseAdrBytes.Length * 8 < maskLen) { throw new FormatException(); } var maskBytes = Bits.GetBitMask(baseAdrBytes.Length, maskLen); baseAdrBytes = Bits.And(baseAdrBytes, maskBytes); return(new IPAddressRange(new IPAddress(baseAdrBytes), new IPAddress(Bits.Or(baseAdrBytes, Bits.Not(maskBytes))))); } // Pattern 2. Uni address: "127.0.0.1", ":;1" var m2 = m2_regex.Match(ipRangeString); if (m2.Success) { return(new IPAddressRange(IPAddress.Parse(stripScopeId(ipRangeString)))); } // Pattern 3. Begin end range: "169.254.0.0-169.254.0.255" var m3 = m3_regex.Match(ipRangeString); if (m3.Success) { // if the left part contains dot, but the right one does not, we treat it as a shortuct notation // and simply copy the part before last dot from the left part as the prefix to the right one var begin = m3.Groups["begin"].Value; var end = m3.Groups["end"].Value; if (begin.Contains('.') && !end.Contains('.')) { if (end.Contains('%')) { throw new FormatException("The end of IPv4 range shortcut notation contains scope id."); } var lastDotAt = begin.LastIndexOf('.'); end = begin.Substring(0, lastDotAt + 1) + end; } return(new IPAddressRange( begin: IPAddress.Parse(stripScopeId(begin)), end: IPAddress.Parse(stripScopeId(end)))); } // Pattern 4. Bit mask range: "192.168.0.0/255.255.255.0" var m4 = m4_regex.Match(ipRangeString); if (m4.Success) { var baseAdrBytes = IPAddress.Parse(stripScopeId(m4.Groups["adr"].Value)).GetAddressBytes(); var maskBytes = IPAddress.Parse(m4.Groups["bitmask"].Value).GetAddressBytes(); baseAdrBytes = Bits.And(baseAdrBytes, maskBytes); return(new IPAddressRange(new IPAddress(baseAdrBytes), new IPAddress(Bits.Or(baseAdrBytes, Bits.Not(maskBytes))))); } throw new FormatException("Unknown IP range string."); }