Skip to content

Commit

Permalink
Change casing
Browse files Browse the repository at this point in the history
  • Loading branch information
Smalls1652 committed Mar 16, 2024
1 parent df4ac7b commit 2a759f4
Show file tree
Hide file tree
Showing 9 changed files with 848 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/Lib/Enums/ParsedNetAddressStringType.cs
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
}
}
80 changes: 80 additions & 0 deletions src/Lib/Models/BinaryNumber.cs
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()}";
}
}
}
62 changes: 62 additions & 0 deletions src/Lib/Models/BitRepresentation.cs
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}";
}
}
}
204 changes: 204 additions & 0 deletions src/Lib/Models/IPv4Subnet.cs
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);
}
}
}
Loading

0 comments on commit 2a759f4

Please sign in to comment.