Work on DHCP

This commit is contained in:
Jöran Malek 2023-11-16 00:38:35 +01:00
parent 377e4744ec
commit ec31039eed
18 changed files with 182 additions and 29 deletions

6
ext/dhcp4.leases Normal file
View file

@ -0,0 +1,6 @@
address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context
192.0.2.1,06:07:08:09:0a:bc,,200,200,8,1,1,host.example.com,0,
192.0.2.2,,,200,200,8,1,1,host.example.com,0,
192.0.2.3,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,100,100,7,0,0,,1,{ "foobar": true }
192.0.2.4,,11:22:33:44:55:66,200,200,8,1,1,host.example.com,0,
192.0.2.5,,,200,200,8,1,1,,1,

7
ext/dhcp6.leases Normal file
View file

@ -0,0 +1,7 @@
address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,state,user_context,hwtype,hwaddr_source,pool_id
2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,200,8,100,0,7,0,1,1,host.example.com,,1,,1,0,0
2001:db8:1::1,,200,200,8,100,0,7,0,1,1,host.example.com,,1,,1,0,0
2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,300,300,6,150,0,8,0,0,0,,,1,,1,0,0
3000:1::,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,0,200,8,0,2,16,64,0,0,,,1,{ "foobar": true },,1,0,0
2001:db8:1::2,00:00:00,200,200,8,100,0,7,0,1,1,host.example.com,,0,,1,0,0
2001:db8:1::3,00:00:00,200,200,8,100,0,7,0,1,1,host.example.com,,1,,1,0,0

View file

@ -0,0 +1,17 @@
namespace pdns_dhcp.Kea;
// ref: https://github.com/isc-projects/kea/blob/Kea-2.5.3/src/lib/dhcpsrv/csv_lease_file4.h
public record struct KeaDhcp4Lease(
string Address,
string HWAddr,
string? ClientId,
UInt32 ValidLifetime,
UInt64 Expire,
string SubnetId,
byte FqdnFwd,
byte FqdnRev,
string Hostname,
UInt32 State,
string UserContext,
UInt32 PoolId
);

View file

@ -0,0 +1,23 @@
namespace pdns_dhcp.Kea;
// ref: https://github.com/isc-projects/kea/blob/Kea-2.5.3/src/lib/dhcpsrv/csv_lease_file6.h
public record struct KeaDhcp6Lease(
string Address,
string DUId,
UInt32 ValidLifetime,
UInt64 Expire,
string SubnetId,
UInt32 PrefLifetime,
LeaseType LeaseType,
UInt32 IAId,
Byte PrefixLen,
byte FqdnFwd,
byte FqdnRev,
string Hostname,
string HWAddr,
UInt32 State,
string UserContext,
UInt16? HWType,
UInt32? HWAddrSource,
UInt32 PoolId
);

View file

@ -0,0 +1,5 @@
namespace pdns_dhcp.Kea;
public class KeaLeaseWatcher
{
}

View file

@ -0,0 +1,9 @@
namespace pdns_dhcp.Kea;
public enum LeaseType : byte
{
NonTempraryIPv6 = 0,
TemporaryIPv6 = 1,
IPv6Prefix = 2,
IPv4 = 3
}

View file

@ -0,0 +1,6 @@
namespace pdns_dhcp.Options;
public class DhcpOptions
{
public KeaDhcpOptions? Kea { get; set; }
}

View file

@ -7,4 +7,4 @@ public class KeaDhcpOptions
public KeaDhcpServerOptions? Dhcp6 { get; set; }
}
public record class KeaDhcpServerOptions(FileInfo Leases);
public record class KeaDhcpServerOptions(string Leases);

View file

@ -0,0 +1,12 @@
using System.Net.Sockets;
using Stl.Interception;
namespace pdns_dhcp.PowerDns;
public interface IPowerDnsFactory : IRequiresFullProxy
{
PowerDnsStreamClient CreateClient(Stream stream);
PowerDnsUnixSocket CreateUnixSocket(string socketPath);
}

View file

@ -1,11 +1,27 @@
using System.Net.Sockets;
using Microsoft.Extensions.Hosting;
namespace pdns_dhcp.PowerDns;
public class PowerDnsSocket
public class PowerDnsUnixSocket : BackgroundService
{
public PowerDnsSocket()
{
private readonly IPowerDnsFactory _factory;
private readonly Socket _socket;
public PowerDnsUnixSocket(string socketPath, IPowerDnsFactory factory)
{
_factory = factory;
_socket = new(SocketType.Stream, ProtocolType.Unspecified);
_socket.Bind(new UnixDomainSocketEndPoint(socketPath));
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_socket.Listen();
while (await _socket.AcceptAsync(stoppingToken) is { } client)
{
var instance = _factory.CreateClient(new NetworkStream(client, true));
}
}
}

View file

@ -0,0 +1,27 @@
namespace pdns_dhcp.PowerDns;
public class PowerDnsStreamClient : IDisposable
{
private readonly Stream _stream;
public PowerDnsStreamClient(Stream stream)
{
_stream = stream;
}
~PowerDnsStreamClient()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
_stream.Dispose();
}
}

View file

@ -1,8 +0,0 @@
using Stl.Interception;
namespace pdns_dhcp.PowerDns;
public interface SocketFactory : IRequiresFullProxy
{
PowerDnsSocket Create();
}

View file

@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using pdns_dhcp.Options;
@ -8,12 +9,12 @@ using pdns_dhcp.Services;
using Stl.Interception;
var builder = Host.CreateApplicationBuilder(args);
builder.Services.Configure<KeaDhcpOptions>(builder.Configuration.GetSection("KeaDhcp"));
builder.Services.Configure<PowerDnsOptions>(builder.Configuration.GetSection("PowerDns"));
builder.Services.Configure<DhcpOptions>(builder.Configuration.GetRequiredSection("Dhcp"));
builder.Services.Configure<PowerDnsOptions>(builder.Configuration.GetRequiredSection("PowerDns"));
builder.Services.AddHostedService<DhcpLeaseWatcher>();
builder.Services.AddHostedService<PowerDnsBackend>();
builder.Services.AddTypedFactory<SocketFactory>();
builder.Services.AddTypedFactory<IPowerDnsFactory>();
builder.Build().Run();

View file

@ -1,20 +1,15 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using pdns_dhcp.Options;
using pdns_dhcp.PowerDns;
namespace pdns_dhcp.Services;
public class DhcpLeaseWatcher : IHostedService
{
private readonly PowerDnsOptions _options;
private readonly PowerDnsSocket _socket;
public DhcpLeaseWatcher(IOptions<PowerDnsOptions> options, SocketFactory factory)
public DhcpLeaseWatcher(IOptions<DhcpOptions> options)
{
_options = options.Value;
_socket = factory.Create();
}
public Task StartAsync(CancellationToken cancellationToken)

View file

@ -1,9 +1,23 @@
using System.Net.Sockets;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using pdns_dhcp.Options;
using pdns_dhcp.PowerDns;
namespace pdns_dhcp.Services;
public class PowerDnsBackend : IHostedService
{
private readonly PowerDnsOptions _options;
public PowerDnsBackend(IOptions<PowerDnsOptions> options, IPowerDnsFactory socketFactory)
{
_options = options.Value;
}
public Task StartAsync(CancellationToken cancellationToken)
{
throw new NotImplementedException();

View file

@ -0,0 +1,17 @@
{
"PowerDns": {
"Listener": {
"Socket": "/run/pdns-dhcp/pdns.sock"
}
},
"Dhcp": {
"Kea": {
"Dhcp4": {
"Leases": "../../ext/kea/dhcp4.leases"
},
"DHcp6": {
"Leases": "../..ext/kea/dhcp4.leases"
}
}
}
}

View file

@ -4,12 +4,14 @@
"Socket": "/run/pdns-dhcp/pdns.sock"
}
},
"KeaDhcp": {
"Dhcp4": {
"Leases": "/var/lib/kea/dhcp4.leases"
},
"Dhcp6": {
"Leases": "/var/lib/kea/dhcp6.leases"
"Dhcp": {
"Kea": {
"Dhcp4": {
"Leases": "/var/lib/kea/dhcp4.leases"
},
"DHcp6": {
"Leases": "/var/lib/kea/dhcp6.leases"
}
}
}
}

View file

@ -6,10 +6,14 @@
<RootNamespace>pdns_dhcp</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishTrimmed>true</PublishTrimmed>
<EnableConfigurationBindingGenerator>true</EnableConfigurationBindingGenerator>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Sep" Version="0.2.7" />
<PackageReference Include="Stl.Generators" Version="6.5.44" />
<PackageReference Include="Stl.Interception" Version="6.5.43" />
</ItemGroup>