From 824cb459fb6b0cb638903614e23c85a79664c69c Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Wed, 14 Dec 2011 15:37:36 +0100 Subject: [PATCH] Parsing works --- zscan.go | 88 ++++--- zscan_rr.go | 656 +++++++++++++++++++++++++++------------------------- 2 files changed, 383 insertions(+), 361 deletions(-) diff --git a/zscan.go b/zscan.go index 4b404be0..bd77da22 100644 --- a/zscan.go +++ b/zscan.go @@ -14,27 +14,27 @@ import ( // * Make each RR fit on one line (NEWLINE is send as last) // * Handle comments: ; const ( - _STRING = iota + _EOF = iota // Don't let it start with zero + _STRING _BLANK _NEWLINE _RRTYPE _OWNER _CLASS + + _EXPECT_OWNER // Ownername + _EXPECT_OWNER_BL // Whitespace after the ownername + _EXPECT_ANY // Expect rrtype, ttl or class + _EXPECT_ANY_NOCLASS // Expect rrtype or ttl + _EXPECT_ANY_NOCLASS_BL // The Whitespace after _EXPECT_ANY_NOCLASS + _EXPECT_ANY_NOTTL // Expect rrtype or class + _EXPECT_ANY_NOTTL_BL // Whitespace after _EXPECT_ANY_NOTTL + _EXPECT_RRTYPE // Expect rrtype + _EXPECT_RRTYPE_BL // Whitespace BEFORE rrtype + _EXPECT_RDATA // The first element of the rdata ) -const ( - _EXPECT_OWNER = iota // Ownername - _EXPECT_OWNER_BL // Whitespace after the ownername - _EXPECT_ANY // Expect rrtype, ttl or class - _EXPECT_ANY_NOCLASS // Expect rrtype or ttl - _EXPECT_ANY_NOCLASS_BL // The Whitespace after _EXPECT_ANY_NOCLASS - _EXPECT_ANY_NOTTL // Expect rrtype or class - _EXPECT_ANY_NOTTL_BL // Whitespace after _EXPECT_ANY_NOTTL - _EXPECT_RRTYPE // Expect rrtype - _EXPECT_RRTYPE_BL // Whitespace BEFORE rrype - _EXPECT_RDATA // The first element of the rdata - _EXPECT_RDATA_BL // Whitespace BEFORE rdata starts -) +var DEBUG = true type ParseError struct { err string @@ -43,7 +43,7 @@ type ParseError struct { func (e *ParseError) Error() string { s := e.err + ": `" + e.lex.token + "' at line: " + strconv.Itoa(e.lex.line) + - "and column: " + strconv.Itoa(e.lex.column) + " and column: " + strconv.Itoa(e.lex.column) return s } @@ -57,17 +57,17 @@ type Lex struct { // ParseString parses a string and returns the RR contained in there. If they string // contains more than one RR, only the first is returned. func NewRRString(s string) (RR, error) { - cr := make(chan RR) - go ParseZone(strings.NewReader(s), cr) - r := <-cr // There are no error send as of yet - return r, nil // Todo: errors + cr := make(chan RR) + go ParseZone(strings.NewReader(s), cr) + r := <-cr // There are no error send as of yet + return r, nil // Todo: errors } func newRRReader(q io.Reader) (RR, error) { - cr := make(chan RR) - go ParseZone(q, cr) - r := <-cr - return r, nil + cr := make(chan RR) + go ParseZone(q, cr) + r := <-cr + return r, nil } // ParseZone reads a RFC 1035 zone from r. It returns each parsed RR on the @@ -94,6 +94,9 @@ func ParseZone(r io.Reader, cr chan RR) { var h RR_Header var ok bool for l := range c { + if DEBUG { + fmt.Printf("[%v]\n", l) + } switch st { case _EXPECT_OWNER: switch l.value { @@ -103,12 +106,12 @@ func ParseZone(r io.Reader, cr chan RR) { h.Name = l.token st = _EXPECT_OWNER_BL default: - fmt.Printf("%s\n", &ParseError{"Error at the start", l}) + fmt.Printf("%s\n", &ParseError{"Error at the start", l}) st = _EXPECT_OWNER } case _EXPECT_OWNER_BL: if l.value != _BLANK { - fmt.Printf("%s\n", &ParseError{"No blank after owner", l}) + fmt.Printf("%s\n", &ParseError{"No blank after owner", l}) } st = _EXPECT_ANY case _EXPECT_ANY: @@ -116,32 +119,32 @@ func ParseZone(r io.Reader, cr chan RR) { case _RRTYPE: h.Rrtype, _ = Str_rr[strings.ToUpper(l.token)] h.Ttl = DefaultTtl - st = _EXPECT_RDATA_BL + st = _EXPECT_RDATA case _CLASS: h.Class, ok = Str_class[strings.ToUpper(l.token)] if !ok { - fmt.Printf("%s\n", &ParseError{"Unknown class", l}) + fmt.Printf("%s\n", &ParseError{"Unknown class", l}) } st = _EXPECT_ANY_NOCLASS_BL case _STRING: // TTL is this case ttl, ok := strconv.Atoi(l.token) if ok != nil { - fmt.Printf("%s\n", &ParseError{"Not a TTL", l}) + fmt.Printf("%s\n", &ParseError{"Not a TTL", l}) } else { h.Ttl = uint32(ttl) } st = _EXPECT_ANY_NOTTL_BL default: - fmt.Printf("%s\n", &ParseError{"Expecting RR type, TTL or class, not this...", l}) + fmt.Printf("%s\n", &ParseError{"Expecting RR type, TTL or class, not this...", l}) } case _EXPECT_ANY_NOCLASS_BL: if l.value != _BLANK { - fmt.Printf("%s\n", &ParseError{"No blank before NOCLASS", l}) + fmt.Printf("%s\n", &ParseError{"No blank before NOCLASS", l}) } st = _EXPECT_ANY_NOCLASS case _EXPECT_ANY_NOTTL_BL: if l.value != _BLANK { - fmt.Printf("%s\n", &ParseError{"No blank before NOTTL", l}) + fmt.Printf("%s\n", &ParseError{"No blank before NOTTL", l}) } st = _EXPECT_ANY_NOTTL case _EXPECT_ANY_NOTTL: @@ -149,47 +152,42 @@ func ParseZone(r io.Reader, cr chan RR) { case _CLASS: h.Class, ok = Str_class[strings.ToUpper(l.token)] if !ok { - fmt.Printf("%s\n", &ParseError{"Unknown class", l}) + fmt.Printf("%s\n", &ParseError{"Unknown class", l}) } st = _EXPECT_RRTYPE_BL case _RRTYPE: h.Rrtype, _ = Str_rr[strings.ToUpper(l.token)] - st = _EXPECT_RDATA_BL + st = _EXPECT_RDATA } case _EXPECT_ANY_NOCLASS: switch l.value { case _STRING: // TTL ttl, ok := strconv.Atoi(l.token) if ok != nil { - fmt.Printf("%s\n", &ParseError{"Not a TTL", l}) + fmt.Printf("%s\n", &ParseError{"Not a TTL", l}) } else { h.Ttl = uint32(ttl) } - st = _EXPECT_RDATA_BL + st = _EXPECT_RDATA case _RRTYPE: h.Rrtype, _ = Str_rr[strings.ToUpper(l.token)] - st = _EXPECT_RDATA_BL + st = _EXPECT_RDATA default: - fmt.Printf("%s\n", &ParseError{"Expecting RR type or TTL, not this...", l}) + fmt.Printf("%s\n", &ParseError{"Expecting RR type or TTL, not this...", l}) } case _EXPECT_RRTYPE_BL: if l.value != _BLANK { - fmt.Printf("%s\n", &ParseError{"No blank after", l}) + fmt.Printf("%s\n", &ParseError{"No blank after", l}) } st = _EXPECT_RRTYPE case _EXPECT_RRTYPE: if l.value != _RRTYPE { - fmt.Printf("%s\n", &ParseError{"Unknown RR type", l}) + fmt.Printf("%s\n", &ParseError{"Unknown RR type", l}) } h.Rrtype, _ = Str_rr[strings.ToUpper(l.token)] - st = _EXPECT_RDATA_BL - case _EXPECT_RDATA_BL: - if l.value != _BLANK { - println("No blank after error") - } st = _EXPECT_RDATA case _EXPECT_RDATA: - r, e := setRR(h, c, l) + r, e := setRR(h, c, l) if e != nil { fmt.Printf("%v\n", e) } diff --git a/zscan_rr.go b/zscan_rr.go index a5563466..d9a2be60 100644 --- a/zscan_rr.go +++ b/zscan_rr.go @@ -1,9 +1,9 @@ package dns import ( - "net" - "strconv" - "strings" + "net" + "strconv" + "strings" ) // All data from c is either _STRING or _BLANK @@ -12,341 +12,364 @@ import ( // an error: garbage after rdata. func slurpRemainder(c chan Lex) error { - l := <-c - switch l.value { - case _BLANK: - l = <-c - if l.value != _NEWLINE { - return &ParseError{"garbage after rdata", l} - } - // Ok - case _NEWLINE: - // Ok - default: - return &ParseError{"garbage after rdata", l} - } - return nil + l := <-c + switch l.value { + case _BLANK: + l = <-c + if l.value != _NEWLINE && l.value != _EOF { + return &ParseError{"garbage after rdata", l} + } + // Ok + case _NEWLINE: + // Ok + case _EOF: + // Ok + default: + return &ParseError{"garbage after rdata", l} + } + return nil } func setRR(h RR_Header, c chan Lex, currenttok Lex) (RR, error) { - var ( - r RR - e error - ) - switch h.Rrtype { - case TypeA: - r, e = setA(h, c) - if se := slurpRemainder(c); se != nil { - return nil, se - } - case TypeAAAA: - r, e = setAAAA(h, c) - if se := slurpRemainder(c); se != nil { - return nil, se - } - case TypeNS: - r, e = setNS(h, c) - if se := slurpRemainder(c); se != nil { - return nil, se - } - case TypeMX: - r, e = setMX(h, c) - if se := slurpRemainder(c); se != nil { - return nil, se - } - case TypeCNAME: - r, e = setCNAME(h, c) - if se := slurpRemainder(c); se != nil { - return nil, se - } - case TypeSOA: - r, e = setSOA(h, c) - if se := slurpRemainder(c); se != nil { - return nil, se - } - // 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 TypeRRSIG: - r, e = setRRSIG(h, c) - case TypeNSEC: - r, e = setNSEC(h, c) - case TypeNSEC3: - r, e = setNSEC3(h, c) - case TypeTXT: - r, e = setTXT(h, c) - default: - return nil, &ParseError{"Unknown RR type", currenttok} - } - return r, e + var ( + r RR + e error + ) + switch h.Rrtype { + case TypeA: + r, e = setA(h, c) + if e != nil { + return nil, e + } + if se := slurpRemainder(c); se != nil { + return nil, se + } + case TypeAAAA: + r, e = setAAAA(h, c) + if e != nil { + return nil, e + } + if se := slurpRemainder(c); se != nil { + return nil, se + } + case TypeNS: + r, e = setNS(h, c) + if e != nil { + return nil, e + } + if se := slurpRemainder(c); se != nil { + return nil, se + } + case TypeMX: + r, e = setMX(h, c) + if e != nil { + return nil, e + } + if se := slurpRemainder(c); se != nil { + return nil, se + } + case TypeCNAME: + r, e = setCNAME(h, c) + if e != nil { + return nil, e + } + if se := slurpRemainder(c); se != nil { + return nil, se + } + case TypeSOA: + r, e = setSOA(h, c) + if e != nil { + return nil, e + } + if se := slurpRemainder(c); se != nil { + return nil, se + } + // 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 TypeRRSIG: + r, e = setRRSIG(h, c) + case TypeNSEC: + r, e = setNSEC(h, c) + case TypeNSEC3: + r, e = setNSEC3(h, c) + case TypeTXT: + r, e = setTXT(h, c) + default: + return nil, &ParseError{"Unknown RR type", currenttok} + } + return r, e } func setA(h RR_Header, c chan Lex) (RR, error) { - rr := new(RR_A) - rr.Hdr = h + rr := new(RR_A) + rr.Hdr = h - l := <-c - rr.A = net.ParseIP(l.token) - if rr.A == nil { - return nil, &ParseError{"bad a", l} - } - return rr, nil + l := <-c + rr.A = net.ParseIP(l.token) + if rr.A == nil { + return nil, &ParseError{"bad a", l} + } + return rr, nil } func setAAAA(h RR_Header, c chan Lex) (RR, error) { - rr := new(RR_AAAA) - rr.Hdr = h + rr := new(RR_AAAA) + rr.Hdr = h - l := <-c - rr.AAAA = net.ParseIP(l.token) - if rr.AAAA == nil { - return nil, &ParseError{"bad AAAA", l} - } - return rr, nil + l := <-c + rr.AAAA = net.ParseIP(l.token) + if rr.AAAA == nil { + return nil, &ParseError{"bad AAAA", l} + } + return rr, nil } func setNS(h RR_Header, c chan Lex) (RR, error) { - rr := new(RR_NS) - rr.Hdr = h + rr := new(RR_NS) + rr.Hdr = h - l := <-c - rr.Ns = l.token - if ! IsDomainName(l.token) { - return nil, &ParseError{"bad NS", l} - } - return rr, nil + l := <-c + rr.Ns = l.token + if !IsDomainName(l.token) { + return nil, &ParseError{"bad NS", l} + } + return rr, nil } func setMX(h RR_Header, c chan Lex) (RR, error) { - rr := new(RR_MX) - rr.Hdr = h + rr := new(RR_MX) + rr.Hdr = h - l := <-c - if i, e := strconv.Atoi(l.token); e != nil { - return nil, &ParseError{"bad MX", l} - } else { - rr.Pref = uint16(i) -} - <-c // _BLANK - l = <-c // _STRING - rr.Mx = l.token - if ! IsDomainName(l.token) { - return nil, &ParseError{"bad CNAME", l} - } - return rr, nil + l := <-c + if i, e := strconv.Atoi(l.token); e != nil { + return nil, &ParseError{"bad MX", l} + } else { + rr.Pref = uint16(i) + } + <-c // _BLANK + l = <-c // _STRING + rr.Mx = l.token + if !IsDomainName(l.token) { + return nil, &ParseError{"bad CNAME", l} + } + return rr, nil } func setCNAME(h RR_Header, c chan Lex) (RR, error) { - rr := new(RR_CNAME) - rr.Hdr = h + rr := new(RR_CNAME) + rr.Hdr = h - l := <-c - rr.Cname = l.token - if ! IsDomainName(l.token) { - return nil, &ParseError{"bad CNAME", l} - } - return rr, nil + l := <-c + rr.Cname = l.token + if !IsDomainName(l.token) { + return nil, &ParseError{"bad CNAME", l} + } + return rr, nil } func setSOA(h RR_Header, c chan Lex) (RR, error) { - rr := new(RR_SOA) - rr.Hdr = h + rr := new(RR_SOA) + rr.Hdr = h - l := <-c - rr.Ns = l.token - <-c // _BLANK - if ! IsDomainName(l.token) { - return nil, &ParseError{"bad SOA", l} - } + l := <-c + rr.Ns = l.token + <-c // _BLANK + if !IsDomainName(l.token) { + return nil, &ParseError{"bad SOA mname", l} + } - l = <-c - rr.Mbox = l.token - if ! IsDomainName(l.token) { - return nil, &ParseError{"bad SOA", l} - } - <-c // _BLANK + l = <-c + rr.Mbox = l.token + if !IsDomainName(l.token) { + return nil, &ParseError{"bad SOA rname", l} + } + <-c // _BLANK - var ( - j int - e error - ) - for i := 0; i < 5; i++ { - l = <-c - if j, e = strconv.Atoi(l.token); e != nil { - return nil, &ParseError{"bad SOA", l} - } - switch i { - case 0: rr.Serial = uint32(j) - case 1: rr.Refresh = uint32(j) - case 2: rr.Retry = uint32(j) - case 3: rr.Expire = uint32(j) - case 4: rr.Minttl = uint32(j) - } - <-c // _BLANK - } - return rr, nil + var j int + var e error + for i := 0; i < 5; i++ { + l = <-c + if j, e = strconv.Atoi(l.token); e != nil { + return nil, &ParseError{"bad SOA zone parameter", l} + } + switch i { + case 0: + rr.Serial = uint32(j) + case 1: + rr.Refresh = uint32(j) + case 2: + rr.Retry = uint32(j) + case 3: + rr.Expire = uint32(j) + case 4: + rr.Minttl = uint32(j) + } + <-c // _BLANK + } + return rr, nil } func setRRSIG(h RR_Header, c chan Lex) (RR, error) { - rr := new(RR_RRSIG) - rr.Hdr = h - l := <-c - if t, ok := Str_rr[strings.ToUpper(l.token)]; !ok { - return nil, &ParseError{"bad RRSIG", l} - } else { - rr.TypeCovered = t - } - <-c // _BLANK - l = <-c - if i, err := strconv.Atoi(l.token); err != nil { - return nil, &ParseError{"bad RRSIG", l} - } else { - rr.Algorithm = uint8(i) - } - <-c // _BLANK - l = <-c - if i, err := strconv.Atoi(l.token); err != nil { - return nil, &ParseError{"bad RRSIG", l} - } else { - rr.Labels = uint8(i) - } - <-c // _BLANK - l = <-c - if i, err := strconv.Atoi(l.token); err != nil { - return nil, &ParseError{"bad RRSIG", l} - } else { - rr.OrigTtl = uint32(i) - } - <-c // _BLANK - l = <-c - if i, err := dateToTime(l.token); err != nil { - return nil, &ParseError{"bad RRSIG", l} - } else { - rr.Expiration = i - } - <-c // _BLANK - l = <-c - if i, err := dateToTime(l.token); err != nil { - return nil, &ParseError{"bad RRSIG", l} - } else { - rr.Inception = i - } - <-c // _BLANK - l = <-c - if i, err := strconv.Atoi(l.token); err != nil { - return nil, &ParseError{"bad RRSIG", l} - } else { - rr.KeyTag = uint16(i) - } - <-c // _BLANK - l = <-c - if ! IsDomainName(l.token) { - return nil, &ParseError{"bad RRSIG", l} - } else { - rr.SignerName = l.token - } - // Get the remaining data until we see a NEWLINE - l = <-c - var s string - for l.value != _NEWLINE { - switch l.value { - case _STRING: - s += l.token - case _BLANK: - // Ok - default: - return nil, &ParseError{"bad RRSIG", l} - } - l = <-c - } - rr.Signature = s - return rr, nil - } + rr := new(RR_RRSIG) + rr.Hdr = h + l := <-c + if t, ok := Str_rr[strings.ToUpper(l.token)]; !ok { + return nil, &ParseError{"bad RRSIG", l} + } else { + rr.TypeCovered = t + } + <-c // _BLANK + l = <-c + if i, err := strconv.Atoi(l.token); err != nil { + return nil, &ParseError{"bad RRSIG", l} + } else { + rr.Algorithm = uint8(i) + } + <-c // _BLANK + l = <-c + if i, err := strconv.Atoi(l.token); err != nil { + return nil, &ParseError{"bad RRSIG", l} + } else { + rr.Labels = uint8(i) + } + <-c // _BLANK + l = <-c + if i, err := strconv.Atoi(l.token); err != nil { + return nil, &ParseError{"bad RRSIG", l} + } else { + rr.OrigTtl = uint32(i) + } + <-c // _BLANK + l = <-c + if i, err := dateToTime(l.token); err != nil { + return nil, &ParseError{"bad RRSIG", l} + } else { + rr.Expiration = i + } + <-c // _BLANK + l = <-c + if i, err := dateToTime(l.token); err != nil { + return nil, &ParseError{"bad RRSIG", l} + } else { + rr.Inception = i + } + <-c // _BLANK + l = <-c + if i, err := strconv.Atoi(l.token); err != nil { + return nil, &ParseError{"bad RRSIG", l} + } else { + rr.KeyTag = uint16(i) + } + <-c // _BLANK + l = <-c + if !IsDomainName(l.token) { + return nil, &ParseError{"bad RRSIG", l} + } else { + rr.SignerName = l.token + } + // Get the remaining data until we see a NEWLINE + l = <-c + var s string + for l.value != _NEWLINE && l.value != _EOF { + switch l.value { + case _STRING: + s += l.token + case _BLANK: + // Ok + default: + return nil, &ParseError{"bad RRSIG", l} + } + l = <-c + } + rr.Signature = s + return rr, nil +} func setNSEC(h RR_Header, c chan Lex) (RR, error) { - rr := new(RR_NSEC) - rr.Hdr = h + rr := new(RR_NSEC) + rr.Hdr = h - l := <-c - if ! IsDomainName(l.token) { - return nil, &ParseError{"bad NSEC", l} - } else { - rr.NextDomain = l.token - } + l := <-c + if !IsDomainName(l.token) { + return nil, &ParseError{"bad NSEC", l} + } else { + rr.NextDomain = l.token + } - rr.TypeBitMap = make([]uint16, 0) - l = <-c - for l.value != _NEWLINE { - switch l.value { - case _BLANK: - // Ok - case _STRING: - if k, ok := Str_rr[strings.ToUpper(l.token)]; !ok { - return nil, &ParseError{"bad NSEC", l} - } else { - rr.TypeBitMap = append(rr.TypeBitMap, k) - } - default: - return nil, &ParseError{"bad NSEC", l} - } - l = <-c - } - return rr, nil - } + rr.TypeBitMap = make([]uint16, 0) + l = <-c + for l.value != _NEWLINE && l.value != _EOF { + switch l.value { + case _BLANK: + // Ok + case _STRING: + if k, ok := Str_rr[strings.ToUpper(l.token)]; !ok { + return nil, &ParseError{"bad NSEC", l} + } else { + rr.TypeBitMap = append(rr.TypeBitMap, k) + } + default: + return nil, &ParseError{"bad NSEC", l} + } + l = <-c + } + return rr, nil +} func setNSEC3(h RR_Header, c chan Lex) (RR, error) { - rr := new(RR_NSEC3) - rr.Hdr = h + rr := new(RR_NSEC3) + rr.Hdr = h - l := <-c - if i, e := strconv.Atoi(l.token); e != nil { - return nil, &ParseError{"bad NSEC3", l} - } else { - rr.Hash = uint8(i) - } - <-c // _BLANK - l = <-c - if i, e := strconv.Atoi(l.token); e != nil { - return nil, &ParseError{"bad NSEC3", l} - } else { - rr.Flags = uint8(i) - } - <-c // _BLANK - l = <-c - if i, e := strconv.Atoi(l.token); e != nil { - return nil, &ParseError{"bad NSEC3", l} - } else { - rr.Iterations = uint16(i) - } - <-c - l = <-c - rr.SaltLength = uint8(len(l.token)) - rr.Salt = l.token // CHECK? + l := <-c + if i, e := strconv.Atoi(l.token); e != nil { + return nil, &ParseError{"bad NSEC3", l} + } else { + rr.Hash = uint8(i) + } + <-c // _BLANK + l = <-c + if i, e := strconv.Atoi(l.token); e != nil { + return nil, &ParseError{"bad NSEC3", l} + } else { + rr.Flags = uint8(i) + } + <-c // _BLANK + l = <-c + if i, e := strconv.Atoi(l.token); e != nil { + return nil, &ParseError{"bad NSEC3", l} + } else { + rr.Iterations = uint16(i) + } + <-c + l = <-c + rr.SaltLength = uint8(len(l.token)) + rr.Salt = l.token // CHECK? - <-c - l = <-c - rr.HashLength = uint8(len(l.token)) - rr.NextDomain = l.token + <-c + l = <-c + rr.HashLength = uint8(len(l.token)) + rr.NextDomain = l.token - rr.TypeBitMap = make([]uint16, 0) - l = <-c - for l.value != _NEWLINE { - switch l.value { - case _BLANK: - // Ok - case _STRING: - if k, ok := Str_rr[strings.ToUpper(l.token)]; !ok { - return nil, &ParseError{"bad NSEC3", l} - } else { - rr.TypeBitMap = append(rr.TypeBitMap, k) - } - default: - return nil, &ParseError{"bad NSEC3", l} - } - l = <-c - } - return rr, nil - } + rr.TypeBitMap = make([]uint16, 0) + l = <-c + for l.value != _NEWLINE && l.value != _EOF { + switch l.value { + case _BLANK: + // Ok + case _STRING: + if k, ok := Str_rr[strings.ToUpper(l.token)]; !ok { + return nil, &ParseError{"bad NSEC3", l} + } else { + rr.TypeBitMap = append(rr.TypeBitMap, k) + } + default: + return nil, &ParseError{"bad NSEC3", l} + } + l = <-c + } + return rr, nil +} /* func setNSEC3PARAM(h RR_Header, c chan Lex) (RR, error) { @@ -375,28 +398,29 @@ func setNSEC3PARAM(h RR_Header, c chan Lex) (RR, error) { */ func setTXT(h RR_Header, c chan Lex) (RR, error) { - rr := new(RR_TXT) - rr.Hdr = h + rr := new(RR_TXT) + rr.Hdr = h - // Get the remaining data until we see a NEWLINE - l := <-c - var s string - for l.value != _NEWLINE { - switch l.value { - case _STRING: - s += l.token - case _BLANK: - // Ok - default: - return nil, &ParseError{"bad TXT", l} - } - l = <-c - } - rr.Txt = s - return rr, nil + // Get the remaining data until we see a NEWLINE + l := <-c + var s string + for l.value != _NEWLINE && l.value != _EOF { + println("tok", l.token, l.value) + switch l.value { + case _STRING: + s += l.token + case _BLANK: + s += l.token + default: + return nil, &ParseError{"bad TXT", l} + } + l = <-c + } + rr.Txt = s + return rr, nil } - /* +/* func setDS(h RR_Header, c chan Lex) (RR, error) { rr := new(RR_DS) rr.Hdr = h