util/dns.lua
author Kim Alvefur <zash@zash.se>
Mon, 07 Mar 2022 00:35:29 +0100
changeset 12392 50fcd3879482
parent 12359 a0ff5c438e9d
child 12979 d10957394a3c
permissions -rw-r--r--
spelling: non-existing mistakes (thanks timeless)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10965
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
-- libunbound based net.adns replacement for Prosody IM
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
-- Copyright (C) 2012-2015 Kim Alvefur
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
-- Copyright (C) 2012 Waqas Hussain
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     4
--
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
-- This file is MIT licensed.
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
local setmetatable = setmetatable;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
local table = table;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
local t_concat = table.concat;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
local t_insert = table.insert;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
local s_byte = string.byte;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    12
local s_format = string.format;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    13
local s_sub = string.sub;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
12240
d0dfd48806f9 util.dns: Move DNS parameters details into util.dnsregistry
Kim Alvefur <zash@zash.se>
parents: 10976
diff changeset
    15
local iana_data = require "util.dnsregistry";
12359
a0ff5c438e9d util.hex: Deprecate to/from in favour of encode/decode, for consistency!
Matthew Wild <mwild1@gmail.com>
parents: 12293
diff changeset
    16
local tohex = require "util.hex".encode;
12293
3a655adf1d0d util.dns: Remove compat for pre-0.11 lack of inet_ntop binding
Kim Alvefur <zash@zash.se>
parents: 12292
diff changeset
    17
local inet_ntop = require "util.net".ntop;
10965
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    18
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    19
-- Simplified versions of Waqas DNS parsers
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    20
-- Only the per RR parsers are needed and only feed a single RR
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    21
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    22
local parsers = {};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    23
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    24
-- No support for pointers, but libunbound appears to take care of that.
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    25
local function readDnsName(packet, pos)
12243
578ce0415398 util.dns: Fix returning read position after zero-length name
Kim Alvefur <zash@zash.se>
parents: 12240
diff changeset
    26
	if s_byte(packet, pos) == 0 then return ".", pos+1; end
10965
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    27
	local pack_len, r, len = #packet, {};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    28
	pos = pos or 1;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    29
	repeat
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    30
		len = s_byte(packet, pos) or 0;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    31
		t_insert(r, s_sub(packet, pos + 1, pos + len));
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    32
		pos = pos + len + 1;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    33
	until len == 0 or pos >= pack_len;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    34
	return t_concat(r, "."), pos;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    35
end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    36
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    37
-- These are just simple names.
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    38
parsers.CNAME = readDnsName;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    39
parsers.NS = readDnsName
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    40
parsers.PTR = readDnsName;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    41
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    42
local soa_mt = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    43
	__tostring = function(rr)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    44
		return s_format("%s %s %d %d %d %d %d", rr.mname, rr.rname, rr.serial, rr.refresh, rr.retry, rr.expire, rr.minimum);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    45
	end;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    46
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    47
function parsers.SOA(packet)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    48
	local mname, rname, offset;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    49
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    50
	mname, offset = readDnsName(packet, 1);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    51
	rname, offset = readDnsName(packet, offset);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    52
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    53
	-- Extract all the bytes of these fields in one call
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    54
	local
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    55
		s1, s2, s3, s4, -- serial
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    56
		r1, r2, r3, r4, -- refresh
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    57
		t1, t2, t3, t4, -- retry
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    58
		e1, e2, e3, e4, -- expire
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    59
		m1, m2, m3, m4  -- minimum
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    60
			= s_byte(packet, offset, offset + 19);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    61
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    62
	return setmetatable({
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    63
		mname = mname;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    64
		rname = rname;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    65
		serial  = s1*0x1000000 + s2*0x10000 + s3*0x100 + s4;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    66
		refresh = r1*0x1000000 + r2*0x10000 + r3*0x100 + r4;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    67
		retry   = t1*0x1000000 + t2*0x10000 + t3*0x100 + t4;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    68
		expire  = e1*0x1000000 + e2*0x10000 + e3*0x100 + e4;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    69
		minimum = m1*0x1000000 + m2*0x10000 + m3*0x100 + m4;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    70
	}, soa_mt);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    71
end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    72
12293
3a655adf1d0d util.dns: Remove compat for pre-0.11 lack of inet_ntop binding
Kim Alvefur <zash@zash.se>
parents: 12292
diff changeset
    73
parsers.A = inet_ntop;
3a655adf1d0d util.dns: Remove compat for pre-0.11 lack of inet_ntop binding
Kim Alvefur <zash@zash.se>
parents: 12292
diff changeset
    74
parsers.AAAA = inet_ntop;
10965
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    75
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    76
local mx_mt = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    77
	__tostring = function(rr)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    78
		return s_format("%d %s", rr.pref, rr.mx)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    79
	end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    80
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    81
function parsers.MX(packet)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    82
	local name = readDnsName(packet, 3);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    83
	local b1,b2 = s_byte(packet, 1, 2);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    84
	return setmetatable({
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    85
		pref = b1*256+b2;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    86
		mx = name;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    87
	}, mx_mt);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    88
end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    89
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    90
local srv_mt = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    91
	__tostring = function(rr)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    92
		return s_format("%d %d %d %s", rr.priority, rr.weight, rr.port, rr.target);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    93
	end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    94
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    95
function parsers.SRV(packet)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    96
	local name = readDnsName(packet, 7);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    97
	local b1, b2, b3, b4, b5, b6 = s_byte(packet, 1, 6);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    98
	return setmetatable({
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    99
		priority = b1*256+b2;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   100
		weight   = b3*256+b4;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   101
		port     = b5*256+b6;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   102
		target   = name;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   103
	}, srv_mt);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   104
end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   105
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   106
local txt_mt = { __tostring = t_concat };
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   107
function parsers.TXT(packet)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   108
	local pack_len = #packet;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   109
	local r, pos, len = {}, 1;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   110
	repeat
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   111
		len = s_byte(packet, pos) or 0;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   112
		t_insert(r, s_sub(packet, pos + 1, pos + len));
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   113
		pos = pos + len + 1;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   114
	until pos >= pack_len;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   115
	return setmetatable(r, txt_mt);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   116
end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   117
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   118
parsers.SPF = parsers.TXT;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   119
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   120
-- Acronyms from RFC 7218
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   121
local tlsa_usages = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   122
	[0] = "PKIX-CA";
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   123
	[1] = "PKIX-EE";
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   124
	[2] = "DANE-TA";
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   125
	[3] = "DANE-EE";
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   126
	[255] = "PrivCert";
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   127
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   128
local tlsa_selectors = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   129
	[0] = "Cert",
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   130
	[1] = "SPKI",
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   131
	[255] = "PrivSel",
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   132
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   133
local tlsa_match_types = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   134
	[0] = "Full",
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   135
	[1] = "SHA2-256",
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   136
	[2] = "SHA2-512",
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   137
	[255] = "PrivMatch",
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   138
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   139
local tlsa_mt = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   140
	__tostring = function(rr)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   141
		return s_format("%s %s %s %s",
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   142
			tlsa_usages[rr.use] or rr.use,
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   143
			tlsa_selectors[rr.select] or rr.select,
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   144
			tlsa_match_types[rr.match] or rr.match,
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   145
			tohex(rr.data));
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   146
	end;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   147
	__index = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   148
		getUsage = function(rr) return tlsa_usages[rr.use] end;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   149
		getSelector = function(rr) return tlsa_selectors[rr.select] end;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   150
		getMatchType = function(rr) return tlsa_match_types[rr.match] end;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   151
	}
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   152
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   153
function parsers.TLSA(packet)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   154
	local use, select, match = s_byte(packet, 1,3);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   155
	return setmetatable({
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   156
		use = use;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   157
		select = select;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   158
		match = match;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   159
		data = s_sub(packet, 4);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   160
	}, tlsa_mt);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   161
end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   162
12245
dd15f42f6312 util.dns: Minor updates of SVCB parser
Kim Alvefur <zash@zash.se>
parents: 12244
diff changeset
   163
local svcb_params = {"alpn"; "no-default-alpn"; "port"; "ipv4hint"; "ech"; "ipv6hint"};
12244
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   164
setmetatable(svcb_params, {__index = function(_, n) return "key" .. tostring(n); end});
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   165
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   166
local svcb_mt = {
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   167
	__tostring = function (rr)
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   168
		local kv = {};
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   169
		for i = 1, #rr.fields do
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   170
			t_insert(kv, s_format("%s=%q", svcb_params[rr.fields[i].key], tostring(rr.fields[i].value)));
12245
dd15f42f6312 util.dns: Minor updates of SVCB parser
Kim Alvefur <zash@zash.se>
parents: 12244
diff changeset
   171
			-- FIXME the =value part may be omitted when the value is "empty"
12244
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   172
		end
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   173
		return s_format("%d %s %s", rr.prio, rr.name, t_concat(kv, " "));
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   174
	end;
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   175
};
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   176
local svbc_ip_mt = {__tostring = function(ip) return t_concat(ip, ", "); end}
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   177
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   178
function parsers.SVCB(packet)
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   179
	local prio_h, prio_l = packet:byte(1,2);
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   180
	local prio = prio_h*256+prio_l;
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   181
	local name, pos = readDnsName(packet, 3);
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   182
	local fields = {};
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   183
	while #packet > pos do
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   184
		local key_h, key_l = packet:byte(pos+0,pos+1);
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   185
		local len_h, len_l = packet:byte(pos+2,pos+3);
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   186
		local key = key_h*256+key_l;
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   187
		local len = len_h*256+len_l;
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   188
		local value = packet:sub(pos+4,pos+4-1+len)
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   189
		if key == 1 then
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   190
			value = setmetatable(parsers.TXT(value), svbc_ip_mt);
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   191
		elseif key == 3 then
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   192
			local port_h, port_l = value:byte(1,2);
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   193
			local port = port_h*256+port_l;
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   194
			value = port;
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   195
		elseif key == 4 then
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   196
			local ip = {};
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   197
			for i = 1, #value, 4 do
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   198
				t_insert(ip, parsers.A(value:sub(i, i+3)));
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   199
			end
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   200
			value = setmetatable(ip, svbc_ip_mt);
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   201
		elseif key == 6 then
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   202
			local ip = {};
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   203
			for i = 1, #value, 16 do
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   204
				t_insert(ip, parsers.AAAA(value:sub(i, i+15)));
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   205
			end
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   206
			value = setmetatable(ip, svbc_ip_mt);
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   207
		end
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   208
		t_insert(fields, { key = key, value = value, len = len });
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   209
		pos = pos+len+4;
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   210
	end
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   211
	return setmetatable({
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   212
			prio = prio, name = name, fields = fields,
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   213
		}, svcb_mt);
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   214
end
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   215
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   216
parsers.HTTPS = parsers.SVCB;
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   217
10965
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   218
local params = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   219
	TLSA = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   220
		use = tlsa_usages;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   221
		select = tlsa_selectors;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   222
		match = tlsa_match_types;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   223
	};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   224
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   225
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   226
local fallback_mt = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   227
	__tostring = function(rr)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   228
		return s_format([[\# %d %s]], #rr.raw, tohex(rr.raw));
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   229
	end;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   230
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   231
local function fallback_parser(packet)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   232
	return setmetatable({ raw = packet },fallback_mt);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   233
end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   234
setmetatable(parsers, { __index = function() return fallback_parser end });
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   235
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   236
return {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   237
	parsers = parsers;
12240
d0dfd48806f9 util.dns: Move DNS parameters details into util.dnsregistry
Kim Alvefur <zash@zash.se>
parents: 10976
diff changeset
   238
	classes = iana_data.classes;
d0dfd48806f9 util.dns: Move DNS parameters details into util.dnsregistry
Kim Alvefur <zash@zash.se>
parents: 10976
diff changeset
   239
	types = iana_data.types;
d0dfd48806f9 util.dns: Move DNS parameters details into util.dnsregistry
Kim Alvefur <zash@zash.se>
parents: 10976
diff changeset
   240
	errors = iana_data.errors;
10965
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   241
	params = params;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   242
};