util/dns.lua
author Kim Alvefur <zash@zash.se>
Tue, 15 Feb 2022 13:03:02 +0100
changeset 12292 08a933450922
parent 12245 dd15f42f6312
child 12293 3a655adf1d0d
permissions -rw-r--r--
util.dns: Replace base16 implementation with util.hex Less code!
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_gsub = string.gsub;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
local s_sub = string.sub;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    15
local s_match = string.match;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    16
local s_gmatch = string.gmatch;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    17
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    18
local have_net, net_util = pcall(require, "util.net");
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    19
12240
d0dfd48806f9 util.dns: Move DNS parameters details into util.dnsregistry
Kim Alvefur <zash@zash.se>
parents: 10976
diff changeset
    20
local iana_data = require "util.dnsregistry";
10965
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    21
if have_net and not net_util.ntop then -- Added in Prosody 0.11
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    22
	have_net = false;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    23
end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    24
12292
08a933450922 util.dns: Replace base16 implementation with util.hex
Kim Alvefur <zash@zash.se>
parents: 12245
diff changeset
    25
local tohex = require "util.hex".to;
10965
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    26
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    27
-- Simplified versions of Waqas DNS parsers
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    28
-- 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
    29
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    30
local parsers = {};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    31
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    32
-- 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
    33
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
    34
	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
    35
	local pack_len, r, len = #packet, {};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    36
	pos = pos or 1;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    37
	repeat
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    38
		len = s_byte(packet, pos) or 0;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    39
		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
    40
		pos = pos + len + 1;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    41
	until len == 0 or pos >= pack_len;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    42
	return t_concat(r, "."), pos;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    43
end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    44
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    45
-- These are just simple names.
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    46
parsers.CNAME = readDnsName;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    47
parsers.NS = readDnsName
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    48
parsers.PTR = readDnsName;
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
local soa_mt = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    51
	__tostring = function(rr)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    52
		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
    53
	end;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    54
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    55
function parsers.SOA(packet)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    56
	local mname, rname, offset;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    57
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    58
	mname, offset = readDnsName(packet, 1);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    59
	rname, offset = readDnsName(packet, offset);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    60
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    61
	-- 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
    62
	local
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    63
		s1, s2, s3, s4, -- serial
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    64
		r1, r2, r3, r4, -- refresh
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    65
		t1, t2, t3, t4, -- retry
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    66
		e1, e2, e3, e4, -- expire
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    67
		m1, m2, m3, m4  -- minimum
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    68
			= s_byte(packet, offset, offset + 19);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    69
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    70
	return setmetatable({
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    71
		mname = mname;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    72
		rname = rname;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    73
		serial  = s1*0x1000000 + s2*0x10000 + s3*0x100 + s4;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    74
		refresh = r1*0x1000000 + r2*0x10000 + r3*0x100 + r4;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    75
		retry   = t1*0x1000000 + t2*0x10000 + t3*0x100 + t4;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    76
		expire  = e1*0x1000000 + e2*0x10000 + e3*0x100 + e4;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    77
		minimum = m1*0x1000000 + m2*0x10000 + m3*0x100 + m4;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    78
	}, soa_mt);
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.A(packet)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    82
	return s_format("%d.%d.%d.%d", s_byte(packet, 1, 4));
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    83
end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    84
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    85
local aaaa = { nil, nil, nil, nil, nil, nil, nil, nil, };
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    86
function parsers.AAAA(packet)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    87
	local hi, lo, ip, len, token;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    88
	for i = 1, 8 do
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    89
		hi, lo = s_byte(packet, i * 2 - 1, i * 2);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    90
		aaaa[i] = s_format("%x", hi * 256 + lo); -- skips leading zeros
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    91
	end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    92
	ip = t_concat(aaaa, ":", 1, 8);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    93
	len = (s_match(ip, "^0:[0:]+()") or 1) - 1;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    94
	for s in s_gmatch(ip, ":0:[0:]+") do
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    95
		if len < #s then len, token = #s, s; end -- find longest sequence of zeros
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    96
	end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    97
	return (s_gsub(ip, token or "^0:[0:]+", "::", 1));
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    98
end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    99
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   100
if have_net then
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   101
	parsers.A = net_util.ntop;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   102
	parsers.AAAA = net_util.ntop;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   103
end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   104
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   105
local mx_mt = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   106
	__tostring = function(rr)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   107
		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
   108
	end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   109
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   110
function parsers.MX(packet)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   111
	local name = readDnsName(packet, 3);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   112
	local b1,b2 = s_byte(packet, 1, 2);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   113
	return setmetatable({
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   114
		pref = b1*256+b2;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   115
		mx = name;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   116
	}, mx_mt);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   117
end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   118
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   119
local srv_mt = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   120
	__tostring = function(rr)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   121
		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
   122
	end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   123
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   124
function parsers.SRV(packet)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   125
	local name = readDnsName(packet, 7);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   126
	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
   127
	return setmetatable({
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   128
		priority = b1*256+b2;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   129
		weight   = b3*256+b4;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   130
		port     = b5*256+b6;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   131
		target   = name;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   132
	}, srv_mt);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   133
end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   134
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   135
local txt_mt = { __tostring = t_concat };
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   136
function parsers.TXT(packet)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   137
	local pack_len = #packet;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   138
	local r, pos, len = {}, 1;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   139
	repeat
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   140
		len = s_byte(packet, pos) or 0;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   141
		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
   142
		pos = pos + len + 1;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   143
	until pos >= pack_len;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   144
	return setmetatable(r, txt_mt);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   145
end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   146
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   147
parsers.SPF = parsers.TXT;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   148
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   149
-- Acronyms from RFC 7218
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   150
local tlsa_usages = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   151
	[0] = "PKIX-CA";
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   152
	[1] = "PKIX-EE";
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   153
	[2] = "DANE-TA";
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   154
	[3] = "DANE-EE";
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   155
	[255] = "PrivCert";
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   156
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   157
local tlsa_selectors = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   158
	[0] = "Cert",
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   159
	[1] = "SPKI",
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   160
	[255] = "PrivSel",
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   161
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   162
local tlsa_match_types = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   163
	[0] = "Full",
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   164
	[1] = "SHA2-256",
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   165
	[2] = "SHA2-512",
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   166
	[255] = "PrivMatch",
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   167
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   168
local tlsa_mt = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   169
	__tostring = function(rr)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   170
		return s_format("%s %s %s %s",
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   171
			tlsa_usages[rr.use] or rr.use,
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   172
			tlsa_selectors[rr.select] or rr.select,
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   173
			tlsa_match_types[rr.match] or rr.match,
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   174
			tohex(rr.data));
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   175
	end;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   176
	__index = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   177
		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
   178
		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
   179
		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
   180
	}
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   181
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   182
function parsers.TLSA(packet)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   183
	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
   184
	return setmetatable({
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   185
		use = use;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   186
		select = select;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   187
		match = match;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   188
		data = s_sub(packet, 4);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   189
	}, tlsa_mt);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   190
end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   191
12245
dd15f42f6312 util.dns: Minor updates of SVCB parser
Kim Alvefur <zash@zash.se>
parents: 12244
diff changeset
   192
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
   193
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
   194
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   195
local svcb_mt = {
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   196
	__tostring = function (rr)
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   197
		local kv = {};
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   198
		for i = 1, #rr.fields do
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   199
			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
   200
			-- 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
   201
		end
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   202
		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
   203
	end;
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   204
};
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   205
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
   206
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   207
function parsers.SVCB(packet)
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   208
	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
   209
	local prio = prio_h*256+prio_l;
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   210
	local name, pos = readDnsName(packet, 3);
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   211
	local fields = {};
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   212
	while #packet > pos do
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   213
		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
   214
		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
   215
		local key = key_h*256+key_l;
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   216
		local len = len_h*256+len_l;
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   217
		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
   218
		if key == 1 then
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   219
			value = setmetatable(parsers.TXT(value), svbc_ip_mt);
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   220
		elseif key == 3 then
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   221
			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
   222
			local port = port_h*256+port_l;
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   223
			value = port;
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   224
		elseif key == 4 then
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   225
			local ip = {};
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   226
			for i = 1, #value, 4 do
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   227
				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
   228
			end
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   229
			value = setmetatable(ip, svbc_ip_mt);
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   230
		elseif key == 6 then
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   231
			local ip = {};
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   232
			for i = 1, #value, 16 do
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   233
				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
   234
			end
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   235
			value = setmetatable(ip, svbc_ip_mt);
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   236
		end
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   237
		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
   238
		pos = pos+len+4;
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   239
	end
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   240
	return setmetatable({
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   241
			prio = prio, name = name, fields = fields,
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   242
		}, svcb_mt);
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   243
end
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   244
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   245
parsers.HTTPS = parsers.SVCB;
ffd66b461f6a util.dns: Implement SVCB record parser
Kim Alvefur <zash@zash.se>
parents: 12243
diff changeset
   246
10965
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   247
local params = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   248
	TLSA = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   249
		use = tlsa_usages;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   250
		select = tlsa_selectors;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   251
		match = tlsa_match_types;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   252
	};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   253
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   254
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   255
local fallback_mt = {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   256
	__tostring = function(rr)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   257
		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
   258
	end;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   259
};
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   260
local function fallback_parser(packet)
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   261
	return setmetatable({ raw = packet },fallback_mt);
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   262
end
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   263
setmetatable(parsers, { __index = function() return fallback_parser end });
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   264
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   265
return {
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   266
	parsers = parsers;
12240
d0dfd48806f9 util.dns: Move DNS parameters details into util.dnsregistry
Kim Alvefur <zash@zash.se>
parents: 10976
diff changeset
   267
	classes = iana_data.classes;
d0dfd48806f9 util.dns: Move DNS parameters details into util.dnsregistry
Kim Alvefur <zash@zash.se>
parents: 10976
diff changeset
   268
	types = iana_data.types;
d0dfd48806f9 util.dns: Move DNS parameters details into util.dnsregistry
Kim Alvefur <zash@zash.se>
parents: 10976
diff changeset
   269
	errors = iana_data.errors;
10965
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   270
	params = params;
f93dce30089a util.dns: Library for decoding DNS records
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   271
};