Dhcp6 parsing
This commit is contained in:
parent
a33c39e841
commit
81aec473ae
3 changed files with 183 additions and 92 deletions
|
|
@ -3,8 +3,12 @@ using System.Net.NetworkInformation;
|
||||||
|
|
||||||
using nietras.SeparatedValues;
|
using nietras.SeparatedValues;
|
||||||
|
|
||||||
|
using Cell = System.ReadOnlySpan<char>;
|
||||||
|
|
||||||
namespace pdns_dhcp.Kea;
|
namespace pdns_dhcp.Kea;
|
||||||
|
|
||||||
|
using Lease = KeaDhcp4Lease;
|
||||||
|
|
||||||
// ref: https://github.com/isc-projects/kea/blob/Kea-2.5.3/src/lib/dhcpsrv/csv_lease_file4.h
|
// ref: https://github.com/isc-projects/kea/blob/Kea-2.5.3/src/lib/dhcpsrv/csv_lease_file4.h
|
||||||
public record struct KeaDhcp4Lease(
|
public record struct KeaDhcp4Lease(
|
||||||
IPAddress Address,
|
IPAddress Address,
|
||||||
|
|
@ -20,9 +24,9 @@ public record struct KeaDhcp4Lease(
|
||||||
string? UserContext,
|
string? UserContext,
|
||||||
uint PoolId)
|
uint PoolId)
|
||||||
{
|
{
|
||||||
public static KeaDhcp4Lease? Parse(in SepReader.Row row)
|
public static Lease? Parse(in SepReader.Row row)
|
||||||
{
|
{
|
||||||
KeaDhcp4Lease result = new();
|
Lease result = new();
|
||||||
for (int i = 0; i < row.ColCount; i++)
|
for (int i = 0; i < row.ColCount; i++)
|
||||||
{
|
{
|
||||||
if (Parse(ref result, i, row[i].Span) == false)
|
if (Parse(ref result, i, row[i].Span) == false)
|
||||||
|
|
@ -34,7 +38,7 @@ public record struct KeaDhcp4Lease(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool? Parse(ref KeaDhcp4Lease lease, int column, in ReadOnlySpan<char> span)
|
private static bool? Parse(ref Lease lease, int column, in Cell span)
|
||||||
{
|
{
|
||||||
return column switch
|
return column switch
|
||||||
{
|
{
|
||||||
|
|
@ -50,84 +54,85 @@ public record struct KeaDhcp4Lease(
|
||||||
9 => ToState(ref lease, span),
|
9 => ToState(ref lease, span),
|
||||||
10 => ToUserContext(ref lease, span),
|
10 => ToUserContext(ref lease, span),
|
||||||
11 => ToPoolId(ref lease, span),
|
11 => ToPoolId(ref lease, span),
|
||||||
|
|
||||||
_ => null
|
_ => null
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool? ToIPAddress(ref KeaDhcp4Lease lease, in ReadOnlySpan<char> span)
|
static bool ToIPAddress(ref Lease lease, in Cell span)
|
||||||
{
|
{
|
||||||
bool result = IPAddress.TryParse(span, out var address);
|
bool result = IPAddress.TryParse(span, out var address);
|
||||||
lease.Address = address!;
|
lease.Address = address!;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool? ToHWAddr(ref KeaDhcp4Lease lease, in ReadOnlySpan<char> span)
|
static bool ToHWAddr(ref Lease lease, in Cell span)
|
||||||
{
|
{
|
||||||
bool result = PhysicalAddress.TryParse(span, out var hwaddr);
|
bool result = PhysicalAddress.TryParse(span, out var hwaddr);
|
||||||
lease.HWAddr = hwaddr!;
|
lease.HWAddr = hwaddr!;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool? ToClientId(ref KeaDhcp4Lease lease, in ReadOnlySpan<char> span)
|
static bool ToClientId(ref Lease lease, in Cell span)
|
||||||
{
|
{
|
||||||
lease.ClientId = span.ToString();
|
lease.ClientId = span.ToString();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool? ToValidLifetime(ref KeaDhcp4Lease lease, in ReadOnlySpan<char> span)
|
static bool ToValidLifetime(ref Lease lease, in Cell span)
|
||||||
{
|
{
|
||||||
bool result = uint.TryParse(span, out var validLifetime);
|
bool result = uint.TryParse(span, out var validLifetime);
|
||||||
lease.ValidLifetime = validLifetime;
|
lease.ValidLifetime = validLifetime;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool? ToExpire(ref KeaDhcp4Lease lease, in ReadOnlySpan<char> span)
|
static bool ToExpire(ref Lease lease, in Cell span)
|
||||||
{
|
{
|
||||||
bool result = ulong.TryParse(span, out var expire);
|
bool result = ulong.TryParse(span, out var expire);
|
||||||
lease.Expire = DateTimeOffset.FromUnixTimeSeconds(unchecked((long)expire));
|
lease.Expire = DateTimeOffset.FromUnixTimeSeconds(unchecked((long)expire));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool? ToSubnetId(ref KeaDhcp4Lease lease, in ReadOnlySpan<char> span)
|
static bool ToSubnetId(ref Lease lease, in Cell span)
|
||||||
{
|
{
|
||||||
bool result = uint.TryParse(span, out var subnetId);
|
bool result = uint.TryParse(span, out var subnetId);
|
||||||
lease.SubnetId = subnetId;
|
lease.SubnetId = subnetId;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool? ToFqdnFwd(ref KeaDhcp4Lease lease, in ReadOnlySpan<char> span)
|
static bool ToFqdnFwd(ref Lease lease, in Cell span)
|
||||||
{
|
{
|
||||||
bool result = byte.TryParse(span, out var fqdnFwd);
|
bool result = byte.TryParse(span, out var fqdnFwd);
|
||||||
lease.FqdnFwd = fqdnFwd != 0;
|
lease.FqdnFwd = fqdnFwd != 0;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool? ToFqdnRev(ref KeaDhcp4Lease lease, in ReadOnlySpan<char> span)
|
static bool ToFqdnRev(ref Lease lease, in Cell span)
|
||||||
{
|
{
|
||||||
bool result = byte.TryParse(span, out var fqdnRev);
|
bool result = byte.TryParse(span, out var fqdnRev);
|
||||||
lease.FqdnRev = fqdnRev != 0;
|
lease.FqdnRev = fqdnRev != 0;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool? ToHostname(ref KeaDhcp4Lease lease, in ReadOnlySpan<char> span)
|
static bool ToHostname(ref Lease lease, in Cell span)
|
||||||
{
|
{
|
||||||
lease.Hostname = KeaDhcpLease.Unescape(span);
|
lease.Hostname = KeaDhcpLease.Unescape(span);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool? ToState(ref KeaDhcp4Lease lease, in ReadOnlySpan<char> span)
|
static bool ToState(ref Lease lease, in Cell span)
|
||||||
{
|
{
|
||||||
bool result = uint.TryParse(span, out var state);
|
bool result = uint.TryParse(span, out var state);
|
||||||
lease.State = state;
|
lease.State = state;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool? ToUserContext(ref KeaDhcp4Lease lease, in ReadOnlySpan<char> span)
|
static bool ToUserContext(ref Lease lease, in Cell span)
|
||||||
{
|
{
|
||||||
lease.UserContext = KeaDhcpLease.Unescape(span);
|
lease.UserContext = KeaDhcpLease.Unescape(span);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool? ToPoolId(ref KeaDhcp4Lease lease, in ReadOnlySpan<char> span)
|
static bool ToPoolId(ref Lease lease, in Cell span)
|
||||||
{
|
{
|
||||||
bool result = uint.TryParse(span, out var poolId);
|
bool result = uint.TryParse(span, out var poolId);
|
||||||
lease.PoolId = poolId;
|
lease.PoolId = poolId;
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,12 @@ using System.Net.NetworkInformation;
|
||||||
|
|
||||||
using nietras.SeparatedValues;
|
using nietras.SeparatedValues;
|
||||||
|
|
||||||
|
using Cell = System.ReadOnlySpan<char>;
|
||||||
|
|
||||||
namespace pdns_dhcp.Kea;
|
namespace pdns_dhcp.Kea;
|
||||||
|
|
||||||
|
using Lease = KeaDhcp6Lease;
|
||||||
|
|
||||||
// ref: https://github.com/isc-projects/kea/blob/Kea-2.5.3/src/lib/dhcpsrv/csv_lease_file6.h
|
// ref: https://github.com/isc-projects/kea/blob/Kea-2.5.3/src/lib/dhcpsrv/csv_lease_file6.h
|
||||||
public record struct KeaDhcp6Lease(
|
public record struct KeaDhcp6Lease(
|
||||||
IPAddress Address,
|
IPAddress Address,
|
||||||
|
|
@ -26,88 +30,167 @@ public record struct KeaDhcp6Lease(
|
||||||
uint? HWAddrSource,
|
uint? HWAddrSource,
|
||||||
uint PoolId)
|
uint PoolId)
|
||||||
{
|
{
|
||||||
public static KeaDhcp6Lease Parse(in SepReader.Row row)
|
public static Lease? Parse(in SepReader.Row row)
|
||||||
{
|
{
|
||||||
KeaDhcp6Lease result = new();
|
Lease result = new();
|
||||||
for (int i = 0; i < row.ColCount; i++)
|
for (int i = 0; i < row.ColCount; i++)
|
||||||
{
|
{
|
||||||
var span = row[i].Span;
|
if (Parse(ref result, i, row[i].Span) == false)
|
||||||
switch (i)
|
|
||||||
{
|
{
|
||||||
case 0:
|
return null;
|
||||||
result.Address = IPAddress.Parse(span);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
result.DUId = span.ToString();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
result.ValidLifetime = uint.Parse(span);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
result.Expire = DateTimeOffset.FromUnixTimeSeconds(unchecked((long)ulong.Parse(span)));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
result.SubnetId = uint.Parse(span);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5:
|
|
||||||
result.PrefLifetime = uint.Parse(span);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 6:
|
|
||||||
result.LeaseType = (LeaseType)byte.Parse(span);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 7:
|
|
||||||
result.IAId = uint.Parse(span);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 8:
|
|
||||||
result.PrefixLen = byte.Parse(span);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 9:
|
|
||||||
result.FqdnFwd = byte.Parse(span) != 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 10:
|
|
||||||
result.FqdnRev = byte.Parse(span) != 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 11:
|
|
||||||
result.Hostname = KeaDhcpLease.Unescape(span);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 12 when !span.IsWhiteSpace():
|
|
||||||
result.HWAddr = PhysicalAddress.Parse(span);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 13:
|
|
||||||
result.State = uint.Parse(span);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 14 when !span.IsWhiteSpace():
|
|
||||||
result.UserContext = KeaDhcpLease.Unescape(span);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 15:
|
|
||||||
result.HWType = ushort.Parse(span);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 16:
|
|
||||||
result.HWAddrSource = uint.Parse(span);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 17:
|
|
||||||
result.PoolId = uint.Parse(span);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool? Parse(ref Lease lease, int column, in Cell span)
|
||||||
|
{
|
||||||
|
return column switch
|
||||||
|
{
|
||||||
|
0 => ToAddress(ref lease, span),
|
||||||
|
1 => ToDUId(ref lease, span),
|
||||||
|
2 => ToValidLifetime(ref lease, span),
|
||||||
|
3 => ToExpire(ref lease, span),
|
||||||
|
4 => ToSubnetId(ref lease, span),
|
||||||
|
5 => ToPrefLifetime(ref lease, span),
|
||||||
|
6 => ToLeaseType(ref lease, span),
|
||||||
|
7 => ToIAId(ref lease, span),
|
||||||
|
8 => ToPrefixLen(ref lease, span),
|
||||||
|
9 => ToFqdnFwd(ref lease, span),
|
||||||
|
10 => ToFqdnRev(ref lease, span),
|
||||||
|
11 => ToHostname(ref lease, span),
|
||||||
|
12 when !span.IsWhiteSpace() => ToHWAddr(ref lease, span),
|
||||||
|
13 => ToState(ref lease, span),
|
||||||
|
14 when !span.IsWhiteSpace() => ToUserContext(ref lease, span),
|
||||||
|
15 => ToHWType(ref lease, span),
|
||||||
|
16 => ToHWAddrSource(ref lease, span),
|
||||||
|
17 => ToPoolId(ref lease, span),
|
||||||
|
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool ToAddress(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
bool result = IPAddress.TryParse(span, out var address);
|
||||||
|
lease.Address = address!;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ToDUId(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
lease.DUId = span.ToString();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ToValidLifetime(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
bool result = uint.TryParse(span, out var validLifetime);
|
||||||
|
lease.ValidLifetime = validLifetime;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ToExpire(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
bool result = ulong.TryParse(span, out var expire);
|
||||||
|
lease.Expire = DateTimeOffset.FromUnixTimeSeconds(unchecked((long)expire));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ToSubnetId(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
bool result = uint.TryParse(span, out var subnetId);
|
||||||
|
lease.SubnetId = subnetId;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ToPrefLifetime(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
bool result = uint.TryParse(span, out var prefLifetime);
|
||||||
|
lease.PrefLifetime = prefLifetime;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ToLeaseType(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
bool result = byte.TryParse(span, out var leaseType);
|
||||||
|
lease.LeaseType = (LeaseType)leaseType;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ToIAId(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
bool result = uint.TryParse(span, out var iaId);
|
||||||
|
lease.IAId = iaId;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ToPrefixLen(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
bool result = byte.TryParse(span, out var prefixLen);
|
||||||
|
lease.PrefixLen = prefixLen;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ToFqdnFwd(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
bool result = byte.TryParse(span, out var fqdnFwd);
|
||||||
|
lease.FqdnFwd = fqdnFwd != 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ToFqdnRev(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
bool result = byte.TryParse(span, out var fqdnRev);
|
||||||
|
lease.FqdnRev = fqdnRev != 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ToHostname(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
lease.Hostname = KeaDhcpLease.Unescape(span);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ToHWAddr(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
bool result = PhysicalAddress.TryParse(span, out var hwAddr);
|
||||||
|
lease.HWAddr = hwAddr!;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ToState(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
bool result = uint.TryParse(span, out var state);
|
||||||
|
lease.State = state;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ToUserContext(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
lease.UserContext = KeaDhcpLease.Unescape(span);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ToHWType(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
bool result = ushort.TryParse(span, out var hwType);
|
||||||
|
lease.HWType = hwType;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ToHWAddrSource(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
bool result = uint.TryParse(span, out var hwAddrSource);
|
||||||
|
lease.HWAddrSource = hwAddrSource;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ToPoolId(ref Lease lease, in Cell span)
|
||||||
|
{
|
||||||
|
bool result = uint.TryParse(span, out var poolId);
|
||||||
|
lease.PoolId = poolId;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,11 @@ public class KeaDhcp6LeaseHandler : IKeaDhcpLeaseHandler
|
||||||
{
|
{
|
||||||
public DhcpLeaseChange? Handle(in SepReader.Row row)
|
public DhcpLeaseChange? Handle(in SepReader.Row row)
|
||||||
{
|
{
|
||||||
KeaDhcp6Lease lease = KeaDhcp6Lease.Parse(row);
|
if (KeaDhcp6Lease.Parse(row) is not { } lease)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return default;
|
return new(lease.Address, lease.Hostname, null, default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue