@nictool/dns-resource-record 1.2.3 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -7
- package/README.md +13 -19
- package/index.js +15 -0
- package/lib/tinydns.js +2 -6
- package/package.json +8 -6
- package/rr/aaaa.js +5 -4
- package/rr/apl.js +108 -0
- package/rr/caa.js +16 -10
- package/rr/cert.js +33 -5
- package/rr/cname.js +1 -2
- package/rr/dhcid.js +60 -0
- package/rr/dname.js +1 -2
- package/rr/dnskey.js +38 -11
- package/rr/ds.js +14 -5
- package/rr/hinfo.js +3 -9
- package/rr/hip.js +102 -0
- package/rr/https.js +12 -0
- package/rr/ipseckey.js +22 -9
- package/rr/key.js +15 -5
- package/rr/kx.js +77 -0
- package/rr/loc.js +6 -20
- package/rr/mx.js +3 -7
- package/rr/naptr.js +5 -2
- package/rr/ns.js +2 -6
- package/rr/nsec.js +12 -6
- package/rr/nsec3.js +2 -10
- package/rr/nxt.js +1 -6
- package/rr/openpgpkey.js +2 -3
- package/rr/rp.js +78 -0
- package/rr/rrsig.js +13 -3
- package/rr/smimea.js +44 -17
- package/rr/soa.js +3 -15
- package/rr/spf.js +1 -4
- package/rr/srv.js +3 -7
- package/rr/sshfp.js +20 -3
- package/rr/svcb.js +12 -0
- package/rr/tlsa.js +35 -19
- package/rr/tsig.js +1 -9
- package/rr/txt.js +7 -6
- package/rr/uri.js +1 -2
- package/rr/wks.js +37 -8
- package/rr.js +16 -32
package/CHANGELOG.md
CHANGED
|
@@ -4,26 +4,44 @@ Notable changes to this project are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
#### Unreleased
|
|
6
6
|
|
|
7
|
+
### [1.3.0] - 2026-03-01
|
|
8
|
+
|
|
9
|
+
- feat: add toTinydns for CERT, HTTPS, NSEC, SMIMEA, SVCB, WKS #51
|
|
10
|
+
- feat: add APL, KX, DHCID, HIP, and RP RR types #50
|
|
11
|
+
- feat: add WKS record setters, rdata fields, and tests #49
|
|
12
|
+
- style: wrap lines to 110 (was 80) chars
|
|
13
|
+
- tlsa: require cert assocc data
|
|
14
|
+
- deps(\*): update to latest, eslint 9 -> 10
|
|
15
|
+
|
|
16
|
+
### [1.2.4] - 2025-10-06
|
|
17
|
+
|
|
18
|
+
- rr: rename ucfirst -> ucFirst
|
|
19
|
+
- rr: setTTL was checking this.owner (copy/paste error)
|
|
20
|
+
- rr: improved throwHelp message formatting
|
|
21
|
+
- aaaa: compress & expand returns lower case
|
|
22
|
+
- caa, dnskey, ds, ipseckey, key, naptr, rrsig, smimea, sshfp, tlsa: refactored opts as JS maps
|
|
23
|
+
- deps: bump to latest versions
|
|
24
|
+
|
|
7
25
|
### [1.2.3] - 2025-04-14
|
|
8
26
|
|
|
9
27
|
- test(\*): fully qualify node modules
|
|
10
28
|
- feat(rr.isIPv?): added regexes to validate format
|
|
11
29
|
- dep(node:{net|util): remove, for browser compatiblity
|
|
12
30
|
- doc(CONTRIBUTORS.md): added
|
|
13
|
-
- ci: disable codeql schedule
|
|
31
|
+
- ci: disable codeql schedule #45
|
|
14
32
|
|
|
15
33
|
### [1.2.2] - 2024-11-17
|
|
16
34
|
|
|
17
35
|
- dep(eslint): update to v9 & config
|
|
18
36
|
- chore: tighten up fromBind regex
|
|
19
|
-
- packaging tweaks
|
|
37
|
+
- packaging tweaks #43
|
|
20
38
|
|
|
21
39
|
### [1.2.1] - 2024-03-10
|
|
22
40
|
|
|
23
41
|
- fix(nsec3param): fixed setHash fname typo
|
|
24
|
-
- feat(SVCB,HTTPS): add record support
|
|
42
|
+
- feat(SVCB,HTTPS): add record support #29
|
|
25
43
|
- feat(OPENGPGPKEY): improved bindline parser, added test
|
|
26
|
-
- feat(throwHelp): far more useful error messages
|
|
44
|
+
- feat(throwHelp): far more useful error messages #41
|
|
27
45
|
- feat(A,MX,AAAA,CAA,IPSECKEY): added getCanonical
|
|
28
46
|
|
|
29
47
|
### [1.2.0] - 2024-03-07
|
|
@@ -31,7 +49,7 @@ Notable changes to this project are documented in this file.
|
|
|
31
49
|
- feat(index): export typeMap (lookup table for type to id)
|
|
32
50
|
- feat(NXT): added bind support
|
|
33
51
|
- feat(TSIG, WKS): added stub class
|
|
34
|
-
- doc(README): move synopsis section into table
|
|
52
|
+
- doc(README): move synopsis section into table #38
|
|
35
53
|
- chore(style): set up prettier
|
|
36
54
|
|
|
37
55
|
### [1.1.6] - 2022-06-21
|
|
@@ -310,6 +328,8 @@ Notable changes to this project are documented in this file.
|
|
|
310
328
|
[1.1.8]: https://github.com/NicTool/dns-resource-record/releases/tag/1.1.8
|
|
311
329
|
[1.1.7]: https://github.com/NicTool/dns-resource-record/releases/tag/1.1.7
|
|
312
330
|
[1.2.0]: https://github.com/NicTool/dns-resource-record/releases/tag/1.2.0
|
|
313
|
-
[1.2.1]: https://github.com/NicTool/dns-resource-record/releases/tag/
|
|
331
|
+
[1.2.1]: https://github.com/NicTool/dns-resource-record/releases/tag/1.2.1
|
|
314
332
|
[1.2.2]: https://github.com/NicTool/dns-resource-record/releases/tag/1.2.2
|
|
315
|
-
[1.2.3]: https://github.com/NicTool/dns-resource-record/releases/tag/
|
|
333
|
+
[1.2.3]: https://github.com/NicTool/dns-resource-record/releases/tag/1.2.3
|
|
334
|
+
[1.2.4]: https://github.com/NicTool/dns-resource-record/releases/tag/1.2.4
|
|
335
|
+
[1.3.0]: https://github.com/NicTool/dns-resource-record/releases/tag/1.3.0
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# dns-resource-record
|
|
5
5
|
|
|
6
|
-
DNS resource record parser, validator, importer, and exporter.
|
|
6
|
+
DNS resource record parser, validator, importer, and exporter for node.js & browsers.
|
|
7
7
|
|
|
8
8
|
## SYNOPSIS
|
|
9
9
|
|
|
@@ -181,7 +181,7 @@ Consider this a "running with scissors" mode.
|
|
|
181
181
|
|
|
182
182
|
## Supported Records
|
|
183
183
|
|
|
184
|
-
This module intends to
|
|
184
|
+
This module intends to support all current (ie, not officially deprecated) DNS RRs **and** all RRs that are in active use on the internet.
|
|
185
185
|
|
|
186
186
|
PRs are welcome, especially PRs with tests.
|
|
187
187
|
|
|
@@ -189,39 +189,44 @@ PRs are welcome, especially PRs with tests.
|
|
|
189
189
|
| :------------: | :----------------: | :----------------: | :----------------: | :----------------: |
|
|
190
190
|
| **A** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
191
191
|
| **AAAA** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
192
|
+
| **APL** | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
|
|
192
193
|
| **CAA** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
193
|
-
| **CERT** | :white_check_mark: |
|
|
194
|
+
| **CERT** | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
|
|
194
195
|
| **CNAME** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
196
|
+
| **DHCID** | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
|
|
195
197
|
| **DNAME** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
196
198
|
| **DNSKEY** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
197
199
|
| **DS** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
198
200
|
| **HINFO** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
199
|
-
|
|
|
201
|
+
| **HIP** | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
|
|
202
|
+
| **HTTPS** | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
|
|
200
203
|
| **IPSECKEY** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
201
204
|
| **KEY** | | | | |
|
|
205
|
+
| **KX** | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
|
|
202
206
|
| **LOC** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
203
207
|
| **MX** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
204
208
|
| **NAPTR** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
205
209
|
| **NS** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
206
|
-
| **NSEC** | :white_check_mark: |
|
|
210
|
+
| **NSEC** | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
|
|
207
211
|
| **NSEC3** | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
|
|
208
212
|
| **NSEC3PARAM** | | | | |
|
|
209
213
|
| **NXT** | | | | |
|
|
210
214
|
| **OPENPGPKEY** | | | | |
|
|
211
215
|
| **PTR** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
216
|
+
| **RP** | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
|
|
212
217
|
| **RRSIG** | | | | |
|
|
213
218
|
| **SIG** | | | | |
|
|
214
|
-
| **SMIMEA** | :white_check_mark: |
|
|
219
|
+
| **SMIMEA** | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
|
|
215
220
|
| **SOA** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
216
221
|
| **SPF** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
217
222
|
| **SRV** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
218
223
|
| **SSHFP** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
219
|
-
| **SVCB** |
|
|
224
|
+
| **SVCB** | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
|
|
220
225
|
| **TLSA** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
221
226
|
| **TSIG** | | | | |
|
|
222
227
|
| **TXT** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
223
228
|
| **URI** | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
|
224
|
-
| **WKS** |
|
|
229
|
+
| **WKS** | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
|
|
225
230
|
|
|
226
231
|
## TIPS
|
|
227
232
|
|
|
@@ -244,17 +249,6 @@ PRs are welcome, especially PRs with tests.
|
|
|
244
249
|
|
|
245
250
|
## TODO
|
|
246
251
|
|
|
247
|
-
- [x] Change all IPs to use [RFC example/doc](https://en.wikipedia.org/wiki/Reserved_IP_addresses) address space
|
|
248
|
-
- [x] change all domains to use reserved doc names
|
|
249
|
-
- [x] import tests from nictool/server/t/12_records.t
|
|
250
|
-
- [x] add defaults for empty values like TTL
|
|
251
|
-
- [x] DNSSEC RRs: DS, NSEC, NSEC3, NSEC3PARAM, RRSIG
|
|
252
|
-
- [x] CERT RRs: CERT, KEY, SIG, OPENPGPKEY
|
|
253
|
-
- [x] RFC 4034: if the type of RR is NS, MD, MF, CNAME, SOA, MB,
|
|
254
|
-
MG, MR, PTR, HINFO, MINFO, MX, RP, AFSDB, RT, SIG, PX, NXT,
|
|
255
|
-
NAPTR, KX, SRV, DNAME, A6, RRSIG, or NSEC, all uppercase
|
|
256
|
-
letters in the DNS names contained within the RDATA are replaced by the lowercase letters;
|
|
257
|
-
- [x] LOC record ingest/out isn't consistent with API
|
|
258
252
|
- [ ] export a web page for each RR type
|
|
259
253
|
|
|
260
254
|
## DEVELOP
|
package/index.js
CHANGED
|
@@ -3,16 +3,20 @@ const typeMap = {}
|
|
|
3
3
|
import RR from './rr.js'
|
|
4
4
|
import A from './rr/a.js'
|
|
5
5
|
import AAAA from './rr/aaaa.js'
|
|
6
|
+
import APL from './rr/apl.js'
|
|
6
7
|
import CAA from './rr/caa.js'
|
|
7
8
|
import CERT from './rr/cert.js'
|
|
8
9
|
import CNAME from './rr/cname.js'
|
|
10
|
+
import DHCID from './rr/dhcid.js'
|
|
9
11
|
import DNAME from './rr/dname.js'
|
|
10
12
|
import DNSKEY from './rr/dnskey.js'
|
|
11
13
|
import DS from './rr/ds.js'
|
|
12
14
|
import HINFO from './rr/hinfo.js'
|
|
15
|
+
import HIP from './rr/hip.js'
|
|
13
16
|
import HTTPS from './rr/https.js'
|
|
14
17
|
import IPSECKEY from './rr/ipseckey.js'
|
|
15
18
|
import KEY from './rr/key.js'
|
|
19
|
+
import KX from './rr/kx.js'
|
|
16
20
|
import LOC from './rr/loc.js'
|
|
17
21
|
import MX from './rr/mx.js'
|
|
18
22
|
import NAPTR from './rr/naptr.js'
|
|
@@ -23,6 +27,7 @@ import NSEC3PARAM from './rr/nsec3param.js'
|
|
|
23
27
|
import NXT from './rr/nxt.js'
|
|
24
28
|
import OPENPGPKEY from './rr/openpgpkey.js'
|
|
25
29
|
import PTR from './rr/ptr.js'
|
|
30
|
+
import RP from './rr/rp.js'
|
|
26
31
|
import RRSIG from './rr/rrsig.js'
|
|
27
32
|
import SIG from './rr/sig.js'
|
|
28
33
|
import SMIMEA from './rr/smimea.js'
|
|
@@ -42,16 +47,20 @@ export default RR
|
|
|
42
47
|
export {
|
|
43
48
|
A,
|
|
44
49
|
AAAA,
|
|
50
|
+
APL,
|
|
45
51
|
CAA,
|
|
46
52
|
CERT,
|
|
47
53
|
CNAME,
|
|
54
|
+
DHCID,
|
|
48
55
|
DNAME,
|
|
49
56
|
DNSKEY,
|
|
50
57
|
DS,
|
|
51
58
|
HINFO,
|
|
59
|
+
HIP,
|
|
52
60
|
HTTPS,
|
|
53
61
|
IPSECKEY,
|
|
54
62
|
KEY,
|
|
63
|
+
KX,
|
|
55
64
|
LOC,
|
|
56
65
|
MX,
|
|
57
66
|
NAPTR,
|
|
@@ -62,6 +71,7 @@ export {
|
|
|
62
71
|
NXT,
|
|
63
72
|
OPENPGPKEY,
|
|
64
73
|
PTR,
|
|
74
|
+
RP,
|
|
65
75
|
RRSIG,
|
|
66
76
|
SIG,
|
|
67
77
|
SMIMEA,
|
|
@@ -81,16 +91,20 @@ export {
|
|
|
81
91
|
for (const c of [
|
|
82
92
|
A,
|
|
83
93
|
AAAA,
|
|
94
|
+
APL,
|
|
84
95
|
CAA,
|
|
85
96
|
CERT,
|
|
86
97
|
CNAME,
|
|
98
|
+
DHCID,
|
|
87
99
|
DNAME,
|
|
88
100
|
DNSKEY,
|
|
89
101
|
DS,
|
|
90
102
|
HINFO,
|
|
103
|
+
HIP,
|
|
91
104
|
HTTPS,
|
|
92
105
|
IPSECKEY,
|
|
93
106
|
KEY,
|
|
107
|
+
KX,
|
|
94
108
|
LOC,
|
|
95
109
|
MX,
|
|
96
110
|
NAPTR,
|
|
@@ -101,6 +115,7 @@ for (const c of [
|
|
|
101
115
|
NXT,
|
|
102
116
|
OPENPGPKEY,
|
|
103
117
|
PTR,
|
|
118
|
+
RP,
|
|
104
119
|
RRSIG,
|
|
105
120
|
SIG,
|
|
106
121
|
SMIMEA,
|
package/lib/tinydns.js
CHANGED
|
@@ -29,9 +29,7 @@ export function escapeOctal(re, str) {
|
|
|
29
29
|
|
|
30
30
|
export function octalToChar(str) {
|
|
31
31
|
// relace instances of \NNN with ASCII
|
|
32
|
-
return str.replace(octalRe, (o) =>
|
|
33
|
-
String.fromCharCode(parseInt(o.substring(1), 8)),
|
|
34
|
-
)
|
|
32
|
+
return str.replace(octalRe, (o) => String.fromCharCode(parseInt(o.substring(1), 8)))
|
|
35
33
|
}
|
|
36
34
|
|
|
37
35
|
export function octalToHex(str) {
|
|
@@ -181,9 +179,7 @@ export function base64toOctal(str) {
|
|
|
181
179
|
const bytes = Buffer.from(str, 'base64')
|
|
182
180
|
let escaped = ''
|
|
183
181
|
for (const b of bytes) {
|
|
184
|
-
escaped += /[A-Za-z0-9\-.]/.test(String.fromCharCode(b))
|
|
185
|
-
? String.fromCharCode(b)
|
|
186
|
-
: UInt8toOctal(b)
|
|
182
|
+
escaped += /[A-Za-z0-9\-.]/.test(String.fromCharCode(b)) ? String.fromCharCode(b) : UInt8toOctal(b)
|
|
187
183
|
}
|
|
188
184
|
return escaped
|
|
189
185
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nictool/dns-resource-record",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "DNS Resource Records",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"prettier:fix": "npx prettier --ignore-path .gitignore --write .",
|
|
20
20
|
"test": "npx mocha",
|
|
21
21
|
"versions": "npx dependency-version-checker check",
|
|
22
|
-
"watch": "npm run test -- --watch"
|
|
22
|
+
"watch": "npm run test -- --watch",
|
|
23
|
+
"versions:fix": "npx dependency-version-checker update"
|
|
23
24
|
},
|
|
24
25
|
"repository": {
|
|
25
26
|
"type": "git",
|
|
@@ -45,12 +46,13 @@
|
|
|
45
46
|
},
|
|
46
47
|
"homepage": "https://github.com/NicTool/dns-resource-record#readme",
|
|
47
48
|
"devDependencies": {
|
|
48
|
-
"@eslint/js": "^10.0.
|
|
49
|
-
"eslint": "^
|
|
50
|
-
"globals": "^
|
|
51
|
-
"mocha": "^11.
|
|
49
|
+
"@eslint/js": "^10.0.1",
|
|
50
|
+
"eslint": "^10.0.2",
|
|
51
|
+
"globals": "^17.4.0",
|
|
52
|
+
"mocha": "^11.7.5"
|
|
52
53
|
},
|
|
53
54
|
"prettier": {
|
|
55
|
+
"printWidth": 110,
|
|
54
56
|
"semi": false,
|
|
55
57
|
"singleQuote": true,
|
|
56
58
|
"trailingComma": "all"
|
package/rr/aaaa.js
CHANGED
|
@@ -15,7 +15,7 @@ export default class AAAA extends RR {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
getCompressed(val) {
|
|
18
|
-
this.compress(val || this.get('address'))
|
|
18
|
+
return this.compress(val || this.get('address'))
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
getDescription() {
|
|
@@ -112,12 +112,12 @@ export default class AAAA extends RR {
|
|
|
112
112
|
|
|
113
113
|
for (const re of mostConsecutiveZeros) {
|
|
114
114
|
if (re.test(r)) {
|
|
115
|
-
r = r.replace(re, '::')
|
|
115
|
+
r = r.replace(re, '::') // 4.2
|
|
116
116
|
break
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
return r
|
|
120
|
+
return r.toLowerCase() // 4.3
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
expand(val, delimiter) {
|
|
@@ -134,11 +134,12 @@ export default class AAAA extends RR {
|
|
|
134
134
|
.split(':')
|
|
135
135
|
.map((s) => s.padStart(4, 0))
|
|
136
136
|
.join(delimiter)
|
|
137
|
+
.toLowerCase()
|
|
137
138
|
}
|
|
138
139
|
|
|
139
140
|
/****** EXPORTERS *******/
|
|
140
141
|
toBind(zone_opts) {
|
|
141
|
-
return `${this.getPrefix(zone_opts)}\t${this.
|
|
142
|
+
return `${this.getPrefix(zone_opts)}\t${this.getCompressed()}\n`
|
|
142
143
|
}
|
|
143
144
|
|
|
144
145
|
toTinydns() {
|
package/rr/apl.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import RR from '../rr.js'
|
|
2
|
+
|
|
3
|
+
import * as TINYDNS from '../lib/tinydns.js'
|
|
4
|
+
|
|
5
|
+
export default class APL extends RR {
|
|
6
|
+
constructor(opts) {
|
|
7
|
+
super(opts)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/****** Resource record specific setters *******/
|
|
11
|
+
setAplRdata(val) {
|
|
12
|
+
if (!val) this.throwHelp('APL: apl rdata is required')
|
|
13
|
+
// apl rdata is a list of address prefix list items, e.g.:
|
|
14
|
+
// 1:192.0.2.0/24 !1:192.0.2.64/28 2:2001:db8::/32
|
|
15
|
+
this.set('apl rdata', val)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
getDescription() {
|
|
19
|
+
return 'Address Prefix List'
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
getRdataFields(arg) {
|
|
23
|
+
return ['apl rdata']
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
getRFCs() {
|
|
27
|
+
return [3123]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
getTypeId() {
|
|
31
|
+
return 42
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
getCanonical() {
|
|
35
|
+
return {
|
|
36
|
+
owner: 'example.com.',
|
|
37
|
+
ttl: 3600,
|
|
38
|
+
class: 'IN',
|
|
39
|
+
type: 'APL',
|
|
40
|
+
'apl rdata': '1:192.0.2.0/24 !1:192.0.2.64/28 2:2001:db8::/32',
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/****** IMPORTERS *******/
|
|
45
|
+
fromBind(opts) {
|
|
46
|
+
// test.example.com 3600 IN APL {[!]afi:address/prefix}*
|
|
47
|
+
const parts = opts.bindline.split(/\s+/)
|
|
48
|
+
const [owner, ttl, c, type] = parts
|
|
49
|
+
return new APL({
|
|
50
|
+
owner,
|
|
51
|
+
ttl: parseInt(ttl, 10),
|
|
52
|
+
class: c,
|
|
53
|
+
type,
|
|
54
|
+
'apl rdata': parts.slice(4).join(' ').trim(),
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/****** EXPORTERS *******/
|
|
59
|
+
toTinydns() {
|
|
60
|
+
return this.getTinydnsGeneric(
|
|
61
|
+
this.get('apl rdata')
|
|
62
|
+
.split(/\s+/)
|
|
63
|
+
.map((item) => {
|
|
64
|
+
const neg = item.startsWith('!')
|
|
65
|
+
const bare = neg ? item.slice(1) : item
|
|
66
|
+
const colonIdx = bare.indexOf(':')
|
|
67
|
+
const afi = parseInt(bare.slice(0, colonIdx), 10)
|
|
68
|
+
const rest = bare.slice(colonIdx + 1)
|
|
69
|
+
const slashIdx = rest.lastIndexOf('/')
|
|
70
|
+
const addr = rest.slice(0, slashIdx)
|
|
71
|
+
const prefix = parseInt(rest.slice(slashIdx + 1), 10)
|
|
72
|
+
|
|
73
|
+
let addrBytes
|
|
74
|
+
if (afi === 1) {
|
|
75
|
+
addrBytes = Buffer.from(addr.split('.').map((n) => parseInt(n, 10)))
|
|
76
|
+
} else {
|
|
77
|
+
const dblIdx = addr.indexOf('::')
|
|
78
|
+
let groups
|
|
79
|
+
if (dblIdx !== -1) {
|
|
80
|
+
const left = addr
|
|
81
|
+
.slice(0, dblIdx)
|
|
82
|
+
.split(':')
|
|
83
|
+
.filter((s) => s !== '')
|
|
84
|
+
const right = addr
|
|
85
|
+
.slice(dblIdx + 2)
|
|
86
|
+
.split(':')
|
|
87
|
+
.filter((s) => s !== '')
|
|
88
|
+
groups = [...left, ...Array(8 - left.length - right.length).fill('0000'), ...right]
|
|
89
|
+
} else {
|
|
90
|
+
groups = addr.split(':')
|
|
91
|
+
}
|
|
92
|
+
addrBytes = Buffer.from(groups.map((g) => g.padStart(4, '0')).join(''), 'hex')
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
let len = addrBytes.length
|
|
96
|
+
while (len > 0 && addrBytes[len - 1] === 0) len--
|
|
97
|
+
const afdPart = addrBytes.slice(0, len)
|
|
98
|
+
|
|
99
|
+
let r = TINYDNS.UInt16toOctal(afi)
|
|
100
|
+
r += TINYDNS.UInt8toOctal(prefix)
|
|
101
|
+
r += TINYDNS.UInt8toOctal((neg ? 0x80 : 0) | afdPart.length)
|
|
102
|
+
for (const b of afdPart) r += TINYDNS.UInt8toOctal(b)
|
|
103
|
+
return r
|
|
104
|
+
})
|
|
105
|
+
.join(''),
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
}
|
package/rr/caa.js
CHANGED
|
@@ -10,25 +10,34 @@ export default class CAA extends RR {
|
|
|
10
10
|
setFlags(val) {
|
|
11
11
|
this.is8bitInt('CAA', 'flags', val)
|
|
12
12
|
|
|
13
|
-
if (!
|
|
13
|
+
if (!this.getFlagsOptions().has(val)) {
|
|
14
14
|
this.throwHelp(`CAA flags ${val} not recognized`)
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
this.set('flags', val)
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
getFlagsOptions() {
|
|
21
|
+
return new Map([
|
|
22
|
+
[0, 'Non Critical'],
|
|
23
|
+
[128, 'Critical'],
|
|
24
|
+
])
|
|
25
|
+
}
|
|
26
|
+
|
|
20
27
|
setTag(val) {
|
|
21
28
|
if (typeof val !== 'string' || val.length < 1 || /[^a-z0-9]/.test(val))
|
|
22
|
-
this.throwHelp(
|
|
23
|
-
`CAA tag must be a sequence of ASCII letters and numbers in lowercase`,
|
|
24
|
-
)
|
|
29
|
+
this.throwHelp(`CAA tag must be a sequence of ASCII letters and numbers in lowercase`)
|
|
25
30
|
|
|
26
|
-
if (!
|
|
31
|
+
if (!this.getTagOptions().has(val)) {
|
|
27
32
|
this.throwHelp(`CAA tag ${val} not recognized`)
|
|
28
33
|
}
|
|
29
34
|
this.set('tag', val)
|
|
30
35
|
}
|
|
31
36
|
|
|
37
|
+
getTagOptions() {
|
|
38
|
+
return new Map([['issue'], ['issuewild'], ['iodef']])
|
|
39
|
+
}
|
|
40
|
+
|
|
32
41
|
setValue(val) {
|
|
33
42
|
// either (2) a quoted string or
|
|
34
43
|
// (1) a contiguous set of characters without interior spaces
|
|
@@ -108,11 +117,8 @@ export default class CAA extends RR {
|
|
|
108
117
|
|
|
109
118
|
fromBind(opts) {
|
|
110
119
|
// test.example.com 3600 IN CAA flags, tags, value
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
.match(
|
|
114
|
-
/^([\S]+)\s+([0-9]{1,10})\s+(IN)\s+(CAA)\s+([0-9]+)\s+(\w+)\s+("[^"]+"|[\S]+?)$/i,
|
|
115
|
-
)
|
|
120
|
+
const regex = /^([\S]+)\s+([0-9]{1,10})\s+(IN)\s+(CAA)\s+([0-9]+)\s+(\w+)\s+("[^"]+"|[\S]+?)$/i
|
|
121
|
+
const fields = opts.bindline.trim().match(regex)
|
|
116
122
|
if (!fields) this.throwHelp(`unable to parse: ${opts.bindline}`)
|
|
117
123
|
|
|
118
124
|
const [owner, ttl, c, type, flags, tag, value] = fields.slice(1)
|
package/rr/cert.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import RR from '../rr.js'
|
|
2
2
|
|
|
3
|
+
import * as TINYDNS from '../lib/tinydns.js'
|
|
4
|
+
|
|
3
5
|
export default class CERT extends RR {
|
|
4
6
|
constructor(opts) {
|
|
5
7
|
super(opts)
|
|
@@ -14,6 +16,24 @@ export default class CERT extends RR {
|
|
|
14
16
|
this.set('cert type', val)
|
|
15
17
|
}
|
|
16
18
|
|
|
19
|
+
getCertTypeValue(val) {
|
|
20
|
+
if (typeof val === 'number') return val
|
|
21
|
+
const types = {
|
|
22
|
+
PKIX: 1,
|
|
23
|
+
SPKI: 2,
|
|
24
|
+
PGP: 3,
|
|
25
|
+
IPKIX: 4,
|
|
26
|
+
ISPKI: 5,
|
|
27
|
+
IPGP: 6,
|
|
28
|
+
ACPKIX: 7,
|
|
29
|
+
IACPKIX: 8,
|
|
30
|
+
URI: 253,
|
|
31
|
+
OID: 254,
|
|
32
|
+
}
|
|
33
|
+
if (Object.hasOwn(types, val)) return types[val]
|
|
34
|
+
this.throwHelp(`CERT: unknown cert type mnemonic: ${val}`)
|
|
35
|
+
}
|
|
36
|
+
|
|
17
37
|
setKeyTag(val) {
|
|
18
38
|
// The key tag field is the 16-bit value
|
|
19
39
|
// The key tag field is represented as an unsigned decimal integer.
|
|
@@ -57,16 +77,13 @@ export default class CERT extends RR {
|
|
|
57
77
|
|
|
58
78
|
fromBind(opts) {
|
|
59
79
|
// test.example.com 3600 IN CERT certtype, keytag, algo, cert
|
|
60
|
-
const [owner, ttl, c, type, certtype, keytag, algo, certificate] =
|
|
61
|
-
opts.bindline.split(/\s+/)
|
|
80
|
+
const [owner, ttl, c, type, certtype, keytag, algo, certificate] = opts.bindline.split(/\s+/)
|
|
62
81
|
return new CERT({
|
|
63
82
|
owner,
|
|
64
83
|
ttl: parseInt(ttl, 10),
|
|
65
84
|
class: c,
|
|
66
85
|
type,
|
|
67
|
-
'cert type': /^[0-9]+$/.test(certtype)
|
|
68
|
-
? parseInt(certtype, 10)
|
|
69
|
-
: certtype,
|
|
86
|
+
'cert type': /^[0-9]+$/.test(certtype) ? parseInt(certtype, 10) : certtype,
|
|
70
87
|
'key tag': parseInt(keytag, 10),
|
|
71
88
|
algorithm: parseInt(algo, 10),
|
|
72
89
|
certificate,
|
|
@@ -74,4 +91,15 @@ export default class CERT extends RR {
|
|
|
74
91
|
}
|
|
75
92
|
|
|
76
93
|
/****** EXPORTERS *******/
|
|
94
|
+
|
|
95
|
+
toTinydns() {
|
|
96
|
+
const dataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
|
|
97
|
+
|
|
98
|
+
return this.getTinydnsGeneric(
|
|
99
|
+
TINYDNS.UInt16toOctal(this.getCertTypeValue(this.get('cert type'))) +
|
|
100
|
+
TINYDNS.UInt16toOctal(this.get('key tag')) +
|
|
101
|
+
TINYDNS.UInt8toOctal(this.get('algorithm')) +
|
|
102
|
+
TINYDNS.escapeOctal(dataRe, this.get('certificate')),
|
|
103
|
+
)
|
|
104
|
+
}
|
|
77
105
|
}
|
package/rr/cname.js
CHANGED
|
@@ -12,8 +12,7 @@ export default class CNAME extends RR {
|
|
|
12
12
|
|
|
13
13
|
if (!val) this.throwHelp('CNAME: cname is required')
|
|
14
14
|
|
|
15
|
-
if (this.isIPv4(val) || this.isIPv6(val))
|
|
16
|
-
this.throwHelp(`CNAME: cname must be a FQDN: RFC 2181`)
|
|
15
|
+
if (this.isIPv4(val) || this.isIPv6(val)) this.throwHelp(`CNAME: cname must be a FQDN: RFC 2181`)
|
|
17
16
|
|
|
18
17
|
if (!this.isFullyQualified('CNAME', 'cname', val)) return
|
|
19
18
|
if (!this.isValidHostname('CNAME', 'cname', val)) return
|
package/rr/dhcid.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import RR from '../rr.js'
|
|
2
|
+
|
|
3
|
+
import * as TINYDNS from '../lib/tinydns.js'
|
|
4
|
+
|
|
5
|
+
export default class DHCID extends RR {
|
|
6
|
+
constructor(opts) {
|
|
7
|
+
super(opts)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/****** Resource record specific setters *******/
|
|
11
|
+
setData(val) {
|
|
12
|
+
if (!val) this.throwHelp('DHCID: data is required')
|
|
13
|
+
this.set('data', val)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
getDescription() {
|
|
17
|
+
return 'DHCP Identifier'
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
getRdataFields(arg) {
|
|
21
|
+
return ['data']
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getRFCs() {
|
|
25
|
+
return [4701]
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getTypeId() {
|
|
29
|
+
return 49
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getCanonical() {
|
|
33
|
+
return {
|
|
34
|
+
owner: 'host.example.com.',
|
|
35
|
+
ttl: 3600,
|
|
36
|
+
class: 'IN',
|
|
37
|
+
type: 'DHCID',
|
|
38
|
+
data: 'AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA=',
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/****** IMPORTERS *******/
|
|
43
|
+
fromBind(opts) {
|
|
44
|
+
// host.example.com 3600 IN DHCID <base64data>
|
|
45
|
+
const parts = opts.bindline.split(/\s+/)
|
|
46
|
+
const [owner, ttl, c, type] = parts
|
|
47
|
+
return new DHCID({
|
|
48
|
+
owner,
|
|
49
|
+
ttl: parseInt(ttl, 10),
|
|
50
|
+
class: c,
|
|
51
|
+
type,
|
|
52
|
+
data: parts.slice(4).join(''),
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/****** EXPORTERS *******/
|
|
57
|
+
toTinydns() {
|
|
58
|
+
return this.getTinydnsGeneric(TINYDNS.base64toOctal(this.get('data')))
|
|
59
|
+
}
|
|
60
|
+
}
|
package/rr/dname.js
CHANGED
|
@@ -10,8 +10,7 @@ export default class DNAME extends RR {
|
|
|
10
10
|
setTarget(val) {
|
|
11
11
|
if (!val) this.throwHelp('DNAME: target is required')
|
|
12
12
|
|
|
13
|
-
if (this.isIPv4(val) || this.isIPv6(val))
|
|
14
|
-
this.throwHelp(`DNAME: target must be a domain name`)
|
|
13
|
+
if (this.isIPv4(val) || this.isIPv6(val)) this.throwHelp(`DNAME: target must be a domain name`)
|
|
15
14
|
|
|
16
15
|
this.isFullyQualified('DNAME', 'target', val)
|
|
17
16
|
this.isValidHostname('DNAME', 'target', val)
|