OSDN Git Service

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