Refactor address classes

This commit is contained in:
femsci 2023-05-03 13:11:27 +02:00
parent d7ccd3069f
commit 912945a142
Signed by: femsci
GPG key ID: 08F7911F0E650C67
11 changed files with 199 additions and 92 deletions

View file

@ -0,0 +1,35 @@
using System.Net;
using System.Net.Sockets;
namespace IPMeow.Lib.Address;
public class IPv4Address
{
public IPv4Address(byte[] bytes)
{
if (bytes.Length != 4)
{
throw new ArgumentException("Invalid byte length.");
}
_addr = BitConverter.ToUInt32(bytes);
}
public IPv4Address(long address)
{
_addr = (uint)address;
}
public IPv4Address(IPAddress address)
{
if (address.AddressFamily != AddressFamily.InterNetwork)
{
throw new ArgumentException($"Invalid address type: {address.AddressFamily}. Expected IPv4.");
}
_addr = BitConverter.ToUInt32(address.GetAddressBytes());
}
private readonly uint _addr;
public static implicit operator IPAddress(IPv4Address addr) => new(addr._addr);
}

View file

@ -0,0 +1,30 @@
using System.Net;
using System.Net.Sockets;
namespace IPMeow.Lib.Address;
public class IPv6Address
{
public IPv6Address(byte[] address)
{
if (address.Length != 16)
{
throw new ArgumentException("Invalid address. Expected 16 bytes.");
}
_addr = address;
}
public IPv6Address(IPAddress address)
{
if (address.AddressFamily != AddressFamily.InterNetworkV6)
{
throw new ArgumentException($"Invalid address type: {address.AddressFamily}. Expected IPv6.");
}
_addr = address.GetAddressBytes();
}
private readonly byte[] _addr;
public static implicit operator IPAddress(IPv6Address addr) => new(addr._addr);
}

View file

@ -0,0 +1,104 @@
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
namespace IPMeow.Lib.Address;
public readonly struct MacAddress
{
public MacAddress(byte[] addr)
{
if (addr.Length != 6)
{
throw new ArgumentException("Invalid address bytes.");
}
addrBytes = addr;
}
public static MacAddress Parse(byte[] addr)
{
if (TryParse(addr, out MacAddress? mac))
{
return mac.Value;
}
throw new ArgumentException("Invalid address byte length. Expected 6 octets.");
}
public static MacAddress Parse(string addr)
{
if (TryParse(addr, out MacAddress? mac))
{
return mac.Value;
}
throw new FormatException("Invalid address format.");
}
public static bool TryParse(byte[] addr, [NotNullWhen(true)] out MacAddress? mac)
{
mac = null;
if (addr.Length != 6)
{
return false;
}
mac = new(addr);
return true;
}
public static bool TryParse(string addr, [NotNullWhen(true)] out MacAddress? mac)
{
mac = null;
string[] bytes = addr.Split(":");
if (bytes.Length != 6)
{
throw new ArgumentException("Invalid address length. Expected 6 octets.");
}
var addrBytes = bytes.Select(byteStr =>
{
if (byte.TryParse(byteStr, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out byte b))
{
return b;
}
throw new ArgumentException($"{byteStr} is not a valid hex byte.");
}).ToArray();
mac = new(addrBytes);
return true;
}
private readonly byte[] addrBytes;
public override readonly bool Equals([NotNullWhen(true)] object? obj)
{
return obj is MacAddress addr && this.addrBytes.SequenceEqual(addr.addrBytes);
}
public static bool operator ==(MacAddress a, MacAddress b)
{
return a.addrBytes.SequenceEqual(b.addrBytes);
}
public static bool operator !=(MacAddress a, MacAddress b)
{
return !(a == b);
}
public override readonly string ToString()
{
return string.Join(':', addrBytes.Select(b => b.ToString("x2")));
}
public override int GetHashCode()
{
return addrBytes.GetHashCode();
}
}

View file

@ -0,0 +1,10 @@
using System.Net;
namespace IPMeow.Lib.Address;
public abstract class Network
{
public abstract bool IsInNetwork(IPAddress addr);
public abstract bool IsSubnetOf(Network n);
};

View file

@ -1,8 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace IPMeow.Lib;
public class BitEnumerator

View file

@ -1,16 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel.DataAnnotations;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
using IPMeow.Lib.Address;
namespace IPMeow.Lib;
namespace IPMeow.Lib.Host;
public class Host : IBindable
{
[Key]
public required string Id { get; set; }
public DateTime? LastPing { get; set; }
public required IPAddressCollection Addresses { get; set; }
public required MacAddress Mac { get; set; }
public required MacAddress Mac { get; set; }
}

View file

@ -0,0 +1,10 @@
using System.Net;
namespace IPMeow.Lib.Host;
public class HostEntry
{
public string? Name { get; set; }
public required IPAddress Address { get; set; }
public int Priority { get; set; } = 0;
}

View file

@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
using IPMeow.Lib.Address;
namespace IPMeow.Lib;
namespace IPMeow.Lib.Host;
public interface IBindable
{

View file

@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
namespace IPMeow.Lib;
public class HostEntry
{
public string? Name { get; set; }
public required IPAddress Address { get; set; }
public int Priority { get; set; } = 0;
}

View file

@ -1,58 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
namespace IPMeow.Lib;
public readonly struct MacAddress
{
public MacAddress(byte[] addr)
{
if (addr.Length != 6)
{
throw new ArgumentException("Invalid address bytes.");
}
addrBytes = addr;
}
public MacAddress(string addr)
{
string[] bytes = addr.Split(":");
if (bytes.Length != 6)
{
throw new ArgumentException("Invalid format.");
}
addrBytes = bytes.Select(byteStr =>
{
if (byte.TryParse(byteStr, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out byte b))
{
return b;
}
throw new ArgumentException($"{byteStr} is not a valid hex byte.");
}).ToArray();
}
private readonly byte[] addrBytes;
public override readonly bool Equals([NotNullWhen(true)] object? obj)
{
return obj is MacAddress addr && this.addrBytes.SequenceEqual(addr.addrBytes);
}
public override readonly string ToString()
{
return string.Join(':', addrBytes.Select(b => b.ToString("x2")));
}
public override int GetHashCode()
{
return addrBytes.GetHashCode();
}
}

View file

@ -1,5 +1,5 @@
using IPMeow.Lib;
using Xunit;
using IPMeow.Lib.Address;
namespace IPMeow.Test;
@ -8,8 +8,8 @@ public class StructTests
[Fact]
public void MacAddressSerializationTest()
{
var addrFromString = new MacAddress("fe:ed:de:ad:be:ef");
var addrFromBytes = new MacAddress(new byte[] { 0xfe, 0xed, 0xde, 0xad, 0xbe, 0xef });
var addrFromString = MacAddress.Parse("fe:ed:de:ad:be:ef");
var addrFromBytes = MacAddress.Parse(new byte[] { 0xfe, 0xed, 0xde, 0xad, 0xbe, 0xef });
Assert.Equal(addrFromString, addrFromBytes);