10 // Parse the rdata of each rrtype.
11 // All data from the channel c is either zString or zBlank.
12 // After the rdata there may come a zBlank and then a zNewline
13 // or immediately a zNewline. If this is not the case we flag
14 // an *ParseError: garbage after rdata.
15 func setRR(h RR_Header, c *zlexer, o, f string) (RR, *ParseError) {
17 if newFn, ok := TypeToRR[h.Rrtype]; ok && canParseAsRR(h.Rrtype) {
24 err := rr.parse(c, o, f)
32 // canParseAsRR returns true if the record type can be parsed as a
33 // concrete RR. It blacklists certain record types that must be parsed
34 // according to RFC 3597 because they lack a presentation format.
35 func canParseAsRR(rrtype uint16) bool {
37 case TypeANY, TypeNULL, TypeOPT, TypeTSIG:
44 // A remainder of the rdata with embedded spaces, return the parsed string (sans the spaces)
46 func endingToString(c *zlexer, errstr, f string) (string, *ParseError) {
48 l, _ := c.Next() // zString
49 for l.value != zNewline && l.value != zEOF {
51 return s, &ParseError{f, errstr, l}
58 return "", &ParseError{f, errstr, l}
66 // A remainder of the rdata with embedded spaces, split on unquoted whitespace
67 // and return the parsed string slice or an error
68 func endingToTxtSlice(c *zlexer, errstr, f string) ([]string, *ParseError) {
69 // Get the remaining data until we see a zNewline
72 return nil, &ParseError{f, errstr, l}
76 s := make([]string, 0)
79 for l.value != zNewline && l.value != zEOF {
81 return nil, &ParseError{f, errstr, l}
86 if len(l.token) > 255 {
87 // split up tokens that are larger than 255 into 255-chunks
91 if i <= len(l.token) {
92 sx = append(sx, l.token[p:i])
94 sx = append(sx, l.token[p:])
104 s = append(s, l.token)
107 // zBlank can only be seen in between txt parts.
108 return nil, &ParseError{f, errstr, l}
117 return nil, &ParseError{f, errstr, l}
123 return nil, &ParseError{f, errstr, l}
129 func (rr *A) parse(c *zlexer, o, f string) *ParseError {
131 if len(l.token) == 0 { // dynamic update rr.
132 return slurpRemainder(c, f)
135 rr.A = net.ParseIP(l.token)
136 if rr.A == nil || l.err {
137 return &ParseError{f, "bad A A", l}
139 return slurpRemainder(c, f)
142 func (rr *AAAA) parse(c *zlexer, o, f string) *ParseError {
144 if len(l.token) == 0 { // dynamic update rr.
145 return slurpRemainder(c, f)
148 rr.AAAA = net.ParseIP(l.token)
149 if rr.AAAA == nil || l.err {
150 return &ParseError{f, "bad AAAA AAAA", l}
152 return slurpRemainder(c, f)
155 func (rr *NS) parse(c *zlexer, o, f string) *ParseError {
158 if len(l.token) == 0 { // dynamic update rr.
159 return slurpRemainder(c, f)
162 name, nameOk := toAbsoluteName(l.token, o)
163 if l.err || !nameOk {
164 return &ParseError{f, "bad NS Ns", l}
167 return slurpRemainder(c, f)
170 func (rr *PTR) parse(c *zlexer, o, f string) *ParseError {
173 if len(l.token) == 0 { // dynamic update rr.
174 return slurpRemainder(c, f)
177 name, nameOk := toAbsoluteName(l.token, o)
178 if l.err || !nameOk {
179 return &ParseError{f, "bad PTR Ptr", l}
182 return slurpRemainder(c, f)
185 func (rr *NSAPPTR) parse(c *zlexer, o, f string) *ParseError {
188 if len(l.token) == 0 { // dynamic update rr.
189 return slurpRemainder(c, f)
192 name, nameOk := toAbsoluteName(l.token, o)
193 if l.err || !nameOk {
194 return &ParseError{f, "bad NSAP-PTR Ptr", l}
197 return slurpRemainder(c, f)
200 func (rr *RP) parse(c *zlexer, o, f string) *ParseError {
203 if len(l.token) == 0 { // dynamic update rr.
204 return slurpRemainder(c, f)
207 mbox, mboxOk := toAbsoluteName(l.token, o)
208 if l.err || !mboxOk {
209 return &ParseError{f, "bad RP Mbox", l}
217 txt, txtOk := toAbsoluteName(l.token, o)
219 return &ParseError{f, "bad RP Txt", l}
223 return slurpRemainder(c, f)
226 func (rr *MR) parse(c *zlexer, o, f string) *ParseError {
229 if len(l.token) == 0 { // dynamic update rr.
230 return slurpRemainder(c, f)
233 name, nameOk := toAbsoluteName(l.token, o)
234 if l.err || !nameOk {
235 return &ParseError{f, "bad MR Mr", l}
238 return slurpRemainder(c, f)
241 func (rr *MB) parse(c *zlexer, o, f string) *ParseError {
244 if len(l.token) == 0 { // dynamic update rr.
245 return slurpRemainder(c, f)
248 name, nameOk := toAbsoluteName(l.token, o)
249 if l.err || !nameOk {
250 return &ParseError{f, "bad MB Mb", l}
253 return slurpRemainder(c, f)
256 func (rr *MG) parse(c *zlexer, o, f string) *ParseError {
259 if len(l.token) == 0 { // dynamic update rr.
260 return slurpRemainder(c, f)
263 name, nameOk := toAbsoluteName(l.token, o)
264 if l.err || !nameOk {
265 return &ParseError{f, "bad MG Mg", l}
268 return slurpRemainder(c, f)
271 func (rr *HINFO) parse(c *zlexer, o, f string) *ParseError {
272 chunks, e := endingToTxtSlice(c, "bad HINFO Fields", f)
277 if ln := len(chunks); ln == 0 {
281 if out := strings.Fields(chunks[0]); len(out) > 1 {
284 chunks = append(chunks, "")
289 rr.Os = strings.Join(chunks[1:], " ")
294 func (rr *MINFO) parse(c *zlexer, o, f string) *ParseError {
297 if len(l.token) == 0 { // dynamic update rr.
298 return slurpRemainder(c, f)
301 rmail, rmailOk := toAbsoluteName(l.token, o)
302 if l.err || !rmailOk {
303 return &ParseError{f, "bad MINFO Rmail", l}
311 email, emailOk := toAbsoluteName(l.token, o)
312 if l.err || !emailOk {
313 return &ParseError{f, "bad MINFO Email", l}
317 return slurpRemainder(c, f)
320 func (rr *MF) parse(c *zlexer, o, f string) *ParseError {
323 if len(l.token) == 0 { // dynamic update rr.
324 return slurpRemainder(c, f)
327 name, nameOk := toAbsoluteName(l.token, o)
328 if l.err || !nameOk {
329 return &ParseError{f, "bad MF Mf", l}
332 return slurpRemainder(c, f)
335 func (rr *MD) parse(c *zlexer, o, f string) *ParseError {
338 if len(l.token) == 0 { // dynamic update rr.
339 return slurpRemainder(c, f)
342 name, nameOk := toAbsoluteName(l.token, o)
343 if l.err || !nameOk {
344 return &ParseError{f, "bad MD Md", l}
347 return slurpRemainder(c, f)
350 func (rr *MX) parse(c *zlexer, o, f string) *ParseError {
352 if len(l.token) == 0 { // dynamic update rr.
353 return slurpRemainder(c, f)
356 i, e := strconv.ParseUint(l.token, 10, 16)
357 if e != nil || l.err {
358 return &ParseError{f, "bad MX Pref", l}
360 rr.Preference = uint16(i)
363 l, _ = c.Next() // zString
366 name, nameOk := toAbsoluteName(l.token, o)
367 if l.err || !nameOk {
368 return &ParseError{f, "bad MX Mx", l}
372 return slurpRemainder(c, f)
375 func (rr *RT) parse(c *zlexer, o, f string) *ParseError {
377 if len(l.token) == 0 { // dynamic update rr.
378 return slurpRemainder(c, f)
381 i, e := strconv.ParseUint(l.token, 10, 16)
383 return &ParseError{f, "bad RT Preference", l}
385 rr.Preference = uint16(i)
388 l, _ = c.Next() // zString
391 name, nameOk := toAbsoluteName(l.token, o)
392 if l.err || !nameOk {
393 return &ParseError{f, "bad RT Host", l}
397 return slurpRemainder(c, f)
400 func (rr *AFSDB) parse(c *zlexer, o, f string) *ParseError {
402 if len(l.token) == 0 { // dynamic update rr.
403 return slurpRemainder(c, f)
406 i, e := strconv.ParseUint(l.token, 10, 16)
407 if e != nil || l.err {
408 return &ParseError{f, "bad AFSDB Subtype", l}
410 rr.Subtype = uint16(i)
413 l, _ = c.Next() // zString
414 rr.Hostname = l.token
416 name, nameOk := toAbsoluteName(l.token, o)
417 if l.err || !nameOk {
418 return &ParseError{f, "bad AFSDB Hostname", l}
421 return slurpRemainder(c, f)
424 func (rr *X25) parse(c *zlexer, o, f string) *ParseError {
426 if len(l.token) == 0 { // dynamic update rr.
427 return slurpRemainder(c, f)
431 return &ParseError{f, "bad X25 PSDNAddress", l}
433 rr.PSDNAddress = l.token
434 return slurpRemainder(c, f)
437 func (rr *KX) parse(c *zlexer, o, f string) *ParseError {
439 if len(l.token) == 0 { // dynamic update rr.
440 return slurpRemainder(c, f)
443 i, e := strconv.ParseUint(l.token, 10, 16)
444 if e != nil || l.err {
445 return &ParseError{f, "bad KX Pref", l}
447 rr.Preference = uint16(i)
450 l, _ = c.Next() // zString
451 rr.Exchanger = l.token
453 name, nameOk := toAbsoluteName(l.token, o)
454 if l.err || !nameOk {
455 return &ParseError{f, "bad KX Exchanger", l}
458 return slurpRemainder(c, f)
461 func (rr *CNAME) parse(c *zlexer, o, f string) *ParseError {
464 if len(l.token) == 0 { // dynamic update rr.
465 return slurpRemainder(c, f)
468 name, nameOk := toAbsoluteName(l.token, o)
469 if l.err || !nameOk {
470 return &ParseError{f, "bad CNAME Target", l}
473 return slurpRemainder(c, f)
476 func (rr *DNAME) parse(c *zlexer, o, f string) *ParseError {
479 if len(l.token) == 0 { // dynamic update rr.
480 return slurpRemainder(c, f)
483 name, nameOk := toAbsoluteName(l.token, o)
484 if l.err || !nameOk {
485 return &ParseError{f, "bad DNAME Target", l}
488 return slurpRemainder(c, f)
491 func (rr *SOA) parse(c *zlexer, o, f string) *ParseError {
494 if len(l.token) == 0 { // dynamic update rr.
495 return slurpRemainder(c, f)
498 ns, nsOk := toAbsoluteName(l.token, o)
500 return &ParseError{f, "bad SOA Ns", l}
508 mbox, mboxOk := toAbsoluteName(l.token, o)
509 if l.err || !mboxOk {
510 return &ParseError{f, "bad SOA Mbox", l}
520 for i := 0; i < 5; i++ {
523 return &ParseError{f, "bad SOA zone parameter", l}
525 if j, e := strconv.ParseUint(l.token, 10, 32); e != nil {
527 // Serial must be a number
528 return &ParseError{f, "bad SOA zone parameter", l}
530 // We allow other fields to be unitful duration strings
531 if v, ok = stringToTTL(l.token); !ok {
532 return &ParseError{f, "bad SOA zone parameter", l}
555 return slurpRemainder(c, f)
558 func (rr *SRV) parse(c *zlexer, o, f string) *ParseError {
560 if len(l.token) == 0 { // dynamic update rr.
561 return slurpRemainder(c, f)
564 i, e := strconv.ParseUint(l.token, 10, 16)
565 if e != nil || l.err {
566 return &ParseError{f, "bad SRV Priority", l}
568 rr.Priority = uint16(i)
571 l, _ = c.Next() // zString
572 i, e = strconv.ParseUint(l.token, 10, 16)
573 if e != nil || l.err {
574 return &ParseError{f, "bad SRV Weight", l}
576 rr.Weight = uint16(i)
579 l, _ = c.Next() // zString
580 i, e = strconv.ParseUint(l.token, 10, 16)
581 if e != nil || l.err {
582 return &ParseError{f, "bad SRV Port", l}
587 l, _ = c.Next() // zString
590 name, nameOk := toAbsoluteName(l.token, o)
591 if l.err || !nameOk {
592 return &ParseError{f, "bad SRV Target", l}
595 return slurpRemainder(c, f)
598 func (rr *NAPTR) parse(c *zlexer, o, f string) *ParseError {
600 if len(l.token) == 0 { // dynamic update rr.
601 return slurpRemainder(c, f)
604 i, e := strconv.ParseUint(l.token, 10, 16)
605 if e != nil || l.err {
606 return &ParseError{f, "bad NAPTR Order", l}
611 l, _ = c.Next() // zString
612 i, e = strconv.ParseUint(l.token, 10, 16)
613 if e != nil || l.err {
614 return &ParseError{f, "bad NAPTR Preference", l}
616 rr.Preference = uint16(i)
620 l, _ = c.Next() // _QUOTE
621 if l.value != zQuote {
622 return &ParseError{f, "bad NAPTR Flags", l}
624 l, _ = c.Next() // Either String or Quote
625 if l.value == zString {
627 l, _ = c.Next() // _QUOTE
628 if l.value != zQuote {
629 return &ParseError{f, "bad NAPTR Flags", l}
631 } else if l.value == zQuote {
634 return &ParseError{f, "bad NAPTR Flags", l}
639 l, _ = c.Next() // _QUOTE
640 if l.value != zQuote {
641 return &ParseError{f, "bad NAPTR Service", l}
643 l, _ = c.Next() // Either String or Quote
644 if l.value == zString {
646 l, _ = c.Next() // _QUOTE
647 if l.value != zQuote {
648 return &ParseError{f, "bad NAPTR Service", l}
650 } else if l.value == zQuote {
653 return &ParseError{f, "bad NAPTR Service", l}
658 l, _ = c.Next() // _QUOTE
659 if l.value != zQuote {
660 return &ParseError{f, "bad NAPTR Regexp", l}
662 l, _ = c.Next() // Either String or Quote
663 if l.value == zString {
665 l, _ = c.Next() // _QUOTE
666 if l.value != zQuote {
667 return &ParseError{f, "bad NAPTR Regexp", l}
669 } else if l.value == zQuote {
672 return &ParseError{f, "bad NAPTR Regexp", l}
675 // After quote no space??
677 l, _ = c.Next() // zString
678 rr.Replacement = l.token
680 name, nameOk := toAbsoluteName(l.token, o)
681 if l.err || !nameOk {
682 return &ParseError{f, "bad NAPTR Replacement", l}
684 rr.Replacement = name
685 return slurpRemainder(c, f)
688 func (rr *TALINK) parse(c *zlexer, o, f string) *ParseError {
690 rr.PreviousName = l.token
691 if len(l.token) == 0 { // dynamic update rr.
692 return slurpRemainder(c, f)
695 previousName, previousNameOk := toAbsoluteName(l.token, o)
696 if l.err || !previousNameOk {
697 return &ParseError{f, "bad TALINK PreviousName", l}
699 rr.PreviousName = previousName
703 rr.NextName = l.token
705 nextName, nextNameOk := toAbsoluteName(l.token, o)
706 if l.err || !nextNameOk {
707 return &ParseError{f, "bad TALINK NextName", l}
709 rr.NextName = nextName
711 return slurpRemainder(c, f)
714 func (rr *LOC) parse(c *zlexer, o, f string) *ParseError {
715 // Non zero defaults for LOC record, see RFC 1876, Section 3.
716 rr.HorizPre = 165 // 10000
717 rr.VertPre = 162 // 10
723 if len(l.token) == 0 { // dynamic update rr.
726 i, e := strconv.ParseUint(l.token, 10, 32)
727 if e != nil || l.err {
728 return &ParseError{f, "bad LOC Latitude", l}
730 rr.Latitude = 1000 * 60 * 60 * uint32(i)
733 // Either number, 'N' or 'S'
735 if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok {
738 i, e = strconv.ParseUint(l.token, 10, 32)
739 if e != nil || l.err {
740 return &ParseError{f, "bad LOC Latitude minutes", l}
742 rr.Latitude += 1000 * 60 * uint32(i)
746 if i, e := strconv.ParseFloat(l.token, 32); e != nil || l.err {
747 return &ParseError{f, "bad LOC Latitude seconds", l}
749 rr.Latitude += uint32(1000 * i)
752 // Either number, 'N' or 'S'
754 if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok {
757 // If still alive, flag an error
758 return &ParseError{f, "bad LOC Latitude North/South", l}
764 if i, e := strconv.ParseUint(l.token, 10, 32); e != nil || l.err {
765 return &ParseError{f, "bad LOC Longitude", l}
767 rr.Longitude = 1000 * 60 * 60 * uint32(i)
770 // Either number, 'E' or 'W'
772 if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok {
775 if i, e := strconv.ParseUint(l.token, 10, 32); e != nil || l.err {
776 return &ParseError{f, "bad LOC Longitude minutes", l}
778 rr.Longitude += 1000 * 60 * uint32(i)
782 if i, e := strconv.ParseFloat(l.token, 32); e != nil || l.err {
783 return &ParseError{f, "bad LOC Longitude seconds", l}
785 rr.Longitude += uint32(1000 * i)
788 // Either number, 'E' or 'W'
790 if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok {
793 // If still alive, flag an error
794 return &ParseError{f, "bad LOC Longitude East/West", l}
799 if len(l.token) == 0 || l.err {
800 return &ParseError{f, "bad LOC Altitude", l}
802 if l.token[len(l.token)-1] == 'M' || l.token[len(l.token)-1] == 'm' {
803 l.token = l.token[0 : len(l.token)-1]
805 if i, e := strconv.ParseFloat(l.token, 32); e != nil {
806 return &ParseError{f, "bad LOC Altitude", l}
808 rr.Altitude = uint32(i*100.0 + 10000000.0 + 0.5)
811 // And now optionally the other values
814 for l.value != zNewline && l.value != zEOF {
819 e, m, ok := stringToCm(l.token)
821 return &ParseError{f, "bad LOC Size", l}
823 rr.Size = e&0x0f | m<<4&0xf0
825 e, m, ok := stringToCm(l.token)
827 return &ParseError{f, "bad LOC HorizPre", l}
829 rr.HorizPre = e&0x0f | m<<4&0xf0
831 e, m, ok := stringToCm(l.token)
833 return &ParseError{f, "bad LOC VertPre", l}
835 rr.VertPre = e&0x0f | m<<4&0xf0
841 return &ParseError{f, "bad LOC Size, HorizPre or VertPre", l}
848 func (rr *HIP) parse(c *zlexer, o, f string) *ParseError {
849 // HitLength is not represented
851 if len(l.token) == 0 { // dynamic update rr.
855 i, e := strconv.ParseUint(l.token, 10, 8)
856 if e != nil || l.err {
857 return &ParseError{f, "bad HIP PublicKeyAlgorithm", l}
859 rr.PublicKeyAlgorithm = uint8(i)
862 l, _ = c.Next() // zString
863 if len(l.token) == 0 || l.err {
864 return &ParseError{f, "bad HIP Hit", l}
866 rr.Hit = l.token // This can not contain spaces, see RFC 5205 Section 6.
867 rr.HitLength = uint8(len(rr.Hit)) / 2
870 l, _ = c.Next() // zString
871 if len(l.token) == 0 || l.err {
872 return &ParseError{f, "bad HIP PublicKey", l}
874 rr.PublicKey = l.token // This cannot contain spaces
875 rr.PublicKeyLength = uint16(base64.StdEncoding.DecodedLen(len(rr.PublicKey)))
877 // RendezvousServers (if any)
880 for l.value != zNewline && l.value != zEOF {
883 name, nameOk := toAbsoluteName(l.token, o)
884 if l.err || !nameOk {
885 return &ParseError{f, "bad HIP RendezvousServers", l}
887 xs = append(xs, name)
891 return &ParseError{f, "bad HIP RendezvousServers", l}
896 rr.RendezvousServers = xs
900 func (rr *CERT) parse(c *zlexer, o, f string) *ParseError {
902 if len(l.token) == 0 { // dynamic update rr.
906 if v, ok := StringToCertType[l.token]; ok {
908 } else if i, e := strconv.ParseUint(l.token, 10, 16); e != nil {
909 return &ParseError{f, "bad CERT Type", l}
914 l, _ = c.Next() // zString
915 i, e := strconv.ParseUint(l.token, 10, 16)
916 if e != nil || l.err {
917 return &ParseError{f, "bad CERT KeyTag", l}
919 rr.KeyTag = uint16(i)
921 l, _ = c.Next() // zString
922 if v, ok := StringToAlgorithm[l.token]; ok {
924 } else if i, e := strconv.ParseUint(l.token, 10, 8); e != nil {
925 return &ParseError{f, "bad CERT Algorithm", l}
927 rr.Algorithm = uint8(i)
929 s, e1 := endingToString(c, "bad CERT Certificate", f)
937 func (rr *OPENPGPKEY) parse(c *zlexer, o, f string) *ParseError {
938 s, e := endingToString(c, "bad OPENPGPKEY PublicKey", f)
946 func (rr *CSYNC) parse(c *zlexer, o, f string) *ParseError {
948 if len(l.token) == 0 { // dynamic update rr.
951 j, e := strconv.ParseUint(l.token, 10, 32)
953 // Serial must be a number
954 return &ParseError{f, "bad CSYNC serial", l}
956 rr.Serial = uint32(j)
961 j, e = strconv.ParseUint(l.token, 10, 16)
963 // Serial must be a number
964 return &ParseError{f, "bad CSYNC flags", l}
968 rr.TypeBitMap = make([]uint16, 0)
974 for l.value != zNewline && l.value != zEOF {
979 tokenUpper := strings.ToUpper(l.token)
980 if k, ok = StringToType[tokenUpper]; !ok {
981 if k, ok = typeToInt(l.token); !ok {
982 return &ParseError{f, "bad CSYNC TypeBitMap", l}
985 rr.TypeBitMap = append(rr.TypeBitMap, k)
987 return &ParseError{f, "bad CSYNC TypeBitMap", l}
994 func (rr *SIG) parse(c *zlexer, o, f string) *ParseError {
995 return rr.RRSIG.parse(c, o, f)
998 func (rr *RRSIG) parse(c *zlexer, o, f string) *ParseError {
1000 if len(l.token) == 0 { // dynamic update rr.
1004 tokenUpper := strings.ToUpper(l.token)
1005 if t, ok := StringToType[tokenUpper]; !ok {
1006 if strings.HasPrefix(tokenUpper, "TYPE") {
1007 t, ok = typeToInt(l.token)
1009 return &ParseError{f, "bad RRSIG Typecovered", l}
1013 return &ParseError{f, "bad RRSIG Typecovered", l}
1021 i, err := strconv.ParseUint(l.token, 10, 8)
1022 if err != nil || l.err {
1023 return &ParseError{f, "bad RRSIG Algorithm", l}
1025 rr.Algorithm = uint8(i)
1029 i, err = strconv.ParseUint(l.token, 10, 8)
1030 if err != nil || l.err {
1031 return &ParseError{f, "bad RRSIG Labels", l}
1033 rr.Labels = uint8(i)
1037 i, err = strconv.ParseUint(l.token, 10, 32)
1038 if err != nil || l.err {
1039 return &ParseError{f, "bad RRSIG OrigTtl", l}
1041 rr.OrigTtl = uint32(i)
1045 if i, err := StringToTime(l.token); err != nil {
1046 // Try to see if all numeric and use it as epoch
1047 if i, err := strconv.ParseInt(l.token, 10, 64); err == nil {
1048 // TODO(miek): error out on > MAX_UINT32, same below
1049 rr.Expiration = uint32(i)
1051 return &ParseError{f, "bad RRSIG Expiration", l}
1059 if i, err := StringToTime(l.token); err != nil {
1060 if i, err := strconv.ParseInt(l.token, 10, 64); err == nil {
1061 rr.Inception = uint32(i)
1063 return &ParseError{f, "bad RRSIG Inception", l}
1071 i, err = strconv.ParseUint(l.token, 10, 16)
1072 if err != nil || l.err {
1073 return &ParseError{f, "bad RRSIG KeyTag", l}
1075 rr.KeyTag = uint16(i)
1079 rr.SignerName = l.token
1080 name, nameOk := toAbsoluteName(l.token, o)
1081 if l.err || !nameOk {
1082 return &ParseError{f, "bad RRSIG SignerName", l}
1084 rr.SignerName = name
1086 s, e := endingToString(c, "bad RRSIG Signature", f)
1095 func (rr *NSEC) parse(c *zlexer, o, f string) *ParseError {
1097 rr.NextDomain = l.token
1098 if len(l.token) == 0 { // dynamic update rr.
1102 name, nameOk := toAbsoluteName(l.token, o)
1103 if l.err || !nameOk {
1104 return &ParseError{f, "bad NSEC NextDomain", l}
1106 rr.NextDomain = name
1108 rr.TypeBitMap = make([]uint16, 0)
1114 for l.value != zNewline && l.value != zEOF {
1119 tokenUpper := strings.ToUpper(l.token)
1120 if k, ok = StringToType[tokenUpper]; !ok {
1121 if k, ok = typeToInt(l.token); !ok {
1122 return &ParseError{f, "bad NSEC TypeBitMap", l}
1125 rr.TypeBitMap = append(rr.TypeBitMap, k)
1127 return &ParseError{f, "bad NSEC TypeBitMap", l}
1134 func (rr *NSEC3) parse(c *zlexer, o, f string) *ParseError {
1136 if len(l.token) == 0 { // dynamic update rr.
1140 i, e := strconv.ParseUint(l.token, 10, 8)
1141 if e != nil || l.err {
1142 return &ParseError{f, "bad NSEC3 Hash", l}
1147 i, e = strconv.ParseUint(l.token, 10, 8)
1148 if e != nil || l.err {
1149 return &ParseError{f, "bad NSEC3 Flags", l}
1154 i, e = strconv.ParseUint(l.token, 10, 16)
1155 if e != nil || l.err {
1156 return &ParseError{f, "bad NSEC3 Iterations", l}
1158 rr.Iterations = uint16(i)
1161 if len(l.token) == 0 || l.err {
1162 return &ParseError{f, "bad NSEC3 Salt", l}
1165 rr.SaltLength = uint8(len(l.token)) / 2
1171 if len(l.token) == 0 || l.err {
1172 return &ParseError{f, "bad NSEC3 NextDomain", l}
1174 rr.HashLength = 20 // Fix for NSEC3 (sha1 160 bits)
1175 rr.NextDomain = l.token
1177 rr.TypeBitMap = make([]uint16, 0)
1183 for l.value != zNewline && l.value != zEOF {
1188 tokenUpper := strings.ToUpper(l.token)
1189 if k, ok = StringToType[tokenUpper]; !ok {
1190 if k, ok = typeToInt(l.token); !ok {
1191 return &ParseError{f, "bad NSEC3 TypeBitMap", l}
1194 rr.TypeBitMap = append(rr.TypeBitMap, k)
1196 return &ParseError{f, "bad NSEC3 TypeBitMap", l}
1203 func (rr *NSEC3PARAM) parse(c *zlexer, o, f string) *ParseError {
1205 if len(l.token) == 0 { // dynamic update rr.
1206 return slurpRemainder(c, f)
1209 i, e := strconv.ParseUint(l.token, 10, 8)
1210 if e != nil || l.err {
1211 return &ParseError{f, "bad NSEC3PARAM Hash", l}
1216 i, e = strconv.ParseUint(l.token, 10, 8)
1217 if e != nil || l.err {
1218 return &ParseError{f, "bad NSEC3PARAM Flags", l}
1223 i, e = strconv.ParseUint(l.token, 10, 16)
1224 if e != nil || l.err {
1225 return &ParseError{f, "bad NSEC3PARAM Iterations", l}
1227 rr.Iterations = uint16(i)
1231 rr.SaltLength = uint8(len(l.token))
1234 return slurpRemainder(c, f)
1237 func (rr *EUI48) parse(c *zlexer, o, f string) *ParseError {
1239 if len(l.token) == 0 { // dynamic update rr.
1240 return slurpRemainder(c, f)
1243 if len(l.token) != 17 || l.err {
1244 return &ParseError{f, "bad EUI48 Address", l}
1246 addr := make([]byte, 12)
1248 for i := 0; i < 10; i += 2 {
1249 addr[i] = l.token[i+dash]
1250 addr[i+1] = l.token[i+1+dash]
1252 if l.token[i+1+dash] != '-' {
1253 return &ParseError{f, "bad EUI48 Address", l}
1256 addr[10] = l.token[15]
1257 addr[11] = l.token[16]
1259 i, e := strconv.ParseUint(string(addr), 16, 48)
1261 return &ParseError{f, "bad EUI48 Address", l}
1264 return slurpRemainder(c, f)
1267 func (rr *EUI64) parse(c *zlexer, o, f string) *ParseError {
1269 if len(l.token) == 0 { // dynamic update rr.
1270 return slurpRemainder(c, f)
1273 if len(l.token) != 23 || l.err {
1274 return &ParseError{f, "bad EUI64 Address", l}
1276 addr := make([]byte, 16)
1278 for i := 0; i < 14; i += 2 {
1279 addr[i] = l.token[i+dash]
1280 addr[i+1] = l.token[i+1+dash]
1282 if l.token[i+1+dash] != '-' {
1283 return &ParseError{f, "bad EUI64 Address", l}
1286 addr[14] = l.token[21]
1287 addr[15] = l.token[22]
1289 i, e := strconv.ParseUint(string(addr), 16, 64)
1291 return &ParseError{f, "bad EUI68 Address", l}
1294 return slurpRemainder(c, f)
1297 func (rr *SSHFP) parse(c *zlexer, o, f string) *ParseError {
1299 if len(l.token) == 0 { // dynamic update rr.
1303 i, e := strconv.ParseUint(l.token, 10, 8)
1304 if e != nil || l.err {
1305 return &ParseError{f, "bad SSHFP Algorithm", l}
1307 rr.Algorithm = uint8(i)
1310 i, e = strconv.ParseUint(l.token, 10, 8)
1311 if e != nil || l.err {
1312 return &ParseError{f, "bad SSHFP Type", l}
1316 s, e1 := endingToString(c, "bad SSHFP Fingerprint", f)
1324 func (rr *DNSKEY) parseDNSKEY(c *zlexer, o, f, typ string) *ParseError {
1326 if len(l.token) == 0 { // dynamic update rr.
1330 i, e := strconv.ParseUint(l.token, 10, 16)
1331 if e != nil || l.err {
1332 return &ParseError{f, "bad " + typ + " Flags", l}
1334 rr.Flags = uint16(i)
1336 l, _ = c.Next() // zString
1337 i, e = strconv.ParseUint(l.token, 10, 8)
1338 if e != nil || l.err {
1339 return &ParseError{f, "bad " + typ + " Protocol", l}
1341 rr.Protocol = uint8(i)
1343 l, _ = c.Next() // zString
1344 i, e = strconv.ParseUint(l.token, 10, 8)
1345 if e != nil || l.err {
1346 return &ParseError{f, "bad " + typ + " Algorithm", l}
1348 rr.Algorithm = uint8(i)
1349 s, e1 := endingToString(c, "bad "+typ+" PublicKey", f)
1357 func (rr *DNSKEY) parse(c *zlexer, o, f string) *ParseError {
1358 return rr.parseDNSKEY(c, o, f, "DNSKEY")
1361 func (rr *KEY) parse(c *zlexer, o, f string) *ParseError {
1362 return rr.parseDNSKEY(c, o, f, "KEY")
1365 func (rr *CDNSKEY) parse(c *zlexer, o, f string) *ParseError {
1366 return rr.parseDNSKEY(c, o, f, "CDNSKEY")
1369 func (rr *RKEY) parse(c *zlexer, o, f string) *ParseError {
1371 if len(l.token) == 0 { // dynamic update rr.
1375 i, e := strconv.ParseUint(l.token, 10, 16)
1376 if e != nil || l.err {
1377 return &ParseError{f, "bad RKEY Flags", l}
1379 rr.Flags = uint16(i)
1381 l, _ = c.Next() // zString
1382 i, e = strconv.ParseUint(l.token, 10, 8)
1383 if e != nil || l.err {
1384 return &ParseError{f, "bad RKEY Protocol", l}
1386 rr.Protocol = uint8(i)
1388 l, _ = c.Next() // zString
1389 i, e = strconv.ParseUint(l.token, 10, 8)
1390 if e != nil || l.err {
1391 return &ParseError{f, "bad RKEY Algorithm", l}
1393 rr.Algorithm = uint8(i)
1394 s, e1 := endingToString(c, "bad RKEY PublicKey", f)
1402 func (rr *EID) parse(c *zlexer, o, f string) *ParseError {
1403 s, e := endingToString(c, "bad EID Endpoint", f)
1411 func (rr *NIMLOC) parse(c *zlexer, o, f string) *ParseError {
1412 s, e := endingToString(c, "bad NIMLOC Locator", f)
1420 func (rr *GPOS) parse(c *zlexer, o, f string) *ParseError {
1422 if len(l.token) == 0 { // dynamic update rr.
1423 return slurpRemainder(c, f)
1426 _, e := strconv.ParseFloat(l.token, 64)
1427 if e != nil || l.err {
1428 return &ParseError{f, "bad GPOS Longitude", l}
1430 rr.Longitude = l.token
1433 _, e = strconv.ParseFloat(l.token, 64)
1434 if e != nil || l.err {
1435 return &ParseError{f, "bad GPOS Latitude", l}
1437 rr.Latitude = l.token
1440 _, e = strconv.ParseFloat(l.token, 64)
1441 if e != nil || l.err {
1442 return &ParseError{f, "bad GPOS Altitude", l}
1444 rr.Altitude = l.token
1445 return slurpRemainder(c, f)
1448 func (rr *DS) parseDS(c *zlexer, o, f, typ string) *ParseError {
1450 if len(l.token) == 0 { // dynamic update rr.
1454 i, e := strconv.ParseUint(l.token, 10, 16)
1455 if e != nil || l.err {
1456 return &ParseError{f, "bad " + typ + " KeyTag", l}
1458 rr.KeyTag = uint16(i)
1461 if i, e = strconv.ParseUint(l.token, 10, 8); e != nil {
1462 tokenUpper := strings.ToUpper(l.token)
1463 i, ok := StringToAlgorithm[tokenUpper]
1465 return &ParseError{f, "bad " + typ + " Algorithm", l}
1469 rr.Algorithm = uint8(i)
1473 i, e = strconv.ParseUint(l.token, 10, 8)
1474 if e != nil || l.err {
1475 return &ParseError{f, "bad " + typ + " DigestType", l}
1477 rr.DigestType = uint8(i)
1478 s, e1 := endingToString(c, "bad "+typ+" Digest", f)
1486 func (rr *DS) parse(c *zlexer, o, f string) *ParseError {
1487 return rr.parseDS(c, o, f, "DS")
1490 func (rr *DLV) parse(c *zlexer, o, f string) *ParseError {
1491 return rr.parseDS(c, o, f, "DLV")
1494 func (rr *CDS) parse(c *zlexer, o, f string) *ParseError {
1495 return rr.parseDS(c, o, f, "CDS")
1498 func (rr *TA) parse(c *zlexer, o, f string) *ParseError {
1500 if len(l.token) == 0 { // dynamic update rr.
1504 i, e := strconv.ParseUint(l.token, 10, 16)
1505 if e != nil || l.err {
1506 return &ParseError{f, "bad TA KeyTag", l}
1508 rr.KeyTag = uint16(i)
1511 if i, e := strconv.ParseUint(l.token, 10, 8); e != nil {
1512 tokenUpper := strings.ToUpper(l.token)
1513 i, ok := StringToAlgorithm[tokenUpper]
1515 return &ParseError{f, "bad TA Algorithm", l}
1519 rr.Algorithm = uint8(i)
1523 i, e = strconv.ParseUint(l.token, 10, 8)
1524 if e != nil || l.err {
1525 return &ParseError{f, "bad TA DigestType", l}
1527 rr.DigestType = uint8(i)
1528 s, err := endingToString(c, "bad TA Digest", f)
1536 func (rr *TLSA) parse(c *zlexer, o, f string) *ParseError {
1538 if len(l.token) == 0 { // dynamic update rr.
1542 i, e := strconv.ParseUint(l.token, 10, 8)
1543 if e != nil || l.err {
1544 return &ParseError{f, "bad TLSA Usage", l}
1549 i, e = strconv.ParseUint(l.token, 10, 8)
1550 if e != nil || l.err {
1551 return &ParseError{f, "bad TLSA Selector", l}
1553 rr.Selector = uint8(i)
1556 i, e = strconv.ParseUint(l.token, 10, 8)
1557 if e != nil || l.err {
1558 return &ParseError{f, "bad TLSA MatchingType", l}
1560 rr.MatchingType = uint8(i)
1561 // So this needs be e2 (i.e. different than e), because...??t
1562 s, e2 := endingToString(c, "bad TLSA Certificate", f)
1570 func (rr *SMIMEA) parse(c *zlexer, o, f string) *ParseError {
1572 if len(l.token) == 0 { // dynamic update rr.
1576 i, e := strconv.ParseUint(l.token, 10, 8)
1577 if e != nil || l.err {
1578 return &ParseError{f, "bad SMIMEA Usage", l}
1583 i, e = strconv.ParseUint(l.token, 10, 8)
1584 if e != nil || l.err {
1585 return &ParseError{f, "bad SMIMEA Selector", l}
1587 rr.Selector = uint8(i)
1590 i, e = strconv.ParseUint(l.token, 10, 8)
1591 if e != nil || l.err {
1592 return &ParseError{f, "bad SMIMEA MatchingType", l}
1594 rr.MatchingType = uint8(i)
1595 // So this needs be e2 (i.e. different than e), because...??t
1596 s, e2 := endingToString(c, "bad SMIMEA Certificate", f)
1604 func (rr *RFC3597) parse(c *zlexer, o, f string) *ParseError {
1606 if l.token != "\\#" {
1607 return &ParseError{f, "bad RFC3597 Rdata", l}
1612 rdlength, e := strconv.Atoi(l.token)
1613 if e != nil || l.err {
1614 return &ParseError{f, "bad RFC3597 Rdata ", l}
1617 s, e1 := endingToString(c, "bad RFC3597 Rdata", f)
1621 if rdlength*2 != len(s) {
1622 return &ParseError{f, "bad RFC3597 Rdata", l}
1628 func (rr *SPF) parse(c *zlexer, o, f string) *ParseError {
1629 s, e := endingToTxtSlice(c, "bad SPF Txt", f)
1637 func (rr *AVC) parse(c *zlexer, o, f string) *ParseError {
1638 s, e := endingToTxtSlice(c, "bad AVC Txt", f)
1646 func (rr *TXT) parse(c *zlexer, o, f string) *ParseError {
1647 // no zBlank reading here, because all this rdata is TXT
1648 s, e := endingToTxtSlice(c, "bad TXT Txt", f)
1656 // identical to setTXT
1657 func (rr *NINFO) parse(c *zlexer, o, f string) *ParseError {
1658 s, e := endingToTxtSlice(c, "bad NINFO ZSData", f)
1666 func (rr *URI) parse(c *zlexer, o, f string) *ParseError {
1668 if len(l.token) == 0 { // dynamic update rr.
1672 i, e := strconv.ParseUint(l.token, 10, 16)
1673 if e != nil || l.err {
1674 return &ParseError{f, "bad URI Priority", l}
1676 rr.Priority = uint16(i)
1679 i, e = strconv.ParseUint(l.token, 10, 16)
1680 if e != nil || l.err {
1681 return &ParseError{f, "bad URI Weight", l}
1683 rr.Weight = uint16(i)
1686 s, err := endingToTxtSlice(c, "bad URI Target", f)
1691 return &ParseError{f, "bad URI Target", l}
1697 func (rr *DHCID) parse(c *zlexer, o, f string) *ParseError {
1698 // awesome record to parse!
1699 s, e := endingToString(c, "bad DHCID Digest", f)
1707 func (rr *NID) parse(c *zlexer, o, f string) *ParseError {
1709 if len(l.token) == 0 { // dynamic update rr.
1710 return slurpRemainder(c, f)
1713 i, e := strconv.ParseUint(l.token, 10, 16)
1714 if e != nil || l.err {
1715 return &ParseError{f, "bad NID Preference", l}
1717 rr.Preference = uint16(i)
1719 l, _ = c.Next() // zString
1720 u, err := stringToNodeID(l)
1721 if err != nil || l.err {
1725 return slurpRemainder(c, f)
1728 func (rr *L32) parse(c *zlexer, o, f string) *ParseError {
1730 if len(l.token) == 0 { // dynamic update rr.
1731 return slurpRemainder(c, f)
1734 i, e := strconv.ParseUint(l.token, 10, 16)
1735 if e != nil || l.err {
1736 return &ParseError{f, "bad L32 Preference", l}
1738 rr.Preference = uint16(i)
1740 l, _ = c.Next() // zString
1741 rr.Locator32 = net.ParseIP(l.token)
1742 if rr.Locator32 == nil || l.err {
1743 return &ParseError{f, "bad L32 Locator", l}
1745 return slurpRemainder(c, f)
1748 func (rr *LP) parse(c *zlexer, o, f string) *ParseError {
1750 if len(l.token) == 0 { // dynamic update rr.
1751 return slurpRemainder(c, f)
1754 i, e := strconv.ParseUint(l.token, 10, 16)
1755 if e != nil || l.err {
1756 return &ParseError{f, "bad LP Preference", l}
1758 rr.Preference = uint16(i)
1761 l, _ = c.Next() // zString
1763 name, nameOk := toAbsoluteName(l.token, o)
1764 if l.err || !nameOk {
1765 return &ParseError{f, "bad LP Fqdn", l}
1769 return slurpRemainder(c, f)
1772 func (rr *L64) parse(c *zlexer, o, f string) *ParseError {
1774 if len(l.token) == 0 { // dynamic update rr.
1775 return slurpRemainder(c, f)
1778 i, e := strconv.ParseUint(l.token, 10, 16)
1779 if e != nil || l.err {
1780 return &ParseError{f, "bad L64 Preference", l}
1782 rr.Preference = uint16(i)
1784 l, _ = c.Next() // zString
1785 u, err := stringToNodeID(l)
1786 if err != nil || l.err {
1790 return slurpRemainder(c, f)
1793 func (rr *UID) parse(c *zlexer, o, f string) *ParseError {
1795 if len(l.token) == 0 { // dynamic update rr.
1796 return slurpRemainder(c, f)
1799 i, e := strconv.ParseUint(l.token, 10, 32)
1800 if e != nil || l.err {
1801 return &ParseError{f, "bad UID Uid", l}
1804 return slurpRemainder(c, f)
1807 func (rr *GID) parse(c *zlexer, o, f string) *ParseError {
1809 if len(l.token) == 0 { // dynamic update rr.
1810 return slurpRemainder(c, f)
1813 i, e := strconv.ParseUint(l.token, 10, 32)
1814 if e != nil || l.err {
1815 return &ParseError{f, "bad GID Gid", l}
1818 return slurpRemainder(c, f)
1821 func (rr *UINFO) parse(c *zlexer, o, f string) *ParseError {
1822 s, e := endingToTxtSlice(c, "bad UINFO Uinfo", f)
1826 if ln := len(s); ln == 0 {
1829 rr.Uinfo = s[0] // silently discard anything after the first character-string
1833 func (rr *PX) parse(c *zlexer, o, f string) *ParseError {
1835 if len(l.token) == 0 { // dynamic update rr.
1836 return slurpRemainder(c, f)
1839 i, e := strconv.ParseUint(l.token, 10, 16)
1840 if e != nil || l.err {
1841 return &ParseError{f, "bad PX Preference", l}
1843 rr.Preference = uint16(i)
1846 l, _ = c.Next() // zString
1848 map822, map822Ok := toAbsoluteName(l.token, o)
1849 if l.err || !map822Ok {
1850 return &ParseError{f, "bad PX Map822", l}
1855 l, _ = c.Next() // zString
1856 rr.Mapx400 = l.token
1857 mapx400, mapx400Ok := toAbsoluteName(l.token, o)
1858 if l.err || !mapx400Ok {
1859 return &ParseError{f, "bad PX Mapx400", l}
1861 rr.Mapx400 = mapx400
1863 return slurpRemainder(c, f)
1866 func (rr *CAA) parse(c *zlexer, o, f string) *ParseError {
1868 if len(l.token) == 0 { // dynamic update rr.
1872 i, err := strconv.ParseUint(l.token, 10, 8)
1873 if err != nil || l.err {
1874 return &ParseError{f, "bad CAA Flag", l}
1879 l, _ = c.Next() // zString
1880 if l.value != zString {
1881 return &ParseError{f, "bad CAA Tag", l}
1886 s, e := endingToTxtSlice(c, "bad CAA Value", f)
1891 return &ParseError{f, "bad CAA Value", l}
1897 func (rr *TKEY) parse(c *zlexer, o, f string) *ParseError {
1901 if l.value != zString {
1902 return &ParseError{f, "bad TKEY algorithm", l}
1904 rr.Algorithm = l.token
1907 // Get the key length and key values
1909 i, err := strconv.ParseUint(l.token, 10, 8)
1910 if err != nil || l.err {
1911 return &ParseError{f, "bad TKEY key length", l}
1913 rr.KeySize = uint16(i)
1916 if l.value != zString {
1917 return &ParseError{f, "bad TKEY key", l}
1922 // Get the otherdata length and string data
1924 i, err = strconv.ParseUint(l.token, 10, 8)
1925 if err != nil || l.err {
1926 return &ParseError{f, "bad TKEY otherdata length", l}
1928 rr.OtherLen = uint16(i)
1931 if l.value != zString {
1932 return &ParseError{f, "bad TKEY otherday", l}
1934 rr.OtherData = l.token