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