public static List <IPNetwork <TAddress> > RangeToSubnets <TAddress>(TAddress endOne, TAddress endTwo, Func <TAddress, int, IPNetwork <TAddress> > createCidr) where TAddress : struct, IIPAddress <TAddress> { var ret = new List <IPNetwork <TAddress> >(); TAddress firstAddress = CalcIPUtils.MinAny(endOne, endTwo); TAddress lastAddress = CalcIPUtils.MaxAny(endOne, endTwo); IPNetwork <TAddress> currentSubnet = createCidr(firstAddress, lastAddress.Bytes.Length * 8); while (firstAddress.CompareTo(lastAddress) <= 0) { // try enlarging the subnet IPNetwork <TAddress> largerSubnet = createCidr(firstAddress, currentSubnet.CidrPrefix.Value - 1); if (!largerSubnet.BaseAddress.Equals(firstAddress) || largerSubnet.LastAddressOfSubnet.CompareTo(lastAddress) > 0) { // we've gone beyond; store what we have and continue with the next chunk ret.Add(currentSubnet); firstAddress = currentSubnet.LastAddressOfSubnet.Add(1); currentSubnet = createCidr(firstAddress, lastAddress.Bytes.Length * 8); } else { // anchor the growth and continue currentSubnet = largerSubnet; } } return(ret); }
public static List <IPNetwork <TAddress> > ResizeNetwork <TAddress>(IPNetwork <TAddress> initialNet, TAddress newSubnetMask, Func <TAddress, TAddress, IPNetwork <TAddress> > createSubnet, out int netComparison) where TAddress : struct, IIPAddress <TAddress> { int initialHostBits = initialNet.CiscoWildcard.Bytes.Sum(b => CalcIPUtils.BytePopCount[b]); int newNetBits = newSubnetMask.Bytes.Sum(b => CalcIPUtils.BytePopCount[b]); int newHostBits = newSubnetMask.BitwiseNot().Bytes.Sum(b => CalcIPUtils.BytePopCount[b]); if (newHostBits > initialHostBits) { // supernet netComparison = -1; TAddress unraveledInitialBaseAddress = CalcIPUtils.UnravelAddress(initialNet.BaseAddress, initialNet.SubnetMask); IPNetwork <TAddress> unraveledShortenedNet = createSubnet(unraveledInitialBaseAddress, newSubnetMask.SubnetMaskFromCidrPrefix(newNetBits)); TAddress wovenNewBaseAddress = CalcIPUtils.WeaveAddress(unraveledShortenedNet.BaseAddress, newSubnetMask); var newNet = createSubnet(wovenNewBaseAddress, newSubnetMask); return(new List <IPNetwork <TAddress> > { newNet }); } else if (newHostBits == initialHostBits) { // samenet netComparison = 0; TAddress unraveledBaseAddress = CalcIPUtils.UnravelAddress(initialNet.BaseAddress, initialNet.SubnetMask); TAddress wovenNewBaseAddress = CalcIPUtils.WeaveAddress(unraveledBaseAddress, newSubnetMask); var newNet = createSubnet(wovenNewBaseAddress, newSubnetMask); return(new List <IPNetwork <TAddress> > { newNet }); } else { // subnet(s) netComparison = 1; TAddress unraveledBaseAddress = CalcIPUtils.UnravelAddress(initialNet.BaseAddress, initialNet.SubnetMask); TAddress unraveledLastAddress = CalcIPUtils.UnravelAddress(initialNet.LastAddressOfSubnet, initialNet.SubnetMask); var ret = new List <IPNetwork <TAddress> >(); TAddress currentUnraveledBaseAddress = unraveledBaseAddress; while (currentUnraveledBaseAddress.CompareTo(unraveledLastAddress) <= 0) { TAddress wovenNewBaseAddress = CalcIPUtils.WeaveAddress(currentUnraveledBaseAddress, newSubnetMask); var newNet = createSubnet(wovenNewBaseAddress, newSubnetMask); ret.Add(newNet); currentUnraveledBaseAddress = newNet.NextSubnetBaseAddress; } return(ret); } }
public IPNetwork(TAddress address, TAddress subnetMask) { // calculate base address by ANDing address with subnet mask TAddress baseAddress = address.BitwiseAnd(subnetMask); BaseAddress = baseAddress; SubnetMask = subnetMask; CidrPrefix = CalcIPUtils.CidrPrefixFromSubnetMaskBytes(subnetMask.Bytes); }
public static TAddress UnravelAddress <TAddress>(TAddress address, TAddress subnetMask) where TAddress : struct, IIPAddress <TAddress> { if (CalcIPUtils.CidrPrefixFromSubnetMaskBytes(subnetMask.Bytes).HasValue) { // nothing to unravel :) return(address); } // given an address ABCDEFGH with subnet mask 11001001, turn it into ABEHCDFG (i.e. with subnet mask 11110000) byte[] addressBytes = address.Bytes; byte[] maskBytes = subnetMask.Bytes; var netBits = new List <bool>(addressBytes.Length); var hostBits = new List <bool>(addressBytes.Length); // find the bits for (int i = 0; i < addressBytes.Length; ++i) { for (int bit = 7; bit >= 0; --bit) { bool addressBit = ((addressBytes[i] & (1 << bit)) != 0); bool isNet = ((maskBytes[i] & (1 << bit)) != 0); if (isNet) { netBits.Add(addressBit); } else { hostBits.Add(addressBit); } } } var unraveledBits = new List <bool>(netBits.Count + hostBits.Count); unraveledBits.AddRange(netBits); unraveledBits.AddRange(hostBits); var retBytes = new byte[addressBytes.Length]; for (int i = 0; i < retBytes.Length; ++i) { byte b = 0; for (int bit = 0; bit < 8; ++bit) { if (unraveledBits[8 * i + bit]) { b |= (byte)(1 << (7 - bit)); } } retBytes[i] = b; } return(address.MaybeFromBytes(retBytes).Value); }
private static void OutputBinaryIPv6Address(IPv6Address addr, IPv6Address?subnetMask = null, ConsoleColor?overrideColor = null) { ushort[] chunks = addr.Chunks; ushort[] maskChunks = subnetMask?.Chunks; for (int i = 0; i < chunks.Length; ++i) { ushort b = chunks[i]; ushort?m = maskChunks?[i]; string bits = CalcIPUtils.UInt16ToBinary(b); string maskBits = m.HasValue ? CalcIPUtils.UInt16ToBinary(m.Value) : null; if (overrideColor.HasValue) { // simply output the address Console.ForegroundColor = overrideColor.Value; Console.Write(bits); } else if (maskBits == null) { // simple output here too Console.ForegroundColor = Color.HostBits; Console.Write(bits); } else { // we must differentiate for (int bit = 0; bit < 16; ++bit) { // assign color if (maskBits != null && maskBits[bit] == '1') { Console.ForegroundColor = Color.NetBits; } else { Console.ForegroundColor = Color.HostBits; } Console.Write(bits[bit]); } } if (i < chunks.Length - 1) { // add separator (colon) Console.ForegroundColor = Color.AddressSeparator; Console.Write(':'); } } }
public static IEnumerable <TAddress> EnumerateNetwork <TAddress>(IPNetwork <TAddress> network) where TAddress : struct, IIPAddress <TAddress> { BigInteger hostCount = network.HostCount; TAddress currentAddress = CalcIPUtils.UnravelAddress(network.BaseAddress, network.SubnetMask); for (BigInteger i = BigInteger.Zero; i < hostCount; ++i) { yield return(CalcIPUtils.WeaveAddress(currentAddress, network.SubnetMask)); currentAddress = currentAddress.Add(1); } }
private static void OutputBinaryIPv4Address(IPv4Address addr, IPv4Address?subnetMask = null, bool colorClass = false, ConsoleColor?overrideColor = null) { byte[] bytes = addr.Bytes; byte[] maskBytes = subnetMask?.Bytes; for (int i = 0; i < bytes.Length; ++i) { byte b = bytes[i]; byte?m = maskBytes?[i]; string bits = CalcIPUtils.ByteToBinary(b); string maskBits = m.HasValue ? CalcIPUtils.ByteToBinary(m.Value) : null; if (overrideColor.HasValue) { // simply output the address Console.ForegroundColor = overrideColor.Value; Console.Write(bits); } else if (maskBits == null) { // simple output here too Console.ForegroundColor = Color.HostBits; Console.Write(bits); } else { // we must differentiate if (i == 0 && colorClass) { // check if this is a classful network if (maskBits[0] == '0') { // first bit isn't part of the network colorClass = false; } else if (bits[0] == '1' && maskBits[1] == '0') { // first bit, 1, is part of the network, but second isn't colorClass = false; } else if (bits[1] == '1' && maskBits[2] == '0') { // first two bits, both 1, are part of the network, but third isn't colorClass = false; } else if (bits[2] == '1' && maskBits[3] == '0') { // first three bits, all 1, are part of the network, but fourth isn't colorClass = false; } } for (int bit = 0; bit < 8; ++bit) { // assign color if (maskBits != null && maskBits[bit] == '1') { Console.ForegroundColor = Color.NetBits; } else { Console.ForegroundColor = Color.HostBits; } if (i == 0 && colorClass) { // the old-style class might be relevant if (bit == 0) { Console.ForegroundColor = Color.ClassBits; } else if (bit == 1 && bits[0] == '1') { Console.ForegroundColor = Color.ClassBits; } else if (bit == 2 && bits.StartsWith("11")) { Console.ForegroundColor = Color.ClassBits; } else if (bit == 3 && bits.StartsWith("111")) { Console.ForegroundColor = Color.ClassBits; } } Console.Write(bits[bit]); } } if (i < bytes.Length - 1) { // add separator (dot) Console.ForegroundColor = Color.AddressSeparator; Console.Write('.'); } } }
public static void OutputIPv4Network(IPNetwork <IPv4Address> net, IPv4Address?addr = null) { const int labelWidth = 11; const int addressWidth = 21; ConsoleColor originalColor = Console.ForegroundColor; Action <string, string> outputInitialColumns = (label, address) => { Console.ForegroundColor = Color.Label; Console.Write(CalcIPUtils.PadRightTo(label, labelWidth)); Console.ForegroundColor = Color.IPAddress; Console.Write(CalcIPUtils.PadRightTo(address, addressWidth)); }; if (addr.HasValue) { outputInitialColumns("Address:", addr.ToString()); OutputBinaryIPv4Address(addr.Value, net.SubnetMask); Console.WriteLine(); outputInitialColumns( "Netmask:", net.CidrPrefix.HasValue ? string.Format("{0} = {1}", net.SubnetMask, net.CidrPrefix.Value) : net.SubnetMask.ToString() ); OutputBinaryIPv4Address(net.SubnetMask, overrideColor: Color.MaskBits); Console.WriteLine(); outputInitialColumns("Wildcard:", net.CiscoWildcard.ToString()); OutputBinaryIPv4Address(net.CiscoWildcard); Console.WriteLine(); Console.ForegroundColor = Color.Label; Console.WriteLine("=>"); } outputInitialColumns( "Network:", net.CidrPrefix.HasValue ? string.Format("{0}/{1}", net.BaseAddress, net.CidrPrefix.Value) : net.SubnetMask.ToString() ); OutputBinaryIPv4Address(net.BaseAddress, net.SubnetMask, colorClass: true); Console.WriteLine(); if (net.FirstHostAddress.HasValue) { outputInitialColumns("HostMin:", net.FirstHostAddress.Value.ToString()); OutputBinaryIPv4Address(net.FirstHostAddress.Value); Console.WriteLine(); outputInitialColumns("HostMax:", net.LastHostAddress.Value.ToString()); OutputBinaryIPv4Address(net.LastHostAddress.Value); Console.WriteLine(); } else { Console.ForegroundColor = Color.Label; Console.WriteLine("no hosts"); } if (net.BroadcastAddress.HasValue) { outputInitialColumns("Broadcast:", net.BroadcastAddress.Value.ToString()); OutputBinaryIPv4Address(net.BroadcastAddress.Value); Console.WriteLine(); } else { Console.ForegroundColor = Color.Label; Console.WriteLine("no broadcast"); } if (net.HostCount.CompareTo(0) > 0) { outputInitialColumns("Hosts/Net:", net.HostCount.ToString()); var topBits = CalcIPUtils.ByteToBinary(net.BaseAddress.Bytes[0]); var topMaskBits = CalcIPUtils.ByteToBinary(net.SubnetMask.Bytes[0]); Console.ForegroundColor = Color.ClassBits; if (topBits.StartsWith("0") && topMaskBits.StartsWith("1")) { Console.Write("Class A"); } else if (topBits.StartsWith("10") && topMaskBits.StartsWith("11")) { Console.Write("Class B"); } else if (topBits.StartsWith("110") && topMaskBits.StartsWith("111")) { Console.Write("Class C"); } else if (topMaskBits.StartsWith("1111")) { if (topBits.StartsWith("1110")) { Console.Write("Class D (multicast)"); } else if (topBits.StartsWith("1111")) { Console.Write("Class E (reserved)"); } } Console.WriteLine(); } else { Console.ForegroundColor = Color.Label; Console.WriteLine("no hosts/net"); } Console.ForegroundColor = originalColor; }
public static void OutputIPv6Network(IPNetwork <IPv6Address> net, IPv6Address?addr = null) { const int labelWidth = 11; const int addressWidth = 46; ConsoleColor originalColor = Console.ForegroundColor; Action <string, string> outputInitialColumns = (label, address) => { Console.ForegroundColor = Color.Label; Console.Write(CalcIPUtils.PadRightTo(label, labelWidth)); Console.ForegroundColor = Color.IPAddress; Console.Write(CalcIPUtils.PadRightTo(address, addressWidth)); }; if (addr.HasValue) { outputInitialColumns("Address:", addr.ToString()); OutputBinaryIPv6Address(addr.Value, net.SubnetMask); Console.WriteLine(); outputInitialColumns( "Netmask:", net.CidrPrefix.HasValue ? string.Format("{0} = {1}", net.SubnetMask, net.CidrPrefix.Value) : net.SubnetMask.ToString() ); OutputBinaryIPv6Address(net.SubnetMask, overrideColor: Color.MaskBits); Console.WriteLine(); outputInitialColumns("Wildcard:", net.CiscoWildcard.ToString()); OutputBinaryIPv6Address(net.CiscoWildcard); Console.WriteLine(); Console.ForegroundColor = Color.Label; Console.WriteLine("=>"); } outputInitialColumns( "Network:", net.CidrPrefix.HasValue ? string.Format("{0}/{1}", net.BaseAddress, net.CidrPrefix.Value) : net.SubnetMask.ToString() ); OutputBinaryIPv6Address(net.BaseAddress, net.SubnetMask); Console.WriteLine(); if (net.FirstHostAddress.HasValue) { outputInitialColumns("HostMin:", net.FirstHostAddress.Value.ToString()); OutputBinaryIPv6Address(net.FirstHostAddress.Value); Console.WriteLine(); outputInitialColumns("HostMax:", net.LastHostAddress.Value.ToString()); OutputBinaryIPv6Address(net.LastHostAddress.Value); Console.WriteLine(); } else { Console.ForegroundColor = Color.Label; Console.WriteLine("no hosts"); } if (net.BroadcastAddress.HasValue) { outputInitialColumns("Broadcast:", net.BroadcastAddress.Value.ToString()); OutputBinaryIPv6Address(net.BroadcastAddress.Value); Console.WriteLine(); } else { Console.ForegroundColor = Color.Label; Console.WriteLine("no broadcast"); } if (net.HostCount.CompareTo(0) > 0) { outputInitialColumns("Hosts/Net:", net.HostCount.ToString()); Console.WriteLine(); } else { Console.ForegroundColor = Color.Label; Console.WriteLine("no hosts/net"); } Console.ForegroundColor = originalColor; }
// derivation functions public IPv4Address SubnetMaskFromCidrPrefix(int cidrPrefix) { return(IPv4Address.MaybeFromBytes(CalcIPUtils.SubnetMaskBytesFromCidrPrefix(4, cidrPrefix)).Value); }
public static TAddress WeaveAddress <TAddress>(TAddress address, TAddress subnetMask) where TAddress : struct, IIPAddress <TAddress> { if (CalcIPUtils.CidrPrefixFromSubnetMaskBytes(subnetMask.Bytes).HasValue) { // nothing to weave :) return(address); } // given an address ABCDEFGH with subnet mask 11001001, convert from subnet mask 11110000 turning it into ABEFCGHD byte[] addressBytes = address.Bytes; byte[] maskBytes = subnetMask.Bytes; int cidrPrefix = subnetMask.Bytes.Sum(b => CalcIPUtils.BytePopCount[b]); var netBits = new List <bool>(addressBytes.Length); var hostBits = new List <bool>(addressBytes.Length); var maskBits = new List <bool>(maskBytes.Length); // find the bits for (int i = 0; i < addressBytes.Length; ++i) { for (int bit = 0; bit < 8; ++bit) { int totalBitIndex = 8 * i + bit; bool addressBit = ((addressBytes[i] & (1 << (7 - bit))) != 0); bool isNet = (totalBitIndex < cidrPrefix); if (isNet) { netBits.Add(addressBit); } else { hostBits.Add(addressBit); } bool maskBit = ((maskBytes[i] & (1 << (7 - bit))) != 0); maskBits.Add(maskBit); } } var retBytes = new byte[addressBytes.Length]; int netIndex = 0; int hostIndex = 0; for (int i = 0; i < retBytes.Length; ++i) { byte b = 0; for (int bit = 0; bit < 8; ++bit) { bool shouldSetBit; if (maskBits[8 * i + bit]) { shouldSetBit = netBits[netIndex]; ++netIndex; } else { shouldSetBit = hostBits[hostIndex]; ++hostIndex; } if (shouldSetBit) { b |= (byte)(1 << (7 - bit)); } } retBytes[i] = b; } return(address.MaybeFromBytes(retBytes).Value); }