diff --git a/src/pdns-dhcp/Kea/KeaDhcp4Lease.cs b/src/pdns-dhcp/Kea/KeaDhcp4Lease.cs index fe5c437..0fb9b4a 100644 --- a/src/pdns-dhcp/Kea/KeaDhcp4Lease.cs +++ b/src/pdns-dhcp/Kea/KeaDhcp4Lease.cs @@ -22,50 +22,62 @@ public record struct KeaDhcp4Lease( { public static KeaDhcp4Lease Parse(in SepReader.Row row) { - var address = IPAddress.Parse(row[0].Span); - PhysicalAddress hwaddr = PhysicalAddress.None; - if (row[1].Span is { IsEmpty: false } physical) + KeaDhcp4Lease result = new(); + for (int i = 0; i < row.ColCount; i++) { - hwaddr = PhysicalAddress.Parse(physical); - } - string? clientId = row[2].ToString(); - uint validLifetime = uint.Parse(row[3].Span); - DateTimeOffset expire = DateTimeOffset.FromUnixTimeSeconds(unchecked((long)ulong.Parse(row[4].Span))); - uint subnetId = uint.Parse(row[5].Span); - bool fqdnFwd = sbyte.Parse(row[6].Span) != 0; - bool fqdnRev = sbyte.Parse(row[7].Span) != 0; - string hostname = KeaDhcpLease.Unescape(row[8].Span); + var span = row[i].Span; + switch (i) + { + case 0: + result.Address = IPAddress.Parse(span); + break; - uint state = 0; - if (row.ColCount > 9) - { - state = uint.Parse(row[9].Span); + case 1 when !span.IsWhiteSpace(): + result.HWAddr = PhysicalAddress.Parse(span); + break; + + case 2: + result.ClientId = span.ToString(); + break; + + case 3: + result.ValidLifetime = uint.Parse(span); + break; + + case 4: + result.Expire = DateTimeOffset.FromUnixTimeSeconds(unchecked((long)ulong.Parse(span))); + break; + + case 5: + result.SubnetId = uint.Parse(span); + break; + + case 6: + result.FqdnFwd = byte.Parse(span) != 0; + break; + + case 7: + result.FqdnRev = byte.Parse(span) != 0; + break; + + case 8: + result.Hostname = KeaDhcpLease.Unescape(span); + break; + + case 9: + result.State = uint.Parse(span); + break; + + case 10: + result.UserContext = KeaDhcpLease.Unescape(span); + break; + + case 11: + result.PoolId = uint.Parse(span); + break; + } } - string? userContext = default; - if (row.ColCount > 10) - { - userContext = KeaDhcpLease.Unescape(row[10].Span); - } - - uint poolId = 0; - if (row.ColCount > 11) - { - poolId = uint.Parse(row[11].Span); - } - - return new( - address, - hwaddr, - clientId, - validLifetime, - expire, - subnetId, - fqdnFwd, - fqdnRev, - hostname, - state, - userContext, - poolId); + return result; } } diff --git a/src/pdns-dhcp/Kea/KeaDhcp6Lease.cs b/src/pdns-dhcp/Kea/KeaDhcp6Lease.cs index c56b9fa..fd374a7 100644 --- a/src/pdns-dhcp/Kea/KeaDhcp6Lease.cs +++ b/src/pdns-dhcp/Kea/KeaDhcp6Lease.cs @@ -1,23 +1,113 @@ +using System.Net; +using System.Net.NetworkInformation; + +using nietras.SeparatedValues; + 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, + IPAddress Address, string DUId, uint ValidLifetime, - ulong Expire, - string SubnetId, + DateTimeOffset Expire, + uint SubnetId, uint PrefLifetime, LeaseType LeaseType, uint IAId, byte PrefixLen, - byte FqdnFwd, - byte FqdnRev, + bool FqdnFwd, + bool FqdnRev, string Hostname, - string HWAddr, + PhysicalAddress HWAddr, uint State, - string UserContext, + string? UserContext, ushort? HWType, uint? HWAddrSource, - uint PoolId -); + uint PoolId) +{ + public static KeaDhcp6Lease Parse(in SepReader.Row row) + { + KeaDhcp6Lease result = new(); + for (int i = 0; i < row.ColCount; i++) + { + var span = row[i].Span; + switch (i) + { + case 0: + 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; + } +}