scan_rr.go raw
1 package dns
2
3 import (
4 "encoding/base64"
5 "errors"
6 "fmt"
7 "net"
8 "strconv"
9 "strings"
10 )
11
12 // A remainder of the rdata with embedded spaces, return the parsed string (sans the spaces)
13 // or an error
14 func endingToString(c *zlexer, errstr string) (string, *ParseError) {
15 var s strings.Builder
16 l, _ := c.Next() // zString
17 for l.value != zNewline && l.value != zEOF {
18 if l.err {
19 return s.String(), &ParseError{err: errstr, lex: l}
20 }
21 switch l.value {
22 case zString:
23 s.WriteString(l.token)
24 case zBlank: // Ok
25 default:
26 return "", &ParseError{err: errstr, lex: l}
27 }
28 l, _ = c.Next()
29 }
30
31 return s.String(), nil
32 }
33
34 // A remainder of the rdata with embedded spaces, split on unquoted whitespace
35 // and return the parsed string slice or an error
36 func endingToTxtSlice(c *zlexer, errstr string) ([]string, *ParseError) {
37 // Get the remaining data until we see a zNewline
38 l, _ := c.Next()
39 if l.err {
40 return nil, &ParseError{err: errstr, lex: l}
41 }
42
43 // Build the slice
44 s := make([]string, 0)
45 quote := false
46 empty := false
47 for l.value != zNewline && l.value != zEOF {
48 if l.err {
49 return nil, &ParseError{err: errstr, lex: l}
50 }
51 switch l.value {
52 case zString:
53 empty = false
54 // split up tokens that are larger than 255 into 255-chunks
55 sx := []string{}
56 p := 0
57 for {
58 i, ok := escapedStringOffset(l.token[p:], 255)
59 if !ok {
60 return nil, &ParseError{err: errstr, lex: l}
61 }
62 if i != -1 && p+i != len(l.token) {
63 sx = append(sx, l.token[p:p+i])
64 } else {
65 sx = append(sx, l.token[p:])
66 break
67
68 }
69 p += i
70 }
71 s = append(s, sx...)
72 case zBlank:
73 if quote {
74 // zBlank can only be seen in between txt parts.
75 return nil, &ParseError{err: errstr, lex: l}
76 }
77 case zQuote:
78 if empty && quote {
79 s = append(s, "")
80 }
81 quote = !quote
82 empty = true
83 default:
84 return nil, &ParseError{err: errstr, lex: l}
85 }
86 l, _ = c.Next()
87 }
88
89 if quote {
90 return nil, &ParseError{err: errstr, lex: l}
91 }
92
93 return s, nil
94 }
95
96 func (rr *A) parse(c *zlexer, o string) *ParseError {
97 l, _ := c.Next()
98 rr.A = net.ParseIP(l.token)
99 // IPv4 addresses cannot include ":".
100 // We do this rather than use net.IP's To4() because
101 // To4() treats IPv4-mapped IPv6 addresses as being
102 // IPv4.
103 isIPv4 := !strings.Contains(l.token, ":")
104 if rr.A == nil || !isIPv4 || l.err {
105 return &ParseError{err: "bad A A", lex: l}
106 }
107 return slurpRemainder(c)
108 }
109
110 func (rr *AAAA) parse(c *zlexer, o string) *ParseError {
111 l, _ := c.Next()
112 rr.AAAA = net.ParseIP(l.token)
113 // IPv6 addresses must include ":", and IPv4
114 // addresses cannot include ":".
115 isIPv6 := strings.Contains(l.token, ":")
116 if rr.AAAA == nil || !isIPv6 || l.err {
117 return &ParseError{err: "bad AAAA AAAA", lex: l}
118 }
119 return slurpRemainder(c)
120 }
121
122 func (rr *NS) parse(c *zlexer, o string) *ParseError {
123 l, _ := c.Next()
124 name, nameOk := toAbsoluteName(l.token, o)
125 if l.err || !nameOk {
126 return &ParseError{err: "bad NS Ns", lex: l}
127 }
128 rr.Ns = name
129 return slurpRemainder(c)
130 }
131
132 func (rr *PTR) parse(c *zlexer, o string) *ParseError {
133 l, _ := c.Next()
134 name, nameOk := toAbsoluteName(l.token, o)
135 if l.err || !nameOk {
136 return &ParseError{err: "bad PTR Ptr", lex: l}
137 }
138 rr.Ptr = name
139 return slurpRemainder(c)
140 }
141
142 func (rr *NSAPPTR) parse(c *zlexer, o string) *ParseError {
143 l, _ := c.Next()
144 name, nameOk := toAbsoluteName(l.token, o)
145 if l.err || !nameOk {
146 return &ParseError{err: "bad NSAP-PTR Ptr", lex: l}
147 }
148 rr.Ptr = name
149 return slurpRemainder(c)
150 }
151
152 func (rr *RP) parse(c *zlexer, o string) *ParseError {
153 l, _ := c.Next()
154 mbox, mboxOk := toAbsoluteName(l.token, o)
155 if l.err || !mboxOk {
156 return &ParseError{err: "bad RP Mbox", lex: l}
157 }
158 rr.Mbox = mbox
159
160 c.Next() // zBlank
161 l, _ = c.Next()
162 rr.Txt = l.token
163
164 txt, txtOk := toAbsoluteName(l.token, o)
165 if l.err || !txtOk {
166 return &ParseError{err: "bad RP Txt", lex: l}
167 }
168 rr.Txt = txt
169
170 return slurpRemainder(c)
171 }
172
173 func (rr *MR) parse(c *zlexer, o string) *ParseError {
174 l, _ := c.Next()
175 name, nameOk := toAbsoluteName(l.token, o)
176 if l.err || !nameOk {
177 return &ParseError{err: "bad MR Mr", lex: l}
178 }
179 rr.Mr = name
180 return slurpRemainder(c)
181 }
182
183 func (rr *MB) parse(c *zlexer, o string) *ParseError {
184 l, _ := c.Next()
185 name, nameOk := toAbsoluteName(l.token, o)
186 if l.err || !nameOk {
187 return &ParseError{err: "bad MB Mb", lex: l}
188 }
189 rr.Mb = name
190 return slurpRemainder(c)
191 }
192
193 func (rr *MG) parse(c *zlexer, o string) *ParseError {
194 l, _ := c.Next()
195 name, nameOk := toAbsoluteName(l.token, o)
196 if l.err || !nameOk {
197 return &ParseError{err: "bad MG Mg", lex: l}
198 }
199 rr.Mg = name
200 return slurpRemainder(c)
201 }
202
203 func (rr *HINFO) parse(c *zlexer, o string) *ParseError {
204 chunks, e := endingToTxtSlice(c, "bad HINFO Fields")
205 if e != nil {
206 return e
207 }
208
209 if ln := len(chunks); ln == 0 {
210 return nil
211 } else if ln == 1 {
212 // Can we split it?
213 if out := strings.Fields(chunks[0]); len(out) > 1 {
214 chunks = out
215 } else {
216 chunks = append(chunks, "")
217 }
218 }
219
220 rr.Cpu = chunks[0]
221 rr.Os = strings.Join(chunks[1:], " ")
222 return nil
223 }
224
225 // according to RFC 1183 the parsing is identical to HINFO, so just use that code.
226 func (rr *ISDN) parse(c *zlexer, o string) *ParseError {
227 chunks, e := endingToTxtSlice(c, "bad ISDN Fields")
228 if e != nil {
229 return e
230 }
231
232 if ln := len(chunks); ln == 0 {
233 return nil
234 } else if ln == 1 {
235 // Can we split it?
236 if out := strings.Fields(chunks[0]); len(out) > 1 {
237 chunks = out
238 } else {
239 chunks = append(chunks, "")
240 }
241 }
242
243 rr.Address = chunks[0]
244 rr.SubAddress = strings.Join(chunks[1:], " ")
245
246 return nil
247 }
248
249 func (rr *MINFO) parse(c *zlexer, o string) *ParseError {
250 l, _ := c.Next()
251 rmail, rmailOk := toAbsoluteName(l.token, o)
252 if l.err || !rmailOk {
253 return &ParseError{err: "bad MINFO Rmail", lex: l}
254 }
255 rr.Rmail = rmail
256
257 c.Next() // zBlank
258 l, _ = c.Next()
259 rr.Email = l.token
260
261 email, emailOk := toAbsoluteName(l.token, o)
262 if l.err || !emailOk {
263 return &ParseError{err: "bad MINFO Email", lex: l}
264 }
265 rr.Email = email
266
267 return slurpRemainder(c)
268 }
269
270 func (rr *MF) parse(c *zlexer, o string) *ParseError {
271 l, _ := c.Next()
272 name, nameOk := toAbsoluteName(l.token, o)
273 if l.err || !nameOk {
274 return &ParseError{err: "bad MF Mf", lex: l}
275 }
276 rr.Mf = name
277 return slurpRemainder(c)
278 }
279
280 func (rr *MD) parse(c *zlexer, o string) *ParseError {
281 l, _ := c.Next()
282 name, nameOk := toAbsoluteName(l.token, o)
283 if l.err || !nameOk {
284 return &ParseError{err: "bad MD Md", lex: l}
285 }
286 rr.Md = name
287 return slurpRemainder(c)
288 }
289
290 func (rr *MX) parse(c *zlexer, o string) *ParseError {
291 l, _ := c.Next()
292 i, e := strconv.ParseUint(l.token, 10, 16)
293 if e != nil || l.err {
294 return &ParseError{err: "bad MX Pref", lex: l}
295 }
296 rr.Preference = uint16(i)
297
298 c.Next() // zBlank
299 l, _ = c.Next() // zString
300 rr.Mx = l.token
301
302 name, nameOk := toAbsoluteName(l.token, o)
303 if l.err || !nameOk {
304 return &ParseError{err: "bad MX Mx", lex: l}
305 }
306 rr.Mx = name
307
308 return slurpRemainder(c)
309 }
310
311 func (rr *RT) parse(c *zlexer, o string) *ParseError {
312 l, _ := c.Next()
313 i, e := strconv.ParseUint(l.token, 10, 16)
314 if e != nil {
315 return &ParseError{err: "bad RT Preference", lex: l}
316 }
317 rr.Preference = uint16(i)
318
319 c.Next() // zBlank
320 l, _ = c.Next() // zString
321 rr.Host = l.token
322
323 name, nameOk := toAbsoluteName(l.token, o)
324 if l.err || !nameOk {
325 return &ParseError{err: "bad RT Host", lex: l}
326 }
327 rr.Host = name
328
329 return slurpRemainder(c)
330 }
331
332 func (rr *AFSDB) parse(c *zlexer, o string) *ParseError {
333 l, _ := c.Next()
334 i, e := strconv.ParseUint(l.token, 10, 16)
335 if e != nil || l.err {
336 return &ParseError{err: "bad AFSDB Subtype", lex: l}
337 }
338 rr.Subtype = uint16(i)
339
340 c.Next() // zBlank
341 l, _ = c.Next() // zString
342 rr.Hostname = l.token
343
344 name, nameOk := toAbsoluteName(l.token, o)
345 if l.err || !nameOk {
346 return &ParseError{err: "bad AFSDB Hostname", lex: l}
347 }
348 rr.Hostname = name
349 return slurpRemainder(c)
350 }
351
352 func (rr *X25) parse(c *zlexer, o string) *ParseError {
353 l, _ := c.Next()
354 if l.err {
355 return &ParseError{err: "bad X25 PSDNAddress", lex: l}
356 }
357 rr.PSDNAddress = l.token
358 return slurpRemainder(c)
359 }
360
361 func (rr *KX) parse(c *zlexer, o string) *ParseError {
362 l, _ := c.Next()
363 i, e := strconv.ParseUint(l.token, 10, 16)
364 if e != nil || l.err {
365 return &ParseError{err: "bad KX Pref", lex: l}
366 }
367 rr.Preference = uint16(i)
368
369 c.Next() // zBlank
370 l, _ = c.Next() // zString
371 rr.Exchanger = l.token
372
373 name, nameOk := toAbsoluteName(l.token, o)
374 if l.err || !nameOk {
375 return &ParseError{err: "bad KX Exchanger", lex: l}
376 }
377 rr.Exchanger = name
378 return slurpRemainder(c)
379 }
380
381 func (rr *CNAME) parse(c *zlexer, o string) *ParseError {
382 l, _ := c.Next()
383 name, nameOk := toAbsoluteName(l.token, o)
384 if l.err || !nameOk {
385 return &ParseError{err: "bad CNAME Target", lex: l}
386 }
387 rr.Target = name
388 return slurpRemainder(c)
389 }
390
391 func (rr *DNAME) parse(c *zlexer, o string) *ParseError {
392 l, _ := c.Next()
393 name, nameOk := toAbsoluteName(l.token, o)
394 if l.err || !nameOk {
395 return &ParseError{err: "bad DNAME Target", lex: l}
396 }
397 rr.Target = name
398 return slurpRemainder(c)
399 }
400
401 func (rr *SOA) parse(c *zlexer, o string) *ParseError {
402 l, _ := c.Next()
403 ns, nsOk := toAbsoluteName(l.token, o)
404 if l.err || !nsOk {
405 return &ParseError{err: "bad SOA Ns", lex: l}
406 }
407 rr.Ns = ns
408
409 c.Next() // zBlank
410 l, _ = c.Next()
411 rr.Mbox = l.token
412
413 mbox, mboxOk := toAbsoluteName(l.token, o)
414 if l.err || !mboxOk {
415 return &ParseError{err: "bad SOA Mbox", lex: l}
416 }
417 rr.Mbox = mbox
418
419 c.Next() // zBlank
420
421 var (
422 v uint32
423 ok bool
424 )
425 for i := 0; i < 5; i++ {
426 l, _ = c.Next()
427 if l.err {
428 return &ParseError{err: "bad SOA zone parameter", lex: l}
429 }
430 if j, err := strconv.ParseUint(l.token, 10, 32); err != nil {
431 if i == 0 {
432 // Serial must be a number
433 return &ParseError{err: "bad SOA zone parameter", lex: l}
434 }
435 // We allow other fields to be unitful duration strings
436 if v, ok = stringToTTL(l.token); !ok {
437 return &ParseError{err: "bad SOA zone parameter", lex: l}
438
439 }
440 } else {
441 v = uint32(j)
442 }
443 switch i {
444 case 0:
445 rr.Serial = v
446 c.Next() // zBlank
447 case 1:
448 rr.Refresh = v
449 c.Next() // zBlank
450 case 2:
451 rr.Retry = v
452 c.Next() // zBlank
453 case 3:
454 rr.Expire = v
455 c.Next() // zBlank
456 case 4:
457 rr.Minttl = v
458 }
459 }
460 return slurpRemainder(c)
461 }
462
463 func (rr *SRV) parse(c *zlexer, o string) *ParseError {
464 l, _ := c.Next()
465 i, e := strconv.ParseUint(l.token, 10, 16)
466 if e != nil || l.err {
467 return &ParseError{err: "bad SRV Priority", lex: l}
468 }
469 rr.Priority = uint16(i)
470
471 c.Next() // zBlank
472 l, _ = c.Next() // zString
473 i, e1 := strconv.ParseUint(l.token, 10, 16)
474 if e1 != nil || l.err {
475 return &ParseError{err: "bad SRV Weight", lex: l}
476 }
477 rr.Weight = uint16(i)
478
479 c.Next() // zBlank
480 l, _ = c.Next() // zString
481 i, e2 := strconv.ParseUint(l.token, 10, 16)
482 if e2 != nil || l.err {
483 return &ParseError{err: "bad SRV Port", lex: l}
484 }
485 rr.Port = uint16(i)
486
487 c.Next() // zBlank
488 l, _ = c.Next() // zString
489 rr.Target = l.token
490
491 name, nameOk := toAbsoluteName(l.token, o)
492 if l.err || !nameOk {
493 return &ParseError{err: "bad SRV Target", lex: l}
494 }
495 rr.Target = name
496 return slurpRemainder(c)
497 }
498
499 func (rr *NAPTR) parse(c *zlexer, o string) *ParseError {
500 l, _ := c.Next()
501 i, e := strconv.ParseUint(l.token, 10, 16)
502 if e != nil || l.err {
503 return &ParseError{err: "bad NAPTR Order", lex: l}
504 }
505 rr.Order = uint16(i)
506
507 c.Next() // zBlank
508 l, _ = c.Next() // zString
509 i, e1 := strconv.ParseUint(l.token, 10, 16)
510 if e1 != nil || l.err {
511 return &ParseError{err: "bad NAPTR Preference", lex: l}
512 }
513 rr.Preference = uint16(i)
514
515 // Flags
516 c.Next() // zBlank
517 l, _ = c.Next() // _QUOTE
518 if l.value != zQuote {
519 return &ParseError{err: "bad NAPTR Flags", lex: l}
520 }
521 l, _ = c.Next() // Either String or Quote
522 if l.value == zString {
523 rr.Flags = l.token
524 l, _ = c.Next() // _QUOTE
525 if l.value != zQuote {
526 return &ParseError{err: "bad NAPTR Flags", lex: l}
527 }
528 } else if l.value == zQuote {
529 rr.Flags = ""
530 } else {
531 return &ParseError{err: "bad NAPTR Flags", lex: l}
532 }
533
534 // Service
535 c.Next() // zBlank
536 l, _ = c.Next() // _QUOTE
537 if l.value != zQuote {
538 return &ParseError{err: "bad NAPTR Service", lex: l}
539 }
540 l, _ = c.Next() // Either String or Quote
541 if l.value == zString {
542 rr.Service = l.token
543 l, _ = c.Next() // _QUOTE
544 if l.value != zQuote {
545 return &ParseError{err: "bad NAPTR Service", lex: l}
546 }
547 } else if l.value == zQuote {
548 rr.Service = ""
549 } else {
550 return &ParseError{err: "bad NAPTR Service", lex: l}
551 }
552
553 // Regexp
554 c.Next() // zBlank
555 l, _ = c.Next() // _QUOTE
556 if l.value != zQuote {
557 return &ParseError{err: "bad NAPTR Regexp", lex: l}
558 }
559 l, _ = c.Next() // Either String or Quote
560 if l.value == zString {
561 rr.Regexp = l.token
562 l, _ = c.Next() // _QUOTE
563 if l.value != zQuote {
564 return &ParseError{err: "bad NAPTR Regexp", lex: l}
565 }
566 } else if l.value == zQuote {
567 rr.Regexp = ""
568 } else {
569 return &ParseError{err: "bad NAPTR Regexp", lex: l}
570 }
571
572 // After quote no space??
573 c.Next() // zBlank
574 l, _ = c.Next() // zString
575 rr.Replacement = l.token
576
577 name, nameOk := toAbsoluteName(l.token, o)
578 if l.err || !nameOk {
579 return &ParseError{err: "bad NAPTR Replacement", lex: l}
580 }
581 rr.Replacement = name
582 return slurpRemainder(c)
583 }
584
585 func (rr *TALINK) parse(c *zlexer, o string) *ParseError {
586 l, _ := c.Next()
587 previousName, previousNameOk := toAbsoluteName(l.token, o)
588 if l.err || !previousNameOk {
589 return &ParseError{err: "bad TALINK PreviousName", lex: l}
590 }
591 rr.PreviousName = previousName
592
593 c.Next() // zBlank
594 l, _ = c.Next()
595 rr.NextName = l.token
596
597 nextName, nextNameOk := toAbsoluteName(l.token, o)
598 if l.err || !nextNameOk {
599 return &ParseError{err: "bad TALINK NextName", lex: l}
600 }
601 rr.NextName = nextName
602
603 return slurpRemainder(c)
604 }
605
606 func (rr *LOC) parse(c *zlexer, o string) *ParseError {
607 // Non zero defaults for LOC record, see RFC 1876, Section 3.
608 rr.Size = 0x12 // 1e2 cm (1m)
609 rr.HorizPre = 0x16 // 1e6 cm (10000m)
610 rr.VertPre = 0x13 // 1e3 cm (10m)
611 ok := false
612
613 // North
614 l, _ := c.Next()
615 i, e := strconv.ParseUint(l.token, 10, 32)
616 if e != nil || l.err || i > 90 {
617 return &ParseError{err: "bad LOC Latitude", lex: l}
618 }
619 rr.Latitude = 1000 * 60 * 60 * uint32(i)
620
621 c.Next() // zBlank
622 // Either number, 'N' or 'S'
623 l, _ = c.Next()
624 if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok {
625 goto East
626 }
627 if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err || i > 59 {
628 return &ParseError{err: "bad LOC Latitude minutes", lex: l}
629 } else {
630 rr.Latitude += 1000 * 60 * uint32(i)
631 }
632
633 c.Next() // zBlank
634 l, _ = c.Next()
635 if i, err := strconv.ParseFloat(l.token, 64); err != nil || l.err || i < 0 || i >= 60 {
636 return &ParseError{err: "bad LOC Latitude seconds", lex: l}
637 } else {
638 rr.Latitude += uint32(1000 * i)
639 }
640 c.Next() // zBlank
641 // Either number, 'N' or 'S'
642 l, _ = c.Next()
643 if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok {
644 goto East
645 }
646 // If still alive, flag an error
647 return &ParseError{err: "bad LOC Latitude North/South", lex: l}
648
649 East:
650 // East
651 c.Next() // zBlank
652 l, _ = c.Next()
653 if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err || i > 180 {
654 return &ParseError{err: "bad LOC Longitude", lex: l}
655 } else {
656 rr.Longitude = 1000 * 60 * 60 * uint32(i)
657 }
658 c.Next() // zBlank
659 // Either number, 'E' or 'W'
660 l, _ = c.Next()
661 if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok {
662 goto Altitude
663 }
664 if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err || i > 59 {
665 return &ParseError{err: "bad LOC Longitude minutes", lex: l}
666 } else {
667 rr.Longitude += 1000 * 60 * uint32(i)
668 }
669 c.Next() // zBlank
670 l, _ = c.Next()
671 if i, err := strconv.ParseFloat(l.token, 64); err != nil || l.err || i < 0 || i >= 60 {
672 return &ParseError{err: "bad LOC Longitude seconds", lex: l}
673 } else {
674 rr.Longitude += uint32(1000 * i)
675 }
676 c.Next() // zBlank
677 // Either number, 'E' or 'W'
678 l, _ = c.Next()
679 if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok {
680 goto Altitude
681 }
682 // If still alive, flag an error
683 return &ParseError{err: "bad LOC Longitude East/West", lex: l}
684
685 Altitude:
686 c.Next() // zBlank
687 l, _ = c.Next()
688 if l.token == "" || l.err {
689 return &ParseError{err: "bad LOC Altitude", lex: l}
690 }
691 if l.token[len(l.token)-1] == 'M' || l.token[len(l.token)-1] == 'm' {
692 l.token = l.token[0 : len(l.token)-1]
693 }
694 if i, err := strconv.ParseFloat(l.token, 64); err != nil {
695 return &ParseError{err: "bad LOC Altitude", lex: l}
696 } else {
697 rr.Altitude = uint32(i*100.0 + 10000000.0 + 0.5)
698 }
699
700 // And now optionally the other values
701 l, _ = c.Next()
702 count := 0
703 for l.value != zNewline && l.value != zEOF {
704 switch l.value {
705 case zString:
706 switch count {
707 case 0: // Size
708 exp, m, ok := stringToCm(l.token)
709 if !ok {
710 return &ParseError{err: "bad LOC Size", lex: l}
711 }
712 rr.Size = exp&0x0f | m<<4&0xf0
713 case 1: // HorizPre
714 exp, m, ok := stringToCm(l.token)
715 if !ok {
716 return &ParseError{err: "bad LOC HorizPre", lex: l}
717 }
718 rr.HorizPre = exp&0x0f | m<<4&0xf0
719 case 2: // VertPre
720 exp, m, ok := stringToCm(l.token)
721 if !ok {
722 return &ParseError{err: "bad LOC VertPre", lex: l}
723 }
724 rr.VertPre = exp&0x0f | m<<4&0xf0
725 }
726 count++
727 case zBlank:
728 // Ok
729 default:
730 return &ParseError{err: "bad LOC Size, HorizPre or VertPre", lex: l}
731 }
732 l, _ = c.Next()
733 }
734 return nil
735 }
736
737 func (rr *HIP) parse(c *zlexer, o string) *ParseError {
738 // HitLength is not represented
739 l, _ := c.Next()
740 i, e := strconv.ParseUint(l.token, 10, 8)
741 if e != nil || l.err {
742 return &ParseError{err: "bad HIP PublicKeyAlgorithm", lex: l}
743 }
744 rr.PublicKeyAlgorithm = uint8(i)
745
746 c.Next() // zBlank
747 l, _ = c.Next() // zString
748 if l.token == "" || l.err {
749 return &ParseError{err: "bad HIP Hit", lex: l}
750 }
751 rr.Hit = l.token // This can not contain spaces, see RFC 5205 Section 6.
752 rr.HitLength = uint8(len(rr.Hit)) / 2
753
754 c.Next() // zBlank
755 l, _ = c.Next() // zString
756 if l.token == "" || l.err {
757 return &ParseError{err: "bad HIP PublicKey", lex: l}
758 }
759 rr.PublicKey = l.token // This cannot contain spaces
760 decodedPK, decodedPKerr := base64.StdEncoding.DecodeString(rr.PublicKey)
761 if decodedPKerr != nil {
762 return &ParseError{err: "bad HIP PublicKey", lex: l}
763 }
764 rr.PublicKeyLength = uint16(len(decodedPK))
765
766 // RendezvousServers (if any)
767 l, _ = c.Next()
768 var xs []string
769 for l.value != zNewline && l.value != zEOF {
770 switch l.value {
771 case zString:
772 name, nameOk := toAbsoluteName(l.token, o)
773 if l.err || !nameOk {
774 return &ParseError{err: "bad HIP RendezvousServers", lex: l}
775 }
776 xs = append(xs, name)
777 case zBlank:
778 // Ok
779 default:
780 return &ParseError{err: "bad HIP RendezvousServers", lex: l}
781 }
782 l, _ = c.Next()
783 }
784
785 rr.RendezvousServers = xs
786 return nil
787 }
788
789 func (rr *CERT) parse(c *zlexer, o string) *ParseError {
790 l, _ := c.Next()
791 if v, ok := StringToCertType[l.token]; ok {
792 rr.Type = v
793 } else if i, err := strconv.ParseUint(l.token, 10, 16); err != nil {
794 return &ParseError{err: "bad CERT Type", lex: l}
795 } else {
796 rr.Type = uint16(i)
797 }
798 c.Next() // zBlank
799 l, _ = c.Next() // zString
800 i, e := strconv.ParseUint(l.token, 10, 16)
801 if e != nil || l.err {
802 return &ParseError{err: "bad CERT KeyTag", lex: l}
803 }
804 rr.KeyTag = uint16(i)
805 c.Next() // zBlank
806 l, _ = c.Next() // zString
807 if v, ok := StringToAlgorithm[l.token]; ok {
808 rr.Algorithm = v
809 } else if i, err := strconv.ParseUint(l.token, 10, 8); err != nil {
810 return &ParseError{err: "bad CERT Algorithm", lex: l}
811 } else {
812 rr.Algorithm = uint8(i)
813 }
814 s, e1 := endingToString(c, "bad CERT Certificate")
815 if e1 != nil {
816 return e1
817 }
818 rr.Certificate = s
819 return nil
820 }
821
822 func (rr *OPENPGPKEY) parse(c *zlexer, o string) *ParseError {
823 s, e := endingToString(c, "bad OPENPGPKEY PublicKey")
824 if e != nil {
825 return e
826 }
827 rr.PublicKey = s
828 return nil
829 }
830
831 func (rr *CSYNC) parse(c *zlexer, o string) *ParseError {
832 l, _ := c.Next()
833 j, e := strconv.ParseUint(l.token, 10, 32)
834 if e != nil {
835 // Serial must be a number
836 return &ParseError{err: "bad CSYNC serial", lex: l}
837 }
838 rr.Serial = uint32(j)
839
840 c.Next() // zBlank
841
842 l, _ = c.Next()
843 j, e1 := strconv.ParseUint(l.token, 10, 16)
844 if e1 != nil {
845 // Serial must be a number
846 return &ParseError{err: "bad CSYNC flags", lex: l}
847 }
848 rr.Flags = uint16(j)
849
850 rr.TypeBitMap = make([]uint16, 0)
851 var (
852 k uint16
853 ok bool
854 )
855 l, _ = c.Next()
856 for l.value != zNewline && l.value != zEOF {
857 switch l.value {
858 case zBlank:
859 // Ok
860 case zString:
861 tokenUpper := strings.ToUpper(l.token)
862 if k, ok = StringToType[tokenUpper]; !ok {
863 if k, ok = typeToInt(l.token); !ok {
864 return &ParseError{err: "bad CSYNC TypeBitMap", lex: l}
865 }
866 }
867 rr.TypeBitMap = append(rr.TypeBitMap, k)
868 default:
869 return &ParseError{err: "bad CSYNC TypeBitMap", lex: l}
870 }
871 l, _ = c.Next()
872 }
873 return nil
874 }
875
876 func (rr *ZONEMD) parse(c *zlexer, o string) *ParseError {
877 l, _ := c.Next()
878 i, e := strconv.ParseUint(l.token, 10, 32)
879 if e != nil || l.err {
880 return &ParseError{err: "bad ZONEMD Serial", lex: l}
881 }
882 rr.Serial = uint32(i)
883
884 c.Next() // zBlank
885 l, _ = c.Next()
886 i, e1 := strconv.ParseUint(l.token, 10, 8)
887 if e1 != nil || l.err {
888 return &ParseError{err: "bad ZONEMD Scheme", lex: l}
889 }
890 rr.Scheme = uint8(i)
891
892 c.Next() // zBlank
893 l, _ = c.Next()
894 i, err := strconv.ParseUint(l.token, 10, 8)
895 if err != nil || l.err {
896 return &ParseError{err: "bad ZONEMD Hash Algorithm", lex: l}
897 }
898 rr.Hash = uint8(i)
899
900 s, e2 := endingToString(c, "bad ZONEMD Digest")
901 if e2 != nil {
902 return e2
903 }
904 rr.Digest = s
905 return nil
906 }
907
908 func (rr *SIG) parse(c *zlexer, o string) *ParseError { return rr.RRSIG.parse(c, o) }
909
910 func (rr *RRSIG) parse(c *zlexer, o string) *ParseError {
911 l, _ := c.Next()
912 tokenUpper := strings.ToUpper(l.token)
913 if t, ok := StringToType[tokenUpper]; !ok {
914 if strings.HasPrefix(tokenUpper, "TYPE") {
915 t, ok = typeToInt(l.token)
916 if !ok {
917 return &ParseError{err: "bad RRSIG Typecovered", lex: l}
918 }
919 rr.TypeCovered = t
920 } else {
921 return &ParseError{err: "bad RRSIG Typecovered", lex: l}
922 }
923 } else {
924 rr.TypeCovered = t
925 }
926
927 c.Next() // zBlank
928 l, _ = c.Next()
929 if l.err {
930 return &ParseError{err: "bad RRSIG Algorithm", lex: l}
931 }
932 i, e := strconv.ParseUint(l.token, 10, 8)
933 rr.Algorithm = uint8(i) // if 0 we'll check the mnemonic in the if
934 if e != nil {
935 v, ok := StringToAlgorithm[l.token]
936 if !ok {
937 return &ParseError{err: "bad RRSIG Algorithm", lex: l}
938 }
939 rr.Algorithm = v
940 }
941
942 c.Next() // zBlank
943 l, _ = c.Next()
944 i, e1 := strconv.ParseUint(l.token, 10, 8)
945 if e1 != nil || l.err {
946 return &ParseError{err: "bad RRSIG Labels", lex: l}
947 }
948 rr.Labels = uint8(i)
949
950 c.Next() // zBlank
951 l, _ = c.Next()
952 i, e2 := strconv.ParseUint(l.token, 10, 32)
953 if e2 != nil || l.err {
954 return &ParseError{err: "bad RRSIG OrigTtl", lex: l}
955 }
956 rr.OrigTtl = uint32(i)
957
958 c.Next() // zBlank
959 l, _ = c.Next()
960 if i, err := StringToTime(l.token); err != nil {
961 // Try to see if all numeric and use it as epoch
962 if i, err := strconv.ParseUint(l.token, 10, 32); err == nil {
963 rr.Expiration = uint32(i)
964 } else {
965 return &ParseError{err: "bad RRSIG Expiration", lex: l}
966 }
967 } else {
968 rr.Expiration = i
969 }
970
971 c.Next() // zBlank
972 l, _ = c.Next()
973 if i, err := StringToTime(l.token); err != nil {
974 if i, err := strconv.ParseUint(l.token, 10, 32); err == nil {
975 rr.Inception = uint32(i)
976 } else {
977 return &ParseError{err: "bad RRSIG Inception", lex: l}
978 }
979 } else {
980 rr.Inception = i
981 }
982
983 c.Next() // zBlank
984 l, _ = c.Next()
985 i, e3 := strconv.ParseUint(l.token, 10, 16)
986 if e3 != nil || l.err {
987 return &ParseError{err: "bad RRSIG KeyTag", lex: l}
988 }
989 rr.KeyTag = uint16(i)
990
991 c.Next() // zBlank
992 l, _ = c.Next()
993 rr.SignerName = l.token
994 name, nameOk := toAbsoluteName(l.token, o)
995 if l.err || !nameOk {
996 return &ParseError{err: "bad RRSIG SignerName", lex: l}
997 }
998 rr.SignerName = name
999
1000 s, e4 := endingToString(c, "bad RRSIG Signature")
1001 if e4 != nil {
1002 return e4
1003 }
1004 rr.Signature = s
1005
1006 return nil
1007 }
1008
1009 func (rr *NXT) parse(c *zlexer, o string) *ParseError { return rr.NSEC.parse(c, o) }
1010
1011 func (rr *NSEC) parse(c *zlexer, o string) *ParseError {
1012 l, _ := c.Next()
1013 name, nameOk := toAbsoluteName(l.token, o)
1014 if l.err || !nameOk {
1015 return &ParseError{err: "bad NSEC NextDomain", lex: l}
1016 }
1017 rr.NextDomain = name
1018
1019 rr.TypeBitMap = make([]uint16, 0)
1020 var (
1021 k uint16
1022 ok bool
1023 )
1024 l, _ = c.Next()
1025 for l.value != zNewline && l.value != zEOF {
1026 switch l.value {
1027 case zBlank:
1028 // Ok
1029 case zString:
1030 tokenUpper := strings.ToUpper(l.token)
1031 if k, ok = StringToType[tokenUpper]; !ok {
1032 if k, ok = typeToInt(l.token); !ok {
1033 return &ParseError{err: "bad NSEC TypeBitMap", lex: l}
1034 }
1035 }
1036 rr.TypeBitMap = append(rr.TypeBitMap, k)
1037 default:
1038 return &ParseError{err: "bad NSEC TypeBitMap", lex: l}
1039 }
1040 l, _ = c.Next()
1041 }
1042 return nil
1043 }
1044
1045 func (rr *NSEC3) parse(c *zlexer, o string) *ParseError {
1046 l, _ := c.Next()
1047 i, e := strconv.ParseUint(l.token, 10, 8)
1048 if e != nil || l.err {
1049 return &ParseError{err: "bad NSEC3 Hash", lex: l}
1050 }
1051 rr.Hash = uint8(i)
1052 c.Next() // zBlank
1053 l, _ = c.Next()
1054 i, e1 := strconv.ParseUint(l.token, 10, 8)
1055 if e1 != nil || l.err {
1056 return &ParseError{err: "bad NSEC3 Flags", lex: l}
1057 }
1058 rr.Flags = uint8(i)
1059 c.Next() // zBlank
1060 l, _ = c.Next()
1061 i, e2 := strconv.ParseUint(l.token, 10, 16)
1062 if e2 != nil || l.err {
1063 return &ParseError{err: "bad NSEC3 Iterations", lex: l}
1064 }
1065 rr.Iterations = uint16(i)
1066 c.Next()
1067 l, _ = c.Next()
1068 if l.token == "" || l.err {
1069 return &ParseError{err: "bad NSEC3 Salt", lex: l}
1070 }
1071 if l.token != "-" {
1072 rr.SaltLength = uint8(len(l.token)) / 2
1073 rr.Salt = l.token
1074 }
1075
1076 c.Next()
1077 l, _ = c.Next()
1078 if l.token == "" || l.err {
1079 return &ParseError{err: "bad NSEC3 NextDomain", lex: l}
1080 }
1081 rr.HashLength = 20 // Fix for NSEC3 (sha1 160 bits)
1082 rr.NextDomain = l.token
1083
1084 rr.TypeBitMap = make([]uint16, 0)
1085 var (
1086 k uint16
1087 ok bool
1088 )
1089 l, _ = c.Next()
1090 for l.value != zNewline && l.value != zEOF {
1091 switch l.value {
1092 case zBlank:
1093 // Ok
1094 case zString:
1095 tokenUpper := strings.ToUpper(l.token)
1096 if k, ok = StringToType[tokenUpper]; !ok {
1097 if k, ok = typeToInt(l.token); !ok {
1098 return &ParseError{err: "bad NSEC3 TypeBitMap", lex: l}
1099 }
1100 }
1101 rr.TypeBitMap = append(rr.TypeBitMap, k)
1102 default:
1103 return &ParseError{err: "bad NSEC3 TypeBitMap", lex: l}
1104 }
1105 l, _ = c.Next()
1106 }
1107 return nil
1108 }
1109
1110 func (rr *NSEC3PARAM) parse(c *zlexer, o string) *ParseError {
1111 l, _ := c.Next()
1112 i, e := strconv.ParseUint(l.token, 10, 8)
1113 if e != nil || l.err {
1114 return &ParseError{err: "bad NSEC3PARAM Hash", lex: l}
1115 }
1116 rr.Hash = uint8(i)
1117 c.Next() // zBlank
1118 l, _ = c.Next()
1119 i, e1 := strconv.ParseUint(l.token, 10, 8)
1120 if e1 != nil || l.err {
1121 return &ParseError{err: "bad NSEC3PARAM Flags", lex: l}
1122 }
1123 rr.Flags = uint8(i)
1124 c.Next() // zBlank
1125 l, _ = c.Next()
1126 i, e2 := strconv.ParseUint(l.token, 10, 16)
1127 if e2 != nil || l.err {
1128 return &ParseError{err: "bad NSEC3PARAM Iterations", lex: l}
1129 }
1130 rr.Iterations = uint16(i)
1131 c.Next()
1132 l, _ = c.Next()
1133 if l.token != "-" {
1134 rr.SaltLength = uint8(len(l.token) / 2)
1135 rr.Salt = l.token
1136 }
1137 return slurpRemainder(c)
1138 }
1139
1140 func (rr *EUI48) parse(c *zlexer, o string) *ParseError {
1141 l, _ := c.Next()
1142 if len(l.token) != 17 || l.err {
1143 return &ParseError{err: "bad EUI48 Address", lex: l}
1144 }
1145 addr := make([]byte, 12)
1146 dash := 0
1147 for i := 0; i < 10; i += 2 {
1148 addr[i] = l.token[i+dash]
1149 addr[i+1] = l.token[i+1+dash]
1150 dash++
1151 if l.token[i+1+dash] != '-' {
1152 return &ParseError{err: "bad EUI48 Address", lex: l}
1153 }
1154 }
1155 addr[10] = l.token[15]
1156 addr[11] = l.token[16]
1157
1158 i, e := strconv.ParseUint(string(addr), 16, 48)
1159 if e != nil {
1160 return &ParseError{err: "bad EUI48 Address", lex: l}
1161 }
1162 rr.Address = i
1163 return slurpRemainder(c)
1164 }
1165
1166 func (rr *EUI64) parse(c *zlexer, o string) *ParseError {
1167 l, _ := c.Next()
1168 if len(l.token) != 23 || l.err {
1169 return &ParseError{err: "bad EUI64 Address", lex: l}
1170 }
1171 addr := make([]byte, 16)
1172 dash := 0
1173 for i := 0; i < 14; i += 2 {
1174 addr[i] = l.token[i+dash]
1175 addr[i+1] = l.token[i+1+dash]
1176 dash++
1177 if l.token[i+1+dash] != '-' {
1178 return &ParseError{err: "bad EUI64 Address", lex: l}
1179 }
1180 }
1181 addr[14] = l.token[21]
1182 addr[15] = l.token[22]
1183
1184 i, e := strconv.ParseUint(string(addr), 16, 64)
1185 if e != nil {
1186 return &ParseError{err: "bad EUI68 Address", lex: l}
1187 }
1188 rr.Address = i
1189 return slurpRemainder(c)
1190 }
1191
1192 func (rr *SSHFP) parse(c *zlexer, o string) *ParseError {
1193 l, _ := c.Next()
1194 i, e := strconv.ParseUint(l.token, 10, 8)
1195 if e != nil || l.err {
1196 return &ParseError{err: "bad SSHFP Algorithm", lex: l}
1197 }
1198 rr.Algorithm = uint8(i)
1199 c.Next() // zBlank
1200 l, _ = c.Next()
1201 i, e1 := strconv.ParseUint(l.token, 10, 8)
1202 if e1 != nil || l.err {
1203 return &ParseError{err: "bad SSHFP Type", lex: l}
1204 }
1205 rr.Type = uint8(i)
1206 c.Next() // zBlank
1207 s, e2 := endingToString(c, "bad SSHFP Fingerprint")
1208 if e2 != nil {
1209 return e2
1210 }
1211 rr.FingerPrint = s
1212 return nil
1213 }
1214
1215 func (rr *DNSKEY) parseDNSKEY(c *zlexer, o, typ string) *ParseError {
1216 l, _ := c.Next()
1217 i, e := strconv.ParseUint(l.token, 10, 16)
1218 if e != nil || l.err {
1219 return &ParseError{err: "bad " + typ + " Flags", lex: l}
1220 }
1221 rr.Flags = uint16(i)
1222 c.Next() // zBlank
1223 l, _ = c.Next() // zString
1224 i, e1 := strconv.ParseUint(l.token, 10, 8)
1225 if e1 != nil || l.err {
1226 return &ParseError{err: "bad " + typ + " Protocol", lex: l}
1227 }
1228 rr.Protocol = uint8(i)
1229 c.Next() // zBlank
1230 l, _ = c.Next() // zString
1231 i, e2 := strconv.ParseUint(l.token, 10, 8)
1232 if e2 != nil || l.err {
1233 return &ParseError{err: "bad " + typ + " Algorithm", lex: l}
1234 }
1235 rr.Algorithm = uint8(i)
1236 s, e3 := endingToString(c, "bad "+typ+" PublicKey")
1237 if e3 != nil {
1238 return e3
1239 }
1240 rr.PublicKey = s
1241 return nil
1242 }
1243
1244 func (rr *DNSKEY) parse(c *zlexer, o string) *ParseError { return rr.parseDNSKEY(c, o, "DNSKEY") }
1245 func (rr *KEY) parse(c *zlexer, o string) *ParseError { return rr.parseDNSKEY(c, o, "KEY") }
1246 func (rr *CDNSKEY) parse(c *zlexer, o string) *ParseError { return rr.parseDNSKEY(c, o, "CDNSKEY") }
1247 func (rr *DS) parse(c *zlexer, o string) *ParseError { return rr.parseDS(c, o, "DS") }
1248 func (rr *DLV) parse(c *zlexer, o string) *ParseError { return rr.parseDS(c, o, "DLV") }
1249 func (rr *CDS) parse(c *zlexer, o string) *ParseError { return rr.parseDS(c, o, "CDS") }
1250
1251 func (rr *IPSECKEY) parse(c *zlexer, o string) *ParseError {
1252 l, _ := c.Next()
1253 num, err := strconv.ParseUint(l.token, 10, 8)
1254 if err != nil || l.err {
1255 return &ParseError{err: "bad IPSECKEY value", lex: l}
1256 }
1257 rr.Precedence = uint8(num)
1258 c.Next() // zBlank
1259
1260 l, _ = c.Next()
1261 num, err = strconv.ParseUint(l.token, 10, 8)
1262 if err != nil || l.err {
1263 return &ParseError{err: "bad IPSECKEY value", lex: l}
1264 }
1265 rr.GatewayType = uint8(num)
1266 c.Next() // zBlank
1267
1268 l, _ = c.Next()
1269 num, err = strconv.ParseUint(l.token, 10, 8)
1270 if err != nil || l.err {
1271 return &ParseError{err: "bad IPSECKEY value", lex: l}
1272 }
1273 rr.Algorithm = uint8(num)
1274 c.Next() // zBlank
1275
1276 l, _ = c.Next()
1277 if l.err {
1278 return &ParseError{err: "bad IPSECKEY gateway", lex: l}
1279 }
1280
1281 rr.GatewayAddr, rr.GatewayHost, err = parseAddrHostUnion(l.token, o, rr.GatewayType)
1282 if err != nil {
1283 return &ParseError{wrappedErr: fmt.Errorf("IPSECKEY %w", err), lex: l}
1284 }
1285
1286 c.Next() // zBlank
1287
1288 s, pErr := endingToString(c, "bad IPSECKEY PublicKey")
1289 if pErr != nil {
1290 return pErr
1291 }
1292 rr.PublicKey = s
1293 return slurpRemainder(c)
1294 }
1295
1296 func (rr *AMTRELAY) parse(c *zlexer, o string) *ParseError {
1297 l, _ := c.Next()
1298 num, err := strconv.ParseUint(l.token, 10, 8)
1299 if err != nil || l.err {
1300 return &ParseError{err: "bad AMTRELAY value", lex: l}
1301 }
1302 rr.Precedence = uint8(num)
1303 c.Next() // zBlank
1304
1305 l, _ = c.Next()
1306 if l.err || !(l.token == "0" || l.token == "1") {
1307 return &ParseError{err: "bad discovery value", lex: l}
1308 }
1309 if l.token == "1" {
1310 rr.GatewayType = 0x80
1311 }
1312
1313 c.Next() // zBlank
1314
1315 l, _ = c.Next()
1316 num, err = strconv.ParseUint(l.token, 10, 8)
1317 if err != nil || l.err {
1318 return &ParseError{err: "bad AMTRELAY value", lex: l}
1319 }
1320 rr.GatewayType |= uint8(num)
1321 c.Next() // zBlank
1322
1323 l, _ = c.Next()
1324 if l.err {
1325 return &ParseError{err: "bad AMTRELAY gateway", lex: l}
1326 }
1327
1328 rr.GatewayAddr, rr.GatewayHost, err = parseAddrHostUnion(l.token, o, rr.GatewayType&0x7f)
1329 if err != nil {
1330 return &ParseError{wrappedErr: fmt.Errorf("AMTRELAY %w", err), lex: l}
1331 }
1332
1333 return slurpRemainder(c)
1334 }
1335
1336 // same constants and parsing between IPSECKEY and AMTRELAY
1337 func parseAddrHostUnion(token, o string, gatewayType uint8) (addr net.IP, host string, err error) {
1338 switch gatewayType {
1339 case IPSECGatewayNone:
1340 if token != "." {
1341 return addr, host, errors.New("gateway type none with gateway set")
1342 }
1343 case IPSECGatewayIPv4, IPSECGatewayIPv6:
1344 addr = net.ParseIP(token)
1345 if addr == nil {
1346 return addr, host, errors.New("gateway IP invalid")
1347 }
1348 if (addr.To4() == nil) == (gatewayType == IPSECGatewayIPv4) {
1349 return addr, host, errors.New("gateway IP family mismatch")
1350 }
1351 case IPSECGatewayHost:
1352 var ok bool
1353 host, ok = toAbsoluteName(token, o)
1354 if !ok {
1355 return addr, host, errors.New("invalid gateway host")
1356 }
1357 }
1358
1359 return addr, host, nil
1360 }
1361
1362 func (rr *RKEY) parse(c *zlexer, o string) *ParseError {
1363 l, _ := c.Next()
1364 i, e := strconv.ParseUint(l.token, 10, 16)
1365 if e != nil || l.err {
1366 return &ParseError{err: "bad RKEY Flags", lex: l}
1367 }
1368 rr.Flags = uint16(i)
1369 c.Next() // zBlank
1370 l, _ = c.Next() // zString
1371 i, e1 := strconv.ParseUint(l.token, 10, 8)
1372 if e1 != nil || l.err {
1373 return &ParseError{err: "bad RKEY Protocol", lex: l}
1374 }
1375 rr.Protocol = uint8(i)
1376 c.Next() // zBlank
1377 l, _ = c.Next() // zString
1378 i, e2 := strconv.ParseUint(l.token, 10, 8)
1379 if e2 != nil || l.err {
1380 return &ParseError{err: "bad RKEY Algorithm", lex: l}
1381 }
1382 rr.Algorithm = uint8(i)
1383 s, e3 := endingToString(c, "bad RKEY PublicKey")
1384 if e3 != nil {
1385 return e3
1386 }
1387 rr.PublicKey = s
1388 return nil
1389 }
1390
1391 func (rr *EID) parse(c *zlexer, o string) *ParseError {
1392 s, e := endingToString(c, "bad EID Endpoint")
1393 if e != nil {
1394 return e
1395 }
1396 rr.Endpoint = s
1397 return nil
1398 }
1399
1400 func (rr *NIMLOC) parse(c *zlexer, o string) *ParseError {
1401 s, e := endingToString(c, "bad NIMLOC Locator")
1402 if e != nil {
1403 return e
1404 }
1405 rr.Locator = s
1406 return nil
1407 }
1408
1409 func (rr *GPOS) parse(c *zlexer, o string) *ParseError {
1410 l, _ := c.Next()
1411 _, e := strconv.ParseFloat(l.token, 64)
1412 if e != nil || l.err {
1413 return &ParseError{err: "bad GPOS Longitude", lex: l}
1414 }
1415 rr.Longitude = l.token
1416 c.Next() // zBlank
1417 l, _ = c.Next()
1418 _, e1 := strconv.ParseFloat(l.token, 64)
1419 if e1 != nil || l.err {
1420 return &ParseError{err: "bad GPOS Latitude", lex: l}
1421 }
1422 rr.Latitude = l.token
1423 c.Next() // zBlank
1424 l, _ = c.Next()
1425 _, e2 := strconv.ParseFloat(l.token, 64)
1426 if e2 != nil || l.err {
1427 return &ParseError{err: "bad GPOS Altitude", lex: l}
1428 }
1429 rr.Altitude = l.token
1430 return slurpRemainder(c)
1431 }
1432
1433 func (rr *DS) parseDS(c *zlexer, o, typ string) *ParseError {
1434 l, _ := c.Next()
1435 i, e := strconv.ParseUint(l.token, 10, 16)
1436 if e != nil || l.err {
1437 return &ParseError{err: "bad " + typ + " KeyTag", lex: l}
1438 }
1439 rr.KeyTag = uint16(i)
1440 c.Next() // zBlank
1441 l, _ = c.Next()
1442 if i, err := strconv.ParseUint(l.token, 10, 8); err != nil {
1443 tokenUpper := strings.ToUpper(l.token)
1444 i, ok := StringToAlgorithm[tokenUpper]
1445 if !ok || l.err {
1446 return &ParseError{err: "bad " + typ + " Algorithm", lex: l}
1447 }
1448 rr.Algorithm = i
1449 } else {
1450 rr.Algorithm = uint8(i)
1451 }
1452 c.Next() // zBlank
1453 l, _ = c.Next()
1454 i, e1 := strconv.ParseUint(l.token, 10, 8)
1455 if e1 != nil || l.err {
1456 return &ParseError{err: "bad " + typ + " DigestType", lex: l}
1457 }
1458 rr.DigestType = uint8(i)
1459 s, e2 := endingToString(c, "bad "+typ+" Digest")
1460 if e2 != nil {
1461 return e2
1462 }
1463 rr.Digest = s
1464 return nil
1465 }
1466
1467 func (rr *TA) parse(c *zlexer, o string) *ParseError {
1468 l, _ := c.Next()
1469 i, e := strconv.ParseUint(l.token, 10, 16)
1470 if e != nil || l.err {
1471 return &ParseError{err: "bad TA KeyTag", lex: l}
1472 }
1473 rr.KeyTag = uint16(i)
1474 c.Next() // zBlank
1475 l, _ = c.Next()
1476 if i, err := strconv.ParseUint(l.token, 10, 8); err != nil {
1477 tokenUpper := strings.ToUpper(l.token)
1478 i, ok := StringToAlgorithm[tokenUpper]
1479 if !ok || l.err {
1480 return &ParseError{err: "bad TA Algorithm", lex: l}
1481 }
1482 rr.Algorithm = i
1483 } else {
1484 rr.Algorithm = uint8(i)
1485 }
1486 c.Next() // zBlank
1487 l, _ = c.Next()
1488 i, e1 := strconv.ParseUint(l.token, 10, 8)
1489 if e1 != nil || l.err {
1490 return &ParseError{err: "bad TA DigestType", lex: l}
1491 }
1492 rr.DigestType = uint8(i)
1493 s, e2 := endingToString(c, "bad TA Digest")
1494 if e2 != nil {
1495 return e2
1496 }
1497 rr.Digest = s
1498 return nil
1499 }
1500
1501 func (rr *TLSA) parse(c *zlexer, o string) *ParseError {
1502 l, _ := c.Next()
1503 i, e := strconv.ParseUint(l.token, 10, 8)
1504 if e != nil || l.err {
1505 return &ParseError{err: "bad TLSA Usage", lex: l}
1506 }
1507 rr.Usage = uint8(i)
1508 c.Next() // zBlank
1509 l, _ = c.Next()
1510 i, e1 := strconv.ParseUint(l.token, 10, 8)
1511 if e1 != nil || l.err {
1512 return &ParseError{err: "bad TLSA Selector", lex: l}
1513 }
1514 rr.Selector = uint8(i)
1515 c.Next() // zBlank
1516 l, _ = c.Next()
1517 i, e2 := strconv.ParseUint(l.token, 10, 8)
1518 if e2 != nil || l.err {
1519 return &ParseError{err: "bad TLSA MatchingType", lex: l}
1520 }
1521 rr.MatchingType = uint8(i)
1522 // So this needs be e2 (i.e. different than e), because...??t
1523 s, e3 := endingToString(c, "bad TLSA Certificate")
1524 if e3 != nil {
1525 return e3
1526 }
1527 rr.Certificate = s
1528 return nil
1529 }
1530
1531 func (rr *SMIMEA) parse(c *zlexer, o string) *ParseError {
1532 l, _ := c.Next()
1533 i, e := strconv.ParseUint(l.token, 10, 8)
1534 if e != nil || l.err {
1535 return &ParseError{err: "bad SMIMEA Usage", lex: l}
1536 }
1537 rr.Usage = uint8(i)
1538 c.Next() // zBlank
1539 l, _ = c.Next()
1540 i, e1 := strconv.ParseUint(l.token, 10, 8)
1541 if e1 != nil || l.err {
1542 return &ParseError{err: "bad SMIMEA Selector", lex: l}
1543 }
1544 rr.Selector = uint8(i)
1545 c.Next() // zBlank
1546 l, _ = c.Next()
1547 i, e2 := strconv.ParseUint(l.token, 10, 8)
1548 if e2 != nil || l.err {
1549 return &ParseError{err: "bad SMIMEA MatchingType", lex: l}
1550 }
1551 rr.MatchingType = uint8(i)
1552 // So this needs be e2 (i.e. different than e), because...??t
1553 s, e3 := endingToString(c, "bad SMIMEA Certificate")
1554 if e3 != nil {
1555 return e3
1556 }
1557 rr.Certificate = s
1558 return nil
1559 }
1560
1561 func (rr *RFC3597) parse(c *zlexer, o string) *ParseError {
1562 l, _ := c.Next()
1563 if l.token != "\\#" {
1564 return &ParseError{err: "bad RFC3597 Rdata", lex: l}
1565 }
1566
1567 c.Next() // zBlank
1568 l, _ = c.Next()
1569 rdlength, e := strconv.ParseUint(l.token, 10, 16)
1570 if e != nil || l.err {
1571 return &ParseError{err: "bad RFC3597 Rdata ", lex: l}
1572 }
1573
1574 s, e1 := endingToString(c, "bad RFC3597 Rdata")
1575 if e1 != nil {
1576 return e1
1577 }
1578 if int(rdlength)*2 != len(s) {
1579 return &ParseError{err: "bad RFC3597 Rdata", lex: l}
1580 }
1581 rr.Rdata = s
1582 return nil
1583 }
1584
1585 func (rr *SPF) parse(c *zlexer, o string) *ParseError {
1586 s, e := endingToTxtSlice(c, "bad SPF Txt")
1587 if e != nil {
1588 return e
1589 }
1590 rr.Txt = s
1591 return nil
1592 }
1593
1594 func (rr *AVC) parse(c *zlexer, o string) *ParseError {
1595 s, e := endingToTxtSlice(c, "bad AVC Txt")
1596 if e != nil {
1597 return e
1598 }
1599 rr.Txt = s
1600 return nil
1601 }
1602
1603 func (rr *TXT) parse(c *zlexer, o string) *ParseError {
1604 // no zBlank reading here, because all this rdata is TXT
1605 s, e := endingToTxtSlice(c, "bad TXT Txt")
1606 if e != nil {
1607 return e
1608 }
1609 rr.Txt = s
1610 return nil
1611 }
1612
1613 // identical to setTXT
1614 func (rr *NINFO) parse(c *zlexer, o string) *ParseError {
1615 s, e := endingToTxtSlice(c, "bad NINFO ZSData")
1616 if e != nil {
1617 return e
1618 }
1619 rr.ZSData = s
1620 return nil
1621 }
1622
1623 // Uses the same format as TXT
1624 func (rr *RESINFO) parse(c *zlexer, o string) *ParseError {
1625 s, e := endingToTxtSlice(c, "bad RESINFO Resinfo")
1626 if e != nil {
1627 return e
1628 }
1629 rr.Txt = s
1630 return nil
1631 }
1632
1633 func (rr *URI) parse(c *zlexer, o string) *ParseError {
1634 l, _ := c.Next()
1635 i, e := strconv.ParseUint(l.token, 10, 16)
1636 if e != nil || l.err {
1637 return &ParseError{err: "bad URI Priority", lex: l}
1638 }
1639 rr.Priority = uint16(i)
1640 c.Next() // zBlank
1641 l, _ = c.Next()
1642 i, e1 := strconv.ParseUint(l.token, 10, 16)
1643 if e1 != nil || l.err {
1644 return &ParseError{err: "bad URI Weight", lex: l}
1645 }
1646 rr.Weight = uint16(i)
1647
1648 c.Next() // zBlank
1649 s, e2 := endingToTxtSlice(c, "bad URI Target")
1650 if e2 != nil {
1651 return e2
1652 }
1653 if len(s) != 1 {
1654 return &ParseError{err: "bad URI Target", lex: l}
1655 }
1656 rr.Target = s[0]
1657 return nil
1658 }
1659
1660 func (rr *DHCID) parse(c *zlexer, o string) *ParseError {
1661 // awesome record to parse!
1662 s, e := endingToString(c, "bad DHCID Digest")
1663 if e != nil {
1664 return e
1665 }
1666 rr.Digest = s
1667 return nil
1668 }
1669
1670 func (rr *NID) parse(c *zlexer, o string) *ParseError {
1671 l, _ := c.Next()
1672 i, e := strconv.ParseUint(l.token, 10, 16)
1673 if e != nil || l.err {
1674 return &ParseError{err: "bad NID Preference", lex: l}
1675 }
1676 rr.Preference = uint16(i)
1677 c.Next() // zBlank
1678 l, _ = c.Next() // zString
1679 u, e1 := stringToNodeID(l)
1680 if e1 != nil || l.err {
1681 return e1
1682 }
1683 rr.NodeID = u
1684 return slurpRemainder(c)
1685 }
1686
1687 func (rr *L32) parse(c *zlexer, o string) *ParseError {
1688 l, _ := c.Next()
1689 i, e := strconv.ParseUint(l.token, 10, 16)
1690 if e != nil || l.err {
1691 return &ParseError{err: "bad L32 Preference", lex: l}
1692 }
1693 rr.Preference = uint16(i)
1694 c.Next() // zBlank
1695 l, _ = c.Next() // zString
1696 rr.Locator32 = net.ParseIP(l.token)
1697 if rr.Locator32 == nil || l.err {
1698 return &ParseError{err: "bad L32 Locator", lex: l}
1699 }
1700 return slurpRemainder(c)
1701 }
1702
1703 func (rr *LP) parse(c *zlexer, o string) *ParseError {
1704 l, _ := c.Next()
1705 i, e := strconv.ParseUint(l.token, 10, 16)
1706 if e != nil || l.err {
1707 return &ParseError{err: "bad LP Preference", lex: l}
1708 }
1709 rr.Preference = uint16(i)
1710
1711 c.Next() // zBlank
1712 l, _ = c.Next() // zString
1713 rr.Fqdn = l.token
1714 name, nameOk := toAbsoluteName(l.token, o)
1715 if l.err || !nameOk {
1716 return &ParseError{err: "bad LP Fqdn", lex: l}
1717 }
1718 rr.Fqdn = name
1719 return slurpRemainder(c)
1720 }
1721
1722 func (rr *L64) parse(c *zlexer, o string) *ParseError {
1723 l, _ := c.Next()
1724 i, e := strconv.ParseUint(l.token, 10, 16)
1725 if e != nil || l.err {
1726 return &ParseError{err: "bad L64 Preference", lex: l}
1727 }
1728 rr.Preference = uint16(i)
1729 c.Next() // zBlank
1730 l, _ = c.Next() // zString
1731 u, e1 := stringToNodeID(l)
1732 if e1 != nil || l.err {
1733 return e1
1734 }
1735 rr.Locator64 = u
1736 return slurpRemainder(c)
1737 }
1738
1739 func (rr *UID) parse(c *zlexer, o string) *ParseError {
1740 l, _ := c.Next()
1741 i, e := strconv.ParseUint(l.token, 10, 32)
1742 if e != nil || l.err {
1743 return &ParseError{err: "bad UID Uid", lex: l}
1744 }
1745 rr.Uid = uint32(i)
1746 return slurpRemainder(c)
1747 }
1748
1749 func (rr *GID) parse(c *zlexer, o string) *ParseError {
1750 l, _ := c.Next()
1751 i, e := strconv.ParseUint(l.token, 10, 32)
1752 if e != nil || l.err {
1753 return &ParseError{err: "bad GID Gid", lex: l}
1754 }
1755 rr.Gid = uint32(i)
1756 return slurpRemainder(c)
1757 }
1758
1759 func (rr *UINFO) parse(c *zlexer, o string) *ParseError {
1760 s, e := endingToTxtSlice(c, "bad UINFO Uinfo")
1761 if e != nil {
1762 return e
1763 }
1764 if ln := len(s); ln == 0 {
1765 return nil
1766 }
1767 rr.Uinfo = s[0] // silently discard anything after the first character-string
1768 return nil
1769 }
1770
1771 func (rr *PX) parse(c *zlexer, o string) *ParseError {
1772 l, _ := c.Next()
1773 i, e := strconv.ParseUint(l.token, 10, 16)
1774 if e != nil || l.err {
1775 return &ParseError{err: "bad PX Preference", lex: l}
1776 }
1777 rr.Preference = uint16(i)
1778
1779 c.Next() // zBlank
1780 l, _ = c.Next() // zString
1781 rr.Map822 = l.token
1782 map822, map822Ok := toAbsoluteName(l.token, o)
1783 if l.err || !map822Ok {
1784 return &ParseError{err: "bad PX Map822", lex: l}
1785 }
1786 rr.Map822 = map822
1787
1788 c.Next() // zBlank
1789 l, _ = c.Next() // zString
1790 rr.Mapx400 = l.token
1791 mapx400, mapx400Ok := toAbsoluteName(l.token, o)
1792 if l.err || !mapx400Ok {
1793 return &ParseError{err: "bad PX Mapx400", lex: l}
1794 }
1795 rr.Mapx400 = mapx400
1796 return slurpRemainder(c)
1797 }
1798
1799 func (rr *CAA) parse(c *zlexer, o string) *ParseError {
1800 l, _ := c.Next()
1801 i, e := strconv.ParseUint(l.token, 10, 8)
1802 if e != nil || l.err {
1803 return &ParseError{err: "bad CAA Flag", lex: l}
1804 }
1805 rr.Flag = uint8(i)
1806
1807 c.Next() // zBlank
1808 l, _ = c.Next() // zString
1809 if l.value != zString {
1810 return &ParseError{err: "bad CAA Tag", lex: l}
1811 }
1812 rr.Tag = l.token
1813
1814 c.Next() // zBlank
1815 s, e1 := endingToTxtSlice(c, "bad CAA Value")
1816 if e1 != nil {
1817 return e1
1818 }
1819 if len(s) != 1 {
1820 return &ParseError{err: "bad CAA Value", lex: l}
1821 }
1822 rr.Value = s[0]
1823 return nil
1824 }
1825
1826 func (rr *TKEY) parse(c *zlexer, o string) *ParseError {
1827 l, _ := c.Next()
1828
1829 // Algorithm
1830 if l.value != zString {
1831 return &ParseError{err: "bad TKEY algorithm", lex: l}
1832 }
1833 rr.Algorithm = l.token
1834 c.Next() // zBlank
1835
1836 // Get the key length and key values
1837 l, _ = c.Next()
1838 i, e := strconv.ParseUint(l.token, 10, 8)
1839 if e != nil || l.err {
1840 return &ParseError{err: "bad TKEY key length", lex: l}
1841 }
1842 rr.KeySize = uint16(i)
1843 c.Next() // zBlank
1844 l, _ = c.Next()
1845 if l.value != zString {
1846 return &ParseError{err: "bad TKEY key", lex: l}
1847 }
1848 rr.Key = l.token
1849 c.Next() // zBlank
1850
1851 // Get the otherdata length and string data
1852 l, _ = c.Next()
1853 i, e1 := strconv.ParseUint(l.token, 10, 8)
1854 if e1 != nil || l.err {
1855 return &ParseError{err: "bad TKEY otherdata length", lex: l}
1856 }
1857 rr.OtherLen = uint16(i)
1858 c.Next() // zBlank
1859 l, _ = c.Next()
1860 if l.value != zString {
1861 return &ParseError{err: "bad TKEY otherday", lex: l}
1862 }
1863 rr.OtherData = l.token
1864 return nil
1865 }
1866
1867 func (rr *APL) parse(c *zlexer, o string) *ParseError {
1868 var prefixes []APLPrefix
1869
1870 for {
1871 l, _ := c.Next()
1872 if l.value == zNewline || l.value == zEOF {
1873 break
1874 }
1875 if l.value == zBlank && prefixes != nil {
1876 continue
1877 }
1878 if l.value != zString {
1879 return &ParseError{err: "unexpected APL field", lex: l}
1880 }
1881
1882 // Expected format: [!]afi:address/prefix
1883
1884 colon := strings.IndexByte(l.token, ':')
1885 if colon == -1 {
1886 return &ParseError{err: "missing colon in APL field", lex: l}
1887 }
1888
1889 family, cidr := l.token[:colon], l.token[colon+1:]
1890
1891 var negation bool
1892 if family != "" && family[0] == '!' {
1893 negation = true
1894 family = family[1:]
1895 }
1896
1897 afi, e := strconv.ParseUint(family, 10, 16)
1898 if e != nil {
1899 return &ParseError{wrappedErr: fmt.Errorf("failed to parse APL family: %w", e), lex: l}
1900 }
1901 var addrLen int
1902 switch afi {
1903 case 1:
1904 addrLen = net.IPv4len
1905 case 2:
1906 addrLen = net.IPv6len
1907 default:
1908 return &ParseError{err: "unrecognized APL family", lex: l}
1909 }
1910
1911 ip, subnet, e1 := net.ParseCIDR(cidr)
1912 if e1 != nil {
1913 return &ParseError{wrappedErr: fmt.Errorf("failed to parse APL address: %w", e1), lex: l}
1914 }
1915 if !ip.Equal(subnet.IP) {
1916 return &ParseError{err: "extra bits in APL address", lex: l}
1917 }
1918
1919 if len(subnet.IP) != addrLen {
1920 return &ParseError{err: "address mismatch with the APL family", lex: l}
1921 }
1922
1923 prefixes = append(prefixes, APLPrefix{
1924 Negation: negation,
1925 Network: *subnet,
1926 })
1927 }
1928
1929 rr.Prefixes = prefixes
1930 return nil
1931 }
1932
1933 // escapedStringOffset finds the offset within a string (which may contain escape
1934 // sequences) that corresponds to a certain byte offset. If the input offset is
1935 // out of bounds, -1 is returned (which is *not* considered an error).
1936 func escapedStringOffset(s string, desiredByteOffset int) (int, bool) {
1937 if desiredByteOffset == 0 {
1938 return 0, true
1939 }
1940
1941 currentByteOffset, i := 0, 0
1942
1943 for i < len(s) {
1944 currentByteOffset += 1
1945
1946 // Skip escape sequences
1947 if s[i] != '\\' {
1948 // Single plain byte, not an escape sequence.
1949 i++
1950 } else if isDDD(s[i+1:]) {
1951 // Skip backslash and DDD.
1952 i += 4
1953 } else if len(s[i+1:]) < 1 {
1954 // No character following the backslash; that's an error.
1955 return 0, false
1956 } else {
1957 // Skip backslash and following byte.
1958 i += 2
1959 }
1960
1961 if currentByteOffset >= desiredByteOffset {
1962 return i, true
1963 }
1964 }
1965
1966 return -1, true
1967 }
1968