-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
df4ac7b
commit 2a759f4
Showing
9 changed files
with
848 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace SmallsOnline.Subnetting.Lib.Enums | ||
{ | ||
public enum ParsedNetAddressStringType | ||
{ | ||
CidrNotation = 0, | ||
SubnetMask = 1 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
|
||
namespace SmallsOnline.Subnetting.Lib.Models | ||
{ | ||
/// <summary> | ||
/// A representation of a binary number. | ||
/// </summary> | ||
public class BinaryNumber | ||
{ | ||
/// <summary> | ||
/// Create from a byte. | ||
/// </summary> | ||
/// <param name="byteItem">A byte value.</param> | ||
public BinaryNumber(byte byteItem) | ||
{ | ||
List<BitRepresentation> 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(); | ||
} | ||
|
||
/// <summary> | ||
/// An array of the bits used for the binary number. | ||
/// </summary> | ||
public BitRepresentation[] BitValues | ||
{ | ||
get => bitValues; | ||
} | ||
|
||
private readonly BitRepresentation[] bitValues; | ||
|
||
/// <summary> | ||
/// Get the amount of unused bits. | ||
/// </summary> | ||
/// <returns>The amount of unused bits.</returns> | ||
public int GetUnusedBits() | ||
{ | ||
int bitsUnused = 0; | ||
|
||
foreach (BitRepresentation bitItem in bitValues) | ||
{ | ||
bitsUnused += bitItem.BitActualValue; | ||
} | ||
|
||
return bitsUnused; | ||
} | ||
|
||
/// <summary> | ||
/// Get the amount of used bits. | ||
/// </summary> | ||
/// <returns>The amount of used bits.</returns> | ||
public int GetUsedBits() | ||
{ | ||
int bitsUsed = 255; | ||
|
||
foreach (BitRepresentation bitItem in bitValues) | ||
{ | ||
bitsUsed -= bitItem.BitActualValue; | ||
} | ||
|
||
return bitsUsed; | ||
} | ||
|
||
/// <summary> | ||
/// Return the amount of unused bits as a string. | ||
/// </summary> | ||
/// <returns>The amount of unused bits.</returns> | ||
public override string ToString() | ||
{ | ||
return $"{GetUnusedBits()}"; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
using System; | ||
|
||
namespace SmallsOnline.Subnetting.Lib.Models | ||
{ | ||
/// <summary> | ||
/// A representation of a bit. | ||
/// </summary> | ||
public class BitRepresentation | ||
{ | ||
/// <summary> | ||
/// Create from the position of the bit and if it's on. | ||
/// </summary> | ||
/// <param name="position">The position of the bit.</param> | ||
/// <param name="isOn">The bit is on and used.</param> | ||
public BitRepresentation(int position, bool isOn) | ||
{ | ||
bitPosition = position; | ||
bitIsOn = isOn; | ||
} | ||
|
||
/// <summary> | ||
/// The position of the bit. | ||
/// </summary> | ||
public int BitPosition | ||
{ | ||
get => bitPosition; | ||
} | ||
|
||
/// <summary> | ||
/// The value of the bit. | ||
/// 2^bitPosition | ||
/// </summary> | ||
public int BitValue | ||
{ | ||
get => (int)Math.Pow(2, bitPosition); | ||
} | ||
|
||
/// <summary> | ||
/// If the bit is on or not. | ||
/// </summary> | ||
public bool BitIsOn | ||
{ | ||
get => bitIsOn; | ||
} | ||
|
||
/// <summary> | ||
/// The actual value of the bit if it's on or not. | ||
/// </summary> | ||
public int BitActualValue | ||
{ | ||
get => bitIsOn ? BitValue : 0; | ||
} | ||
|
||
private readonly int bitPosition; | ||
private readonly bool bitIsOn; | ||
|
||
public override string ToString() | ||
{ | ||
return $"{BitActualValue}"; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
using System; | ||
using System.Net; | ||
|
||
namespace SmallsOnline.Subnetting.Lib.Models | ||
{ | ||
using SmallsOnline.Subnetting.Lib.Enums; | ||
/// <summary> | ||
/// A representation of an IPv4 subnet. | ||
/// </summary> | ||
public class IPv4Subnet | ||
{ | ||
/// <summary> | ||
/// Create from an IP address and CIDR mask. | ||
/// </summary> | ||
/// <param name="ipAddress">An IP address in a subnet.</param> | ||
/// <param name="cidr">The CIDR mask for the subnet.</param> | ||
public IPv4Subnet(IPAddress ipAddress, double cidr) | ||
{ | ||
_subnetMask = new(cidr); | ||
_networkAddress = GetSubnetBoundary(ipAddress, _subnetMask); | ||
_broadcastAddress = GetBroadcastAddress(_networkAddress, _subnetMask); | ||
_usableHostRange = new(_networkAddress, _broadcastAddress); | ||
} | ||
|
||
/// <summary> | ||
/// Create from an IP address and CIDR mask. | ||
/// </summary> | ||
/// <param name="ipAddress">An IP address in a subnet.</param> | ||
/// <param name="subnetMask">The subnet mask.</param> | ||
public IPv4Subnet(IPAddress ipAddress, IPv4SubnetMask subnetMask) | ||
{ | ||
_subnetMask = subnetMask; | ||
_networkAddress = GetSubnetBoundary(ipAddress, _subnetMask); | ||
_broadcastAddress = GetBroadcastAddress(_networkAddress, _subnetMask); | ||
_usableHostRange = new(_networkAddress, _broadcastAddress); | ||
} | ||
|
||
/// <summary> | ||
/// Create from an IP address and CIDR mask. | ||
/// </summary> | ||
/// <param name="ipAddress">An IP address in a subnet.</param> | ||
/// <param name="subnetMask">The subnet mask.</param> | ||
public IPv4Subnet(IPAddress ipAddress, IPAddress subnetMask) | ||
{ | ||
_subnetMask = new(subnetMask.GetAddressBytes()); | ||
_networkAddress = GetSubnetBoundary(ipAddress, _subnetMask); | ||
_broadcastAddress = GetBroadcastAddress(_networkAddress, _subnetMask); | ||
_usableHostRange = new(_networkAddress, _broadcastAddress); | ||
} | ||
|
||
/// <summary> | ||
/// Create from a string of a network. | ||
/// For example: | ||
/// 10.21.6.0/18 | ||
/// </summary> | ||
/// <param name="networkString">A network written in a string format.</param> | ||
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); | ||
} | ||
|
||
/// <summary> | ||
/// The network address of the subnet. | ||
/// </summary> | ||
public IPAddress NetworkAddress | ||
{ | ||
get => _networkAddress; | ||
} | ||
|
||
/// <summary> | ||
/// The subnet mask of the subnet. | ||
/// </summary> | ||
public IPv4SubnetMask SubnetMask | ||
{ | ||
get => _subnetMask; | ||
} | ||
|
||
/// <summary> | ||
/// The CIDR mask of the subnet. | ||
/// </summary> | ||
public double CidrMask | ||
{ | ||
get => _subnetMask.CidrNotation; | ||
} | ||
|
||
/// <summary> | ||
/// The broadcast address of the subnet. | ||
/// </summary> | ||
public IPAddress BroadcastAddress | ||
{ | ||
get => _broadcastAddress; | ||
} | ||
|
||
/// <summary> | ||
/// The total amount of addresses in the subnet. | ||
/// </summary> | ||
public double TotalAddresses | ||
{ | ||
get => _subnetMask.TotalAddresses; | ||
} | ||
|
||
/// <summary> | ||
/// The total amount of usable addresses in the subnet. | ||
/// </summary> | ||
public double UsableAddresses | ||
{ | ||
get => _subnetMask.TotalAddresses - 2; | ||
} | ||
|
||
/// <summary> | ||
/// The range of hosts available for use in the subnet. | ||
/// </summary> | ||
public UsableHostRange UsableHostRange | ||
{ | ||
get => _usableHostRange; | ||
} | ||
|
||
private readonly IPAddress _networkAddress; | ||
private readonly IPv4SubnetMask _subnetMask; | ||
private readonly IPAddress _broadcastAddress; | ||
private readonly UsableHostRange _usableHostRange; | ||
|
||
/// <summary> | ||
/// Display the subnet as a string. | ||
/// </summary> | ||
/// <returns>A string representation of the subnet with the network address and CIDR mask.</returns> | ||
public override string ToString() | ||
{ | ||
return $"{_networkAddress}/{CidrMask}"; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the network address of the subnet from the supplied IP address and the subnet mask. | ||
/// </summary> | ||
/// <param name="ipAddress">The IP address in the subnet.</param> | ||
/// <param name="subnetMask">The subnet mask of the subnet.</param> | ||
/// <returns>The network address of the subnet.</returns> | ||
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); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the broadcast address of the subnet. | ||
/// </summary> | ||
/// <param name="networkAddress">The network address of the subnet.</param> | ||
/// <param name="subnetMask">The subnet mask of the subnet.</param> | ||
/// <returns>The broadcast address for the subnet.</returns> | ||
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); | ||
} | ||
} | ||
} |
Oops, something went wrong.