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();
+ }
}