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 chan lex, 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 chan lex, 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 chan lex, errstr, f string) (string, *ParseError, string) {
49	s := ""
50	l := <-c // 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
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 chan lex, errstr, f string) ([]string, *ParseError, string) {
70	// Get the remaining data until we see a zNewline
71	l := <-c
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
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 chan lex, o, f string) (RR, *ParseError, string) {
129	rr := new(A)
130	rr.Hdr = h
131
132	l := <-c
133	if l.length == 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 chan lex, o, f string) (RR, *ParseError, string) {
145	rr := new(AAAA)
146	rr.Hdr = h
147
148	l := <-c
149	if l.length == 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 chan lex, o, f string) (RR, *ParseError, string) {
161	rr := new(NS)
162	rr.Hdr = h
163
164	l := <-c
165	rr.Ns = l.token
166	if l.length == 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 chan lex, o, f string) (RR, *ParseError, string) {
179	rr := new(PTR)
180	rr.Hdr = h
181
182	l := <-c
183	rr.Ptr = l.token
184	if l.length == 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 chan lex, o, f string) (RR, *ParseError, string) {
197	rr := new(NSAPPTR)
198	rr.Hdr = h
199
200	l := <-c
201	rr.Ptr = l.token
202	if l.length == 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 chan lex, o, f string) (RR, *ParseError, string) {
215	rr := new(RP)
216	rr.Hdr = h
217
218	l := <-c
219	rr.Mbox = l.token
220	if l.length == 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 // zBlank
231	l = <-c
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 chan lex, o, f string) (RR, *ParseError, string) {
244	rr := new(MR)
245	rr.Hdr = h
246
247	l := <-c
248	rr.Mr = l.token
249	if l.length == 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 chan lex, o, f string) (RR, *ParseError, string) {
262	rr := new(MB)
263	rr.Hdr = h
264
265	l := <-c
266	rr.Mb = l.token
267	if l.length == 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 chan lex, o, f string) (RR, *ParseError, string) {
280	rr := new(MG)
281	rr.Hdr = h
282
283	l := <-c
284	rr.Mg = l.token
285	if l.length == 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 chan lex, 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 chan lex, o, f string) (RR, *ParseError, string) {
324	rr := new(MINFO)
325	rr.Hdr = h
326
327	l := <-c
328	rr.Rmail = l.token
329	if l.length == 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 // zBlank
340	l = <-c
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 chan lex, o, f string) (RR, *ParseError, string) {
353	rr := new(MF)
354	rr.Hdr = h
355
356	l := <-c
357	rr.Mf = l.token
358	if l.length == 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 chan lex, o, f string) (RR, *ParseError, string) {
371	rr := new(MD)
372	rr.Hdr = h
373
374	l := <-c
375	rr.Md = l.token
376	if l.length == 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 chan lex, o, f string) (RR, *ParseError, string) {
389	rr := new(MX)
390	rr.Hdr = h
391
392	l := <-c
393	if l.length == 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     // zBlank
404	l = <-c // 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 chan lex, o, f string) (RR, *ParseError, string) {
417	rr := new(RT)
418	rr.Hdr = h
419
420	l := <-c
421	if l.length == 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     // zBlank
432	l = <-c // 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 chan lex, o, f string) (RR, *ParseError, string) {
445	rr := new(AFSDB)
446	rr.Hdr = h
447
448	l := <-c
449	if l.length == 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     // zBlank
460	l = <-c // 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 chan lex, o, f string) (RR, *ParseError, string) {
472	rr := new(X25)
473	rr.Hdr = h
474
475	l := <-c
476	if l.length == 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 chan lex, o, f string) (RR, *ParseError, string) {
488	rr := new(KX)
489	rr.Hdr = h
490
491	l := <-c
492	if l.length == 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     // zBlank
503	l = <-c // 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 chan lex, o, f string) (RR, *ParseError, string) {
515	rr := new(CNAME)
516	rr.Hdr = h
517
518	l := <-c
519	rr.Target = l.token
520	if l.length == 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 chan lex, o, f string) (RR, *ParseError, string) {
533	rr := new(DNAME)
534	rr.Hdr = h
535
536	l := <-c
537	rr.Target = l.token
538	if l.length == 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 chan lex, o, f string) (RR, *ParseError, string) {
551	rr := new(SOA)
552	rr.Hdr = h
553
554	l := <-c
555	rr.Ns = l.token
556	if l.length == 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 // zBlank
567	l = <-c
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 // zBlank
577
578	var (
579		v  uint32
580		ok bool
581	)
582	for i := 0; i < 5; i++ {
583		l = <-c
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 // zBlank
604		case 1:
605			rr.Refresh = v
606			<-c // zBlank
607		case 2:
608			rr.Retry = v
609			<-c // zBlank
610		case 3:
611			rr.Expire = v
612			<-c // zBlank
613		case 4:
614			rr.Minttl = v
615		}
616	}
617	return rr, nil, ""
618}
619
620func setSRV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
621	rr := new(SRV)
622	rr.Hdr = h
623
624	l := <-c
625	if l.length == 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     // zBlank
636	l = <-c // 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     // zBlank
644	l = <-c // 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     // zBlank
652	l = <-c // 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 chan lex, o, f string) (RR, *ParseError, string) {
664	rr := new(NAPTR)
665	rr.Hdr = h
666
667	l := <-c
668	if l.length == 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     // zBlank
679	l = <-c // 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     // zBlank
688	l = <-c // _QUOTE
689	if l.value != zQuote {
690		return nil, &ParseError{f, "bad NAPTR Flags", l}, ""
691	}
692	l = <-c // Either String or Quote
693	if l.value == zString {
694		rr.Flags = l.token
695		l = <-c // _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     // zBlank
707	l = <-c // _QUOTE
708	if l.value != zQuote {
709		return nil, &ParseError{f, "bad NAPTR Service", l}, ""
710	}
711	l = <-c // Either String or Quote
712	if l.value == zString {
713		rr.Service = l.token
714		l = <-c // _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     // zBlank
726	l = <-c // _QUOTE
727	if l.value != zQuote {
728		return nil, &ParseError{f, "bad NAPTR Regexp", l}, ""
729	}
730	l = <-c // Either String or Quote
731	if l.value == zString {
732		rr.Regexp = l.token
733		l = <-c // _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     // zBlank
745	l = <-c // 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 chan lex, o, f string) (RR, *ParseError, string) {
757	rr := new(TALINK)
758	rr.Hdr = h
759
760	l := <-c
761	rr.PreviousName = l.token
762	if l.length == 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 // zBlank
773	l = <-c
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 chan lex, 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
796	if l.length == 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 // zBlank
806	// Either number, 'N' or 'S'
807	l = <-c
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 // zBlank
818	l = <-c
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 // zBlank
825	// Either number, 'N' or 'S'
826	l = <-c
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 // zBlank
836	l = <-c
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 // zBlank
843	// Either number, 'E' or 'W'
844	l = <-c
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 // zBlank
854	l = <-c
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 // zBlank
861	// Either number, 'E' or 'W'
862	l = <-c
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 // zBlank
871	l = <-c
872	if l.length == 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
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
917	}
918	return rr, nil, ""
919}
920
921func setHIP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
922	rr := new(HIP)
923	rr.Hdr = h
924
925	// HitLength is not represented
926	l := <-c
927	if l.length == 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     // zBlank
938	l = <-c // zString
939	if l.length == 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     // zBlank
946	l = <-c // zString
947	if l.length == 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
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
970	}
971	rr.RendezvousServers = xs
972	return rr, nil, l.comment
973}
974
975func setCERT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
976	rr := new(CERT)
977	rr.Hdr = h
978
979	l := <-c
980	if l.length == 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     // zBlank
992	l = <-c // 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     // zBlank
999	l = <-c // 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 chan lex, 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 chan lex, o, f string) (RR, *ParseError, string) {
1028	rr := new(CSYNC)
1029	rr.Hdr = h
1030
1031	l := <-c
1032	if l.length == 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 // zBlank
1043
1044	l = <-c
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
1058	for l.value != zNewline && l.value != zEOF {
1059		switch l.value {
1060		case zBlank:
1061			// Ok
1062		case zString:
1063			if k, ok = StringToType[l.tokenUpper]; !ok {
1064				if k, ok = typeToInt(l.tokenUpper); !ok {
1065					return nil, &ParseError{f, "bad CSYNC TypeBitMap", l}, ""
1066				}
1067			}
1068			rr.TypeBitMap = append(rr.TypeBitMap, k)
1069		default:
1070			return nil, &ParseError{f, "bad CSYNC TypeBitMap", l}, ""
1071		}
1072		l = <-c
1073	}
1074	return rr, nil, l.comment
1075}
1076
1077func setSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1078	r, e, s := setRRSIG(h, c, o, f)
1079	if r != nil {
1080		return &SIG{*r.(*RRSIG)}, e, s
1081	}
1082	return nil, e, s
1083}
1084
1085func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1086	rr := new(RRSIG)
1087	rr.Hdr = h
1088
1089	l := <-c
1090	if l.length == 0 { // dynamic update rr.
1091		return rr, nil, l.comment
1092	}
1093
1094	if t, ok := StringToType[l.tokenUpper]; !ok {
1095		if strings.HasPrefix(l.tokenUpper, "TYPE") {
1096			t, ok = typeToInt(l.tokenUpper)
1097			if !ok {
1098				return nil, &ParseError{f, "bad RRSIG Typecovered", l}, ""
1099			}
1100			rr.TypeCovered = t
1101		} else {
1102			return nil, &ParseError{f, "bad RRSIG Typecovered", l}, ""
1103		}
1104	} else {
1105		rr.TypeCovered = t
1106	}
1107
1108	<-c // zBlank
1109	l = <-c
1110	i, err := strconv.ParseUint(l.token, 10, 8)
1111	if err != nil || l.err {
1112		return nil, &ParseError{f, "bad RRSIG Algorithm", l}, ""
1113	}
1114	rr.Algorithm = uint8(i)
1115
1116	<-c // zBlank
1117	l = <-c
1118	i, err = strconv.ParseUint(l.token, 10, 8)
1119	if err != nil || l.err {
1120		return nil, &ParseError{f, "bad RRSIG Labels", l}, ""
1121	}
1122	rr.Labels = uint8(i)
1123
1124	<-c // zBlank
1125	l = <-c
1126	i, err = strconv.ParseUint(l.token, 10, 32)
1127	if err != nil || l.err {
1128		return nil, &ParseError{f, "bad RRSIG OrigTtl", l}, ""
1129	}
1130	rr.OrigTtl = uint32(i)
1131
1132	<-c // zBlank
1133	l = <-c
1134	if i, err := StringToTime(l.token); err != nil {
1135		// Try to see if all numeric and use it as epoch
1136		if i, err := strconv.ParseInt(l.token, 10, 64); err == nil {
1137			// TODO(miek): error out on > MAX_UINT32, same below
1138			rr.Expiration = uint32(i)
1139		} else {
1140			return nil, &ParseError{f, "bad RRSIG Expiration", l}, ""
1141		}
1142	} else {
1143		rr.Expiration = i
1144	}
1145
1146	<-c // zBlank
1147	l = <-c
1148	if i, err := StringToTime(l.token); err != nil {
1149		if i, err := strconv.ParseInt(l.token, 10, 64); err == nil {
1150			rr.Inception = uint32(i)
1151		} else {
1152			return nil, &ParseError{f, "bad RRSIG Inception", l}, ""
1153		}
1154	} else {
1155		rr.Inception = i
1156	}
1157
1158	<-c // zBlank
1159	l = <-c
1160	i, err = strconv.ParseUint(l.token, 10, 16)
1161	if err != nil || l.err {
1162		return nil, &ParseError{f, "bad RRSIG KeyTag", l}, ""
1163	}
1164	rr.KeyTag = uint16(i)
1165
1166	<-c // zBlank
1167	l = <-c
1168	rr.SignerName = l.token
1169	name, nameOk := toAbsoluteName(l.token, o)
1170	if l.err || !nameOk {
1171		return nil, &ParseError{f, "bad RRSIG SignerName", l}, ""
1172	}
1173	rr.SignerName = name
1174
1175	s, e, c1 := endingToString(c, "bad RRSIG Signature", f)
1176	if e != nil {
1177		return nil, e, c1
1178	}
1179	rr.Signature = s
1180
1181	return rr, nil, c1
1182}
1183
1184func setNSEC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1185	rr := new(NSEC)
1186	rr.Hdr = h
1187
1188	l := <-c
1189	rr.NextDomain = l.token
1190	if l.length == 0 { // dynamic update rr.
1191		return rr, nil, l.comment
1192	}
1193
1194	name, nameOk := toAbsoluteName(l.token, o)
1195	if l.err || !nameOk {
1196		return nil, &ParseError{f, "bad NSEC NextDomain", l}, ""
1197	}
1198	rr.NextDomain = name
1199
1200	rr.TypeBitMap = make([]uint16, 0)
1201	var (
1202		k  uint16
1203		ok bool
1204	)
1205	l = <-c
1206	for l.value != zNewline && l.value != zEOF {
1207		switch l.value {
1208		case zBlank:
1209			// Ok
1210		case zString:
1211			if k, ok = StringToType[l.tokenUpper]; !ok {
1212				if k, ok = typeToInt(l.tokenUpper); !ok {
1213					return nil, &ParseError{f, "bad NSEC TypeBitMap", l}, ""
1214				}
1215			}
1216			rr.TypeBitMap = append(rr.TypeBitMap, k)
1217		default:
1218			return nil, &ParseError{f, "bad NSEC TypeBitMap", l}, ""
1219		}
1220		l = <-c
1221	}
1222	return rr, nil, l.comment
1223}
1224
1225func setNSEC3(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1226	rr := new(NSEC3)
1227	rr.Hdr = h
1228
1229	l := <-c
1230	if l.length == 0 { // dynamic update rr.
1231		return rr, nil, l.comment
1232	}
1233
1234	i, e := strconv.ParseUint(l.token, 10, 8)
1235	if e != nil || l.err {
1236		return nil, &ParseError{f, "bad NSEC3 Hash", l}, ""
1237	}
1238	rr.Hash = uint8(i)
1239	<-c // zBlank
1240	l = <-c
1241	i, e = strconv.ParseUint(l.token, 10, 8)
1242	if e != nil || l.err {
1243		return nil, &ParseError{f, "bad NSEC3 Flags", l}, ""
1244	}
1245	rr.Flags = uint8(i)
1246	<-c // zBlank
1247	l = <-c
1248	i, e = strconv.ParseUint(l.token, 10, 16)
1249	if e != nil || l.err {
1250		return nil, &ParseError{f, "bad NSEC3 Iterations", l}, ""
1251	}
1252	rr.Iterations = uint16(i)
1253	<-c
1254	l = <-c
1255	if len(l.token) == 0 || l.err {
1256		return nil, &ParseError{f, "bad NSEC3 Salt", l}, ""
1257	}
1258	if l.token != "-" {
1259		rr.SaltLength = uint8(len(l.token)) / 2
1260		rr.Salt = l.token
1261	}
1262
1263	<-c
1264	l = <-c
1265	if len(l.token) == 0 || l.err {
1266		return nil, &ParseError{f, "bad NSEC3 NextDomain", l}, ""
1267	}
1268	rr.HashLength = 20 // Fix for NSEC3 (sha1 160 bits)
1269	rr.NextDomain = l.token
1270
1271	rr.TypeBitMap = make([]uint16, 0)
1272	var (
1273		k  uint16
1274		ok bool
1275	)
1276	l = <-c
1277	for l.value != zNewline && l.value != zEOF {
1278		switch l.value {
1279		case zBlank:
1280			// Ok
1281		case zString:
1282			if k, ok = StringToType[l.tokenUpper]; !ok {
1283				if k, ok = typeToInt(l.tokenUpper); !ok {
1284					return nil, &ParseError{f, "bad NSEC3 TypeBitMap", l}, ""
1285				}
1286			}
1287			rr.TypeBitMap = append(rr.TypeBitMap, k)
1288		default:
1289			return nil, &ParseError{f, "bad NSEC3 TypeBitMap", l}, ""
1290		}
1291		l = <-c
1292	}
1293	return rr, nil, l.comment
1294}
1295
1296func setNSEC3PARAM(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1297	rr := new(NSEC3PARAM)
1298	rr.Hdr = h
1299
1300	l := <-c
1301	if l.length == 0 { // dynamic update rr.
1302		return rr, nil, ""
1303	}
1304
1305	i, e := strconv.ParseUint(l.token, 10, 8)
1306	if e != nil || l.err {
1307		return nil, &ParseError{f, "bad NSEC3PARAM Hash", l}, ""
1308	}
1309	rr.Hash = uint8(i)
1310	<-c // zBlank
1311	l = <-c
1312	i, e = strconv.ParseUint(l.token, 10, 8)
1313	if e != nil || l.err {
1314		return nil, &ParseError{f, "bad NSEC3PARAM Flags", l}, ""
1315	}
1316	rr.Flags = uint8(i)
1317	<-c // zBlank
1318	l = <-c
1319	i, e = strconv.ParseUint(l.token, 10, 16)
1320	if e != nil || l.err {
1321		return nil, &ParseError{f, "bad NSEC3PARAM Iterations", l}, ""
1322	}
1323	rr.Iterations = uint16(i)
1324	<-c
1325	l = <-c
1326	if l.token != "-" {
1327		rr.SaltLength = uint8(len(l.token))
1328		rr.Salt = l.token
1329	}
1330	return rr, nil, ""
1331}
1332
1333func setEUI48(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1334	rr := new(EUI48)
1335	rr.Hdr = h
1336
1337	l := <-c
1338	if l.length == 0 { // dynamic update rr.
1339		return rr, nil, ""
1340	}
1341
1342	if l.length != 17 || l.err {
1343		return nil, &ParseError{f, "bad EUI48 Address", l}, ""
1344	}
1345	addr := make([]byte, 12)
1346	dash := 0
1347	for i := 0; i < 10; i += 2 {
1348		addr[i] = l.token[i+dash]
1349		addr[i+1] = l.token[i+1+dash]
1350		dash++
1351		if l.token[i+1+dash] != '-' {
1352			return nil, &ParseError{f, "bad EUI48 Address", l}, ""
1353		}
1354	}
1355	addr[10] = l.token[15]
1356	addr[11] = l.token[16]
1357
1358	i, e := strconv.ParseUint(string(addr), 16, 48)
1359	if e != nil {
1360		return nil, &ParseError{f, "bad EUI48 Address", l}, ""
1361	}
1362	rr.Address = i
1363	return rr, nil, ""
1364}
1365
1366func setEUI64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1367	rr := new(EUI64)
1368	rr.Hdr = h
1369
1370	l := <-c
1371	if l.length == 0 { // dynamic update rr.
1372		return rr, nil, ""
1373	}
1374
1375	if l.length != 23 || l.err {
1376		return nil, &ParseError{f, "bad EUI64 Address", l}, ""
1377	}
1378	addr := make([]byte, 16)
1379	dash := 0
1380	for i := 0; i < 14; i += 2 {
1381		addr[i] = l.token[i+dash]
1382		addr[i+1] = l.token[i+1+dash]
1383		dash++
1384		if l.token[i+1+dash] != '-' {
1385			return nil, &ParseError{f, "bad EUI64 Address", l}, ""
1386		}
1387	}
1388	addr[14] = l.token[21]
1389	addr[15] = l.token[22]
1390
1391	i, e := strconv.ParseUint(string(addr), 16, 64)
1392	if e != nil {
1393		return nil, &ParseError{f, "bad EUI68 Address", l}, ""
1394	}
1395	rr.Address = uint64(i)
1396	return rr, nil, ""
1397}
1398
1399func setSSHFP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1400	rr := new(SSHFP)
1401	rr.Hdr = h
1402
1403	l := <-c
1404	if l.length == 0 { // dynamic update rr.
1405		return rr, nil, ""
1406	}
1407
1408	i, e := strconv.ParseUint(l.token, 10, 8)
1409	if e != nil || l.err {
1410		return nil, &ParseError{f, "bad SSHFP Algorithm", l}, ""
1411	}
1412	rr.Algorithm = uint8(i)
1413	<-c // zBlank
1414	l = <-c
1415	i, e = strconv.ParseUint(l.token, 10, 8)
1416	if e != nil || l.err {
1417		return nil, &ParseError{f, "bad SSHFP Type", l}, ""
1418	}
1419	rr.Type = uint8(i)
1420	<-c // zBlank
1421	s, e1, c1 := endingToString(c, "bad SSHFP Fingerprint", f)
1422	if e1 != nil {
1423		return nil, e1, c1
1424	}
1425	rr.FingerPrint = s
1426	return rr, nil, ""
1427}
1428
1429func setDNSKEYs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string) {
1430	rr := new(DNSKEY)
1431	rr.Hdr = h
1432
1433	l := <-c
1434	if l.length == 0 { // dynamic update rr.
1435		return rr, nil, l.comment
1436	}
1437
1438	i, e := strconv.ParseUint(l.token, 10, 16)
1439	if e != nil || l.err {
1440		return nil, &ParseError{f, "bad " + typ + " Flags", l}, ""
1441	}
1442	rr.Flags = uint16(i)
1443	<-c     // zBlank
1444	l = <-c // zString
1445	i, e = strconv.ParseUint(l.token, 10, 8)
1446	if e != nil || l.err {
1447		return nil, &ParseError{f, "bad " + typ + " Protocol", l}, ""
1448	}
1449	rr.Protocol = uint8(i)
1450	<-c     // zBlank
1451	l = <-c // zString
1452	i, e = strconv.ParseUint(l.token, 10, 8)
1453	if e != nil || l.err {
1454		return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, ""
1455	}
1456	rr.Algorithm = uint8(i)
1457	s, e1, c1 := endingToString(c, "bad "+typ+" PublicKey", f)
1458	if e1 != nil {
1459		return nil, e1, c1
1460	}
1461	rr.PublicKey = s
1462	return rr, nil, c1
1463}
1464
1465func setKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1466	r, e, s := setDNSKEYs(h, c, o, f, "KEY")
1467	if r != nil {
1468		return &KEY{*r.(*DNSKEY)}, e, s
1469	}
1470	return nil, e, s
1471}
1472
1473func setDNSKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1474	r, e, s := setDNSKEYs(h, c, o, f, "DNSKEY")
1475	return r, e, s
1476}
1477
1478func setCDNSKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1479	r, e, s := setDNSKEYs(h, c, o, f, "CDNSKEY")
1480	if r != nil {
1481		return &CDNSKEY{*r.(*DNSKEY)}, e, s
1482	}
1483	return nil, e, s
1484}
1485
1486func setRKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1487	rr := new(RKEY)
1488	rr.Hdr = h
1489
1490	l := <-c
1491	if l.length == 0 { // dynamic update rr.
1492		return rr, nil, l.comment
1493	}
1494
1495	i, e := strconv.ParseUint(l.token, 10, 16)
1496	if e != nil || l.err {
1497		return nil, &ParseError{f, "bad RKEY Flags", l}, ""
1498	}
1499	rr.Flags = uint16(i)
1500	<-c     // zBlank
1501	l = <-c // zString
1502	i, e = strconv.ParseUint(l.token, 10, 8)
1503	if e != nil || l.err {
1504		return nil, &ParseError{f, "bad RKEY Protocol", l}, ""
1505	}
1506	rr.Protocol = uint8(i)
1507	<-c     // zBlank
1508	l = <-c // zString
1509	i, e = strconv.ParseUint(l.token, 10, 8)
1510	if e != nil || l.err {
1511		return nil, &ParseError{f, "bad RKEY Algorithm", l}, ""
1512	}
1513	rr.Algorithm = uint8(i)
1514	s, e1, c1 := endingToString(c, "bad RKEY PublicKey", f)
1515	if e1 != nil {
1516		return nil, e1, c1
1517	}
1518	rr.PublicKey = s
1519	return rr, nil, c1
1520}
1521
1522func setEID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1523	rr := new(EID)
1524	rr.Hdr = h
1525	s, e, c1 := endingToString(c, "bad EID Endpoint", f)
1526	if e != nil {
1527		return nil, e, c1
1528	}
1529	rr.Endpoint = s
1530	return rr, nil, c1
1531}
1532
1533func setNIMLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1534	rr := new(NIMLOC)
1535	rr.Hdr = h
1536	s, e, c1 := endingToString(c, "bad NIMLOC Locator", f)
1537	if e != nil {
1538		return nil, e, c1
1539	}
1540	rr.Locator = s
1541	return rr, nil, c1
1542}
1543
1544func setGPOS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1545	rr := new(GPOS)
1546	rr.Hdr = h
1547
1548	l := <-c
1549	if l.length == 0 { // dynamic update rr.
1550		return rr, nil, ""
1551	}
1552
1553	_, e := strconv.ParseFloat(l.token, 64)
1554	if e != nil || l.err {
1555		return nil, &ParseError{f, "bad GPOS Longitude", l}, ""
1556	}
1557	rr.Longitude = l.token
1558	<-c // zBlank
1559	l = <-c
1560	_, e = strconv.ParseFloat(l.token, 64)
1561	if e != nil || l.err {
1562		return nil, &ParseError{f, "bad GPOS Latitude", l}, ""
1563	}
1564	rr.Latitude = l.token
1565	<-c // zBlank
1566	l = <-c
1567	_, e = strconv.ParseFloat(l.token, 64)
1568	if e != nil || l.err {
1569		return nil, &ParseError{f, "bad GPOS Altitude", l}, ""
1570	}
1571	rr.Altitude = l.token
1572	return rr, nil, ""
1573}
1574
1575func setDSs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string) {
1576	rr := new(DS)
1577	rr.Hdr = h
1578
1579	l := <-c
1580	if l.length == 0 { // dynamic update rr.
1581		return rr, nil, l.comment
1582	}
1583
1584	i, e := strconv.ParseUint(l.token, 10, 16)
1585	if e != nil || l.err {
1586		return nil, &ParseError{f, "bad " + typ + " KeyTag", l}, ""
1587	}
1588	rr.KeyTag = uint16(i)
1589	<-c // zBlank
1590	l = <-c
1591	if i, e = strconv.ParseUint(l.token, 10, 8); e != nil {
1592		i, ok := StringToAlgorithm[l.tokenUpper]
1593		if !ok || l.err {
1594			return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, ""
1595		}
1596		rr.Algorithm = i
1597	} else {
1598		rr.Algorithm = uint8(i)
1599	}
1600	<-c // zBlank
1601	l = <-c
1602	i, e = strconv.ParseUint(l.token, 10, 8)
1603	if e != nil || l.err {
1604		return nil, &ParseError{f, "bad " + typ + " DigestType", l}, ""
1605	}
1606	rr.DigestType = uint8(i)
1607	s, e1, c1 := endingToString(c, "bad "+typ+" Digest", f)
1608	if e1 != nil {
1609		return nil, e1, c1
1610	}
1611	rr.Digest = s
1612	return rr, nil, c1
1613}
1614
1615func setDS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1616	r, e, s := setDSs(h, c, o, f, "DS")
1617	return r, e, s
1618}
1619
1620func setDLV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1621	r, e, s := setDSs(h, c, o, f, "DLV")
1622	if r != nil {
1623		return &DLV{*r.(*DS)}, e, s
1624	}
1625	return nil, e, s
1626}
1627
1628func setCDS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1629	r, e, s := setDSs(h, c, o, f, "CDS")
1630	if r != nil {
1631		return &CDS{*r.(*DS)}, e, s
1632	}
1633	return nil, e, s
1634}
1635
1636func setTA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1637	rr := new(TA)
1638	rr.Hdr = h
1639
1640	l := <-c
1641	if l.length == 0 { // dynamic update rr.
1642		return rr, nil, l.comment
1643	}
1644
1645	i, e := strconv.ParseUint(l.token, 10, 16)
1646	if e != nil || l.err {
1647		return nil, &ParseError{f, "bad TA KeyTag", l}, ""
1648	}
1649	rr.KeyTag = uint16(i)
1650	<-c // zBlank
1651	l = <-c
1652	if i, e := strconv.ParseUint(l.token, 10, 8); e != nil {
1653		i, ok := StringToAlgorithm[l.tokenUpper]
1654		if !ok || l.err {
1655			return nil, &ParseError{f, "bad TA Algorithm", l}, ""
1656		}
1657		rr.Algorithm = i
1658	} else {
1659		rr.Algorithm = uint8(i)
1660	}
1661	<-c // zBlank
1662	l = <-c
1663	i, e = strconv.ParseUint(l.token, 10, 8)
1664	if e != nil || l.err {
1665		return nil, &ParseError{f, "bad TA DigestType", l}, ""
1666	}
1667	rr.DigestType = uint8(i)
1668	s, e, c1 := endingToString(c, "bad TA Digest", f)
1669	if e != nil {
1670		return nil, e.(*ParseError), c1
1671	}
1672	rr.Digest = s
1673	return rr, nil, c1
1674}
1675
1676func setTLSA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1677	rr := new(TLSA)
1678	rr.Hdr = h
1679
1680	l := <-c
1681	if l.length == 0 { // dynamic update rr.
1682		return rr, nil, l.comment
1683	}
1684
1685	i, e := strconv.ParseUint(l.token, 10, 8)
1686	if e != nil || l.err {
1687		return nil, &ParseError{f, "bad TLSA Usage", l}, ""
1688	}
1689	rr.Usage = uint8(i)
1690	<-c // zBlank
1691	l = <-c
1692	i, e = strconv.ParseUint(l.token, 10, 8)
1693	if e != nil || l.err {
1694		return nil, &ParseError{f, "bad TLSA Selector", l}, ""
1695	}
1696	rr.Selector = uint8(i)
1697	<-c // zBlank
1698	l = <-c
1699	i, e = strconv.ParseUint(l.token, 10, 8)
1700	if e != nil || l.err {
1701		return nil, &ParseError{f, "bad TLSA MatchingType", l}, ""
1702	}
1703	rr.MatchingType = uint8(i)
1704	// So this needs be e2 (i.e. different than e), because...??t
1705	s, e2, c1 := endingToString(c, "bad TLSA Certificate", f)
1706	if e2 != nil {
1707		return nil, e2, c1
1708	}
1709	rr.Certificate = s
1710	return rr, nil, c1
1711}
1712
1713func setSMIMEA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1714	rr := new(SMIMEA)
1715	rr.Hdr = h
1716
1717	l := <-c
1718	if l.length == 0 { // dynamic update rr.
1719		return rr, nil, l.comment
1720	}
1721
1722	i, e := strconv.ParseUint(l.token, 10, 8)
1723	if e != nil || l.err {
1724		return nil, &ParseError{f, "bad SMIMEA Usage", l}, ""
1725	}
1726	rr.Usage = uint8(i)
1727	<-c // zBlank
1728	l = <-c
1729	i, e = strconv.ParseUint(l.token, 10, 8)
1730	if e != nil || l.err {
1731		return nil, &ParseError{f, "bad SMIMEA Selector", l}, ""
1732	}
1733	rr.Selector = uint8(i)
1734	<-c // zBlank
1735	l = <-c
1736	i, e = strconv.ParseUint(l.token, 10, 8)
1737	if e != nil || l.err {
1738		return nil, &ParseError{f, "bad SMIMEA MatchingType", l}, ""
1739	}
1740	rr.MatchingType = uint8(i)
1741	// So this needs be e2 (i.e. different than e), because...??t
1742	s, e2, c1 := endingToString(c, "bad SMIMEA Certificate", f)
1743	if e2 != nil {
1744		return nil, e2, c1
1745	}
1746	rr.Certificate = s
1747	return rr, nil, c1
1748}
1749
1750func setRFC3597(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1751	rr := new(RFC3597)
1752	rr.Hdr = h
1753
1754	l := <-c
1755	if l.token != "\\#" {
1756		return nil, &ParseError{f, "bad RFC3597 Rdata", l}, ""
1757	}
1758
1759	<-c // zBlank
1760	l = <-c
1761	rdlength, e := strconv.Atoi(l.token)
1762	if e != nil || l.err {
1763		return nil, &ParseError{f, "bad RFC3597 Rdata ", l}, ""
1764	}
1765
1766	s, e1, c1 := endingToString(c, "bad RFC3597 Rdata", f)
1767	if e1 != nil {
1768		return nil, e1, c1
1769	}
1770	if rdlength*2 != len(s) {
1771		return nil, &ParseError{f, "bad RFC3597 Rdata", l}, ""
1772	}
1773	rr.Rdata = s
1774	return rr, nil, c1
1775}
1776
1777func setSPF(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1778	rr := new(SPF)
1779	rr.Hdr = h
1780
1781	s, e, c1 := endingToTxtSlice(c, "bad SPF Txt", f)
1782	if e != nil {
1783		return nil, e, ""
1784	}
1785	rr.Txt = s
1786	return rr, nil, c1
1787}
1788
1789func setAVC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1790	rr := new(AVC)
1791	rr.Hdr = h
1792
1793	s, e, c1 := endingToTxtSlice(c, "bad AVC Txt", f)
1794	if e != nil {
1795		return nil, e, ""
1796	}
1797	rr.Txt = s
1798	return rr, nil, c1
1799}
1800
1801func setTXT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1802	rr := new(TXT)
1803	rr.Hdr = h
1804
1805	// no zBlank reading here, because all this rdata is TXT
1806	s, e, c1 := endingToTxtSlice(c, "bad TXT Txt", f)
1807	if e != nil {
1808		return nil, e, ""
1809	}
1810	rr.Txt = s
1811	return rr, nil, c1
1812}
1813
1814// identical to setTXT
1815func setNINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1816	rr := new(NINFO)
1817	rr.Hdr = h
1818
1819	s, e, c1 := endingToTxtSlice(c, "bad NINFO ZSData", f)
1820	if e != nil {
1821		return nil, e, ""
1822	}
1823	rr.ZSData = s
1824	return rr, nil, c1
1825}
1826
1827func setURI(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1828	rr := new(URI)
1829	rr.Hdr = h
1830
1831	l := <-c
1832	if l.length == 0 { // dynamic update rr.
1833		return rr, nil, ""
1834	}
1835
1836	i, e := strconv.ParseUint(l.token, 10, 16)
1837	if e != nil || l.err {
1838		return nil, &ParseError{f, "bad URI Priority", l}, ""
1839	}
1840	rr.Priority = uint16(i)
1841	<-c // zBlank
1842	l = <-c
1843	i, e = strconv.ParseUint(l.token, 10, 16)
1844	if e != nil || l.err {
1845		return nil, &ParseError{f, "bad URI Weight", l}, ""
1846	}
1847	rr.Weight = uint16(i)
1848
1849	<-c // zBlank
1850	s, err, c1 := endingToTxtSlice(c, "bad URI Target", f)
1851	if err != nil {
1852		return nil, err, ""
1853	}
1854	if len(s) != 1 {
1855		return nil, &ParseError{f, "bad URI Target", l}, ""
1856	}
1857	rr.Target = s[0]
1858	return rr, nil, c1
1859}
1860
1861func setDHCID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1862	// awesome record to parse!
1863	rr := new(DHCID)
1864	rr.Hdr = h
1865
1866	s, e, c1 := endingToString(c, "bad DHCID Digest", f)
1867	if e != nil {
1868		return nil, e, c1
1869	}
1870	rr.Digest = s
1871	return rr, nil, c1
1872}
1873
1874func setNID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1875	rr := new(NID)
1876	rr.Hdr = h
1877
1878	l := <-c
1879	if l.length == 0 { // dynamic update rr.
1880		return rr, nil, ""
1881	}
1882
1883	i, e := strconv.ParseUint(l.token, 10, 16)
1884	if e != nil || l.err {
1885		return nil, &ParseError{f, "bad NID Preference", l}, ""
1886	}
1887	rr.Preference = uint16(i)
1888	<-c     // zBlank
1889	l = <-c // zString
1890	u, err := stringToNodeID(l)
1891	if err != nil || l.err {
1892		return nil, err, ""
1893	}
1894	rr.NodeID = u
1895	return rr, nil, ""
1896}
1897
1898func setL32(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1899	rr := new(L32)
1900	rr.Hdr = h
1901
1902	l := <-c
1903	if l.length == 0 { // dynamic update rr.
1904		return rr, nil, ""
1905	}
1906
1907	i, e := strconv.ParseUint(l.token, 10, 16)
1908	if e != nil || l.err {
1909		return nil, &ParseError{f, "bad L32 Preference", l}, ""
1910	}
1911	rr.Preference = uint16(i)
1912	<-c     // zBlank
1913	l = <-c // zString
1914	rr.Locator32 = net.ParseIP(l.token)
1915	if rr.Locator32 == nil || l.err {
1916		return nil, &ParseError{f, "bad L32 Locator", l}, ""
1917	}
1918	return rr, nil, ""
1919}
1920
1921func setLP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1922	rr := new(LP)
1923	rr.Hdr = h
1924
1925	l := <-c
1926	if l.length == 0 { // dynamic update rr.
1927		return rr, nil, ""
1928	}
1929
1930	i, e := strconv.ParseUint(l.token, 10, 16)
1931	if e != nil || l.err {
1932		return nil, &ParseError{f, "bad LP Preference", l}, ""
1933	}
1934	rr.Preference = uint16(i)
1935
1936	<-c     // zBlank
1937	l = <-c // zString
1938	rr.Fqdn = l.token
1939	name, nameOk := toAbsoluteName(l.token, o)
1940	if l.err || !nameOk {
1941		return nil, &ParseError{f, "bad LP Fqdn", l}, ""
1942	}
1943	rr.Fqdn = name
1944
1945	return rr, nil, ""
1946}
1947
1948func setL64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1949	rr := new(L64)
1950	rr.Hdr = h
1951
1952	l := <-c
1953	if l.length == 0 { // dynamic update rr.
1954		return rr, nil, ""
1955	}
1956
1957	i, e := strconv.ParseUint(l.token, 10, 16)
1958	if e != nil || l.err {
1959		return nil, &ParseError{f, "bad L64 Preference", l}, ""
1960	}
1961	rr.Preference = uint16(i)
1962	<-c     // zBlank
1963	l = <-c // zString
1964	u, err := stringToNodeID(l)
1965	if err != nil || l.err {
1966		return nil, err, ""
1967	}
1968	rr.Locator64 = u
1969	return rr, nil, ""
1970}
1971
1972func setUID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1973	rr := new(UID)
1974	rr.Hdr = h
1975
1976	l := <-c
1977	if l.length == 0 { // dynamic update rr.
1978		return rr, nil, ""
1979	}
1980
1981	i, e := strconv.ParseUint(l.token, 10, 32)
1982	if e != nil || l.err {
1983		return nil, &ParseError{f, "bad UID Uid", l}, ""
1984	}
1985	rr.Uid = uint32(i)
1986	return rr, nil, ""
1987}
1988
1989func setGID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1990	rr := new(GID)
1991	rr.Hdr = h
1992
1993	l := <-c
1994	if l.length == 0 { // dynamic update rr.
1995		return rr, nil, ""
1996	}
1997
1998	i, e := strconv.ParseUint(l.token, 10, 32)
1999	if e != nil || l.err {
2000		return nil, &ParseError{f, "bad GID Gid", l}, ""
2001	}
2002	rr.Gid = uint32(i)
2003	return rr, nil, ""
2004}
2005
2006func setUINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
2007	rr := new(UINFO)
2008	rr.Hdr = h
2009
2010	s, e, c1 := endingToTxtSlice(c, "bad UINFO Uinfo", f)
2011	if e != nil {
2012		return nil, e, c1
2013	}
2014	if ln := len(s); ln == 0 {
2015		return rr, nil, c1
2016	}
2017	rr.Uinfo = s[0] // silently discard anything after the first character-string
2018	return rr, nil, c1
2019}
2020
2021func setPX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
2022	rr := new(PX)
2023	rr.Hdr = h
2024
2025	l := <-c
2026	if l.length == 0 { // dynamic update rr.
2027		return rr, nil, ""
2028	}
2029
2030	i, e := strconv.ParseUint(l.token, 10, 16)
2031	if e != nil || l.err {
2032		return nil, &ParseError{f, "bad PX Preference", l}, ""
2033	}
2034	rr.Preference = uint16(i)
2035
2036	<-c     // zBlank
2037	l = <-c // zString
2038	rr.Map822 = l.token
2039	map822, map822Ok := toAbsoluteName(l.token, o)
2040	if l.err || !map822Ok {
2041		return nil, &ParseError{f, "bad PX Map822", l}, ""
2042	}
2043	rr.Map822 = map822
2044
2045	<-c     // zBlank
2046	l = <-c // zString
2047	rr.Mapx400 = l.token
2048	mapx400, mapx400Ok := toAbsoluteName(l.token, o)
2049	if l.err || !mapx400Ok {
2050		return nil, &ParseError{f, "bad PX Mapx400", l}, ""
2051	}
2052	rr.Mapx400 = mapx400
2053
2054	return rr, nil, ""
2055}
2056
2057func setCAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
2058	rr := new(CAA)
2059	rr.Hdr = h
2060
2061	l := <-c
2062	if l.length == 0 { // dynamic update rr.
2063		return rr, nil, l.comment
2064	}
2065
2066	i, err := strconv.ParseUint(l.token, 10, 8)
2067	if err != nil || l.err {
2068		return nil, &ParseError{f, "bad CAA Flag", l}, ""
2069	}
2070	rr.Flag = uint8(i)
2071
2072	<-c     // zBlank
2073	l = <-c // zString
2074	if l.value != zString {
2075		return nil, &ParseError{f, "bad CAA Tag", l}, ""
2076	}
2077	rr.Tag = l.token
2078
2079	<-c // zBlank
2080	s, e, c1 := endingToTxtSlice(c, "bad CAA Value", f)
2081	if e != nil {
2082		return nil, e, ""
2083	}
2084	if len(s) != 1 {
2085		return nil, &ParseError{f, "bad CAA Value", l}, ""
2086	}
2087	rr.Value = s[0]
2088	return rr, nil, c1
2089}
2090
2091func setTKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
2092	rr := new(TKEY)
2093	rr.Hdr = h
2094
2095	l := <-c
2096
2097	// Algorithm
2098	if l.value != zString {
2099		return nil, &ParseError{f, "bad TKEY algorithm", l}, ""
2100	}
2101	rr.Algorithm = l.token
2102	<-c // zBlank
2103
2104	// Get the key length and key values
2105	l = <-c
2106	i, err := strconv.ParseUint(l.token, 10, 8)
2107	if err != nil || l.err {
2108		return nil, &ParseError{f, "bad TKEY key length", l}, ""
2109	}
2110	rr.KeySize = uint16(i)
2111	<-c // zBlank
2112	l = <-c
2113	if l.value != zString {
2114		return nil, &ParseError{f, "bad TKEY key", l}, ""
2115	}
2116	rr.Key = l.token
2117	<-c // zBlank
2118
2119	// Get the otherdata length and string data
2120	l = <-c
2121	i, err = strconv.ParseUint(l.token, 10, 8)
2122	if err != nil || l.err {
2123		return nil, &ParseError{f, "bad TKEY otherdata length", l}, ""
2124	}
2125	rr.OtherLen = uint16(i)
2126	<-c // zBlank
2127	l = <-c
2128	if l.value != zString {
2129		return nil, &ParseError{f, "bad TKEY otherday", l}, ""
2130	}
2131	rr.OtherData = l.token
2132
2133	return rr, nil, ""
2134}
2135
2136var typeToparserFunc = map[uint16]parserFunc{
2137	TypeAAAA:       {setAAAA, false},
2138	TypeAFSDB:      {setAFSDB, false},
2139	TypeA:          {setA, false},
2140	TypeCAA:        {setCAA, true},
2141	TypeCDS:        {setCDS, true},
2142	TypeCDNSKEY:    {setCDNSKEY, true},
2143	TypeCERT:       {setCERT, true},
2144	TypeCNAME:      {setCNAME, false},
2145	TypeCSYNC:      {setCSYNC, true},
2146	TypeDHCID:      {setDHCID, true},
2147	TypeDLV:        {setDLV, true},
2148	TypeDNAME:      {setDNAME, false},
2149	TypeKEY:        {setKEY, true},
2150	TypeDNSKEY:     {setDNSKEY, true},
2151	TypeDS:         {setDS, true},
2152	TypeEID:        {setEID, true},
2153	TypeEUI48:      {setEUI48, false},
2154	TypeEUI64:      {setEUI64, false},
2155	TypeGID:        {setGID, false},
2156	TypeGPOS:       {setGPOS, false},
2157	TypeHINFO:      {setHINFO, true},
2158	TypeHIP:        {setHIP, true},
2159	TypeKX:         {setKX, false},
2160	TypeL32:        {setL32, false},
2161	TypeL64:        {setL64, false},
2162	TypeLOC:        {setLOC, true},
2163	TypeLP:         {setLP, false},
2164	TypeMB:         {setMB, false},
2165	TypeMD:         {setMD, false},
2166	TypeMF:         {setMF, false},
2167	TypeMG:         {setMG, false},
2168	TypeMINFO:      {setMINFO, false},
2169	TypeMR:         {setMR, false},
2170	TypeMX:         {setMX, false},
2171	TypeNAPTR:      {setNAPTR, false},
2172	TypeNID:        {setNID, false},
2173	TypeNIMLOC:     {setNIMLOC, true},
2174	TypeNINFO:      {setNINFO, true},
2175	TypeNSAPPTR:    {setNSAPPTR, false},
2176	TypeNSEC3PARAM: {setNSEC3PARAM, false},
2177	TypeNSEC3:      {setNSEC3, true},
2178	TypeNSEC:       {setNSEC, true},
2179	TypeNS:         {setNS, false},
2180	TypeOPENPGPKEY: {setOPENPGPKEY, true},
2181	TypePTR:        {setPTR, false},
2182	TypePX:         {setPX, false},
2183	TypeSIG:        {setSIG, true},
2184	TypeRKEY:       {setRKEY, true},
2185	TypeRP:         {setRP, false},
2186	TypeRRSIG:      {setRRSIG, true},
2187	TypeRT:         {setRT, false},
2188	TypeSMIMEA:     {setSMIMEA, true},
2189	TypeSOA:        {setSOA, false},
2190	TypeSPF:        {setSPF, true},
2191	TypeAVC:        {setAVC, true},
2192	TypeSRV:        {setSRV, false},
2193	TypeSSHFP:      {setSSHFP, true},
2194	TypeTALINK:     {setTALINK, false},
2195	TypeTA:         {setTA, true},
2196	TypeTLSA:       {setTLSA, true},
2197	TypeTXT:        {setTXT, true},
2198	TypeUID:        {setUID, false},
2199	TypeUINFO:      {setUINFO, true},
2200	TypeURI:        {setURI, true},
2201	TypeX25:        {setX25, false},
2202	TypeTKEY:       {setTKEY, true},
2203}
2204