diff --git a/.nyoki b/.nyoki new file mode 100644 index 0000000..a570c40 --- /dev/null +++ b/.nyoki @@ -0,0 +1,3 @@ +{ + "instanceId": "792b8690-893e-4c08-af61-1dd602d96cd4" +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..8541e7e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "sonarlint.connectedMode.project": { + "connectionId": "", + "projectKey": "" + } +} diff --git a/src/IPMeow.Dhcp/IPMeow.Dhcp.csproj b/src/IPMeow.Dhcp/IPMeow.Dhcp.csproj index 39a53d2..499b6e0 100644 --- a/src/IPMeow.Dhcp/IPMeow.Dhcp.csproj +++ b/src/IPMeow.Dhcp/IPMeow.Dhcp.csproj @@ -4,6 +4,10 @@ + + + + Exe net7.0 diff --git a/src/IPMeow.Dhcp/Program.cs b/src/IPMeow.Dhcp/Program.cs index 0b99310..50d605c 100644 --- a/src/IPMeow.Dhcp/Program.cs +++ b/src/IPMeow.Dhcp/Program.cs @@ -1,4 +1,6 @@ using IPMeow.Dhcp.Server.Dhcp4; +using IPMeow.Lib.Host; +using Microsoft.Extensions.Hosting; namespace IPMeow.Dhcp { @@ -6,10 +8,11 @@ namespace IPMeow.Dhcp { public static async Task Main(string[] args) { - Console.WriteLine("Listening on DHCP..."); - var dhcp = new DhcpServer(); + var app = Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args).Build(); - await dhcp.Run(); + Console.WriteLine("Listening on DHCP..."); + + await app.RunAsync(); } } } diff --git a/src/IPMeow.Dhcp/Server/Dhcp4/DhcpServer.cs b/src/IPMeow.Dhcp/Server/Dhcp4/DhcpServer.cs index a5adc83..fb9e642 100644 --- a/src/IPMeow.Dhcp/Server/Dhcp4/DhcpServer.cs +++ b/src/IPMeow.Dhcp/Server/Dhcp4/DhcpServer.cs @@ -1,17 +1,23 @@ using System.Net; using System.Net.Sockets; +using IPMeow.Lib.Address; namespace IPMeow.Dhcp.Server.Dhcp4; -public class DhcpServer +public class Dhcp4Server : IDhcpServer, IDisposable { public const int clientPort = 68, serverPort = 67; - public DhcpServer() + public Dhcp4Server(IAddressProvider addressProvider) { + _addrProvider = addressProvider; _udp = new UdpClient(serverPort, AddressFamily.InterNetwork); } + private readonly IAddressProvider _addrProvider; + + public event EventHandler DhcpRequestedEvent; + public async Task Run() { while (true) @@ -61,9 +67,13 @@ public class DhcpServer return false; } - return true; } + public void Dispose() + { + throw new NotImplementedException(); + } + private readonly UdpClient _udp; } diff --git a/src/IPMeow.Dhcp/Server/Dhcp6/DhcpServer.cs b/src/IPMeow.Dhcp/Server/Dhcp6/DhcpServer.cs index a83039e..7ee2bcb 100644 --- a/src/IPMeow.Dhcp/Server/Dhcp6/DhcpServer.cs +++ b/src/IPMeow.Dhcp/Server/Dhcp6/DhcpServer.cs @@ -1,18 +1,24 @@ using System.Net; using System.Net.Sockets; +using IPMeow.Lib.Address; namespace IPMeow.Dhcp.Server.Dhcp6; -public class DhcpServer : IDhcpServer, IDisposable +public class Dhcp6Server : IDhcpServer, IDisposable { public const int clientPort = 546, serverPort = 547; - public DhcpServer() + public Dhcp6Server(IAddressProvider addressProvider) { + _addrProvider = addressProvider; _listener = new(new IPEndPoint(IPAddress.Parse("ff02::1:2"), serverPort)); _sender = new(clientPort, AddressFamily.InterNetworkV6); } - private UdpClient _listener, _sender; + + private readonly IAddressProvider _addrProvider; + private readonly UdpClient _listener, _sender; + + public event EventHandler DhcpRequestedEvent; public void Dispose() { diff --git a/src/IPMeow.Dhcp/Server/DhcpEvent.cs b/src/IPMeow.Dhcp/Server/DhcpEvent.cs new file mode 100644 index 0000000..1dc3548 --- /dev/null +++ b/src/IPMeow.Dhcp/Server/DhcpEvent.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Threading.Tasks; +using IPMeow.Lib.Address; + +namespace IPMeow.Dhcp.Server; + +public class DhcpRequestEvent +{ + public bool IsV6 { get; init; } + public IPAddress? RequestOrigin { get; init; } + public MacAddress? MacAddress { get; init; } +} diff --git a/src/IPMeow.Dhcp/Server/IDhcpServer.cs b/src/IPMeow.Dhcp/Server/IDhcpServer.cs index b509d35..9d5977f 100644 --- a/src/IPMeow.Dhcp/Server/IDhcpServer.cs +++ b/src/IPMeow.Dhcp/Server/IDhcpServer.cs @@ -2,5 +2,7 @@ namespace IPMeow.Dhcp.Server; public interface IDhcpServer { - public Task Run(); + Task Run(); + + event EventHandler DhcpRequestedEvent; } diff --git a/src/IPMeow.Dhcp/Standalone/DecoupledAddressProvider.cs b/src/IPMeow.Dhcp/Standalone/DecoupledAddressProvider.cs new file mode 100644 index 0000000..37aa955 --- /dev/null +++ b/src/IPMeow.Dhcp/Standalone/DecoupledAddressProvider.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Threading.Tasks; +using IPMeow.Lib.Address; + +namespace IPMeow.Dhcp.Standalone; +public class DecoupledIPv6AddressProvider : IPv6AddressProvider +{ + public DecoupledIPv6AddressProvider(HttpClient http) + { + _http = http; + } + + private readonly HttpClient _http; + + public IPv6Address GetAddress() + { + _http.GetAsync("/api/request/6/free"); + throw new NotImplementedException(); + } + + public IPv6Address GetAddress(MacAddress mac) + { + throw new NotImplementedException(); + } +} + +public class DecoupledIPv4AddressProvider : IPv4AddressProvider +{ + public DecoupledIPv4AddressProvider(HttpClient http) + { + _http = http; + } + + private readonly HttpClient _http; + + public IPv4Address GetAddress() + { + _http.GetAsync("/api/request/4/free"); + throw new NotImplementedException(); + } + + public IPv4Address GetAddress(MacAddress mac) + { + _http.GetAsync($"/api/request/4/mac/{mac}"); + throw new NotImplementedException(); + } +} diff --git a/src/IPMeow.Lib/Address/IAddressProvider.cs b/src/IPMeow.Lib/Address/IAddressProvider.cs new file mode 100644 index 0000000..b2f4e3a --- /dev/null +++ b/src/IPMeow.Lib/Address/IAddressProvider.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Threading.Tasks; + +namespace IPMeow.Lib.Address; + +public interface IAddressProvider +{ + public IPAddress GetAddress(); + public IPAddress GetAddress(MacAddress mac); +} + +public interface IPv4AddressProvider +{ + public IPv4Address GetAddress(); + public IPv4Address GetAddress(MacAddress mac); +} + +public interface IPv6AddressProvider +{ + public IPv6Address GetAddress(); + public IPv6Address GetAddress(MacAddress mac); +} diff --git a/src/IPMeow.Lib/Address/IPv4Address.cs b/src/IPMeow.Lib/Address/IPv4Address.cs index 8cecac6..5a8f901 100644 --- a/src/IPMeow.Lib/Address/IPv4Address.cs +++ b/src/IPMeow.Lib/Address/IPv4Address.cs @@ -1,9 +1,10 @@ +using System.Diagnostics.CodeAnalysis; using System.Net; using System.Net.Sockets; namespace IPMeow.Lib.Address; -public class IPv4Address +public readonly struct IPv4Address { public IPv4Address(byte[] bytes) { @@ -32,4 +33,24 @@ public class IPv4Address private readonly uint _addr; public static implicit operator IPAddress(IPv4Address addr) => new(addr._addr); + + public override bool Equals([NotNullWhen(true)] object? obj) + { + return obj is IPv4Address addr && addr._addr == _addr; + } + + public override int GetHashCode() + { + return Math.Abs((int)_addr); + } + + public override string ToString() + { + byte o4 = (byte)(_addr & 0x000000ff), + o3 = (byte)(_addr & 0x0000ff00 >> 8), + o2 = (byte)(_addr & 0x00ff0000 >> 16), + o1 = (byte)(_addr & 0xff000000 >> 24); + + return $"{o1}.{o2}.{o3}.{o4}"; + } } diff --git a/src/IPMeow.Lib/Address/IPv6Address.cs b/src/IPMeow.Lib/Address/IPv6Address.cs index 837d605..d20b877 100644 --- a/src/IPMeow.Lib/Address/IPv6Address.cs +++ b/src/IPMeow.Lib/Address/IPv6Address.cs @@ -27,4 +27,19 @@ public class IPv6Address private readonly byte[] _addr; public static implicit operator IPAddress(IPv6Address addr) => new(addr._addr); + + public override bool Equals(object? obj) + { + return obj is IPv6Address addr && _addr.SequenceEqual(addr._addr); + } + + public override int GetHashCode() + { + return _addr.GetHashCode(); + } + + public override string? ToString() + { + return new IPAddress(_addr).ToString(); + } }