MailSharp / MailSharp.DNS / Records / RecordIPSECKEY.cs
Code · 87 lines · 2648 bytes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/*
https://www.rfc-editor.org/rfc/rfc4025.html

 The RDATA for an IPSECKEY RR consists of a precedence value, a
   gateway type, a public key, algorithm type, and an optional gateway
   address.

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |  precedence   | gateway type  |  algorithm  |     gateway     |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------+                 +
      ~                            gateway                            ~
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                                                               /
      /                          public key                           /
      /                                                               /
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
 */

using MailSharp.DNS.Records;
using System.Net;

namespace MailSharp.DNS.Records;

public record RecordIPSECKEY : DnsRecord
{
	public byte Precedence { get; init; }
	public GatewayType GatewayType { get; init; }
	public byte Algorithm { get; init; }
	public IPAddress? GatewayAddress { get; init; }
	public string? GatewayName { get; init; }

	public byte[] PublicKey { get; init; }

	public RecordIPSECKEY(RecordReader rr) : base(rr)
	{
		ushort rdLength = rr.ReadUInt16(-2);

		Precedence = rr.ReadByte();
		GatewayType = (GatewayType)rr.ReadByte();
		Algorithm = rr.ReadByte();

		switch (GatewayType)
		{
			case GatewayType.NoGateway:
				// 1 byte "."
				if (rr.ReadByte() != 0) throw new FormatException("Expected root label for . gateway");
				break;

			case GatewayType.IPv4:
				GatewayAddress = new IPAddress(rr.ReadBytes(4));
				break;

			case GatewayType.IPv6:
				GatewayAddress = new IPAddress(rr.ReadBytes(16));
				break;

			case GatewayType.WireFormatDomainName:
				GatewayName = rr.ReadDomainName();
				break;
		}

		PublicKey = rr.ReadBytes(rdLength - rr.Position);
	}

	public override string ToString()
	{
		string gateway = GatewayType switch
		{
			GatewayType.NoGateway => ".",
			GatewayType.IPv4 => GatewayAddress?.ToString() ?? "0.0.0.0",
			GatewayType.IPv6 => GatewayAddress?.ToString() ?? "::",
			GatewayType.WireFormatDomainName => GatewayName ?? ".",
			_ => "?"
		};

		// Public key wordt standaard als Base64 getoond (zonder newlines)
		string base64Key = PublicKey.Length == 0
			? "."
			: Convert.ToBase64String(PublicKey);

		return $"{Precedence} {(byte)GatewayType} {Algorithm} {gateway} {base64Key}";
	}

}