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