From 04bd6e5d60b6d26fd3759bc9ebb21a46cbb68909 Mon Sep 17 00:00:00 2001 From: Timothy Small Date: Sat, 16 Mar 2024 15:32:21 -0400 Subject: [PATCH 01/14] Move ParsedNetAddressStringType to Models namespace --- src/Lib/{Enums => Models}/ParsedNetAddressStringType.cs | 2 +- src/Lib/enums/ParsedNetAddressStringType.cs | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) rename src/Lib/{Enums => Models}/ParsedNetAddressStringType.cs (64%) delete mode 100644 src/Lib/enums/ParsedNetAddressStringType.cs diff --git a/src/Lib/Enums/ParsedNetAddressStringType.cs b/src/Lib/Models/ParsedNetAddressStringType.cs similarity index 64% rename from src/Lib/Enums/ParsedNetAddressStringType.cs rename to src/Lib/Models/ParsedNetAddressStringType.cs index ebe9a22..e8ca1e5 100644 --- a/src/Lib/Enums/ParsedNetAddressStringType.cs +++ b/src/Lib/Models/ParsedNetAddressStringType.cs @@ -1,4 +1,4 @@ -namespace SmallsOnline.Subnetting.Lib.Enums; +namespace SmallsOnline.Subnetting.Lib.Models; public enum ParsedNetAddressStringType { diff --git a/src/Lib/enums/ParsedNetAddressStringType.cs b/src/Lib/enums/ParsedNetAddressStringType.cs deleted file mode 100644 index ebe9a22..0000000 --- a/src/Lib/enums/ParsedNetAddressStringType.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace SmallsOnline.Subnetting.Lib.Enums; - -public enum ParsedNetAddressStringType -{ - CidrNotation = 0, - SubnetMask = 1 -} From 627af6bda62498d0d6e99fcb85cc331adc91b497 Mon Sep 17 00:00:00 2001 From: Timothy Small Date: Sat, 16 Mar 2024 15:36:19 -0400 Subject: [PATCH 02/14] Fix cached git files --- src/Lib/models/BinaryNumber.cs | 77 -------- src/Lib/models/BitRepresentation.cs | 59 ------ src/Lib/models/IPv4Subnet.cs | 202 ------------------- src/Lib/models/IPv4SubnetMask.cs | 242 ----------------------- src/Lib/models/IPv4WildcardMask.cs | 47 ----- src/Lib/models/Octet.cs | 63 ------ src/Lib/models/ParsedNetAddressString.cs | 77 -------- src/Lib/models/UsableHostRange.cs | 52 ----- 8 files changed, 819 deletions(-) delete mode 100644 src/Lib/models/BinaryNumber.cs delete mode 100644 src/Lib/models/BitRepresentation.cs delete mode 100644 src/Lib/models/IPv4Subnet.cs delete mode 100644 src/Lib/models/IPv4SubnetMask.cs delete mode 100644 src/Lib/models/IPv4WildcardMask.cs delete mode 100644 src/Lib/models/Octet.cs delete mode 100644 src/Lib/models/ParsedNetAddressString.cs delete mode 100644 src/Lib/models/UsableHostRange.cs diff --git a/src/Lib/models/BinaryNumber.cs b/src/Lib/models/BinaryNumber.cs deleted file mode 100644 index cd9ed73..0000000 --- a/src/Lib/models/BinaryNumber.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System.Collections; - -namespace SmallsOnline.Subnetting.Lib.Models; - -/// -/// A representation of a binary number. -/// -public class BinaryNumber -{ - /// - /// Create from a byte. - /// - /// A byte value. - public BinaryNumber(byte byteItem) - { - List bitValuesList = new(); - - BitArray bitArray = new(new byte[] { byteItem }); - for (int i = bitArray.Length - 1; i >= 0; i--) - { - bitValuesList.Add(new(i, bitArray[i])); - } - - bitValues = bitValuesList.ToArray(); - } - - /// - /// An array of the bits used for the binary number. - /// - public BitRepresentation[] BitValues - { - get => bitValues; - } - - private readonly BitRepresentation[] bitValues; - - /// - /// Get the amount of unused bits. - /// - /// The amount of unused bits. - public int GetUnusedBits() - { - int bitsUnused = 0; - - foreach (BitRepresentation bitItem in bitValues) - { - bitsUnused += bitItem.BitActualValue; - } - - return bitsUnused; - } - - /// - /// Get the amount of used bits. - /// - /// The amount of used bits. - public int GetUsedBits() - { - int bitsUsed = 255; - - foreach (BitRepresentation bitItem in bitValues) - { - bitsUsed -= bitItem.BitActualValue; - } - - return bitsUsed; - } - - /// - /// Return the amount of unused bits as a string. - /// - /// The amount of unused bits. - public override string ToString() - { - return $"{GetUnusedBits()}"; - } -} \ No newline at end of file diff --git a/src/Lib/models/BitRepresentation.cs b/src/Lib/models/BitRepresentation.cs deleted file mode 100644 index 21f12ed..0000000 --- a/src/Lib/models/BitRepresentation.cs +++ /dev/null @@ -1,59 +0,0 @@ -namespace SmallsOnline.Subnetting.Lib.Models; - -/// -/// A representation of a bit. -/// -public class BitRepresentation -{ - /// - /// Create from the position of the bit and if it's on. - /// - /// The position of the bit. - /// The bit is on and used. - public BitRepresentation(int position, bool isOn) - { - bitPosition = position; - bitIsOn = isOn; - } - - /// - /// The position of the bit. - /// - public int BitPosition - { - get => bitPosition; - } - - /// - /// The value of the bit. - /// 2^bitPosition - /// - public int BitValue - { - get => (int)Math.Pow(2, bitPosition); - } - - /// - /// If the bit is on or not. - /// - public bool BitIsOn - { - get => bitIsOn; - } - - /// - /// The actual value of the bit if it's on or not. - /// - public int BitActualValue - { - get => bitIsOn ? BitValue : 0; - } - - private readonly int bitPosition; - private readonly bool bitIsOn; - - public override string ToString() - { - return $"{BitActualValue}"; - } -} diff --git a/src/Lib/models/IPv4Subnet.cs b/src/Lib/models/IPv4Subnet.cs deleted file mode 100644 index 94d1ea8..0000000 --- a/src/Lib/models/IPv4Subnet.cs +++ /dev/null @@ -1,202 +0,0 @@ -using System.Net; -using SmallsOnline.Subnetting.Lib.Enums; - -namespace SmallsOnline.Subnetting.Lib.Models; - -/// -/// A representation of an IPv4 subnet. -/// -public class IPv4Subnet -{ - /// - /// Create from an IP address and CIDR mask. - /// - /// An IP address in a subnet. - /// The CIDR mask for the subnet. - public IPv4Subnet(IPAddress ipAddress, double cidr) - { - _subnetMask = new(cidr); - _networkAddress = GetSubnetBoundary(ipAddress, _subnetMask); - _broadcastAddress = GetBroadcastAddress(_networkAddress, _subnetMask); - _usableHostRange = new(_networkAddress, _broadcastAddress); - } - - /// - /// Create from an IP address and CIDR mask. - /// - /// An IP address in a subnet. - /// The subnet mask. - public IPv4Subnet(IPAddress ipAddress, IPv4SubnetMask subnetMask) - { - _subnetMask = subnetMask; - _networkAddress = GetSubnetBoundary(ipAddress, _subnetMask); - _broadcastAddress = GetBroadcastAddress(_networkAddress, _subnetMask); - _usableHostRange = new(_networkAddress, _broadcastAddress); - } - - /// - /// Create from an IP address and CIDR mask. - /// - /// An IP address in a subnet. - /// The subnet mask. - public IPv4Subnet(IPAddress ipAddress, IPAddress subnetMask) - { - _subnetMask = new(subnetMask.GetAddressBytes()); - _networkAddress = GetSubnetBoundary(ipAddress, _subnetMask); - _broadcastAddress = GetBroadcastAddress(_networkAddress, _subnetMask); - _usableHostRange = new(_networkAddress, _broadcastAddress); - } - - /// - /// Create from a string of a network. - /// For example: - /// 10.21.6.0/18 - /// - /// A network written in a string format. - public IPv4Subnet(string networkString) - { - ParsedNetAddressString parsedNetAddress = new(networkString); - - _subnetMask = parsedNetAddress.ParsedType switch - { - ParsedNetAddressStringType.SubnetMask => new(parsedNetAddress.SubnetMask.GetAddressBytes()), - _ => new(parsedNetAddress.CidrNotation) - }; - - _networkAddress = GetSubnetBoundary(parsedNetAddress.IPAddress, _subnetMask); - _broadcastAddress = GetBroadcastAddress(_networkAddress, _subnetMask); - _usableHostRange = new(_networkAddress, _broadcastAddress); - } - - /// - /// The network address of the subnet. - /// - public IPAddress NetworkAddress - { - get => _networkAddress; - } - - /// - /// The subnet mask of the subnet. - /// - public IPv4SubnetMask SubnetMask - { - get => _subnetMask; - } - - /// - /// The CIDR mask of the subnet. - /// - public double CidrMask - { - get => _subnetMask.CidrNotation; - } - - /// - /// The broadcast address of the subnet. - /// - public IPAddress BroadcastAddress - { - get => _broadcastAddress; - } - - /// - /// The total amount of addresses in the subnet. - /// - public double TotalAddresses - { - get => _subnetMask.TotalAddresses; - } - - /// - /// The total amount of usable addresses in the subnet. - /// - public double UsableAddresses - { - get => _subnetMask.TotalAddresses - 2; - } - - /// - /// The range of hosts available for use in the subnet. - /// - public UsableHostRange UsableHostRange - { - get => _usableHostRange; - } - - private readonly IPAddress _networkAddress; - private readonly IPv4SubnetMask _subnetMask; - private readonly IPAddress _broadcastAddress; - private readonly UsableHostRange _usableHostRange; - - /// - /// Display the subnet as a string. - /// - /// A string representation of the subnet with the network address and CIDR mask. - public override string ToString() - { - return $"{_networkAddress}/{CidrMask}"; - } - - /// - /// Gets the network address of the subnet from the supplied IP address and the subnet mask. - /// - /// The IP address in the subnet. - /// The subnet mask of the subnet. - /// The network address of the subnet. - private static IPAddress GetSubnetBoundary(IPAddress ipAddress, IPv4SubnetMask subnetMask) - { - // Get the byte arrays of the IP address and the subnet mask. - byte[] ipAddressBytes = ipAddress.GetAddressBytes(); - byte[] subnetMaskBytes = subnetMask.ToBytes(); - - // Get the last used octet in the subnet mask. - Octet lastUsedOctet = subnetMask.GetLastUsedOctet(); - - // Create the byte array for generating the network address. - byte[] netAddressBytes = new byte[4]; - for (int i = 0; i < netAddressBytes.Length; i++) - { - if (i < lastUsedOctet.OctetPosition - 1) - { - // If the current loop count is less than the last used octet's position - // then set the current index for the network address to the same value as - // the IP address. - netAddressBytes[i] = ipAddressBytes[i]; - } - else - { - // If the current loop count is less than the last used octet's position - // then set the current index for the network address to the value of a - // bitwise AND operation of the IP address and the subnet mask. - netAddressBytes[i] = ipAddressBytes[i] &= subnetMaskBytes[i]; - } - } - - return new(netAddressBytes); - } - - /// - /// Gets the broadcast address of the subnet. - /// - /// The network address of the subnet. - /// The subnet mask of the subnet. - /// The broadcast address for the subnet. - private static IPAddress GetBroadcastAddress(IPAddress networkAddress, IPv4SubnetMask subnetMask) - { - // Create an empty byte array for the broadcast address. - byte[] broadcastAddressBytes = new byte[4]; - - // Get the bytes for the wildcard subnet mask. - byte[] networkAddressBytes = networkAddress.GetAddressBytes(); - byte[] wildcardBytes = subnetMask.WildcardMask.WildcardBytes; - - // Iterate through each index of the network address bytes and add the amount from the wildcard bytes. - for (int i = 0; i < broadcastAddressBytes.Length; i++) - { - broadcastAddressBytes[i] = (byte)(networkAddressBytes[i] + wildcardBytes[i]); - } - - return new(broadcastAddressBytes); - } -} diff --git a/src/Lib/models/IPv4SubnetMask.cs b/src/Lib/models/IPv4SubnetMask.cs deleted file mode 100644 index de6f76a..0000000 --- a/src/Lib/models/IPv4SubnetMask.cs +++ /dev/null @@ -1,242 +0,0 @@ -using System.Net; - -namespace SmallsOnline.Subnetting.Lib.Models; - -/// -/// A representation of an IPv4 subnet mask. -/// -public class IPv4SubnetMask -{ - /// - /// Create from a CIDR notation. - /// - /// The CIDR notation of the subnet mask. - public IPv4SubnetMask(double cidr) - { - wildcardMask = GetWildcardMask_FromCidr(cidr); - octets = GetSubnetMaskOctets_FromWildcardMask(wildcardMask); - cidrNotation = cidr; - totalAddresses = (int)GetMaxAddresses_FromCidr(cidr); - } - - /// - /// Create from a byte array. - /// - /// The byte array of the subnet mask. - public IPv4SubnetMask(byte[] bytes) - { - octets = GetOctets_FromBytes(bytes); - wildcardMask = new(bytes); - cidrNotation = GetCidrMask_FromSubnetMask(octets); - totalAddresses = (int)GetMaxAddresses_FromCidr(cidrNotation); - } - - /// - /// The octets of the subnet mask. - /// - public Octet[] Octets - { - get => octets; - } - - /// - /// The wildcard mask of the subnet mask. - /// - public IPv4WildcardMask WildcardMask - { - get => wildcardMask; - } - - /// - /// The CIDR notation of the subnet mask. - /// - public double CidrNotation - { - get => cidrNotation; - } - - /// - /// The total amount of addresses available from the subnet mask. - /// - public int TotalAddresses - { - get => totalAddresses; - } - - private readonly Octet[] octets; - private readonly IPv4WildcardMask wildcardMask; - private readonly double cidrNotation; - private readonly int totalAddresses; - - /// - /// Gets the last octet that was borrowed from. - /// - /// The last octet borrowed from. - public Octet GetLastUsedOctet() - { - List octetsList = new(octets); - - Octet lastUsedOctet = octetsList.FindAll((octetItem) => octetItem.BitsUsed == true)[0]; - - return lastUsedOctet; - } - - /// - /// Returns the subnet mask as a byte array. - /// - /// A byte array of the subnet mask. - public byte[] ToBytes() - { - byte[] byteArray = new byte[4]; - for (int i = 0; i < octets.Length; i++) - { - byteArray[i] = (byte)(byte.MinValue + octets[i].ToByte()); - } - - return byteArray; - } - - /// - /// Returns the subnet mask as an IPAddress. - /// - /// An IPAddress type. - public IPAddress ToIPAddress() - { - return new(ToBytes()); - } - - /// - /// Displays the subnet mask as a string. - /// - /// A string representation of the subnet mask. - public override string ToString() - { - return string.Join(".", ToBytes()); - } - - /// - /// Gets the value of the octets for the subnet mask from a byte array. - /// - /// A byte array of the subnet mask. - /// An array of the octets. - private static Octet[] GetOctets_FromBytes(byte[] bytes) - { - Octet[] _octets = new Octet[4]; - for (int i = 0; i < _octets.Length; i++) - { - _octets[i] = new(i + 1, bytes[i]); - } - - return _octets; - } - - /// - /// Calculate the total amount of addresses available from a CIDR notation. - /// - /// The CIDR notation of the subnet mask. - /// The total amount of addresses. - private static double GetMaxAddresses_FromCidr(double cidr) - { - // Get the maximum amount of addresses that can be used. - // Calculated by: 2^(32-cidrNotation) - return Math.Pow(2, GetBitBlock_FromCidr(cidr)); - } - - private static double GetBitBlock_FromCidr(double cidr) - { - return 32 - cidr; - } - - /// - /// Get the wildcard mask of the subnet mask from a CIDR notation. - /// - /// The CIDR notation of the subnet mask. - /// The wildcard mask of the subnet mask. - private static IPv4WildcardMask GetWildcardMask_FromCidr(double cidr) - { - byte[] wildcardByteArray = new byte[4]; - - double maxAddresses = GetMaxAddresses_FromCidr(cidr); - - // Get the amount of bytes filled. - // This is calculated by getting the log of the max addresses from the base of 256 and rounding to the lowest number. - double bytesFilled = Math.Floor(Math.Log(maxAddresses, 256)); - - // Get the amount of bits used. - // This is calculated by: maxAddresses / 256^bytesFilled - double bitsUsed = maxAddresses / Math.Pow(256, bytesFilled); - - // Determine the position to fill the amount of bits used. - int byteArrayPosition = bytesFilled switch - { - 0 => 3, - 1 => 2, - 2 => 1, - 3 => 0, - _ => 0 - }; - - // Set the position in the wildcard byte array to the amount of bits used. - // The value of 'bitsUsed' is subtracted by 1, since a byte is denoted from 0 - 255. - wildcardByteArray[byteArrayPosition] = (byte)(bitsUsed - 1); - - // If needed, fill the remaining bytes to the right of the previously modified byte position. - for (int i = byteArrayPosition + 1; i < wildcardByteArray.Length; i++) - { - wildcardByteArray[i] = byte.MaxValue; - } - - return new(wildcardByteArray, true); - } - - /// - /// Get the octets of a subnet mask from the wildcard mask. - /// - /// The wildcard mask of a subnet mask. - /// An array of octets of the subnet mask. - private static Octet[] GetSubnetMaskOctets_FromWildcardMask(IPv4WildcardMask _wildcardMask) - { - Octet[] _octets = new Octet[4]; - for (int i = _wildcardMask.WildcardBytes.Length - 1; i >= 0; i--) - { - _octets[i] = new(i + 1, (byte)(byte.MaxValue - _wildcardMask.WildcardBytes[i])); - } - - return _octets; - } - - /// - /// Get the CIDR notation from the subnet mask's octets. - /// - /// The octets of the subnet mask. - /// The CIDR notation of the subnet mask. - private static double GetCidrMask_FromSubnetMask(Octet[] _octets) - { - List bitList = new(); - foreach (Octet octetItem in _octets) - { - bitList.AddRange(octetItem.BinaryValue.BitValues); - } - int countOfUsedBits = bitList.FindAll((item) => item.BitIsOn == false).Count; - - return 32 - countOfUsedBits; - } - - /// - /// Calculate the total amount of addresses from the octets of a subnet mask. - /// - /// The octets of the subnet mask. - /// The total amount of addresses. - private static int GetTotalAddresses_FromSubnetMask(Octet _octet) - { - // Note: - // ------ - // This is still bugging out. - // 255.255.255.0 (/24), 255.255.0 (/16), and 255.0.0.0 (/8) are still returning 0. - // Since I've gotten the CIDR notation being calculated already, I've switched to using - // the GetMaxAddresses_FromCidr() method instead. Will keep looking into fixing this. - // ------ - - return (int)(Math.Pow(256, _octet.OctetPosition - 1) * _octet.BinaryValue.GetUnusedBits()); - } -} diff --git a/src/Lib/models/IPv4WildcardMask.cs b/src/Lib/models/IPv4WildcardMask.cs deleted file mode 100644 index 9922ba2..0000000 --- a/src/Lib/models/IPv4WildcardMask.cs +++ /dev/null @@ -1,47 +0,0 @@ -namespace SmallsOnline.Subnetting.Lib.Models; - -/// -/// A representation of the wildcard mask of an IPv4 subnet mask. -/// -public class IPv4WildcardMask -{ - /// - /// Generate the wildcard mask from a byte array. - /// - /// A byte array of a subnet mask or wildcard mask. - /// Whether the input byte array has already been calculated. - public IPv4WildcardMask(byte[] bytes, bool isAlreadyCalculated = false) - { - if (isAlreadyCalculated) - { - wildcardBytes = bytes; - } - else - { - wildcardBytes = new byte[4]; - for (int i = 0; i < bytes.Length; i++) - { - wildcardBytes[i] = (byte)(byte.MaxValue - bytes[i]); - } - } - } - - /// - /// The bytes of the wildcard mask. - /// - public byte[] WildcardBytes - { - get => wildcardBytes; - } - - private readonly byte[] wildcardBytes; - - /// - /// Displays the wildcard mask as a string. - /// - /// A string representation of the wildcard mask. - public override string ToString() - { - return string.Join(".", wildcardBytes); - } -} diff --git a/src/Lib/models/Octet.cs b/src/Lib/models/Octet.cs deleted file mode 100644 index 1dac429..0000000 --- a/src/Lib/models/Octet.cs +++ /dev/null @@ -1,63 +0,0 @@ -namespace SmallsOnline.Subnetting.Lib.Models; - -/// -/// A representation of an octet. -/// -public class Octet -{ - /// - /// Create with the position of the octet and it's byte value. - /// - /// The position of the octet. - /// The byte value of the octet. - public Octet(int position, byte byteItem) - { - octetPosition = position; - binaryValue = new(byteItem); - } - - /// - /// The position of the octet. - /// - public int OctetPosition - { - get => octetPosition; - } - - /// - /// The binary value of the octet. - /// - public BinaryNumber BinaryValue - { - get => binaryValue; - } - - /// - /// If bits have been used. - /// - public bool BitsUsed - { - get => binaryValue.GetUsedBits() > 0; - } - - private readonly int octetPosition; - private readonly BinaryNumber binaryValue; - - /// - /// Return the byte value of the octet. - /// - /// The byte value of the octet. - public byte ToByte() - { - return Convert.ToByte(binaryValue.GetUnusedBits()); - } - - /// - /// Returns the value of the octet as a string. - /// - /// The value of the octet as a string. - public override string ToString() - { - return $"{binaryValue.GetUnusedBits()}"; - } -} diff --git a/src/Lib/models/ParsedNetAddressString.cs b/src/Lib/models/ParsedNetAddressString.cs deleted file mode 100644 index ee1a9fd..0000000 --- a/src/Lib/models/ParsedNetAddressString.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System.Net; -using System.Text.RegularExpressions; -using SmallsOnline.Subnetting.Lib.Enums; - -namespace SmallsOnline.Subnetting.Lib.Models; - -/// -/// A representation of a parsed network address. -/// -public class ParsedNetAddressString -{ - /// - /// Create from a network string. - /// - /// The string of the network. - public ParsedNetAddressString(string netAddressString) - { - Initialize(netAddressString); - } - - /// - /// The parsed IP address. - /// - public IPAddress IPAddress - { - get => _ipAddress; - } - - /// - /// The parsed CIDR notation. - /// - public double CidrNotation - { - get => _cidrNotation; - } - - /// - /// The parsed subnet mask. - /// - public IPAddress SubnetMask - { - get => _subnetMask; - } - - public ParsedNetAddressStringType ParsedType - { - get => _parsedType; - } - - private IPAddress _ipAddress; - private double _cidrNotation; - private IPAddress _subnetMask; - private ParsedNetAddressStringType _parsedType; - - /// - /// Parses the string and sets the properties for the IP address and CIDR notation. - /// - /// The string of the network. - private void Initialize(string netAddressString) - { - Regex netAddressRegex = new(@"^(?'netAddress'(?:\d{1,3}(?:\.|)){4})(?:(?:\/)(?'cidrNotation'\d{1,2})|(?:\/|\s)(?'subnetMask'(?:\d{1,3}(?:\.|)){4}))$"); - Match netAddressMatch = netAddressRegex.Match(netAddressString); - - _ipAddress = IPAddress.Parse(netAddressMatch.Groups["netAddress"].Value); - - if (netAddressMatch.Groups["cidrNotation"].Success) - { - _cidrNotation = Convert.ToDouble(netAddressMatch.Groups["cidrNotation"].Value); - _parsedType = ParsedNetAddressStringType.CidrNotation; - } - else if (netAddressMatch.Groups["subnetMask"].Success) - { - _subnetMask = IPAddress.Parse(netAddressMatch.Groups["subnetMask"].Value); - _parsedType = ParsedNetAddressStringType.SubnetMask; - } - } -} diff --git a/src/Lib/models/UsableHostRange.cs b/src/Lib/models/UsableHostRange.cs deleted file mode 100644 index 17bd3e0..0000000 --- a/src/Lib/models/UsableHostRange.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Net; - -namespace SmallsOnline.Subnetting.Lib.Models; - -/// -/// A representation of the usable host range of a subnet. -/// -public class UsableHostRange -{ - /// - /// Create from the network and broadcast address. - /// - /// The network address of the subnet. - /// The broadcast address of the subnet. - public UsableHostRange(IPAddress netAddress, IPAddress broadcastAddress) - { - Initialize(netAddress, broadcastAddress); - } - - /// - /// The first usable host address in the subnet. - /// - public IPAddress FirstUsableHostAddress - { - get => _firstUsableHostAddress; - } - - /// - /// The last usable host address in the subnet. - /// - public IPAddress LastUsableHostAddress - { - get => _lastUsableHostAddress; - } - - private IPAddress _firstUsableHostAddress; - private IPAddress _lastUsableHostAddress; - - private void Initialize(IPAddress netAddress, IPAddress broadcastAddress) - { - byte[] netAddressBytes = netAddress.GetAddressBytes(); - byte[] broadcastAddressBytes = broadcastAddress.GetAddressBytes(); - - _firstUsableHostAddress = new(new byte[] { netAddressBytes[0], netAddressBytes[1], netAddressBytes[2], (byte)(netAddressBytes[3] + 1) }); - _lastUsableHostAddress = new(new byte[] { broadcastAddressBytes[0], broadcastAddressBytes[1], broadcastAddressBytes[2], (byte)(broadcastAddressBytes[3] - 1) }); - } - - public override string ToString() - { - return $"{_firstUsableHostAddress} - {_lastUsableHostAddress}"; - } -} From 29b80a1ae8c58231aff5898e49b4e56621dfea9e Mon Sep 17 00:00:00 2001 From: Timothy Small Date: Sat, 16 Mar 2024 15:36:51 -0400 Subject: [PATCH 03/14] Remove using statements --- src/Lib/Models/IPv4Subnet.cs | 1 - src/Lib/Models/ParsedNetAddressString.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Lib/Models/IPv4Subnet.cs b/src/Lib/Models/IPv4Subnet.cs index 94d1ea8..93054a5 100644 --- a/src/Lib/Models/IPv4Subnet.cs +++ b/src/Lib/Models/IPv4Subnet.cs @@ -1,5 +1,4 @@ using System.Net; -using SmallsOnline.Subnetting.Lib.Enums; namespace SmallsOnline.Subnetting.Lib.Models; diff --git a/src/Lib/Models/ParsedNetAddressString.cs b/src/Lib/Models/ParsedNetAddressString.cs index ee1a9fd..856e903 100644 --- a/src/Lib/Models/ParsedNetAddressString.cs +++ b/src/Lib/Models/ParsedNetAddressString.cs @@ -1,6 +1,5 @@ using System.Net; using System.Text.RegularExpressions; -using SmallsOnline.Subnetting.Lib.Enums; namespace SmallsOnline.Subnetting.Lib.Models; From 4919967854cabb39dc9dff5bf8c6c4a61291baa8 Mon Sep 17 00:00:00 2001 From: Timothy Small Date: Sat, 16 Mar 2024 16:22:44 -0400 Subject: [PATCH 04/14] Rename ParsedNetAddressStringType to ParsedNetworkAddressStringType --- src/Lib/Models/ParsedNetAddressStringType.cs | 7 ------- .../Models/ParsedNetworkAddressStringType.cs | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) delete mode 100644 src/Lib/Models/ParsedNetAddressStringType.cs create mode 100644 src/Lib/Models/ParsedNetworkAddressStringType.cs diff --git a/src/Lib/Models/ParsedNetAddressStringType.cs b/src/Lib/Models/ParsedNetAddressStringType.cs deleted file mode 100644 index e8ca1e5..0000000 --- a/src/Lib/Models/ParsedNetAddressStringType.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace SmallsOnline.Subnetting.Lib.Models; - -public enum ParsedNetAddressStringType -{ - CidrNotation = 0, - SubnetMask = 1 -} diff --git a/src/Lib/Models/ParsedNetworkAddressStringType.cs b/src/Lib/Models/ParsedNetworkAddressStringType.cs new file mode 100644 index 0000000..61a966a --- /dev/null +++ b/src/Lib/Models/ParsedNetworkAddressStringType.cs @@ -0,0 +1,17 @@ +namespace SmallsOnline.Subnetting.Lib.Models; + +/// +/// The type of parsed network address string. +/// +public enum ParsedNetworkAddressStringType +{ + /// + /// A CIDR notation. + /// + CidrNotation = 0, + + /// + /// A subnet mask. + /// + SubnetMask = 1 +} From 7e1be1687a65558f287b2af1bf6fe2f56987ece9 Mon Sep 17 00:00:00 2001 From: Timothy Small Date: Sat, 16 Mar 2024 16:29:07 -0400 Subject: [PATCH 05/14] Update ParsedNetAddressString - Public properties will just use the automatically created backing field during compilation. - Change the regex to source generated regex. - Split out parsing methods. - Update constructor. - Add missing code doc for the ParsedType property. --- src/Lib/Models/ParsedNetAddressString.cs | 119 ++++++++++++++++------- 1 file changed, 84 insertions(+), 35 deletions(-) diff --git a/src/Lib/Models/ParsedNetAddressString.cs b/src/Lib/Models/ParsedNetAddressString.cs index 856e903..284ecf9 100644 --- a/src/Lib/Models/ParsedNetAddressString.cs +++ b/src/Lib/Models/ParsedNetAddressString.cs @@ -6,71 +6,120 @@ namespace SmallsOnline.Subnetting.Lib.Models; /// /// A representation of a parsed network address. /// -public class ParsedNetAddressString +public partial class ParsedNetAddressString { /// /// Create from a network string. /// - /// The string of the network. - public ParsedNetAddressString(string netAddressString) + /// The string of the network. + public ParsedNetAddressString(string networkAddressString) { - Initialize(netAddressString); + Match networkAddressMatch = ParseNetworkAddressString(networkAddressString); + + IPAddress = GetIPAddressFromMatch(networkAddressMatch); + ParsedType = GetParsedTypeFromMatch(networkAddressMatch); + + if (ParsedType == ParsedNetworkAddressStringType.CidrNotation) + { + CidrNotation = GetCidrNotationFromMatch(networkAddressMatch); + } + else + { + SubnetMask = GetSubnetMaskFromMatch(networkAddressMatch); + } } /// /// The parsed IP address. /// - public IPAddress IPAddress - { - get => _ipAddress; - } + public IPAddress IPAddress { get; } /// /// The parsed CIDR notation. /// - public double CidrNotation - { - get => _cidrNotation; - } + public double CidrNotation { get; } /// /// The parsed subnet mask. /// - public IPAddress SubnetMask + public IPAddress? SubnetMask { get; } + + /// + /// The parsed type of the network address string. + /// + public ParsedNetworkAddressStringType ParsedType { get; } + + /// + /// Parse the network address string. + /// + /// The network address string. + /// A item of the network address string. + /// The network address string is not valid. + private static Match ParseNetworkAddressString(string networkAddressString) { - get => _subnetMask; + Match networkAddressMatch = NetAddressRegex().Match(networkAddressString); + + if (!networkAddressMatch.Success) + { + throw new InvalidOperationException("The network address string is not valid."); + } + + return networkAddressMatch; } - public ParsedNetAddressStringType ParsedType + /// + /// Get the IP address from the match. + /// + /// The match of the network address string. + /// The IP address from the match. + private static IPAddress GetIPAddressFromMatch(Match networkAddressMatch) { - get => _parsedType; + return IPAddress.Parse(networkAddressMatch.Groups["netAddress"].Value); } - private IPAddress _ipAddress; - private double _cidrNotation; - private IPAddress _subnetMask; - private ParsedNetAddressStringType _parsedType; - /// - /// Parses the string and sets the properties for the IP address and CIDR notation. + /// Get the parsed type from the match. /// - /// The string of the network. - private void Initialize(string netAddressString) + /// The match of the network address string. + /// The parsed type from the match. + /// Could not determine the type of the network address string. + private static ParsedNetworkAddressStringType GetParsedTypeFromMatch(Match networkAddressMatch) { - Regex netAddressRegex = new(@"^(?'netAddress'(?:\d{1,3}(?:\.|)){4})(?:(?:\/)(?'cidrNotation'\d{1,2})|(?:\/|\s)(?'subnetMask'(?:\d{1,3}(?:\.|)){4}))$"); - Match netAddressMatch = netAddressRegex.Match(netAddressString); - - _ipAddress = IPAddress.Parse(netAddressMatch.Groups["netAddress"].Value); - - if (netAddressMatch.Groups["cidrNotation"].Success) + if (networkAddressMatch.Groups["cidrNotation"].Success) { - _cidrNotation = Convert.ToDouble(netAddressMatch.Groups["cidrNotation"].Value); - _parsedType = ParsedNetAddressStringType.CidrNotation; + return ParsedNetworkAddressStringType.CidrNotation; } - else if (netAddressMatch.Groups["subnetMask"].Success) + + if (networkAddressMatch.Groups["subnetMask"].Success) { - _subnetMask = IPAddress.Parse(netAddressMatch.Groups["subnetMask"].Value); - _parsedType = ParsedNetAddressStringType.SubnetMask; + return ParsedNetworkAddressStringType.SubnetMask; } + + throw new InvalidOperationException("Could not determine the type of the network address string."); + } + + /// + /// Get the subnet mask from the match. + /// + /// The match of the network address string. + /// The subnet mask from the match. + private static IPAddress GetSubnetMaskFromMatch(Match networkAddressMatch) + { + return IPAddress.Parse(networkAddressMatch.Groups["subnetMask"].Value); } + + /// + /// Get the CIDR notation from the match. + /// + /// The match of the network address string. + /// The CIDR notation from the match. + private static double GetCidrNotationFromMatch(Match networkAddressMatch) + { + return Convert.ToDouble(networkAddressMatch.Groups["cidrNotation"].Value); + } + + [GeneratedRegex( + pattern: @"^(?'netAddress'(?:\d{1,3}(?:\.|)){4})(?:(?:\/)(?'cidrNotation'\d{1,2})|(?:\/|\s)(?'subnetMask'(?:\d{1,3}(?:\.|)){4}))$" + )] + internal static partial Regex NetAddressRegex(); } From a96ad69b35b0ee6eafe02f4158b3ba07fdd870de Mon Sep 17 00:00:00 2001 From: Timothy Small Date: Sat, 16 Mar 2024 16:31:03 -0400 Subject: [PATCH 06/14] Update UsableHostRange - Public properties will just use the automatically created backing field during compilation. - Split out methods. - Update constructor. --- src/Lib/Models/UsableHostRange.cs | 55 +++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/src/Lib/Models/UsableHostRange.cs b/src/Lib/Models/UsableHostRange.cs index 17bd3e0..5a0d9bf 100644 --- a/src/Lib/Models/UsableHostRange.cs +++ b/src/Lib/Models/UsableHostRange.cs @@ -10,43 +10,64 @@ public class UsableHostRange /// /// Create from the network and broadcast address. /// - /// The network address of the subnet. + /// The network address of the subnet. /// The broadcast address of the subnet. - public UsableHostRange(IPAddress netAddress, IPAddress broadcastAddress) + public UsableHostRange(IPAddress networkAddress, IPAddress broadcastAddress) { - Initialize(netAddress, broadcastAddress); + FirstUsableHostAddress = GetFirstUsableHostAddress(networkAddress); + LastUsableHostAddress = GetLastUsableHostAddress(broadcastAddress); } /// /// The first usable host address in the subnet. /// - public IPAddress FirstUsableHostAddress - { - get => _firstUsableHostAddress; - } + public IPAddress FirstUsableHostAddress { get; } /// /// The last usable host address in the subnet. /// - public IPAddress LastUsableHostAddress + public IPAddress LastUsableHostAddress { get; } + + /// + /// Get the first usable host address in the subnet. + /// + /// The network address of the subnet. + /// The first usable host address in the subnet. + private static IPAddress GetFirstUsableHostAddress(IPAddress networkAddress) { - get => _lastUsableHostAddress; - } + byte[] networkAddressBytes = networkAddress.GetAddressBytes(); - private IPAddress _firstUsableHostAddress; - private IPAddress _lastUsableHostAddress; + return new( + address: [ + networkAddressBytes[0], + networkAddressBytes[1], + networkAddressBytes[2], + (byte)(networkAddressBytes[3] + 1) + ] + ); + } - private void Initialize(IPAddress netAddress, IPAddress broadcastAddress) + /// + /// Get the last usable host address in the subnet. + /// + /// The broadcast address of the subnet. + /// The last usable host address in the subnet. + private static IPAddress GetLastUsableHostAddress(IPAddress broadcastAddress) { - byte[] netAddressBytes = netAddress.GetAddressBytes(); byte[] broadcastAddressBytes = broadcastAddress.GetAddressBytes(); - _firstUsableHostAddress = new(new byte[] { netAddressBytes[0], netAddressBytes[1], netAddressBytes[2], (byte)(netAddressBytes[3] + 1) }); - _lastUsableHostAddress = new(new byte[] { broadcastAddressBytes[0], broadcastAddressBytes[1], broadcastAddressBytes[2], (byte)(broadcastAddressBytes[3] - 1) }); + return new( + address: [ + broadcastAddressBytes[0], + broadcastAddressBytes[1], + broadcastAddressBytes[2], + (byte)(broadcastAddressBytes[3] - 1) + ] + ); } public override string ToString() { - return $"{_firstUsableHostAddress} - {_lastUsableHostAddress}"; + return $"{FirstUsableHostAddress} - {LastUsableHostAddress}"; } } From 2ebfd913abab232b0e5330792101386bc6e78fcc Mon Sep 17 00:00:00 2001 From: Timothy Small Date: Sat, 16 Mar 2024 16:31:33 -0400 Subject: [PATCH 07/14] Update Octet - Public properties will just use the automatically created backing field during compilation. --- src/Lib/Models/Octet.cs | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/Lib/Models/Octet.cs b/src/Lib/Models/Octet.cs index 1dac429..ef29ebf 100644 --- a/src/Lib/Models/Octet.cs +++ b/src/Lib/Models/Octet.cs @@ -12,44 +12,35 @@ public class Octet /// The byte value of the octet. public Octet(int position, byte byteItem) { - octetPosition = position; - binaryValue = new(byteItem); + OctetPosition = position; + BinaryValue = new(byteItem); } /// /// The position of the octet. /// - public int OctetPosition - { - get => octetPosition; - } + public int OctetPosition { get; } /// /// The binary value of the octet. /// - public BinaryNumber BinaryValue - { - get => binaryValue; - } + public BinaryNumber BinaryValue { get; } /// /// If bits have been used. /// public bool BitsUsed { - get => binaryValue.GetUsedBits() > 0; + get => BinaryValue.GetUsedBits() > 0; } - private readonly int octetPosition; - private readonly BinaryNumber binaryValue; - /// /// Return the byte value of the octet. /// /// The byte value of the octet. public byte ToByte() { - return Convert.ToByte(binaryValue.GetUnusedBits()); + return Convert.ToByte(BinaryValue.GetUnusedBits()); } /// @@ -58,6 +49,6 @@ public byte ToByte() /// The value of the octet as a string. public override string ToString() { - return $"{binaryValue.GetUnusedBits()}"; + return $"{BinaryValue.GetUnusedBits()}"; } } From 9374838e8831e6cb851f7fc1512b229fa1142b4c Mon Sep 17 00:00:00 2001 From: Timothy Small Date: Sat, 16 Mar 2024 16:32:04 -0400 Subject: [PATCH 08/14] Update IPv4WildcardMask - Public properties will just use the automatically created backing field during compilation. --- src/Lib/Models/IPv4WildcardMask.cs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/Lib/Models/IPv4WildcardMask.cs b/src/Lib/Models/IPv4WildcardMask.cs index 9922ba2..68ab0d2 100644 --- a/src/Lib/Models/IPv4WildcardMask.cs +++ b/src/Lib/Models/IPv4WildcardMask.cs @@ -14,14 +14,14 @@ public IPv4WildcardMask(byte[] bytes, bool isAlreadyCalculated = false) { if (isAlreadyCalculated) { - wildcardBytes = bytes; + WildcardBytes = bytes; } else { - wildcardBytes = new byte[4]; + WildcardBytes = new byte[4]; for (int i = 0; i < bytes.Length; i++) { - wildcardBytes[i] = (byte)(byte.MaxValue - bytes[i]); + WildcardBytes[i] = (byte)(byte.MaxValue - bytes[i]); } } } @@ -29,12 +29,7 @@ public IPv4WildcardMask(byte[] bytes, bool isAlreadyCalculated = false) /// /// The bytes of the wildcard mask. /// - public byte[] WildcardBytes - { - get => wildcardBytes; - } - - private readonly byte[] wildcardBytes; + public byte[] WildcardBytes { get; } /// /// Displays the wildcard mask as a string. @@ -42,6 +37,6 @@ public byte[] WildcardBytes /// A string representation of the wildcard mask. public override string ToString() { - return string.Join(".", wildcardBytes); + return string.Join(".", WildcardBytes); } } From 47267a9ca5ed1398a84808c56108b184bac662c1 Mon Sep 17 00:00:00 2001 From: Timothy Small Date: Sat, 16 Mar 2024 16:34:17 -0400 Subject: [PATCH 09/14] Update IPv4SubnetMask - Public properties will just use the automatically created backing field during compilation. - All methods with an underscore in their name have been renamed to not have it. - Any local variables or method parameters don't have an underscore as a prefix anymore. --- src/Lib/Models/IPv4SubnetMask.cs | 91 +++++++++++++------------------- 1 file changed, 37 insertions(+), 54 deletions(-) diff --git a/src/Lib/Models/IPv4SubnetMask.cs b/src/Lib/Models/IPv4SubnetMask.cs index de6f76a..783a6fe 100644 --- a/src/Lib/Models/IPv4SubnetMask.cs +++ b/src/Lib/Models/IPv4SubnetMask.cs @@ -13,10 +13,10 @@ public class IPv4SubnetMask /// The CIDR notation of the subnet mask. public IPv4SubnetMask(double cidr) { - wildcardMask = GetWildcardMask_FromCidr(cidr); - octets = GetSubnetMaskOctets_FromWildcardMask(wildcardMask); - cidrNotation = cidr; - totalAddresses = (int)GetMaxAddresses_FromCidr(cidr); + WildcardMask = GetWildcardMaskFromCidr(cidr); + Octets = GetSubnetMaskOctetsFromWildcardMask(WildcardMask); + CidrNotation = cidr; + TotalAddresses = (int)GetMaxAddressesFromCidr(cidr); } /// @@ -25,48 +25,31 @@ public IPv4SubnetMask(double cidr) /// The byte array of the subnet mask. public IPv4SubnetMask(byte[] bytes) { - octets = GetOctets_FromBytes(bytes); - wildcardMask = new(bytes); - cidrNotation = GetCidrMask_FromSubnetMask(octets); - totalAddresses = (int)GetMaxAddresses_FromCidr(cidrNotation); + Octets = GetOctetsFromBytes(bytes); + WildcardMask = new(bytes); + CidrNotation = GetCidrMaskFromSubnetMask(Octets); + TotalAddresses = (int)GetMaxAddressesFromCidr(CidrNotation); } /// /// The octets of the subnet mask. /// - public Octet[] Octets - { - get => octets; - } + public Octet[] Octets { get; } /// /// The wildcard mask of the subnet mask. /// - public IPv4WildcardMask WildcardMask - { - get => wildcardMask; - } + public IPv4WildcardMask WildcardMask { get; } /// /// The CIDR notation of the subnet mask. /// - public double CidrNotation - { - get => cidrNotation; - } + public double CidrNotation { get; } /// /// The total amount of addresses available from the subnet mask. /// - public int TotalAddresses - { - get => totalAddresses; - } - - private readonly Octet[] octets; - private readonly IPv4WildcardMask wildcardMask; - private readonly double cidrNotation; - private readonly int totalAddresses; + public int TotalAddresses { get; } /// /// Gets the last octet that was borrowed from. @@ -74,7 +57,7 @@ public int TotalAddresses /// The last octet borrowed from. public Octet GetLastUsedOctet() { - List octetsList = new(octets); + List octetsList = new(Octets); Octet lastUsedOctet = octetsList.FindAll((octetItem) => octetItem.BitsUsed == true)[0]; @@ -88,9 +71,9 @@ public Octet GetLastUsedOctet() public byte[] ToBytes() { byte[] byteArray = new byte[4]; - for (int i = 0; i < octets.Length; i++) + for (int i = 0; i < Octets.Length; i++) { - byteArray[i] = (byte)(byte.MinValue + octets[i].ToByte()); + byteArray[i] = (byte)(byte.MinValue + Octets[i].ToByte()); } return byteArray; @@ -119,15 +102,15 @@ public override string ToString() /// /// A byte array of the subnet mask. /// An array of the octets. - private static Octet[] GetOctets_FromBytes(byte[] bytes) + private static Octet[] GetOctetsFromBytes(byte[] bytes) { - Octet[] _octets = new Octet[4]; - for (int i = 0; i < _octets.Length; i++) + Octet[] octets = new Octet[4]; + for (int i = 0; i < octets.Length; i++) { - _octets[i] = new(i + 1, bytes[i]); + octets[i] = new(i + 1, bytes[i]); } - return _octets; + return octets; } /// @@ -135,14 +118,14 @@ private static Octet[] GetOctets_FromBytes(byte[] bytes) /// /// The CIDR notation of the subnet mask. /// The total amount of addresses. - private static double GetMaxAddresses_FromCidr(double cidr) + private static double GetMaxAddressesFromCidr(double cidr) { // Get the maximum amount of addresses that can be used. // Calculated by: 2^(32-cidrNotation) - return Math.Pow(2, GetBitBlock_FromCidr(cidr)); + return Math.Pow(2, GetBitBlockFromCidr(cidr)); } - private static double GetBitBlock_FromCidr(double cidr) + private static double GetBitBlockFromCidr(double cidr) { return 32 - cidr; } @@ -152,11 +135,11 @@ private static double GetBitBlock_FromCidr(double cidr) /// /// The CIDR notation of the subnet mask. /// The wildcard mask of the subnet mask. - private static IPv4WildcardMask GetWildcardMask_FromCidr(double cidr) + private static IPv4WildcardMask GetWildcardMaskFromCidr(double cidr) { byte[] wildcardByteArray = new byte[4]; - double maxAddresses = GetMaxAddresses_FromCidr(cidr); + double maxAddresses = GetMaxAddressesFromCidr(cidr); // Get the amount of bytes filled. // This is calculated by getting the log of the max addresses from the base of 256 and rounding to the lowest number. @@ -192,28 +175,28 @@ private static IPv4WildcardMask GetWildcardMask_FromCidr(double cidr) /// /// Get the octets of a subnet mask from the wildcard mask. /// - /// The wildcard mask of a subnet mask. + /// The wildcard mask of a subnet mask. /// An array of octets of the subnet mask. - private static Octet[] GetSubnetMaskOctets_FromWildcardMask(IPv4WildcardMask _wildcardMask) + private static Octet[] GetSubnetMaskOctetsFromWildcardMask(IPv4WildcardMask wildcardMask) { - Octet[] _octets = new Octet[4]; - for (int i = _wildcardMask.WildcardBytes.Length - 1; i >= 0; i--) + Octet[] octets = new Octet[4]; + for (int i = wildcardMask.WildcardBytes.Length - 1; i >= 0; i--) { - _octets[i] = new(i + 1, (byte)(byte.MaxValue - _wildcardMask.WildcardBytes[i])); + octets[i] = new(i + 1, (byte)(byte.MaxValue - wildcardMask.WildcardBytes[i])); } - return _octets; + return octets; } /// /// Get the CIDR notation from the subnet mask's octets. /// - /// The octets of the subnet mask. + /// The octets of the subnet mask. /// The CIDR notation of the subnet mask. - private static double GetCidrMask_FromSubnetMask(Octet[] _octets) + private static double GetCidrMaskFromSubnetMask(Octet[] octets) { List bitList = new(); - foreach (Octet octetItem in _octets) + foreach (Octet octetItem in octets) { bitList.AddRange(octetItem.BinaryValue.BitValues); } @@ -225,9 +208,9 @@ private static double GetCidrMask_FromSubnetMask(Octet[] _octets) /// /// Calculate the total amount of addresses from the octets of a subnet mask. /// - /// The octets of the subnet mask. + /// The octets of the subnet mask. /// The total amount of addresses. - private static int GetTotalAddresses_FromSubnetMask(Octet _octet) + private static int GetTotalAddressesFromSubnetMask(Octet octet) { // Note: // ------ @@ -237,6 +220,6 @@ private static int GetTotalAddresses_FromSubnetMask(Octet _octet) // the GetMaxAddresses_FromCidr() method instead. Will keep looking into fixing this. // ------ - return (int)(Math.Pow(256, _octet.OctetPosition - 1) * _octet.BinaryValue.GetUnusedBits()); + return (int)(Math.Pow(256, octet.OctetPosition - 1) * octet.BinaryValue.GetUnusedBits()); } } From 0078d5ed2a0afc90eeabc26e7ddd53989c42c71b Mon Sep 17 00:00:00 2001 From: Timothy Small Date: Sat, 16 Mar 2024 16:34:50 -0400 Subject: [PATCH 10/14] Update IPv4Subnet - Public properties will just use the automatically created backing field during compilation. --- src/Lib/Models/IPv4Subnet.cs | 67 ++++++++++++++---------------------- 1 file changed, 25 insertions(+), 42 deletions(-) diff --git a/src/Lib/Models/IPv4Subnet.cs b/src/Lib/Models/IPv4Subnet.cs index 93054a5..6d70df6 100644 --- a/src/Lib/Models/IPv4Subnet.cs +++ b/src/Lib/Models/IPv4Subnet.cs @@ -14,10 +14,10 @@ public class IPv4Subnet /// The CIDR mask for the subnet. public IPv4Subnet(IPAddress ipAddress, double cidr) { - _subnetMask = new(cidr); - _networkAddress = GetSubnetBoundary(ipAddress, _subnetMask); - _broadcastAddress = GetBroadcastAddress(_networkAddress, _subnetMask); - _usableHostRange = new(_networkAddress, _broadcastAddress); + SubnetMask = new(cidr); + NetworkAddress = GetSubnetBoundary(ipAddress, SubnetMask); + BroadcastAddress = GetBroadcastAddress(NetworkAddress, SubnetMask); + UsableHostRange = new(NetworkAddress, BroadcastAddress); } /// @@ -27,10 +27,10 @@ public IPv4Subnet(IPAddress ipAddress, double cidr) /// The subnet mask. public IPv4Subnet(IPAddress ipAddress, IPv4SubnetMask subnetMask) { - _subnetMask = subnetMask; - _networkAddress = GetSubnetBoundary(ipAddress, _subnetMask); - _broadcastAddress = GetBroadcastAddress(_networkAddress, _subnetMask); - _usableHostRange = new(_networkAddress, _broadcastAddress); + SubnetMask = subnetMask; + NetworkAddress = GetSubnetBoundary(ipAddress, SubnetMask); + BroadcastAddress = GetBroadcastAddress(NetworkAddress, SubnetMask); + UsableHostRange = new(NetworkAddress, BroadcastAddress); } /// @@ -40,10 +40,10 @@ public IPv4Subnet(IPAddress ipAddress, IPv4SubnetMask subnetMask) /// The subnet mask. public IPv4Subnet(IPAddress ipAddress, IPAddress subnetMask) { - _subnetMask = new(subnetMask.GetAddressBytes()); - _networkAddress = GetSubnetBoundary(ipAddress, _subnetMask); - _broadcastAddress = GetBroadcastAddress(_networkAddress, _subnetMask); - _usableHostRange = new(_networkAddress, _broadcastAddress); + SubnetMask = new(subnetMask.GetAddressBytes()); + NetworkAddress = GetSubnetBoundary(ipAddress, SubnetMask); + BroadcastAddress = GetBroadcastAddress(NetworkAddress, SubnetMask); + UsableHostRange = new(NetworkAddress, BroadcastAddress); } /// @@ -56,55 +56,46 @@ public IPv4Subnet(string networkString) { ParsedNetAddressString parsedNetAddress = new(networkString); - _subnetMask = parsedNetAddress.ParsedType switch + SubnetMask = parsedNetAddress.ParsedType switch { - ParsedNetAddressStringType.SubnetMask => new(parsedNetAddress.SubnetMask.GetAddressBytes()), + ParsedNetAddressStringType.SubnetMask => new(parsedNetAddress.SubnetMask!.GetAddressBytes()), _ => new(parsedNetAddress.CidrNotation) }; - _networkAddress = GetSubnetBoundary(parsedNetAddress.IPAddress, _subnetMask); - _broadcastAddress = GetBroadcastAddress(_networkAddress, _subnetMask); - _usableHostRange = new(_networkAddress, _broadcastAddress); + NetworkAddress = GetSubnetBoundary(parsedNetAddress.IPAddress, SubnetMask); + BroadcastAddress = GetBroadcastAddress(NetworkAddress, SubnetMask); + UsableHostRange = new(NetworkAddress, BroadcastAddress); } /// /// The network address of the subnet. /// - public IPAddress NetworkAddress - { - get => _networkAddress; - } + public IPAddress NetworkAddress { get; } /// /// The subnet mask of the subnet. /// - public IPv4SubnetMask SubnetMask - { - get => _subnetMask; - } + public IPv4SubnetMask SubnetMask { get; } /// /// The CIDR mask of the subnet. /// public double CidrMask { - get => _subnetMask.CidrNotation; + get => SubnetMask.CidrNotation; } /// /// The broadcast address of the subnet. /// - public IPAddress BroadcastAddress - { - get => _broadcastAddress; - } + public IPAddress BroadcastAddress { get; } /// /// The total amount of addresses in the subnet. /// public double TotalAddresses { - get => _subnetMask.TotalAddresses; + get => SubnetMask.TotalAddresses; } /// @@ -112,21 +103,13 @@ public double TotalAddresses /// public double UsableAddresses { - get => _subnetMask.TotalAddresses - 2; + get => SubnetMask.TotalAddresses - 2; } /// /// The range of hosts available for use in the subnet. /// - public UsableHostRange UsableHostRange - { - get => _usableHostRange; - } - - private readonly IPAddress _networkAddress; - private readonly IPv4SubnetMask _subnetMask; - private readonly IPAddress _broadcastAddress; - private readonly UsableHostRange _usableHostRange; + public UsableHostRange UsableHostRange { get; } /// /// Display the subnet as a string. @@ -134,7 +117,7 @@ public UsableHostRange UsableHostRange /// A string representation of the subnet with the network address and CIDR mask. public override string ToString() { - return $"{_networkAddress}/{CidrMask}"; + return $"{NetworkAddress}/{CidrMask}"; } /// From a6066c26ec35ac16d7e876fc8bde1e5373df063c Mon Sep 17 00:00:00 2001 From: Timothy Small Date: Sat, 16 Mar 2024 16:35:16 -0400 Subject: [PATCH 11/14] Update BitRepresentation - Public properties will just use the automatically created backing field during compilation. --- src/Lib/Models/BitRepresentation.cs | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/Lib/Models/BitRepresentation.cs b/src/Lib/Models/BitRepresentation.cs index 21f12ed..424dac8 100644 --- a/src/Lib/Models/BitRepresentation.cs +++ b/src/Lib/Models/BitRepresentation.cs @@ -12,17 +12,14 @@ public class BitRepresentation /// The bit is on and used. public BitRepresentation(int position, bool isOn) { - bitPosition = position; - bitIsOn = isOn; + BitPosition = position; + BitIsOn = isOn; } /// /// The position of the bit. /// - public int BitPosition - { - get => bitPosition; - } + public int BitPosition { get; } /// /// The value of the bit. @@ -30,28 +27,22 @@ public int BitPosition /// public int BitValue { - get => (int)Math.Pow(2, bitPosition); + get => (int)Math.Pow(2, BitPosition); } /// /// If the bit is on or not. /// - public bool BitIsOn - { - get => bitIsOn; - } + public bool BitIsOn { get; } /// /// The actual value of the bit if it's on or not. /// public int BitActualValue { - get => bitIsOn ? BitValue : 0; + get => BitIsOn ? BitValue : 0; } - private readonly int bitPosition; - private readonly bool bitIsOn; - public override string ToString() { return $"{BitActualValue}"; From 59c2f27d8e8651b65fdde242b6f5e18eb5662cdd Mon Sep 17 00:00:00 2001 From: Timothy Small Date: Sat, 16 Mar 2024 16:36:18 -0400 Subject: [PATCH 12/14] Update BinaryNumber - Public properties will just use the automatically created backing field during compilation. - Remove casting from List to an array and just initialize as an array. --- src/Lib/Models/BinaryNumber.cs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/Lib/Models/BinaryNumber.cs b/src/Lib/Models/BinaryNumber.cs index cd9ed73..aa6a057 100644 --- a/src/Lib/Models/BinaryNumber.cs +++ b/src/Lib/Models/BinaryNumber.cs @@ -13,26 +13,23 @@ public class BinaryNumber /// A byte value. public BinaryNumber(byte byteItem) { - List bitValuesList = new(); - BitArray bitArray = new(new byte[] { byteItem }); + + BitValues = new BitRepresentation[bitArray.Length]; + for (int i = bitArray.Length - 1; i >= 0; i--) { - bitValuesList.Add(new(i, bitArray[i])); + BitValues[i] = new BitRepresentation( + position: i, + isOn: bitArray[i] + ); } - - bitValues = bitValuesList.ToArray(); } /// /// An array of the bits used for the binary number. /// - public BitRepresentation[] BitValues - { - get => bitValues; - } - - private readonly BitRepresentation[] bitValues; + public BitRepresentation[] BitValues { get; } /// /// Get the amount of unused bits. @@ -42,7 +39,7 @@ public int GetUnusedBits() { int bitsUnused = 0; - foreach (BitRepresentation bitItem in bitValues) + foreach (BitRepresentation bitItem in BitValues) { bitsUnused += bitItem.BitActualValue; } @@ -58,7 +55,7 @@ public int GetUsedBits() { int bitsUsed = 255; - foreach (BitRepresentation bitItem in bitValues) + foreach (BitRepresentation bitItem in BitValues) { bitsUsed -= bitItem.BitActualValue; } From b933eefc9c278a545d7d883056c18320bac5ab0a Mon Sep 17 00:00:00 2001 From: Timothy Small Date: Sat, 16 Mar 2024 16:38:14 -0400 Subject: [PATCH 13/14] Rename ParsedNetAddressString to ParsedNetworkAddressString --- src/Lib/Models/IPv4Subnet.cs | 4 ++-- ...arsedNetAddressString.cs => ParsedNetworkAddressString.cs} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/Lib/Models/{ParsedNetAddressString.cs => ParsedNetworkAddressString.cs} (97%) diff --git a/src/Lib/Models/IPv4Subnet.cs b/src/Lib/Models/IPv4Subnet.cs index 6d70df6..132d991 100644 --- a/src/Lib/Models/IPv4Subnet.cs +++ b/src/Lib/Models/IPv4Subnet.cs @@ -54,11 +54,11 @@ public IPv4Subnet(IPAddress ipAddress, IPAddress subnetMask) /// A network written in a string format. public IPv4Subnet(string networkString) { - ParsedNetAddressString parsedNetAddress = new(networkString); + ParsedNetworkAddressString parsedNetAddress = new(networkString); SubnetMask = parsedNetAddress.ParsedType switch { - ParsedNetAddressStringType.SubnetMask => new(parsedNetAddress.SubnetMask!.GetAddressBytes()), + ParsedNetworkAddressStringType.SubnetMask => new(parsedNetAddress.SubnetMask!.GetAddressBytes()), _ => new(parsedNetAddress.CidrNotation) }; diff --git a/src/Lib/Models/ParsedNetAddressString.cs b/src/Lib/Models/ParsedNetworkAddressString.cs similarity index 97% rename from src/Lib/Models/ParsedNetAddressString.cs rename to src/Lib/Models/ParsedNetworkAddressString.cs index 284ecf9..6d3584f 100644 --- a/src/Lib/Models/ParsedNetAddressString.cs +++ b/src/Lib/Models/ParsedNetworkAddressString.cs @@ -6,13 +6,13 @@ namespace SmallsOnline.Subnetting.Lib.Models; /// /// A representation of a parsed network address. /// -public partial class ParsedNetAddressString +public partial class ParsedNetworkAddressString { /// /// Create from a network string. /// /// The string of the network. - public ParsedNetAddressString(string networkAddressString) + public ParsedNetworkAddressString(string networkAddressString) { Match networkAddressMatch = ParseNetworkAddressString(networkAddressString); From 618bb8259c487a52103330620729210b763e3d24 Mon Sep 17 00:00:00 2001 From: Timothy Small Date: Sat, 16 Mar 2024 16:42:09 -0400 Subject: [PATCH 14/14] Only use source generated regex when targeting .NET 8 or higher --- src/Lib/Models/ParsedNetworkAddressString.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Lib/Models/ParsedNetworkAddressString.cs b/src/Lib/Models/ParsedNetworkAddressString.cs index 6d3584f..a031cf7 100644 --- a/src/Lib/Models/ParsedNetworkAddressString.cs +++ b/src/Lib/Models/ParsedNetworkAddressString.cs @@ -118,8 +118,12 @@ private static double GetCidrNotationFromMatch(Match networkAddressMatch) return Convert.ToDouble(networkAddressMatch.Groups["cidrNotation"].Value); } +#if NET8_0_OR_GREATER [GeneratedRegex( pattern: @"^(?'netAddress'(?:\d{1,3}(?:\.|)){4})(?:(?:\/)(?'cidrNotation'\d{1,2})|(?:\/|\s)(?'subnetMask'(?:\d{1,3}(?:\.|)){4}))$" )] - internal static partial Regex NetAddressRegex(); + private static partial Regex NetAddressRegex(); +#else + private static Regex NetAddressRegex() => new(@"^(?'netAddress'(?:\d{1,3}(?:\.|)){4})(?:(?:\/)(?'cidrNotation'\d{1,2})|(?:\/|\s)(?'subnetMask'(?:\d{1,3}(?:\.|)){4}))$"); +#endif }