package dns
import (
"encoding/base64"
"errors"
"fmt"
"net"
"strconv"
"strings"
)
func endingToString(c *zlexer , errstr string ) (string , *ParseError ) {
var s strings .Builder
l , _ := c .Next ()
for l .value != zNewline && l .value != zEOF {
if l .err {
return s .String (), &ParseError {err : errstr , lex : l }
}
switch l .value {
case zString :
s .WriteString (l .token )
case zBlank :
default :
return "" , &ParseError {err : errstr , lex : l }
}
l , _ = c .Next ()
}
return s .String (), nil
}
func endingToTxtSlice(c *zlexer , errstr string ) ([]string , *ParseError ) {
l , _ := c .Next ()
if l .err {
return nil , &ParseError {err : errstr , lex : l }
}
s := make ([]string , 0 )
quote := false
empty := false
for l .value != zNewline && l .value != zEOF {
if l .err {
return nil , &ParseError {err : errstr , lex : l }
}
switch l .value {
case zString :
empty = false
sx := []string {}
p := 0
for {
i , ok := escapedStringOffset (l .token [p :], 255 )
if !ok {
return nil , &ParseError {err : errstr , lex : l }
}
if i != -1 && p +i != len (l .token ) {
sx = append (sx , l .token [p :p +i ])
} else {
sx = append (sx , l .token [p :])
break
}
p += i
}
s = append (s , sx ...)
case zBlank :
if quote {
return nil , &ParseError {err : errstr , lex : l }
}
case zQuote :
if empty && quote {
s = append (s , "" )
}
quote = !quote
empty = true
default :
return nil , &ParseError {err : errstr , lex : l }
}
l , _ = c .Next ()
}
if quote {
return nil , &ParseError {err : errstr , lex : l }
}
return s , nil
}
func (rr *A ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
rr .A = net .ParseIP (l .token )
isIPv4 := !strings .Contains (l .token , ":" )
if rr .A == nil || !isIPv4 || l .err {
return &ParseError {err : "bad A A" , lex : l }
}
return slurpRemainder (c )
}
func (rr *AAAA ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
rr .AAAA = net .ParseIP (l .token )
isIPv6 := strings .Contains (l .token , ":" )
if rr .AAAA == nil || !isIPv6 || l .err {
return &ParseError {err : "bad AAAA AAAA" , lex : l }
}
return slurpRemainder (c )
}
func (rr *NS ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad NS Ns" , lex : l }
}
rr .Ns = name
return slurpRemainder (c )
}
func (rr *PTR ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad PTR Ptr" , lex : l }
}
rr .Ptr = name
return slurpRemainder (c )
}
func (rr *NSAPPTR ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad NSAP-PTR Ptr" , lex : l }
}
rr .Ptr = name
return slurpRemainder (c )
}
func (rr *RP ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
mbox , mboxOk := toAbsoluteName (l .token , o )
if l .err || !mboxOk {
return &ParseError {err : "bad RP Mbox" , lex : l }
}
rr .Mbox = mbox
c .Next ()
l , _ = c .Next ()
rr .Txt = l .token
txt , txtOk := toAbsoluteName (l .token , o )
if l .err || !txtOk {
return &ParseError {err : "bad RP Txt" , lex : l }
}
rr .Txt = txt
return slurpRemainder (c )
}
func (rr *MR ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad MR Mr" , lex : l }
}
rr .Mr = name
return slurpRemainder (c )
}
func (rr *MB ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad MB Mb" , lex : l }
}
rr .Mb = name
return slurpRemainder (c )
}
func (rr *MG ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad MG Mg" , lex : l }
}
rr .Mg = name
return slurpRemainder (c )
}
func (rr *HINFO ) parse (c *zlexer , o string ) *ParseError {
chunks , e := endingToTxtSlice (c , "bad HINFO Fields" )
if e != nil {
return e
}
if ln := len (chunks ); ln == 0 {
return nil
} else if ln == 1 {
if out := strings .Fields (chunks [0 ]); len (out ) > 1 {
chunks = out
} else {
chunks = append (chunks , "" )
}
}
rr .Cpu = chunks [0 ]
rr .Os = strings .Join (chunks [1 :], " " )
return nil
}
func (rr *ISDN ) parse (c *zlexer , o string ) *ParseError {
chunks , e := endingToTxtSlice (c , "bad ISDN Fields" )
if e != nil {
return e
}
if ln := len (chunks ); ln == 0 {
return nil
} else if ln == 1 {
if out := strings .Fields (chunks [0 ]); len (out ) > 1 {
chunks = out
} else {
chunks = append (chunks , "" )
}
}
rr .Address = chunks [0 ]
rr .SubAddress = strings .Join (chunks [1 :], " " )
return nil
}
func (rr *MINFO ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
rmail , rmailOk := toAbsoluteName (l .token , o )
if l .err || !rmailOk {
return &ParseError {err : "bad MINFO Rmail" , lex : l }
}
rr .Rmail = rmail
c .Next ()
l , _ = c .Next ()
rr .Email = l .token
email , emailOk := toAbsoluteName (l .token , o )
if l .err || !emailOk {
return &ParseError {err : "bad MINFO Email" , lex : l }
}
rr .Email = email
return slurpRemainder (c )
}
func (rr *MF ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad MF Mf" , lex : l }
}
rr .Mf = name
return slurpRemainder (c )
}
func (rr *MD ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad MD Md" , lex : l }
}
rr .Md = name
return slurpRemainder (c )
}
func (rr *MX ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil || l .err {
return &ParseError {err : "bad MX Pref" , lex : l }
}
rr .Preference = uint16 (i )
c .Next ()
l , _ = c .Next ()
rr .Mx = l .token
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad MX Mx" , lex : l }
}
rr .Mx = name
return slurpRemainder (c )
}
func (rr *RT ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil {
return &ParseError {err : "bad RT Preference" , lex : l }
}
rr .Preference = uint16 (i )
c .Next ()
l , _ = c .Next ()
rr .Host = l .token
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad RT Host" , lex : l }
}
rr .Host = name
return slurpRemainder (c )
}
func (rr *AFSDB ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil || l .err {
return &ParseError {err : "bad AFSDB Subtype" , lex : l }
}
rr .Subtype = uint16 (i )
c .Next ()
l , _ = c .Next ()
rr .Hostname = l .token
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad AFSDB Hostname" , lex : l }
}
rr .Hostname = name
return slurpRemainder (c )
}
func (rr *X25 ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
if l .err {
return &ParseError {err : "bad X25 PSDNAddress" , lex : l }
}
rr .PSDNAddress = l .token
return slurpRemainder (c )
}
func (rr *KX ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil || l .err {
return &ParseError {err : "bad KX Pref" , lex : l }
}
rr .Preference = uint16 (i )
c .Next ()
l , _ = c .Next ()
rr .Exchanger = l .token
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad KX Exchanger" , lex : l }
}
rr .Exchanger = name
return slurpRemainder (c )
}
func (rr *CNAME ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad CNAME Target" , lex : l }
}
rr .Target = name
return slurpRemainder (c )
}
func (rr *DNAME ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad DNAME Target" , lex : l }
}
rr .Target = name
return slurpRemainder (c )
}
func (rr *SOA ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
ns , nsOk := toAbsoluteName (l .token , o )
if l .err || !nsOk {
return &ParseError {err : "bad SOA Ns" , lex : l }
}
rr .Ns = ns
c .Next ()
l , _ = c .Next ()
rr .Mbox = l .token
mbox , mboxOk := toAbsoluteName (l .token , o )
if l .err || !mboxOk {
return &ParseError {err : "bad SOA Mbox" , lex : l }
}
rr .Mbox = mbox
c .Next ()
var (
v uint32
ok bool
)
for i := 0 ; i < 5 ; i ++ {
l , _ = c .Next ()
if l .err {
return &ParseError {err : "bad SOA zone parameter" , lex : l }
}
if j , err := strconv .ParseUint (l .token , 10 , 32 ); err != nil {
if i == 0 {
return &ParseError {err : "bad SOA zone parameter" , lex : l }
}
if v , ok = stringToTTL (l .token ); !ok {
return &ParseError {err : "bad SOA zone parameter" , lex : l }
}
} else {
v = uint32 (j )
}
switch i {
case 0 :
rr .Serial = v
c .Next ()
case 1 :
rr .Refresh = v
c .Next ()
case 2 :
rr .Retry = v
c .Next ()
case 3 :
rr .Expire = v
c .Next ()
case 4 :
rr .Minttl = v
}
}
return slurpRemainder (c )
}
func (rr *SRV ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil || l .err {
return &ParseError {err : "bad SRV Priority" , lex : l }
}
rr .Priority = uint16 (i )
c .Next ()
l , _ = c .Next ()
i , e1 := strconv .ParseUint (l .token , 10 , 16 )
if e1 != nil || l .err {
return &ParseError {err : "bad SRV Weight" , lex : l }
}
rr .Weight = uint16 (i )
c .Next ()
l , _ = c .Next ()
i , e2 := strconv .ParseUint (l .token , 10 , 16 )
if e2 != nil || l .err {
return &ParseError {err : "bad SRV Port" , lex : l }
}
rr .Port = uint16 (i )
c .Next ()
l , _ = c .Next ()
rr .Target = l .token
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad SRV Target" , lex : l }
}
rr .Target = name
return slurpRemainder (c )
}
func (rr *NAPTR ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil || l .err {
return &ParseError {err : "bad NAPTR Order" , lex : l }
}
rr .Order = uint16 (i )
c .Next ()
l , _ = c .Next ()
i , e1 := strconv .ParseUint (l .token , 10 , 16 )
if e1 != nil || l .err {
return &ParseError {err : "bad NAPTR Preference" , lex : l }
}
rr .Preference = uint16 (i )
c .Next ()
l , _ = c .Next ()
if l .value != zQuote {
return &ParseError {err : "bad NAPTR Flags" , lex : l }
}
l , _ = c .Next ()
if l .value == zString {
rr .Flags = l .token
l , _ = c .Next ()
if l .value != zQuote {
return &ParseError {err : "bad NAPTR Flags" , lex : l }
}
} else if l .value == zQuote {
rr .Flags = ""
} else {
return &ParseError {err : "bad NAPTR Flags" , lex : l }
}
c .Next ()
l , _ = c .Next ()
if l .value != zQuote {
return &ParseError {err : "bad NAPTR Service" , lex : l }
}
l , _ = c .Next ()
if l .value == zString {
rr .Service = l .token
l , _ = c .Next ()
if l .value != zQuote {
return &ParseError {err : "bad NAPTR Service" , lex : l }
}
} else if l .value == zQuote {
rr .Service = ""
} else {
return &ParseError {err : "bad NAPTR Service" , lex : l }
}
c .Next ()
l , _ = c .Next ()
if l .value != zQuote {
return &ParseError {err : "bad NAPTR Regexp" , lex : l }
}
l , _ = c .Next ()
if l .value == zString {
rr .Regexp = l .token
l , _ = c .Next ()
if l .value != zQuote {
return &ParseError {err : "bad NAPTR Regexp" , lex : l }
}
} else if l .value == zQuote {
rr .Regexp = ""
} else {
return &ParseError {err : "bad NAPTR Regexp" , lex : l }
}
c .Next ()
l , _ = c .Next ()
rr .Replacement = l .token
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad NAPTR Replacement" , lex : l }
}
rr .Replacement = name
return slurpRemainder (c )
}
func (rr *TALINK ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
previousName , previousNameOk := toAbsoluteName (l .token , o )
if l .err || !previousNameOk {
return &ParseError {err : "bad TALINK PreviousName" , lex : l }
}
rr .PreviousName = previousName
c .Next ()
l , _ = c .Next ()
rr .NextName = l .token
nextName , nextNameOk := toAbsoluteName (l .token , o )
if l .err || !nextNameOk {
return &ParseError {err : "bad TALINK NextName" , lex : l }
}
rr .NextName = nextName
return slurpRemainder (c )
}
func (rr *LOC ) parse (c *zlexer , o string ) *ParseError {
rr .Size = 0x12
rr .HorizPre = 0x16
rr .VertPre = 0x13
ok := false
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 32 )
if e != nil || l .err || i > 90 {
return &ParseError {err : "bad LOC Latitude" , lex : l }
}
rr .Latitude = 1000 * 60 * 60 * uint32 (i )
c .Next ()
l , _ = c .Next ()
if rr .Latitude , ok = locCheckNorth (l .token , rr .Latitude ); ok {
goto East
}
if i , err := strconv .ParseUint (l .token , 10 , 32 ); err != nil || l .err || i > 59 {
return &ParseError {err : "bad LOC Latitude minutes" , lex : l }
} else {
rr .Latitude += 1000 * 60 * uint32 (i )
}
c .Next ()
l , _ = c .Next ()
if i , err := strconv .ParseFloat (l .token , 64 ); err != nil || l .err || i < 0 || i >= 60 {
return &ParseError {err : "bad LOC Latitude seconds" , lex : l }
} else {
rr .Latitude += uint32 (1000 * i )
}
c .Next ()
l , _ = c .Next ()
if rr .Latitude , ok = locCheckNorth (l .token , rr .Latitude ); ok {
goto East
}
return &ParseError {err : "bad LOC Latitude North/South" , lex : l }
East :
c .Next ()
l , _ = c .Next ()
if i , err := strconv .ParseUint (l .token , 10 , 32 ); err != nil || l .err || i > 180 {
return &ParseError {err : "bad LOC Longitude" , lex : l }
} else {
rr .Longitude = 1000 * 60 * 60 * uint32 (i )
}
c .Next ()
l , _ = c .Next ()
if rr .Longitude , ok = locCheckEast (l .token , rr .Longitude ); ok {
goto Altitude
}
if i , err := strconv .ParseUint (l .token , 10 , 32 ); err != nil || l .err || i > 59 {
return &ParseError {err : "bad LOC Longitude minutes" , lex : l }
} else {
rr .Longitude += 1000 * 60 * uint32 (i )
}
c .Next ()
l , _ = c .Next ()
if i , err := strconv .ParseFloat (l .token , 64 ); err != nil || l .err || i < 0 || i >= 60 {
return &ParseError {err : "bad LOC Longitude seconds" , lex : l }
} else {
rr .Longitude += uint32 (1000 * i )
}
c .Next ()
l , _ = c .Next ()
if rr .Longitude , ok = locCheckEast (l .token , rr .Longitude ); ok {
goto Altitude
}
return &ParseError {err : "bad LOC Longitude East/West" , lex : l }
Altitude :
c .Next ()
l , _ = c .Next ()
if l .token == "" || l .err {
return &ParseError {err : "bad LOC Altitude" , lex : l }
}
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 , err := strconv .ParseFloat (l .token , 64 ); err != nil {
return &ParseError {err : "bad LOC Altitude" , lex : l }
} else {
rr .Altitude = uint32 (i *100.0 + 10000000.0 + 0.5 )
}
l , _ = c .Next ()
count := 0
for l .value != zNewline && l .value != zEOF {
switch l .value {
case zString :
switch count {
case 0 :
exp , m , ok := stringToCm (l .token )
if !ok {
return &ParseError {err : "bad LOC Size" , lex : l }
}
rr .Size = exp &0x0f | m <<4 &0xf0
case 1 :
exp , m , ok := stringToCm (l .token )
if !ok {
return &ParseError {err : "bad LOC HorizPre" , lex : l }
}
rr .HorizPre = exp &0x0f | m <<4 &0xf0
case 2 :
exp , m , ok := stringToCm (l .token )
if !ok {
return &ParseError {err : "bad LOC VertPre" , lex : l }
}
rr .VertPre = exp &0x0f | m <<4 &0xf0
}
count ++
case zBlank :
default :
return &ParseError {err : "bad LOC Size, HorizPre or VertPre" , lex : l }
}
l , _ = c .Next ()
}
return nil
}
func (rr *HIP ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 8 )
if e != nil || l .err {
return &ParseError {err : "bad HIP PublicKeyAlgorithm" , lex : l }
}
rr .PublicKeyAlgorithm = uint8 (i )
c .Next ()
l , _ = c .Next ()
if l .token == "" || l .err {
return &ParseError {err : "bad HIP Hit" , lex : l }
}
rr .Hit = l .token
rr .HitLength = uint8 (len (rr .Hit )) / 2
c .Next ()
l , _ = c .Next ()
if l .token == "" || l .err {
return &ParseError {err : "bad HIP PublicKey" , lex : l }
}
rr .PublicKey = l .token
decodedPK , decodedPKerr := base64 .StdEncoding .DecodeString (rr .PublicKey )
if decodedPKerr != nil {
return &ParseError {err : "bad HIP PublicKey" , lex : l }
}
rr .PublicKeyLength = uint16 (len (decodedPK ))
l , _ = c .Next ()
var xs []string
for l .value != zNewline && l .value != zEOF {
switch l .value {
case zString :
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad HIP RendezvousServers" , lex : l }
}
xs = append (xs , name )
case zBlank :
default :
return &ParseError {err : "bad HIP RendezvousServers" , lex : l }
}
l , _ = c .Next ()
}
rr .RendezvousServers = xs
return nil
}
func (rr *CERT ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
if v , ok := StringToCertType [l .token ]; ok {
rr .Type = v
} else if i , err := strconv .ParseUint (l .token , 10 , 16 ); err != nil {
return &ParseError {err : "bad CERT Type" , lex : l }
} else {
rr .Type = uint16 (i )
}
c .Next ()
l , _ = c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil || l .err {
return &ParseError {err : "bad CERT KeyTag" , lex : l }
}
rr .KeyTag = uint16 (i )
c .Next ()
l , _ = c .Next ()
if v , ok := StringToAlgorithm [l .token ]; ok {
rr .Algorithm = v
} else if i , err := strconv .ParseUint (l .token , 10 , 8 ); err != nil {
return &ParseError {err : "bad CERT Algorithm" , lex : l }
} else {
rr .Algorithm = uint8 (i )
}
s , e1 := endingToString (c , "bad CERT Certificate" )
if e1 != nil {
return e1
}
rr .Certificate = s
return nil
}
func (rr *OPENPGPKEY ) parse (c *zlexer , o string ) *ParseError {
s , e := endingToString (c , "bad OPENPGPKEY PublicKey" )
if e != nil {
return e
}
rr .PublicKey = s
return nil
}
func (rr *CSYNC ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
j , e := strconv .ParseUint (l .token , 10 , 32 )
if e != nil {
return &ParseError {err : "bad CSYNC serial" , lex : l }
}
rr .Serial = uint32 (j )
c .Next ()
l , _ = c .Next ()
j , e1 := strconv .ParseUint (l .token , 10 , 16 )
if e1 != nil {
return &ParseError {err : "bad CSYNC flags" , lex : l }
}
rr .Flags = uint16 (j )
rr .TypeBitMap = make ([]uint16 , 0 )
var (
k uint16
ok bool
)
l , _ = c .Next ()
for l .value != zNewline && l .value != zEOF {
switch l .value {
case zBlank :
case zString :
tokenUpper := strings .ToUpper (l .token )
if k , ok = StringToType [tokenUpper ]; !ok {
if k , ok = typeToInt (l .token ); !ok {
return &ParseError {err : "bad CSYNC TypeBitMap" , lex : l }
}
}
rr .TypeBitMap = append (rr .TypeBitMap , k )
default :
return &ParseError {err : "bad CSYNC TypeBitMap" , lex : l }
}
l , _ = c .Next ()
}
return nil
}
func (rr *ZONEMD ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 32 )
if e != nil || l .err {
return &ParseError {err : "bad ZONEMD Serial" , lex : l }
}
rr .Serial = uint32 (i )
c .Next ()
l , _ = c .Next ()
i , e1 := strconv .ParseUint (l .token , 10 , 8 )
if e1 != nil || l .err {
return &ParseError {err : "bad ZONEMD Scheme" , lex : l }
}
rr .Scheme = uint8 (i )
c .Next ()
l , _ = c .Next ()
i , err := strconv .ParseUint (l .token , 10 , 8 )
if err != nil || l .err {
return &ParseError {err : "bad ZONEMD Hash Algorithm" , lex : l }
}
rr .Hash = uint8 (i )
s , e2 := endingToString (c , "bad ZONEMD Digest" )
if e2 != nil {
return e2
}
rr .Digest = s
return nil
}
func (rr *SIG ) parse (c *zlexer , o string ) *ParseError { return rr .RRSIG .parse (c , o ) }
func (rr *RRSIG ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
tokenUpper := strings .ToUpper (l .token )
if t , ok := StringToType [tokenUpper ]; !ok {
if strings .HasPrefix (tokenUpper , "TYPE" ) {
t , ok = typeToInt (l .token )
if !ok {
return &ParseError {err : "bad RRSIG Typecovered" , lex : l }
}
rr .TypeCovered = t
} else {
return &ParseError {err : "bad RRSIG Typecovered" , lex : l }
}
} else {
rr .TypeCovered = t
}
c .Next ()
l , _ = c .Next ()
if l .err {
return &ParseError {err : "bad RRSIG Algorithm" , lex : l }
}
i , e := strconv .ParseUint (l .token , 10 , 8 )
rr .Algorithm = uint8 (i )
if e != nil {
v , ok := StringToAlgorithm [l .token ]
if !ok {
return &ParseError {err : "bad RRSIG Algorithm" , lex : l }
}
rr .Algorithm = v
}
c .Next ()
l , _ = c .Next ()
i , e1 := strconv .ParseUint (l .token , 10 , 8 )
if e1 != nil || l .err {
return &ParseError {err : "bad RRSIG Labels" , lex : l }
}
rr .Labels = uint8 (i )
c .Next ()
l , _ = c .Next ()
i , e2 := strconv .ParseUint (l .token , 10 , 32 )
if e2 != nil || l .err {
return &ParseError {err : "bad RRSIG OrigTtl" , lex : l }
}
rr .OrigTtl = uint32 (i )
c .Next ()
l , _ = c .Next ()
if i , err := StringToTime (l .token ); err != nil {
if i , err := strconv .ParseUint (l .token , 10 , 32 ); err == nil {
rr .Expiration = uint32 (i )
} else {
return &ParseError {err : "bad RRSIG Expiration" , lex : l }
}
} else {
rr .Expiration = i
}
c .Next ()
l , _ = c .Next ()
if i , err := StringToTime (l .token ); err != nil {
if i , err := strconv .ParseUint (l .token , 10 , 32 ); err == nil {
rr .Inception = uint32 (i )
} else {
return &ParseError {err : "bad RRSIG Inception" , lex : l }
}
} else {
rr .Inception = i
}
c .Next ()
l , _ = c .Next ()
i , e3 := strconv .ParseUint (l .token , 10 , 16 )
if e3 != nil || l .err {
return &ParseError {err : "bad RRSIG KeyTag" , lex : l }
}
rr .KeyTag = uint16 (i )
c .Next ()
l , _ = c .Next ()
rr .SignerName = l .token
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad RRSIG SignerName" , lex : l }
}
rr .SignerName = name
s , e4 := endingToString (c , "bad RRSIG Signature" )
if e4 != nil {
return e4
}
rr .Signature = s
return nil
}
func (rr *NXT ) parse (c *zlexer , o string ) *ParseError { return rr .NSEC .parse (c , o ) }
func (rr *NSEC ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad NSEC NextDomain" , lex : l }
}
rr .NextDomain = name
rr .TypeBitMap = make ([]uint16 , 0 )
var (
k uint16
ok bool
)
l , _ = c .Next ()
for l .value != zNewline && l .value != zEOF {
switch l .value {
case zBlank :
case zString :
tokenUpper := strings .ToUpper (l .token )
if k , ok = StringToType [tokenUpper ]; !ok {
if k , ok = typeToInt (l .token ); !ok {
return &ParseError {err : "bad NSEC TypeBitMap" , lex : l }
}
}
rr .TypeBitMap = append (rr .TypeBitMap , k )
default :
return &ParseError {err : "bad NSEC TypeBitMap" , lex : l }
}
l , _ = c .Next ()
}
return nil
}
func (rr *NSEC3 ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 8 )
if e != nil || l .err {
return &ParseError {err : "bad NSEC3 Hash" , lex : l }
}
rr .Hash = uint8 (i )
c .Next ()
l , _ = c .Next ()
i , e1 := strconv .ParseUint (l .token , 10 , 8 )
if e1 != nil || l .err {
return &ParseError {err : "bad NSEC3 Flags" , lex : l }
}
rr .Flags = uint8 (i )
c .Next ()
l , _ = c .Next ()
i , e2 := strconv .ParseUint (l .token , 10 , 16 )
if e2 != nil || l .err {
return &ParseError {err : "bad NSEC3 Iterations" , lex : l }
}
rr .Iterations = uint16 (i )
c .Next ()
l , _ = c .Next ()
if l .token == "" || l .err {
return &ParseError {err : "bad NSEC3 Salt" , lex : l }
}
if l .token != "-" {
rr .SaltLength = uint8 (len (l .token )) / 2
rr .Salt = l .token
}
c .Next ()
l , _ = c .Next ()
if l .token == "" || l .err {
return &ParseError {err : "bad NSEC3 NextDomain" , lex : l }
}
rr .HashLength = 20
rr .NextDomain = l .token
rr .TypeBitMap = make ([]uint16 , 0 )
var (
k uint16
ok bool
)
l , _ = c .Next ()
for l .value != zNewline && l .value != zEOF {
switch l .value {
case zBlank :
case zString :
tokenUpper := strings .ToUpper (l .token )
if k , ok = StringToType [tokenUpper ]; !ok {
if k , ok = typeToInt (l .token ); !ok {
return &ParseError {err : "bad NSEC3 TypeBitMap" , lex : l }
}
}
rr .TypeBitMap = append (rr .TypeBitMap , k )
default :
return &ParseError {err : "bad NSEC3 TypeBitMap" , lex : l }
}
l , _ = c .Next ()
}
return nil
}
func (rr *NSEC3PARAM ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 8 )
if e != nil || l .err {
return &ParseError {err : "bad NSEC3PARAM Hash" , lex : l }
}
rr .Hash = uint8 (i )
c .Next ()
l , _ = c .Next ()
i , e1 := strconv .ParseUint (l .token , 10 , 8 )
if e1 != nil || l .err {
return &ParseError {err : "bad NSEC3PARAM Flags" , lex : l }
}
rr .Flags = uint8 (i )
c .Next ()
l , _ = c .Next ()
i , e2 := strconv .ParseUint (l .token , 10 , 16 )
if e2 != nil || l .err {
return &ParseError {err : "bad NSEC3PARAM Iterations" , lex : l }
}
rr .Iterations = uint16 (i )
c .Next ()
l , _ = c .Next ()
if l .token != "-" {
rr .SaltLength = uint8 (len (l .token ) / 2 )
rr .Salt = l .token
}
return slurpRemainder (c )
}
func (rr *EUI48 ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
if len (l .token ) != 17 || l .err {
return &ParseError {err : "bad EUI48 Address" , lex : 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 &ParseError {err : "bad EUI48 Address" , lex : l }
}
}
addr [10 ] = l .token [15 ]
addr [11 ] = l .token [16 ]
i , e := strconv .ParseUint (string (addr ), 16 , 48 )
if e != nil {
return &ParseError {err : "bad EUI48 Address" , lex : l }
}
rr .Address = i
return slurpRemainder (c )
}
func (rr *EUI64 ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
if len (l .token ) != 23 || l .err {
return &ParseError {err : "bad EUI64 Address" , lex : 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 &ParseError {err : "bad EUI64 Address" , lex : l }
}
}
addr [14 ] = l .token [21 ]
addr [15 ] = l .token [22 ]
i , e := strconv .ParseUint (string (addr ), 16 , 64 )
if e != nil {
return &ParseError {err : "bad EUI68 Address" , lex : l }
}
rr .Address = i
return slurpRemainder (c )
}
func (rr *SSHFP ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 8 )
if e != nil || l .err {
return &ParseError {err : "bad SSHFP Algorithm" , lex : l }
}
rr .Algorithm = uint8 (i )
c .Next ()
l , _ = c .Next ()
i , e1 := strconv .ParseUint (l .token , 10 , 8 )
if e1 != nil || l .err {
return &ParseError {err : "bad SSHFP Type" , lex : l }
}
rr .Type = uint8 (i )
c .Next ()
s , e2 := endingToString (c , "bad SSHFP Fingerprint" )
if e2 != nil {
return e2
}
rr .FingerPrint = s
return nil
}
func (rr *DNSKEY ) parseDNSKEY (c *zlexer , o , typ string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil || l .err {
return &ParseError {err : "bad " + typ + " Flags" , lex : l }
}
rr .Flags = uint16 (i )
c .Next ()
l , _ = c .Next ()
i , e1 := strconv .ParseUint (l .token , 10 , 8 )
if e1 != nil || l .err {
return &ParseError {err : "bad " + typ + " Protocol" , lex : l }
}
rr .Protocol = uint8 (i )
c .Next ()
l , _ = c .Next ()
i , e2 := strconv .ParseUint (l .token , 10 , 8 )
if e2 != nil || l .err {
return &ParseError {err : "bad " + typ + " Algorithm" , lex : l }
}
rr .Algorithm = uint8 (i )
s , e3 := endingToString (c , "bad " +typ +" PublicKey" )
if e3 != nil {
return e3
}
rr .PublicKey = s
return nil
}
func (rr *DNSKEY ) parse (c *zlexer , o string ) *ParseError { return rr .parseDNSKEY (c , o , "DNSKEY" ) }
func (rr *KEY ) parse (c *zlexer , o string ) *ParseError { return rr .parseDNSKEY (c , o , "KEY" ) }
func (rr *CDNSKEY ) parse (c *zlexer , o string ) *ParseError { return rr .parseDNSKEY (c , o , "CDNSKEY" ) }
func (rr *DS ) parse (c *zlexer , o string ) *ParseError { return rr .parseDS (c , o , "DS" ) }
func (rr *DLV ) parse (c *zlexer , o string ) *ParseError { return rr .parseDS (c , o , "DLV" ) }
func (rr *CDS ) parse (c *zlexer , o string ) *ParseError { return rr .parseDS (c , o , "CDS" ) }
func (rr *IPSECKEY ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
num , err := strconv .ParseUint (l .token , 10 , 8 )
if err != nil || l .err {
return &ParseError {err : "bad IPSECKEY value" , lex : l }
}
rr .Precedence = uint8 (num )
c .Next ()
l , _ = c .Next ()
num , err = strconv .ParseUint (l .token , 10 , 8 )
if err != nil || l .err {
return &ParseError {err : "bad IPSECKEY value" , lex : l }
}
rr .GatewayType = uint8 (num )
c .Next ()
l , _ = c .Next ()
num , err = strconv .ParseUint (l .token , 10 , 8 )
if err != nil || l .err {
return &ParseError {err : "bad IPSECKEY value" , lex : l }
}
rr .Algorithm = uint8 (num )
c .Next ()
l , _ = c .Next ()
if l .err {
return &ParseError {err : "bad IPSECKEY gateway" , lex : l }
}
rr .GatewayAddr , rr .GatewayHost , err = parseAddrHostUnion (l .token , o , rr .GatewayType )
if err != nil {
return &ParseError {wrappedErr : fmt .Errorf ("IPSECKEY %w" , err ), lex : l }
}
c .Next ()
s , pErr := endingToString (c , "bad IPSECKEY PublicKey" )
if pErr != nil {
return pErr
}
rr .PublicKey = s
return slurpRemainder (c )
}
func (rr *AMTRELAY ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
num , err := strconv .ParseUint (l .token , 10 , 8 )
if err != nil || l .err {
return &ParseError {err : "bad AMTRELAY value" , lex : l }
}
rr .Precedence = uint8 (num )
c .Next ()
l , _ = c .Next ()
if l .err || !(l .token == "0" || l .token == "1" ) {
return &ParseError {err : "bad discovery value" , lex : l }
}
if l .token == "1" {
rr .GatewayType = 0x80
}
c .Next ()
l , _ = c .Next ()
num , err = strconv .ParseUint (l .token , 10 , 8 )
if err != nil || l .err {
return &ParseError {err : "bad AMTRELAY value" , lex : l }
}
rr .GatewayType |= uint8 (num )
c .Next ()
l , _ = c .Next ()
if l .err {
return &ParseError {err : "bad AMTRELAY gateway" , lex : l }
}
rr .GatewayAddr , rr .GatewayHost , err = parseAddrHostUnion (l .token , o , rr .GatewayType &0x7f )
if err != nil {
return &ParseError {wrappedErr : fmt .Errorf ("AMTRELAY %w" , err ), lex : l }
}
return slurpRemainder (c )
}
func parseAddrHostUnion(token , o string , gatewayType uint8 ) (addr net .IP , host string , err error ) {
switch gatewayType {
case IPSECGatewayNone :
if token != "." {
return addr , host , errors .New ("gateway type none with gateway set" )
}
case IPSECGatewayIPv4 , IPSECGatewayIPv6 :
addr = net .ParseIP (token )
if addr == nil {
return addr , host , errors .New ("gateway IP invalid" )
}
if (addr .To4 () == nil ) == (gatewayType == IPSECGatewayIPv4 ) {
return addr , host , errors .New ("gateway IP family mismatch" )
}
case IPSECGatewayHost :
var ok bool
host , ok = toAbsoluteName (token , o )
if !ok {
return addr , host , errors .New ("invalid gateway host" )
}
}
return addr , host , nil
}
func (rr *RKEY ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil || l .err {
return &ParseError {err : "bad RKEY Flags" , lex : l }
}
rr .Flags = uint16 (i )
c .Next ()
l , _ = c .Next ()
i , e1 := strconv .ParseUint (l .token , 10 , 8 )
if e1 != nil || l .err {
return &ParseError {err : "bad RKEY Protocol" , lex : l }
}
rr .Protocol = uint8 (i )
c .Next ()
l , _ = c .Next ()
i , e2 := strconv .ParseUint (l .token , 10 , 8 )
if e2 != nil || l .err {
return &ParseError {err : "bad RKEY Algorithm" , lex : l }
}
rr .Algorithm = uint8 (i )
s , e3 := endingToString (c , "bad RKEY PublicKey" )
if e3 != nil {
return e3
}
rr .PublicKey = s
return nil
}
func (rr *EID ) parse (c *zlexer , o string ) *ParseError {
s , e := endingToString (c , "bad EID Endpoint" )
if e != nil {
return e
}
rr .Endpoint = s
return nil
}
func (rr *NIMLOC ) parse (c *zlexer , o string ) *ParseError {
s , e := endingToString (c , "bad NIMLOC Locator" )
if e != nil {
return e
}
rr .Locator = s
return nil
}
func (rr *GPOS ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
_ , e := strconv .ParseFloat (l .token , 64 )
if e != nil || l .err {
return &ParseError {err : "bad GPOS Longitude" , lex : l }
}
rr .Longitude = l .token
c .Next ()
l , _ = c .Next ()
_ , e1 := strconv .ParseFloat (l .token , 64 )
if e1 != nil || l .err {
return &ParseError {err : "bad GPOS Latitude" , lex : l }
}
rr .Latitude = l .token
c .Next ()
l , _ = c .Next ()
_ , e2 := strconv .ParseFloat (l .token , 64 )
if e2 != nil || l .err {
return &ParseError {err : "bad GPOS Altitude" , lex : l }
}
rr .Altitude = l .token
return slurpRemainder (c )
}
func (rr *DS ) parseDS (c *zlexer , o , typ string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil || l .err {
return &ParseError {err : "bad " + typ + " KeyTag" , lex : l }
}
rr .KeyTag = uint16 (i )
c .Next ()
l , _ = c .Next ()
if i , err := strconv .ParseUint (l .token , 10 , 8 ); err != nil {
tokenUpper := strings .ToUpper (l .token )
i , ok := StringToAlgorithm [tokenUpper ]
if !ok || l .err {
return &ParseError {err : "bad " + typ + " Algorithm" , lex : l }
}
rr .Algorithm = i
} else {
rr .Algorithm = uint8 (i )
}
c .Next ()
l , _ = c .Next ()
i , e1 := strconv .ParseUint (l .token , 10 , 8 )
if e1 != nil || l .err {
return &ParseError {err : "bad " + typ + " DigestType" , lex : l }
}
rr .DigestType = uint8 (i )
s , e2 := endingToString (c , "bad " +typ +" Digest" )
if e2 != nil {
return e2
}
rr .Digest = s
return nil
}
func (rr *TA ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil || l .err {
return &ParseError {err : "bad TA KeyTag" , lex : l }
}
rr .KeyTag = uint16 (i )
c .Next ()
l , _ = c .Next ()
if i , err := strconv .ParseUint (l .token , 10 , 8 ); err != nil {
tokenUpper := strings .ToUpper (l .token )
i , ok := StringToAlgorithm [tokenUpper ]
if !ok || l .err {
return &ParseError {err : "bad TA Algorithm" , lex : l }
}
rr .Algorithm = i
} else {
rr .Algorithm = uint8 (i )
}
c .Next ()
l , _ = c .Next ()
i , e1 := strconv .ParseUint (l .token , 10 , 8 )
if e1 != nil || l .err {
return &ParseError {err : "bad TA DigestType" , lex : l }
}
rr .DigestType = uint8 (i )
s , e2 := endingToString (c , "bad TA Digest" )
if e2 != nil {
return e2
}
rr .Digest = s
return nil
}
func (rr *TLSA ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 8 )
if e != nil || l .err {
return &ParseError {err : "bad TLSA Usage" , lex : l }
}
rr .Usage = uint8 (i )
c .Next ()
l , _ = c .Next ()
i , e1 := strconv .ParseUint (l .token , 10 , 8 )
if e1 != nil || l .err {
return &ParseError {err : "bad TLSA Selector" , lex : l }
}
rr .Selector = uint8 (i )
c .Next ()
l , _ = c .Next ()
i , e2 := strconv .ParseUint (l .token , 10 , 8 )
if e2 != nil || l .err {
return &ParseError {err : "bad TLSA MatchingType" , lex : l }
}
rr .MatchingType = uint8 (i )
s , e3 := endingToString (c , "bad TLSA Certificate" )
if e3 != nil {
return e3
}
rr .Certificate = s
return nil
}
func (rr *SMIMEA ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 8 )
if e != nil || l .err {
return &ParseError {err : "bad SMIMEA Usage" , lex : l }
}
rr .Usage = uint8 (i )
c .Next ()
l , _ = c .Next ()
i , e1 := strconv .ParseUint (l .token , 10 , 8 )
if e1 != nil || l .err {
return &ParseError {err : "bad SMIMEA Selector" , lex : l }
}
rr .Selector = uint8 (i )
c .Next ()
l , _ = c .Next ()
i , e2 := strconv .ParseUint (l .token , 10 , 8 )
if e2 != nil || l .err {
return &ParseError {err : "bad SMIMEA MatchingType" , lex : l }
}
rr .MatchingType = uint8 (i )
s , e3 := endingToString (c , "bad SMIMEA Certificate" )
if e3 != nil {
return e3
}
rr .Certificate = s
return nil
}
func (rr *RFC3597 ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
if l .token != "\\#" {
return &ParseError {err : "bad RFC3597 Rdata" , lex : l }
}
c .Next ()
l , _ = c .Next ()
rdlength , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil || l .err {
return &ParseError {err : "bad RFC3597 Rdata " , lex : l }
}
s , e1 := endingToString (c , "bad RFC3597 Rdata" )
if e1 != nil {
return e1
}
if int (rdlength )*2 != len (s ) {
return &ParseError {err : "bad RFC3597 Rdata" , lex : l }
}
rr .Rdata = s
return nil
}
func (rr *SPF ) parse (c *zlexer , o string ) *ParseError {
s , e := endingToTxtSlice (c , "bad SPF Txt" )
if e != nil {
return e
}
rr .Txt = s
return nil
}
func (rr *AVC ) parse (c *zlexer , o string ) *ParseError {
s , e := endingToTxtSlice (c , "bad AVC Txt" )
if e != nil {
return e
}
rr .Txt = s
return nil
}
func (rr *TXT ) parse (c *zlexer , o string ) *ParseError {
s , e := endingToTxtSlice (c , "bad TXT Txt" )
if e != nil {
return e
}
rr .Txt = s
return nil
}
func (rr *NINFO ) parse (c *zlexer , o string ) *ParseError {
s , e := endingToTxtSlice (c , "bad NINFO ZSData" )
if e != nil {
return e
}
rr .ZSData = s
return nil
}
func (rr *RESINFO ) parse (c *zlexer , o string ) *ParseError {
s , e := endingToTxtSlice (c , "bad RESINFO Resinfo" )
if e != nil {
return e
}
rr .Txt = s
return nil
}
func (rr *URI ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil || l .err {
return &ParseError {err : "bad URI Priority" , lex : l }
}
rr .Priority = uint16 (i )
c .Next ()
l , _ = c .Next ()
i , e1 := strconv .ParseUint (l .token , 10 , 16 )
if e1 != nil || l .err {
return &ParseError {err : "bad URI Weight" , lex : l }
}
rr .Weight = uint16 (i )
c .Next ()
s , e2 := endingToTxtSlice (c , "bad URI Target" )
if e2 != nil {
return e2
}
if len (s ) != 1 {
return &ParseError {err : "bad URI Target" , lex : l }
}
rr .Target = s [0 ]
return nil
}
func (rr *DHCID ) parse (c *zlexer , o string ) *ParseError {
s , e := endingToString (c , "bad DHCID Digest" )
if e != nil {
return e
}
rr .Digest = s
return nil
}
func (rr *NID ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil || l .err {
return &ParseError {err : "bad NID Preference" , lex : l }
}
rr .Preference = uint16 (i )
c .Next ()
l , _ = c .Next ()
u , e1 := stringToNodeID (l )
if e1 != nil || l .err {
return e1
}
rr .NodeID = u
return slurpRemainder (c )
}
func (rr *L32 ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil || l .err {
return &ParseError {err : "bad L32 Preference" , lex : l }
}
rr .Preference = uint16 (i )
c .Next ()
l , _ = c .Next ()
rr .Locator32 = net .ParseIP (l .token )
if rr .Locator32 == nil || l .err {
return &ParseError {err : "bad L32 Locator" , lex : l }
}
return slurpRemainder (c )
}
func (rr *LP ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil || l .err {
return &ParseError {err : "bad LP Preference" , lex : l }
}
rr .Preference = uint16 (i )
c .Next ()
l , _ = c .Next ()
rr .Fqdn = l .token
name , nameOk := toAbsoluteName (l .token , o )
if l .err || !nameOk {
return &ParseError {err : "bad LP Fqdn" , lex : l }
}
rr .Fqdn = name
return slurpRemainder (c )
}
func (rr *L64 ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil || l .err {
return &ParseError {err : "bad L64 Preference" , lex : l }
}
rr .Preference = uint16 (i )
c .Next ()
l , _ = c .Next ()
u , e1 := stringToNodeID (l )
if e1 != nil || l .err {
return e1
}
rr .Locator64 = u
return slurpRemainder (c )
}
func (rr *UID ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 32 )
if e != nil || l .err {
return &ParseError {err : "bad UID Uid" , lex : l }
}
rr .Uid = uint32 (i )
return slurpRemainder (c )
}
func (rr *GID ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 32 )
if e != nil || l .err {
return &ParseError {err : "bad GID Gid" , lex : l }
}
rr .Gid = uint32 (i )
return slurpRemainder (c )
}
func (rr *UINFO ) parse (c *zlexer , o string ) *ParseError {
s , e := endingToTxtSlice (c , "bad UINFO Uinfo" )
if e != nil {
return e
}
if ln := len (s ); ln == 0 {
return nil
}
rr .Uinfo = s [0 ]
return nil
}
func (rr *PX ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 16 )
if e != nil || l .err {
return &ParseError {err : "bad PX Preference" , lex : l }
}
rr .Preference = uint16 (i )
c .Next ()
l , _ = c .Next ()
rr .Map822 = l .token
map822 , map822Ok := toAbsoluteName (l .token , o )
if l .err || !map822Ok {
return &ParseError {err : "bad PX Map822" , lex : l }
}
rr .Map822 = map822
c .Next ()
l , _ = c .Next ()
rr .Mapx400 = l .token
mapx400 , mapx400Ok := toAbsoluteName (l .token , o )
if l .err || !mapx400Ok {
return &ParseError {err : "bad PX Mapx400" , lex : l }
}
rr .Mapx400 = mapx400
return slurpRemainder (c )
}
func (rr *CAA ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 8 )
if e != nil || l .err {
return &ParseError {err : "bad CAA Flag" , lex : l }
}
rr .Flag = uint8 (i )
c .Next ()
l , _ = c .Next ()
if l .value != zString {
return &ParseError {err : "bad CAA Tag" , lex : l }
}
rr .Tag = l .token
c .Next ()
s , e1 := endingToTxtSlice (c , "bad CAA Value" )
if e1 != nil {
return e1
}
if len (s ) != 1 {
return &ParseError {err : "bad CAA Value" , lex : l }
}
rr .Value = s [0 ]
return nil
}
func (rr *TKEY ) parse (c *zlexer , o string ) *ParseError {
l , _ := c .Next ()
if l .value != zString {
return &ParseError {err : "bad TKEY algorithm" , lex : l }
}
rr .Algorithm = l .token
c .Next ()
l , _ = c .Next ()
i , e := strconv .ParseUint (l .token , 10 , 8 )
if e != nil || l .err {
return &ParseError {err : "bad TKEY key length" , lex : l }
}
rr .KeySize = uint16 (i )
c .Next ()
l , _ = c .Next ()
if l .value != zString {
return &ParseError {err : "bad TKEY key" , lex : l }
}
rr .Key = l .token
c .Next ()
l , _ = c .Next ()
i , e1 := strconv .ParseUint (l .token , 10 , 8 )
if e1 != nil || l .err {
return &ParseError {err : "bad TKEY otherdata length" , lex : l }
}
rr .OtherLen = uint16 (i )
c .Next ()
l , _ = c .Next ()
if l .value != zString {
return &ParseError {err : "bad TKEY otherday" , lex : l }
}
rr .OtherData = l .token
return nil
}
func (rr *APL ) parse (c *zlexer , o string ) *ParseError {
var prefixes []APLPrefix
for {
l , _ := c .Next ()
if l .value == zNewline || l .value == zEOF {
break
}
if l .value == zBlank && prefixes != nil {
continue
}
if l .value != zString {
return &ParseError {err : "unexpected APL field" , lex : l }
}
colon := strings .IndexByte (l .token , ':' )
if colon == -1 {
return &ParseError {err : "missing colon in APL field" , lex : l }
}
family , cidr := l .token [:colon ], l .token [colon +1 :]
var negation bool
if family != "" && family [0 ] == '!' {
negation = true
family = family [1 :]
}
afi , e := strconv .ParseUint (family , 10 , 16 )
if e != nil {
return &ParseError {wrappedErr : fmt .Errorf ("failed to parse APL family: %w" , e ), lex : l }
}
var addrLen int
switch afi {
case 1 :
addrLen = net .IPv4len
case 2 :
addrLen = net .IPv6len
default :
return &ParseError {err : "unrecognized APL family" , lex : l }
}
ip , subnet , e1 := net .ParseCIDR (cidr )
if e1 != nil {
return &ParseError {wrappedErr : fmt .Errorf ("failed to parse APL address: %w" , e1 ), lex : l }
}
if !ip .Equal (subnet .IP ) {
return &ParseError {err : "extra bits in APL address" , lex : l }
}
if len (subnet .IP ) != addrLen {
return &ParseError {err : "address mismatch with the APL family" , lex : l }
}
prefixes = append (prefixes , APLPrefix {
Negation : negation ,
Network : *subnet ,
})
}
rr .Prefixes = prefixes
return nil
}
func escapedStringOffset(s string , desiredByteOffset int ) (int , bool ) {
if desiredByteOffset == 0 {
return 0 , true
}
currentByteOffset , i := 0 , 0
for i < len (s ) {
currentByteOffset += 1
if s [i ] != '\\' {
i ++
} else if isDDD (s [i +1 :]) {
i += 4
} else if len (s [i +1 :]) < 1 {
return 0 , false
} else {
i += 2
}
if currentByteOffset >= desiredByteOffset {
return i , true
}
}
return -1 , true
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .