dns/zscan_rr.go
Miek Gieben ef732d1050 RRSIGs: parse epoch timestamp too
According to RFC4034 the timestamp in RRSIG may also be an EPOCH.
Check for this when parsing. Knot DNS zone dumps contain timestamp
RRSIG, this makes those parseable by Go DNS.
2014-01-11 08:50:10 +00:00

2093 lines
44 KiB
Go

// Copyright 2011 Miek Gieben. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package dns
import (
"encoding/base64"
"net"
"strconv"
"strings"
)
// Parse the rdata of each rrtype.
// All data from the channel c is either _STRING or _BLANK.
// After the rdata there may come a _BLANK and then a _NEWLINE
// or immediately a _NEWLINE. If this is not the case we flag
// an *ParseError: garbage after rdata.
func setRR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
var r RR
e := new(ParseError)
switch h.Rrtype {
case TypeA:
r, e = setA(h, c, f)
goto Slurp
case TypeAAAA:
r, e = setAAAA(h, c, f)
goto Slurp
case TypeHINFO:
r, e = setHINFO(h, c, f)
goto Slurp
case TypeMINFO:
r, e = setMINFO(h, c, o, f)
goto Slurp
case TypeNS:
r, e = setNS(h, c, o, f)
goto Slurp
case TypePTR:
r, e = setPTR(h, c, o, f)
goto Slurp
case TypeMF:
r, e = setMF(h, c, o, f)
goto Slurp
case TypeMD:
r, e = setMD(h, c, o, f)
goto Slurp
case TypeMG:
r, e = setMG(h, c, o, f)
goto Slurp
case TypeRT:
r, e = setRT(h, c, o, f)
goto Slurp
case TypeAFSDB:
r, e = setAFSDB(h, c, o, f)
goto Slurp
case TypeX25:
r, e = setX25(h, c, f)
goto Slurp
case TypeMX:
r, e = setMX(h, c, o, f)
goto Slurp
case TypeCNAME:
r, e = setCNAME(h, c, o, f)
goto Slurp
case TypeDNAME:
r, e = setDNAME(h, c, o, f)
goto Slurp
case TypeSOA:
r, e = setSOA(h, c, o, f)
goto Slurp
case TypeSSHFP:
r, e = setSSHFP(h, c, f)
goto Slurp
case TypeSRV:
r, e = setSRV(h, c, o, f)
goto Slurp
case TypeNAPTR:
r, e = setNAPTR(h, c, o, f)
goto Slurp
case TypeTALINK:
r, e = setTALINK(h, c, o, f)
goto Slurp
case TypeRP:
r, e = setRP(h, c, o, f)
goto Slurp
case TypeMR:
r, e = setMR(h, c, o, f)
goto Slurp
case TypeMB:
r, e = setMB(h, c, o, f)
goto Slurp
case TypeKX:
r, e = setKX(h, c, o, f)
goto Slurp
case TypeNID:
r, e = setNID(h, c, f)
goto Slurp
case TypeL32:
r, e = setL32(h, c, f)
goto Slurp
case TypeL64:
r, e = setL64(h, c, f)
goto Slurp
case TypeLP:
r, e = setLP(h, c, o, f)
goto Slurp
case TypeNSEC3PARAM:
r, e = setNSEC3PARAM(h, c, f)
goto Slurp
case TypeEUI48:
r, e = setEUI48(h, c, f)
goto Slurp
case TypeEUI64:
r, e = setEUI64(h, c, f)
goto Slurp
case TypeUID:
r, e = setUID(h, c, f)
goto Slurp
case TypeGID:
r, e = setGID(h, c, f)
goto Slurp
case TypeLOC:
r, e = setLOC(h, c, f)
goto Slurp
case TypeNSAPPTR:
r, e = setNSAPPTR(h, c, o, f)
goto Slurp
case TypeGPOS:
r, e = setGPOS(h, c, f)
goto Slurp
case TypePX:
r, e = setPX(h, c, o, f)
goto Slurp
// These types have a variable ending: either chunks of txt or chunks/base64 or hex.
// They need to search for the end of the RR themselves, hence they look for the ending
// newline. Thus there is no need to slurp the remainder, because there is none.
case TypeEID:
return setEID(h, c, f)
case TypeNIMLOC:
return setNIMLOC(h, c, f)
case TypeNSAP:
return setNSAP(h, c, f)
case TypeDNSKEY:
return setDNSKEY(h, c, f)
case TypeRKEY:
return setRKEY(h, c, f)
case TypeRRSIG:
return setRRSIG(h, c, o, f)
case TypeNSEC:
return setNSEC(h, c, o, f)
case TypeNSEC3:
return setNSEC3(h, c, o, f)
case TypeWKS:
return setWKS(h, c, f)
case TypeDS:
return setDS(h, c, f)
case TypeCDS:
return setCDS(h, c, f)
case TypeDLV:
return setDLV(h, c, f)
case TypeTA:
return setTA(h, c, f)
case TypeTLSA:
return setTLSA(h, c, f)
case TypeTXT:
return setTXT(h, c, f)
case TypeURI:
return setURI(h, c, f)
case TypeNINFO:
return setNINFO(h, c, f)
case TypeHIP:
return setHIP(h, c, o, f)
case TypeSPF:
return setSPF(h, c, f)
case TypeDHCID:
return setDHCID(h, c, f)
case TypeIPSECKEY:
return setIPSECKEY(h, c, o, f)
case TypeUINFO:
return setUINFO(h, c, f)
case TypeCERT:
return setCERT(h, c, f)
default:
// RFC3957 RR (Unknown RR handling)
return setRFC3597(h, c, f)
}
Slurp:
if e != nil {
return nil, e, ""
}
se, com := slurpRemainder(c, f)
if se != nil {
return nil, se, ""
}
return r, e, com
}
// A remainder of the rdata with embedded spaces, return the parsed string (sans the spaces)
// or an error
func endingToString(c chan lex, errstr, f string) (string, *ParseError, string) {
s := ""
l := <-c // _STRING
for l.value != _NEWLINE && l.value != _EOF {
switch l.value {
case _STRING:
s += l.token
case _BLANK: // Ok
default:
return "", &ParseError{f, errstr, l}, ""
}
l = <-c
}
return s, nil, l.comment
}
// A remainder of the rdata with embedded spaces, return the parsed string slice (sans the spaces)
// or an error
func endingToTxtSlice(c chan lex, errstr, f string) ([]string, *ParseError, string) {
// Get the remaining data until we see a NEWLINE
quote := false
l := <-c
var s []string
switch l.value == _QUOTE {
case true: // A number of quoted string
s = make([]string, 0)
empty := true
for l.value != _NEWLINE && l.value != _EOF {
switch l.value {
case _STRING:
empty = false
s = append(s, l.token)
case _BLANK:
if quote {
// _BLANK can only be seen in between txt parts.
return nil, &ParseError{f, errstr, l}, ""
}
case _QUOTE:
if empty && quote {
s = append(s, "")
}
quote = !quote
empty = true
default:
return nil, &ParseError{f, errstr, l}, ""
}
l = <-c
}
if quote {
return nil, &ParseError{f, errstr, l}, ""
}
case false: // Unquoted text record
s = make([]string, 1)
for l.value != _NEWLINE && l.value != _EOF {
s[0] += l.token
l = <-c
}
}
return s, nil, l.comment
}
func setA(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(A)
rr.Hdr = h
l := <-c
rr.A = net.ParseIP(l.token)
if rr.A == nil {
return nil, &ParseError{f, "bad A A", l}
}
return rr, nil
}
func setAAAA(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(AAAA)
rr.Hdr = h
l := <-c
rr.AAAA = net.ParseIP(l.token)
if rr.AAAA == nil {
return nil, &ParseError{f, "bad AAAA AAAA", l}
}
return rr, nil
}
func setNS(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(NS)
rr.Hdr = h
l := <-c
rr.Ns = l.token
if l.token == "@" {
rr.Ns = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad NS Ns", l}
}
if rr.Ns[l.length-1] != '.' {
rr.Ns = appendOrigin(rr.Ns, o)
}
return rr, nil
}
func setPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(PTR)
rr.Hdr = h
l := <-c
rr.Ptr = l.token
if l.token == "@" {
rr.Ptr = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad PTR Ptr", l}
}
if rr.Ptr[l.length-1] != '.' {
rr.Ptr = appendOrigin(rr.Ptr, o)
}
return rr, nil
}
func setNSAPPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(NSAPPTR)
rr.Hdr = h
l := <-c
rr.Ptr = l.token
if l.token == "@" {
rr.Ptr = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad NSAP-PTR Ptr", l}
}
if rr.Ptr[l.length-1] != '.' {
rr.Ptr = appendOrigin(rr.Ptr, o)
}
return rr, nil
}
func setRP(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(RP)
rr.Hdr = h
l := <-c
rr.Mbox = l.token
if l.token == "@" {
rr.Mbox = o
} else {
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad RP Mbox", l}
}
if rr.Mbox[l.length-1] != '.' {
rr.Mbox = appendOrigin(rr.Mbox, o)
}
}
<-c // _BLANK
l = <-c
rr.Txt = l.token
if l.token == "@" {
rr.Txt = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad RP Txt", l}
}
if rr.Txt[l.length-1] != '.' {
rr.Txt = appendOrigin(rr.Txt, o)
}
return rr, nil
}
func setMR(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(MR)
rr.Hdr = h
l := <-c
rr.Mr = l.token
if l.token == "@" {
rr.Mr = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad MR Mr", l}
}
if rr.Mr[l.length-1] != '.' {
rr.Mr = appendOrigin(rr.Mr, o)
}
return rr, nil
}
func setMB(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(MB)
rr.Hdr = h
l := <-c
rr.Mb = l.token
if l.token == "@" {
rr.Mb = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad MB Mb", l}
}
if rr.Mb[l.length-1] != '.' {
rr.Mb = appendOrigin(rr.Mb, o)
}
return rr, nil
}
func setMG(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(MG)
rr.Hdr = h
l := <-c
rr.Mg = l.token
if l.token == "@" {
rr.Mg = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad MG Mg", l}
}
if rr.Mg[l.length-1] != '.' {
rr.Mg = appendOrigin(rr.Mg, o)
}
return rr, nil
}
func setHINFO(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(HINFO)
rr.Hdr = h
l := <-c
rr.Cpu = l.token
<-c // _BLANK
l = <-c // _STRING
rr.Os = l.token
return rr, nil
}
func setMINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(MINFO)
rr.Hdr = h
l := <-c
rr.Rmail = l.token
if l.token == "@" {
rr.Rmail = o
} else {
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad MINFO Rmail", l}
}
if rr.Rmail[l.length-1] != '.' {
rr.Rmail = appendOrigin(rr.Rmail, o)
}
}
<-c // _BLANK
l = <-c
rr.Email = l.token
if l.token == "@" {
rr.Email = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad MINFO Email", l}
}
if rr.Email[l.length-1] != '.' {
rr.Email = appendOrigin(rr.Email, o)
}
return rr, nil
}
func setMF(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(MF)
rr.Hdr = h
l := <-c
rr.Mf = l.token
if l.token == "@" {
rr.Mf = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad MF Mf", l}
}
if rr.Mf[l.length-1] != '.' {
rr.Mf = appendOrigin(rr.Mf, o)
}
return rr, nil
}
func setMD(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(MD)
rr.Hdr = h
l := <-c
rr.Md = l.token
if l.token == "@" {
rr.Md = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad MD Md", l}
}
if rr.Md[l.length-1] != '.' {
rr.Md = appendOrigin(rr.Md, o)
}
return rr, nil
}
func setMX(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(MX)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad MX Pref", l}
} else {
rr.Preference = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
rr.Mx = l.token
if l.token == "@" {
rr.Mx = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad MX Mx", l}
}
if rr.Mx[l.length-1] != '.' {
rr.Mx = appendOrigin(rr.Mx, o)
}
return rr, nil
}
func setRT(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(RT)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad RT Preference", l}
} else {
rr.Preference = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
rr.Host = l.token
if l.token == "@" {
rr.Host = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad RT Host", l}
}
if rr.Host[l.length-1] != '.' {
rr.Host = appendOrigin(rr.Host, o)
}
return rr, nil
}
func setAFSDB(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(AFSDB)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad AFSDB Subtype", l}
} else {
rr.Subtype = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
rr.Hostname = l.token
if l.token == "@" {
rr.Hostname = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad AFSDB Hostname", l}
}
if rr.Hostname[l.length-1] != '.' {
rr.Hostname = appendOrigin(rr.Hostname, o)
}
return rr, nil
}
func setX25(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(X25)
rr.Hdr = h
l := <-c
rr.PSDNAddress = l.token
return rr, nil
}
func setKX(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(KX)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad KX Pref", l}
} else {
rr.Preference = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
rr.Exchanger = l.token
if l.token == "@" {
rr.Exchanger = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad KX Exchanger", l}
}
if rr.Exchanger[l.length-1] != '.' {
rr.Exchanger = appendOrigin(rr.Exchanger, o)
}
return rr, nil
}
func setCNAME(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(CNAME)
rr.Hdr = h
l := <-c
rr.Target = l.token
if l.token == "@" {
rr.Target = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad CNAME Target", l}
}
if rr.Target[l.length-1] != '.' {
rr.Target = appendOrigin(rr.Target, o)
}
return rr, nil
}
func setDNAME(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(DNAME)
rr.Hdr = h
l := <-c
rr.Target = l.token
if l.token == "@" {
rr.Target = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad CNAME Target", l}
}
if rr.Target[l.length-1] != '.' {
rr.Target = appendOrigin(rr.Target, o)
}
return rr, nil
}
func setSOA(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(SOA)
rr.Hdr = h
l := <-c
rr.Ns = l.token
<-c // _BLANK
if l.token == "@" {
rr.Ns = o
} else {
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad SOA Ns", l}
}
if rr.Ns[l.length-1] != '.' {
rr.Ns = appendOrigin(rr.Ns, o)
}
}
l = <-c
rr.Mbox = l.token
if l.token == "@" {
rr.Mbox = o
} else {
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad SOA Mbox", l}
}
if rr.Mbox[l.length-1] != '.' {
rr.Mbox = appendOrigin(rr.Mbox, o)
}
}
<-c // _BLANK
var (
v uint32
ok bool
)
for i := 0; i < 5; i++ {
l = <-c
if j, e := strconv.Atoi(l.token); e != nil {
if i == 0 {
// Serial should be a number
return nil, &ParseError{f, "bad SOA zone parameter", l}
}
if v, ok = stringToTtl(l.token); !ok {
return nil, &ParseError{f, "bad SOA zone parameter", l}
}
} else {
v = uint32(j)
}
switch i {
case 0:
rr.Serial = v
<-c // _BLANK
case 1:
rr.Refresh = v
<-c // _BLANK
case 2:
rr.Retry = v
<-c // _BLANK
case 3:
rr.Expire = v
<-c // _BLANK
case 4:
rr.Minttl = v
}
}
return rr, nil
}
func setSRV(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(SRV)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad SRV Priority", l}
} else {
rr.Priority = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad SRV Weight", l}
} else {
rr.Weight = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad SRV Port", l}
} else {
rr.Port = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
rr.Target = l.token
if l.token == "@" {
rr.Target = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad SRV Target", l}
}
if rr.Target[l.length-1] != '.' {
rr.Target = appendOrigin(rr.Target, o)
}
return rr, nil
}
func setNAPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(NAPTR)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad NAPTR Order", l}
} else {
rr.Order = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad NAPTR Preference", l}
} else {
rr.Preference = uint16(i)
}
// Flags
<-c // _BLANK
l = <-c // _QUOTE
if l.value != _QUOTE {
return nil, &ParseError{f, "bad NAPTR Flags", l}
}
l = <-c // Either String or Quote
if l.value == _STRING {
rr.Flags = l.token
l = <-c // _QUOTE
if l.value != _QUOTE {
return nil, &ParseError{f, "bad NAPTR Flags", l}
}
} else if l.value == _QUOTE {
rr.Flags = ""
} else {
return nil, &ParseError{f, "bad NAPTR Flags", l}
}
// Service
<-c // _BLANK
l = <-c // _QUOTE
if l.value != _QUOTE {
return nil, &ParseError{f, "bad NAPTR Service", l}
}
l = <-c // Either String or Quote
if l.value == _STRING {
rr.Service = l.token
l = <-c // _QUOTE
if l.value != _QUOTE {
return nil, &ParseError{f, "bad NAPTR Service", l}
}
} else if l.value == _QUOTE {
rr.Service = ""
} else {
return nil, &ParseError{f, "bad NAPTR Service", l}
}
// Regexp
<-c // _BLANK
l = <-c // _QUOTE
if l.value != _QUOTE {
return nil, &ParseError{f, "bad NAPTR Regexp", l}
}
l = <-c // Either String or Quote
if l.value == _STRING {
rr.Regexp = l.token
l = <-c // _QUOTE
if l.value != _QUOTE {
return nil, &ParseError{f, "bad NAPTR Regexp", l}
}
} else if l.value == _QUOTE {
rr.Regexp = ""
} else {
return nil, &ParseError{f, "bad NAPTR Regexp", l}
}
// After quote no space??
<-c // _BLANK
l = <-c // _STRING
rr.Replacement = l.token
if l.token == "@" {
rr.Replacement = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad NAPTR Replacement", l}
}
if rr.Replacement[l.length-1] != '.' {
rr.Replacement = appendOrigin(rr.Replacement, o)
}
return rr, nil
}
func setTALINK(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(TALINK)
rr.Hdr = h
l := <-c
rr.PreviousName = l.token
if l.token == "@" {
rr.PreviousName = o
} else {
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad TALINK PreviousName", l}
}
if rr.PreviousName[l.length-1] != '.' {
rr.PreviousName = appendOrigin(rr.PreviousName, o)
}
}
<-c // _BLANK
l = <-c
rr.NextName = l.token
if l.token == "@" {
rr.NextName = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad TALINK NextName", l}
}
if rr.NextName[l.length-1] != '.' {
rr.NextName = appendOrigin(rr.NextName, o)
}
return rr, nil
}
func setLOC(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(LOC)
rr.Hdr = h
// Non zero defaults for LOC record, see RFC 1876, Section 3.
rr.HorizPre = 165 // 10000
rr.VertPre = 162 // 10
rr.Size = 18 // 1
ok := false
// North
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad LOC Latitude", l}
} else {
rr.Latitude = 1000 * 60 * 60 * uint32(i)
}
<-c // _BLANK
// Either number, 'N' or 'S'
l = <-c
if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok {
goto East
}
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad LOC Latitude minutes", l}
} else {
rr.Latitude += 1000 * 60 * uint32(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.ParseFloat(l.token, 32); e != nil {
return nil, &ParseError{f, "bad LOC Latitude seconds", l}
} else {
rr.Latitude += uint32(1000 * i)
}
<-c // _BLANK
// Either number, 'N' or 'S'
l = <-c
if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok {
goto East
}
// If still alive, flag an error
return nil, &ParseError{f, "bad LOC Latitude North/South", l}
East:
// East
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad LOC Longitude", l}
} else {
rr.Longitude = 1000 * 60 * 60 * uint32(i)
}
<-c // _BLANK
// Either number, 'E' or 'W'
l = <-c
if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok {
goto Altitude
}
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad LOC Longitude minutes", l}
} else {
rr.Longitude += 1000 * 60 * uint32(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.ParseFloat(l.token, 32); e != nil {
return nil, &ParseError{f, "bad LOC Longitude seconds", l}
} else {
rr.Longitude += uint32(1000 * i)
}
<-c // _BLANK
// Either number, 'E' or 'W'
l = <-c
if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok {
goto Altitude
}
// If still alive, flag an error
return nil, &ParseError{f, "bad LOC Longitude East/West", l}
Altitude:
<-c // _BLANK
l = <-c
if l.token[len(l.token)-1] == 'M' || l.token[len(l.token)-1] == 'm' {
l.token = l.token[0 : len(l.token)-1]
}
if i, e := strconv.ParseFloat(l.token, 32); e != nil {
return nil, &ParseError{f, "bad LOC Altitude", l}
} else {
rr.Altitude = uint32(i*100.0 + 10000000.0 + 0.5)
}
// And now optionally the other values
l = <-c
count := 0
for l.value != _NEWLINE && l.value != _EOF {
switch l.value {
case _STRING:
switch count {
case 0: // Size
if e, m, ok := stringToCm(l.token); !ok {
return nil, &ParseError{f, "bad LOC Size", l}
} else {
rr.Size = (e & 0x0f) | (m << 4 & 0xf0)
}
case 1: // HorizPre
if e, m, ok := stringToCm(l.token); !ok {
return nil, &ParseError{f, "bad LOC HorizPre", l}
} else {
rr.HorizPre = (e & 0x0f) | (m << 4 & 0xf0)
}
case 2: // VertPre
if e, m, ok := stringToCm(l.token); !ok {
return nil, &ParseError{f, "bad LOC VertPre", l}
} else {
rr.VertPre = (e & 0x0f) | (m << 4 & 0xf0)
}
}
count++
case _BLANK:
// Ok
default:
return nil, &ParseError{f, "bad LOC Size, HorizPre or VertPre", l}
}
l = <-c
}
return rr, nil
}
func setHIP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr := new(HIP)
rr.Hdr = h
// HitLength is not represented
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad HIP PublicKeyAlgorithm", l}, ""
} else {
rr.PublicKeyAlgorithm = uint8(i)
}
<-c // _BLANK
l = <-c // _STRING
rr.Hit = l.token // This can not contain spaces, see RFC 5205 Section 6.
rr.HitLength = uint8(len(rr.Hit)) / 2
<-c // _BLANK
l = <-c // _STRING
rr.PublicKey = l.token // This cannot contain spaces
rr.PublicKeyLength = uint16(base64.StdEncoding.DecodedLen(len(rr.PublicKey)))
// RendezvousServers (if any)
l = <-c
xs := make([]string, 0)
for l.value != _NEWLINE && l.value != _EOF {
switch l.value {
case _STRING:
if l.token == "@" {
xs = append(xs, o)
continue
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad HIP RendezvousServers", l}, ""
}
if l.token[l.length-1] != '.' {
l.token = appendOrigin(l.token, o)
}
xs = append(xs, l.token)
case _BLANK:
// Ok
default:
return nil, &ParseError{f, "bad HIP RendezvousServers", l}, ""
}
l = <-c
}
rr.RendezvousServers = xs
return rr, nil, l.comment
}
func setCERT(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(CERT)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad CERT Type", l}, ""
} else {
rr.Type = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad CERT KeyTag", l}, ""
} else {
rr.KeyTag = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad CERT Algorithm", l}, ""
} else {
rr.Algorithm = uint8(i)
}
s, e, c1 := endingToString(c, "bad CERT Certificate", f)
if e != nil {
return nil, e, c1
}
rr.Certificate = s
return rr, nil, c1
}
func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr := new(RRSIG)
rr.Hdr = h
l := <-c
if t, ok := StringToType[strings.ToUpper(l.token)]; !ok {
if strings.HasPrefix(strings.ToUpper(l.token), "TYPE") {
if t, ok = typeToInt(l.token); !ok {
return nil, &ParseError{f, "bad RRSIG Typecovered", l}, ""
} else {
rr.TypeCovered = t
}
} else {
return nil, &ParseError{f, "bad RRSIG Typecovered", l}, ""
}
} else {
rr.TypeCovered = t
}
<-c // _BLANK
l = <-c
if i, err := strconv.Atoi(l.token); err != nil {
return nil, &ParseError{f, "bad RRSIG Algorithm", l}, ""
} else {
rr.Algorithm = uint8(i)
}
<-c // _BLANK
l = <-c
if i, err := strconv.Atoi(l.token); err != nil {
return nil, &ParseError{f, "bad RRSIG Labels", l}, ""
} else {
rr.Labels = uint8(i)
}
<-c // _BLANK
l = <-c
if i, err := strconv.Atoi(l.token); err != nil {
return nil, &ParseError{f, "bad RRSIG OrigTtl", l}, ""
} else {
rr.OrigTtl = uint32(i)
}
<-c // _BLANK
l = <-c
if i, err := StringToTime(l.token); err != nil {
// Try to see if all numeric and use it as epoch
if i, err := strconv.ParseInt(l.token, 10, 64); err == nil {
// TODO(miek): error out on > MAX_UINT32, same below
rr.Expiration = uint32(i)
} else {
return nil, &ParseError{f, "bad RRSIG Expiration", l}, ""
}
} else {
rr.Expiration = i
}
<-c // _BLANK
l = <-c
if i, err := StringToTime(l.token); err != nil {
if i, err := strconv.ParseInt(l.token, 10, 64); err == nil {
rr.Inception = uint32(i)
} else {
return nil, &ParseError{f, "bad RRSIG Inception", l}, ""
}
} else {
rr.Inception = i
}
<-c // _BLANK
l = <-c
if i, err := strconv.Atoi(l.token); err != nil {
return nil, &ParseError{f, "bad RRSIG KeyTag", l}, ""
} else {
rr.KeyTag = uint16(i)
}
<-c // _BLANK
l = <-c
rr.SignerName = l.token
if l.token == "@" {
rr.SignerName = o
} else {
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad RRSIG SignerName", l}, ""
}
if rr.SignerName[l.length-1] != '.' {
rr.SignerName = appendOrigin(rr.SignerName, o)
}
}
s, e, c1 := endingToString(c, "bad RRSIG Signature", f)
if e != nil {
return nil, e, c1
}
rr.Signature = s
return rr, nil, c1
}
func setNSEC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr := new(NSEC)
rr.Hdr = h
l := <-c
rr.NextDomain = l.token
if l.token == "@" {
rr.NextDomain = o
} else {
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad NSEC NextDomain", l}, ""
}
if rr.NextDomain[l.length-1] != '.' {
rr.NextDomain = appendOrigin(rr.NextDomain, o)
}
}
rr.TypeBitMap = make([]uint16, 0)
var (
k uint16
ok bool
)
l = <-c
for l.value != _NEWLINE && l.value != _EOF {
switch l.value {
case _BLANK:
// Ok
case _STRING:
if k, ok = StringToType[strings.ToUpper(l.token)]; !ok {
if k, ok = typeToInt(l.token); !ok {
return nil, &ParseError{f, "bad NSEC TypeBitMap", l}, ""
}
}
rr.TypeBitMap = append(rr.TypeBitMap, k)
default:
return nil, &ParseError{f, "bad NSEC TypeBitMap", l}, ""
}
l = <-c
}
return rr, nil, l.comment
}
func setNSEC3(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr := new(NSEC3)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad NSEC3 Hash", l}, ""
} else {
rr.Hash = uint8(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad NSEC3 Flags", l}, ""
} else {
rr.Flags = uint8(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad NSEC3 Iterations", l}, ""
} else {
rr.Iterations = uint16(i)
}
<-c
l = <-c
if len(l.token) == 0 {
return nil, &ParseError{f, "bad NSEC3 Salt", l}, ""
}
rr.SaltLength = uint8(len(l.token)) / 2
rr.Salt = l.token
<-c
l = <-c
rr.HashLength = 20 // Fix for NSEC3 (sha1 160 bits)
rr.NextDomain = l.token
rr.TypeBitMap = make([]uint16, 0)
var (
k uint16
ok bool
)
l = <-c
for l.value != _NEWLINE && l.value != _EOF {
switch l.value {
case _BLANK:
// Ok
case _STRING:
if k, ok = StringToType[strings.ToUpper(l.token)]; !ok {
if k, ok = typeToInt(l.token); !ok {
return nil, &ParseError{f, "bad NSEC3 TypeBitMap", l}, ""
}
}
rr.TypeBitMap = append(rr.TypeBitMap, k)
default:
return nil, &ParseError{f, "bad NSEC3 TypeBitMap", l}, ""
}
l = <-c
}
return rr, nil, l.comment
}
func setNSEC3PARAM(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(NSEC3PARAM)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad NSEC3PARAM Hash", l}
} else {
rr.Hash = uint8(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad NSEC3PARAM Flags", l}
} else {
rr.Flags = uint8(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad NSEC3PARAM Iterations", l}
} else {
rr.Iterations = uint16(i)
}
<-c
l = <-c
rr.SaltLength = uint8(len(l.token))
rr.Salt = l.token
return rr, nil
}
func setEUI48(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(EUI48)
rr.Hdr = h
l := <-c
if len(l.token) != 17 {
return nil, &ParseError{f, "bad EUI48 Address", l}
}
addr := make([]byte, 12)
dash := 0
for i := 0; i < 10; i += 2 {
addr[i] = l.token[i+dash]
addr[i+1] = l.token[i+1+dash]
dash++
if l.token[i+1+dash] != '-' {
return nil, &ParseError{f, "bad EUI48 Address", l}
}
}
addr[10] = l.token[15]
addr[11] = l.token[16]
if i, e := strconv.ParseUint(string(addr), 16, 48); e != nil {
return nil, &ParseError{f, "bad EUI48 Address", l}
} else {
rr.Address = i
}
return rr, nil
}
func setEUI64(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(EUI64)
rr.Hdr = h
l := <-c
if len(l.token) != 23 {
return nil, &ParseError{f, "bad EUI64 Address", l}
}
addr := make([]byte, 16)
dash := 0
for i := 0; i < 14; i += 2 {
addr[i] = l.token[i+dash]
addr[i+1] = l.token[i+1+dash]
dash++
if l.token[i+1+dash] != '-' {
return nil, &ParseError{f, "bad EUI64 Address", l}
}
}
addr[14] = l.token[21]
addr[15] = l.token[22]
if i, e := strconv.ParseUint(string(addr), 16, 64); e != nil {
return nil, &ParseError{f, "bad EUI68 Address", l}
} else {
rr.Address = uint64(i)
}
return rr, nil
}
func setWKS(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(WKS)
rr.Hdr = h
l := <-c
rr.Address = net.ParseIP(l.token)
if rr.Address == nil {
return nil, &ParseError{f, "bad WKS Address", l}, ""
}
<-c // _BLANK
l = <-c
proto := "tcp"
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad WKS Protocol", l}, ""
} else {
rr.Protocol = uint8(i)
switch rr.Protocol {
case 17:
proto = "udp"
case 6:
proto = "tcp"
default:
return nil, &ParseError{f, "bad WKS Protocol", l}, ""
}
}
<-c
l = <-c
rr.BitMap = make([]uint16, 0)
var (
k int
err error
)
for l.value != _NEWLINE && l.value != _EOF {
switch l.value {
case _BLANK:
// Ok
case _STRING:
if k, err = net.LookupPort(proto, l.token); err != nil {
if i, e := strconv.Atoi(l.token); e != nil { // If a number use that
rr.BitMap = append(rr.BitMap, uint16(i))
} else {
return nil, &ParseError{f, "bad WKS BitMap", l}, ""
}
}
rr.BitMap = append(rr.BitMap, uint16(k))
default:
return nil, &ParseError{f, "bad WKS BitMap", l}, ""
}
l = <-c
}
return rr, nil, l.comment
}
func setSSHFP(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(SSHFP)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad SSHFP Algorithm", l}
} else {
rr.Algorithm = uint8(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad SSHFP Type", l}
} else {
rr.Type = uint8(i)
}
<-c // _BLANK
l = <-c
rr.FingerPrint = l.token
return rr, nil
}
func setDNSKEY(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(DNSKEY)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad DNSKEY Flags", l}, ""
} else {
rr.Flags = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad DNSKEY Protocol", l}, ""
} else {
rr.Protocol = uint8(i)
}
<-c // _BLANK
l = <-c // _STRING
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad DNSKEY Algorithm", l}, ""
} else {
rr.Algorithm = uint8(i)
}
s, e, c1 := endingToString(c, "bad DNSKEY PublicKey", f)
if e != nil {
return nil, e, c1
}
rr.PublicKey = s
return rr, nil, c1
}
func setRKEY(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(RKEY)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad RKEY Flags", l}, ""
} else {
rr.Flags = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad RKEY Protocol", l}, ""
} else {
rr.Protocol = uint8(i)
}
<-c // _BLANK
l = <-c // _STRING
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad RKEY Algorithm", l}, ""
} else {
rr.Algorithm = uint8(i)
}
s, e, c1 := endingToString(c, "bad RKEY PublicKey", f)
if e != nil {
return nil, e, c1
}
rr.PublicKey = s
return rr, nil, c1
}
func setDS(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(DS)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad DS KeyTag", l}, ""
} else {
rr.KeyTag = uint16(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
if i, ok := StringToAlgorithm[strings.ToUpper(l.token)]; !ok {
return nil, &ParseError{f, "bad DS Algorithm", l}, ""
} else {
rr.Algorithm = i
}
} else {
rr.Algorithm = uint8(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad DS DigestType", l}, ""
} else {
rr.DigestType = uint8(i)
}
s, e, c1 := endingToString(c, "bad DS Digest", f)
if e != nil {
return nil, e, c1
}
rr.Digest = s
return rr, nil, c1
}
func setEID(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(EID)
rr.Hdr = h
s, e, c1 := endingToString(c, "bad EID Endpoint", f)
if e != nil {
return nil, e, c1
}
rr.Endpoint = s
return rr, nil, c1
}
func setNIMLOC(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(NIMLOC)
rr.Hdr = h
s, e, c1 := endingToString(c, "bad NIMLOC Locator", f)
if e != nil {
return nil, e, c1
}
rr.Locator = s
return rr, nil, c1
}
func setNSAP(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(NSAP)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad NSAP Length", l}, ""
} else {
rr.Length = uint8(i)
}
<-c // _BLANK
s, e, c1 := endingToString(c, "bad NSAP Nsap", f)
if e != nil {
return nil, e, c1
}
rr.Nsap = s
return rr, nil, c1
}
func setGPOS(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(GPOS)
rr.Hdr = h
l := <-c
if _, e := strconv.ParseFloat(l.token, 64); e != nil {
return nil, &ParseError{f, "bad GPOS Longitude", l}
} else {
rr.Longitude = l.token
}
<-c // _BLANK
l = <-c
if _, e := strconv.ParseFloat(l.token, 64); e != nil {
return nil, &ParseError{f, "bad GPOS Latitude", l}
} else {
rr.Latitude = l.token
}
<-c // _BLANK
l = <-c
if _, e := strconv.ParseFloat(l.token, 64); e != nil {
return nil, &ParseError{f, "bad GPOS Altitude", l}
} else {
rr.Altitude = l.token
}
return rr, nil
}
func setCDS(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(CDS)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad CDS KeyTag", l}, ""
} else {
rr.KeyTag = uint16(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
if i, ok := StringToAlgorithm[strings.ToUpper(l.token)]; !ok {
return nil, &ParseError{f, "bad CDS Algorithm", l}, ""
} else {
rr.Algorithm = i
}
} else {
rr.Algorithm = uint8(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad CDS DigestType", l}, ""
} else {
rr.DigestType = uint8(i)
}
s, e, c1 := endingToString(c, "bad CDS Digest", f)
if e != nil {
return nil, e, c1
}
rr.Digest = s
return rr, nil, c1
}
func setDLV(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(DLV)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad DLV KeyTag", l}, ""
} else {
rr.KeyTag = uint16(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
if i, ok := StringToAlgorithm[strings.ToUpper(l.token)]; !ok {
return nil, &ParseError{f, "bad DLV Algorithm", l}, ""
} else {
rr.Algorithm = i
}
} else {
rr.Algorithm = uint8(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad DLV DigestType", l}, ""
} else {
rr.DigestType = uint8(i)
}
s, e, c1 := endingToString(c, "bad DLV Digest", f)
if e != nil {
return nil, e, c1
}
rr.Digest = s
return rr, nil, c1
}
func setTA(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(TA)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad TA KeyTag", l}, ""
} else {
rr.KeyTag = uint16(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
if i, ok := StringToAlgorithm[strings.ToUpper(l.token)]; !ok {
return nil, &ParseError{f, "bad TA Algorithm", l}, ""
} else {
rr.Algorithm = i
}
} else {
rr.Algorithm = uint8(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad TA DigestType", l}, ""
} else {
rr.DigestType = uint8(i)
}
s, e, c1 := endingToString(c, "bad TA Digest", f)
if e != nil {
return nil, e, c1
}
rr.Digest = s
return rr, nil, c1
}
func setTLSA(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(TLSA)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad TLSA Usage", l}, ""
} else {
rr.Usage = uint8(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad TLSA Selector", l}, ""
} else {
rr.Selector = uint8(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad TLSA MatchingType", l}, ""
} else {
rr.MatchingType = uint8(i)
}
s, e, c1 := endingToString(c, "bad TLSA Certificate", f)
if e != nil {
return nil, e, c1
}
rr.Certificate = s
return rr, nil, c1
}
func setRFC3597(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(RFC3597)
rr.Hdr = h
l := <-c
if l.token != "\\#" {
return nil, &ParseError{f, "bad RFC3597 Rdata", l}, ""
}
<-c // _BLANK
l = <-c
rdlength, e := strconv.Atoi(l.token)
if e != nil {
return nil, &ParseError{f, "bad RFC3597 Rdata ", l}, ""
}
s, e1, c1 := endingToString(c, "bad RFC3597 Rdata", f)
if e1 != nil {
return nil, e1, c1
}
if rdlength*2 != len(s) {
return nil, &ParseError{f, "bad RFC3597 Rdata", l}, ""
}
rr.Rdata = s
return rr, nil, c1
}
func setSPF(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(SPF)
rr.Hdr = h
s, e, c1 := endingToTxtSlice(c, "bad SPF Txt", f)
if e != nil {
return nil, e, ""
}
rr.Txt = s
return rr, nil, c1
}
func setTXT(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(TXT)
rr.Hdr = h
// No _BLANK reading here, because this is all rdata is TXT
s, e, c1 := endingToTxtSlice(c, "bad TXT Txt", f)
if e != nil {
return nil, e, ""
}
rr.Txt = s
return rr, nil, c1
}
// identical to setTXT
func setNINFO(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(NINFO)
rr.Hdr = h
s, e, c1 := endingToTxtSlice(c, "bad NINFO ZSData", f)
if e != nil {
return nil, e, ""
}
rr.ZSData = s
return rr, nil, c1
}
func setURI(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(URI)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad URI Priority", l}, ""
} else {
rr.Priority = uint16(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad URI Weight", l}, ""
} else {
rr.Weight = uint16(i)
}
<-c // _BLANK
s, e, c1 := endingToTxtSlice(c, "bad URI Target", f)
if e != nil {
return nil, e, ""
}
rr.Target = s
return rr, nil, c1
}
func setIPSECKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr := new(IPSECKEY)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad IPSECKEY Precedence", l}, ""
} else {
rr.Precedence = uint8(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad IPSECKEY GatewayType", l}, ""
} else {
rr.GatewayType = uint8(i)
}
<-c // _BLANK
l = <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad IPSECKEY Algorithm", l}, ""
} else {
rr.Algorithm = uint8(i)
}
<-c
l = <-c
rr.Gateway = l.token
s, e, c1 := endingToString(c, "bad IPSECKEY PublicKey", f)
if e != nil {
return nil, e, c1
}
rr.PublicKey = s
return rr, nil, c1
}
func setDHCID(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
// awesome record to parse!
rr := new(DHCID)
rr.Hdr = h
s, e, c1 := endingToString(c, "bad DHCID Digest", f)
if e != nil {
return nil, e, c1
}
rr.Digest = s
return rr, nil, c1
}
func setNID(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(NID)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad NID Preference", l}
} else {
rr.Preference = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
u, err := stringToNodeID(l)
if err != nil {
return nil, err
}
rr.NodeID = u
return rr, nil
}
func setL32(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(L32)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad L32 Preference", l}
} else {
rr.Preference = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
rr.Locator32 = net.ParseIP(l.token)
if rr.Locator32 == nil {
return nil, &ParseError{f, "bad L32 Locator", l}
}
return rr, nil
}
func setLP(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(LP)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad LP Preference", l}
} else {
rr.Preference = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
rr.Fqdn = l.token
if l.token == "@" {
rr.Fqdn = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad LP Fqdn", l}
}
if rr.Fqdn[l.length-1] != '.' {
rr.Fqdn = appendOrigin(rr.Fqdn, o)
}
return rr, nil
}
func setL64(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(L64)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad L64 Preference", l}
} else {
rr.Preference = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
u, err := stringToNodeID(l)
if err != nil {
return nil, err
}
rr.Locator64 = u
return rr, nil
}
func setUID(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(UID)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad UID Uid", l}
} else {
rr.Uid = uint32(i)
}
return rr, nil
}
func setGID(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(GID)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad GID Gid", l}
} else {
rr.Gid = uint32(i)
}
return rr, nil
}
func setUINFO(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(UINFO)
rr.Hdr = h
s, e, c1 := endingToTxtSlice(c, "bad UINFO Uinfo", f)
if e != nil {
return nil, e, ""
}
rr.Uinfo = s[0] // silently discard anything above
return rr, nil, c1
}
func setPX(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(PX)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad PX Preference", l}
} else {
rr.Preference = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
rr.Map822 = l.token
if l.token == "@" {
rr.Map822 = o
return rr, nil
}
_, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad PX Map822", l}
}
if rr.Map822[l.length-1] != '.' {
rr.Map822 = appendOrigin(rr.Map822, o)
}
<-c // _BLANK
l = <-c // _STRING
rr.Mapx400 = l.token
if l.token == "@" {
rr.Mapx400 = o
return rr, nil
}
_, ok = IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad PX Mapx400", l}
}
if rr.Mapx400[l.length-1] != '.' {
rr.Mapx400 = appendOrigin(rr.Mapx400, o)
}
return rr, nil
}