diff --git a/msg.go b/msg.go index 1e16b055..b560d26e 100644 --- a/msg.go +++ b/msg.go @@ -588,35 +588,6 @@ func packStructValue(val reflect.Value, msg []byte, off int, compression map[str return lenmsg, err } } - case `dns:"txt"`: - if txtTmp == nil { - txtTmp = make([]byte, 256*4+1) - } - off, err = packTxt(fv.Interface().([]string), msg, off, txtTmp) - if err != nil { - return lenmsg, err - } - case `dns:"opt"`: // edns - for j := 0; j < val.Field(i).Len(); j++ { - element := val.Field(i).Index(j).Interface() - b, err := element.(EDNS0).pack() - if err != nil || off+3 > lenmsg { - return lenmsg, &Error{err: "overflow packing opt"} - } - // Option code - binary.BigEndian.PutUint16(msg[off:], element.(EDNS0).Option()) - // Length - binary.BigEndian.PutUint16(msg[off+2:], uint16(len(b))) - off += 4 - if off+len(b) > lenmsg { - copy(msg[off:], b) - off = lenmsg - continue - } - // Actual data - copy(msg[off:off+len(b)], b) - off += len(b) - } case `dns:"a"`: if val.Type().String() == "dns.IPSECKEY" { // Field(2) is GatewayType, must be 1 @@ -899,108 +870,6 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, err er servers = append(servers, s) } fv.Set(reflect.ValueOf(servers)) - case `dns:"txt"`: - if off == lenmsg { - break - } - var txt []string - txt, off, err = unpackTxt(msg, off) - if err != nil { - return lenmsg, err - } - fv.Set(reflect.ValueOf(txt)) - case `dns:"opt"`: // edns0 - if off == lenmsg { - // This is an EDNS0 (OPT Record) with no rdata - // We can safely return here. - break - } - var edns []EDNS0 - Option: - code := uint16(0) - if off+4 > lenmsg { - return lenmsg, &Error{err: "overflow unpacking opt"} - } - code = binary.BigEndian.Uint16(msg[off:]) - off += 2 - optlen := binary.BigEndian.Uint16(msg[off:]) - off1 := off + 2 - if off1+int(optlen) > lenmsg { - return lenmsg, &Error{err: "overflow unpacking opt"} - } - switch code { - case EDNS0NSID: - e := new(EDNS0_NSID) - if err := e.unpack(msg[off1 : off1+int(optlen)]); err != nil { - return lenmsg, err - } - edns = append(edns, e) - off = off1 + int(optlen) - case EDNS0SUBNET, EDNS0SUBNETDRAFT: - e := new(EDNS0_SUBNET) - if err := e.unpack(msg[off1 : off1+int(optlen)]); err != nil { - return lenmsg, err - } - edns = append(edns, e) - off = off1 + int(optlen) - if code == EDNS0SUBNETDRAFT { - e.DraftOption = true - } - case EDNS0COOKIE: - e := new(EDNS0_COOKIE) - if err := e.unpack(msg[off1 : off1+int(optlen)]); err != nil { - return lenmsg, err - } - edns = append(edns, e) - off = off1 + int(optlen) - case EDNS0UL: - e := new(EDNS0_UL) - if err := e.unpack(msg[off1 : off1+int(optlen)]); err != nil { - return lenmsg, err - } - edns = append(edns, e) - off = off1 + int(optlen) - case EDNS0LLQ: - e := new(EDNS0_LLQ) - if err := e.unpack(msg[off1 : off1+int(optlen)]); err != nil { - return lenmsg, err - } - edns = append(edns, e) - off = off1 + int(optlen) - case EDNS0DAU: - e := new(EDNS0_DAU) - if err := e.unpack(msg[off1 : off1+int(optlen)]); err != nil { - return lenmsg, err - } - edns = append(edns, e) - off = off1 + int(optlen) - case EDNS0DHU: - e := new(EDNS0_DHU) - if err := e.unpack(msg[off1 : off1+int(optlen)]); err != nil { - return lenmsg, err - } - edns = append(edns, e) - off = off1 + int(optlen) - case EDNS0N3U: - e := new(EDNS0_N3U) - if err := e.unpack(msg[off1 : off1+int(optlen)]); err != nil { - return lenmsg, err - } - edns = append(edns, e) - off = off1 + int(optlen) - default: - e := new(EDNS0_LOCAL) - e.Code = code - if err := e.unpack(msg[off1 : off1+int(optlen)]); err != nil { - return lenmsg, err - } - edns = append(edns, e) - off = off1 + int(optlen) - } - if off < lenmsg { - goto Option - } - fv.Set(reflect.ValueOf(edns)) case `dns:"a"`: if val.Type().String() == "dns.IPSECKEY" { // Field(2) is GatewayType, must be 1 @@ -1296,11 +1165,10 @@ func PackRR(rr RR, msg []byte, off int, compression map[string]int, compress boo return len(msg), &Error{err: "nil rr"} } - _, ok := typeToUnpack[rr.Header().Rrtype] + _, ok := blacklist[rr.Header().Rrtype] switch ok { - case true: + case false: off1, err = rr.pack(msg, off, compression, compress) - // TODO(miek): revert the logic and make a blacklist for types that still use reflection. Kill typeToUnpack. default: off1, err = packStructCompress(rr, msg, off, compression, compress) } @@ -1322,14 +1190,17 @@ func UnpackRR(msg []byte, off int) (rr RR, off1 int, err error) { } end := off + int(h.Rdlength) - fn, ok := typeToUnpack[h.Rrtype] + _, ok := blacklist[h.Rrtype] switch ok { - case true: + case false: // Shortcut reflection. - rr, off, err = fn(h, msg, off) + if fn, known := typeToUnpack[h.Rrtype]; !known { + rr, off, err = unpackRFC3597(h, msg, off) + } else { + rr, off, err = fn(h, msg, off) + } default: - mk, known := TypeToRR[h.Rrtype] - if !known { + if mk, known := TypeToRR[h.Rrtype]; !known { rr = new(RFC3597) } else { rr = mk() @@ -1982,25 +1853,10 @@ func unpackMsgHdr(msg []byte, off int) (Header, int, error) { return dh, off, err } -// Which types have type specific unpack functions. -var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){ - TypeAAAA: unpackAAAA, - TypeA: unpackA, - TypeCNAME: unpackCNAME, - TypeDNAME: unpackDNAME, - TypeL32: unpackL32, - TypeLOC: unpackLOC, - TypeMB: unpackMB, - TypeMD: unpackMD, - TypeMF: unpackMF, - TypeMG: unpackMG, - TypeMR: unpackMR, - TypeMX: unpackMX, - TypeNID: unpackNID, - TypeNS: unpackNS, - TypePTR: unpackPTR, - TypeRP: unpackRP, - TypeSRV: unpackSRV, - TypeHINFO: unpackHINFO, - TypeDNSKEY: unpackDNSKEY, +// Which types do no work reflectionless yet. +var blacklist = map[uint16]bool{ + TypeHIP: true, + TypeIPSECKEY: true, + TypeNSEC3: true, + TypeTSIG: true, } diff --git a/msg_generate.go b/msg_generate.go index 9076bfc1..6e63b704 100644 --- a/msg_generate.go +++ b/msg_generate.go @@ -16,17 +16,11 @@ import ( "os" ) -// All RR pack and unpack functions should be generated, currently RR that present some -// problems -// * NSEC/NSEC3 - type bitmap -// * TXT/SPF - string slice -// * URI - weird octet thing there -// * NSEC3/TSIG - size hex -// * OPT RR - EDNS0 parsing - needs to some looking at +// All RR pack and unpack functions should be generated, currently RR that present some problems +// * NSEC3 - size hex +// * TSIG - size hex // * HIP - uses "hex", but is actually size-hex - might drop size-hex? -// * Z -// * NINFO -// * PrivateRR +// * IPSECKEY - var packageHdr = ` // *** DO NOT MODIFY *** @@ -90,10 +84,7 @@ func main() { fmt.Fprint(b, "// pack*() functions\n\n") for _, name := range namedTypes { o := scope.Lookup(name) - st, isEmbedded := getTypeStruct(o.Type(), scope) - if isEmbedded { - continue - } + st, _ := getTypeStruct(o.Type(), scope) fmt.Fprintf(b, "func (rr *%s) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {\n", name) fmt.Fprint(b, `off, err := rr.Hdr.pack(msg, off, compression, compress) @@ -113,19 +104,23 @@ return off, err if _, ok := st.Field(i).Type().(*types.Slice); ok { switch st.Tag(i) { - case `dns:"-"`: - // ignored + case `dns:"-"`: // ignored case `dns:"txt"`: o("off, err = packStringTxt(rr.%s, msg, off)\n") + case `dns:"opt"`: + o("off, err = packDataOpt(rr.%s, msg, off)\n") + case `dns:"nsec"`: + o("off, err = packDataNsec(rr.%s, msg, off)\n") + case `dns:"domain-name"`: + o("off, err = packDataDomainNames(rr.%s, msg, off, compression, compress)\n") default: - //log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) + log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) } continue } switch st.Tag(i) { - case `dns:"-"`: - // ignored + case `dns:"-"`: // ignored case `dns:"cdomain-name"`: fallthrough case `dns:"domain-name"`: @@ -142,6 +137,10 @@ return off, err o("off, err = packStringBase32(rr.%s, msg, off)\n") case `dns:"base64"`: o("off, err = packStringBase64(rr.%s, msg, off)\n") + case `dns:"hex"`: + o("off, err = packStringHex(rr.%s, msg, off)\n") + case `dns:"octet"`: + o("off, err = packStringOctet(rr.%s, msg, off)\n") case "": switch st.Field(i).Type().(*types.Basic).Kind() { case types.Uint8: @@ -169,14 +168,11 @@ return off, err fmt.Fprint(b, "// unpack*() functions\n\n") for _, name := range namedTypes { o := scope.Lookup(name) - st, isEmbedded := getTypeStruct(o.Type(), scope) - if isEmbedded { - continue - } + st, _ := getTypeStruct(o.Type(), scope) fmt.Fprintf(b, "func unpack%s(h RR_Header, msg []byte, off int) (RR, int, error) {\n", name) fmt.Fprint(b, `if noRdata(h) { -return nil, off, nil +return &h, off, nil } var err error rdStart := off @@ -196,19 +192,23 @@ return rr, off, err if _, ok := st.Field(i).Type().(*types.Slice); ok { switch st.Tag(i) { - case `dns:"-"`: - // ignored + case `dns:"-"`: // ignored case `dns:"txt"`: o("rr.%s, off, err = unpackStringTxt(msg, off)\n") + case `dns:"opt"`: + o("rr.%s, off, err = unpackDataOpt(msg, off)\n") + case `dns:"nsec"`: + o("rr.%s, off, err = unpackDataNsec(msg, off)\n") + case `dns:"domain-name"`: + o("rr.%s, off, err = unpackDataDomainNames(msg, off, rdStart + int(rr.Hdr.Rdlength))\n") default: - //log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) + log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) } continue } switch st.Tag(i) { - case `dns:"-"`: - // ignored + case `dns:"-"`: // ignored case `dns:"cdomain-name"`: fallthrough case `dns:"domain-name"`: @@ -225,6 +225,10 @@ return rr, off, err o("rr.%s, off, err = unpackStringBase32(msg, off, rdStart + int(rr.Hdr.Rdlength))\n") case `dns:"base64"`: o("rr.%s, off, err = unpackStringBase64(msg, off, rdStart + int(rr.Hdr.Rdlength))\n") + case `dns:"hex"`: + o("rr.%s, off, err = unpackStringHex(msg, off, rdStart + int(rr.Hdr.Rdlength))\n") + case `dns:"octet"`: + o("rr.%s, off, err = unpackStringOctet(msg, off)\n") case "": switch st.Field(i).Type().(*types.Basic).Kind() { case types.Uint8: @@ -253,6 +257,15 @@ return rr, off, nil } fmt.Fprintf(b, "return rr, off, err }\n\n") } + // Generate typeToUnpack map + fmt.Fprintln(b, "var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){") + for _, name := range namedTypes { + if name == "RFC3597" { + continue + } + fmt.Fprintf(b, "Type%s: unpack%s,\n", name, name) + } + fmt.Fprintln(b, "}\n") // gofmt res, err := format.Source(b.Bytes()) diff --git a/msg_helpers.go b/msg_helpers.go index 0364dee8..00c6255a 100644 --- a/msg_helpers.go +++ b/msg_helpers.go @@ -359,3 +359,251 @@ func packStringTxt(s []string, msg []byte, off int) (int, error) { } return off, nil } + +func unpackDataOpt(msg []byte, off int) ([]EDNS0, int, error) { + var edns []EDNS0 +Option: + code := uint16(0) + if off+4 > len(msg) { + return nil, len(msg), &Error{err: "overflow unpacking opt"} + } + code = binary.BigEndian.Uint16(msg[off:]) + off += 2 + optlen := binary.BigEndian.Uint16(msg[off:]) + off += 2 + if off+int(optlen) > len(msg) { + return nil, len(msg), &Error{err: "overflow unpacking opt"} + } + switch code { + case EDNS0NSID: + e := new(EDNS0_NSID) + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + case EDNS0SUBNET, EDNS0SUBNETDRAFT: + e := new(EDNS0_SUBNET) + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + if code == EDNS0SUBNETDRAFT { + e.DraftOption = true + } + case EDNS0COOKIE: + e := new(EDNS0_COOKIE) + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + case EDNS0UL: + e := new(EDNS0_UL) + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + case EDNS0LLQ: + e := new(EDNS0_LLQ) + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + case EDNS0DAU: + e := new(EDNS0_DAU) + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + case EDNS0DHU: + e := new(EDNS0_DHU) + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + case EDNS0N3U: + e := new(EDNS0_N3U) + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + default: + e := new(EDNS0_LOCAL) + e.Code = code + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + } + + if off < len(msg) { + goto Option + } + + return edns, off, nil +} + +func packDataOpt(options []EDNS0, msg []byte, off int) (int, error) { + for _, el := range options { + b, err := el.pack() + if err != nil || off+3 > len(msg) { + return len(msg), &Error{err: "overflow packing opt"} + } + binary.BigEndian.PutUint16(msg[off:], el.Option()) // Option code + binary.BigEndian.PutUint16(msg[off+2:], uint16(len(b))) // Length + off += 4 + if off+len(b) > len(msg) { + copy(msg[off:], b) + off = len(msg) + continue + } + // Actual data + copy(msg[off:off+len(b)], b) + off += len(b) + } + return off, nil +} + +func unpackStringOctet(msg []byte, off int) (string, int, error) { + s := string(msg[off:]) + return s, len(msg), nil +} + +func packStringOctet(s string, msg []byte, off int) (int, error) { + txtTmp := make([]byte, 256*4+1) + off, err := packOctetString(s, msg, off, txtTmp) + if err != nil { + return len(msg), err + } + return off, nil +} + +func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) { + var nsec []uint16 + length, window, lastwindow := 0, 0, -1 + for off < len(msg) { + if off+2 > len(msg) { + return nsec, len(msg), &Error{err: "overflow unpacking nsecx"} + } + window = int(msg[off]) + length = int(msg[off+1]) + off += 2 + if window <= lastwindow { + // RFC 4034: Blocks are present in the NSEC RR RDATA in + // increasing numerical order. + return nsec, len(msg), &Error{err: "out of order NSEC block"} + } + if length == 0 { + // RFC 4034: Blocks with no types present MUST NOT be included. + return nsec, len(msg), &Error{err: "empty NSEC block"} + } + if length > 32 { + return nsec, len(msg), &Error{err: "NSEC block too long"} + } + if off+length > len(msg) { + return nsec, len(msg), &Error{err: "overflowing NSEC block"} + } + + // Walk the bytes in the window and extract the type bits + for j := 0; j < length; j++ { + b := msg[off+j] + // Check the bits one by one, and set the type + if b&0x80 == 0x80 { + nsec = append(nsec, uint16(window*256+j*8+0)) + } + if b&0x40 == 0x40 { + nsec = append(nsec, uint16(window*256+j*8+1)) + } + if b&0x20 == 0x20 { + nsec = append(nsec, uint16(window*256+j*8+2)) + } + if b&0x10 == 0x10 { + nsec = append(nsec, uint16(window*256+j*8+3)) + } + if b&0x8 == 0x8 { + nsec = append(nsec, uint16(window*256+j*8+4)) + } + if b&0x4 == 0x4 { + nsec = append(nsec, uint16(window*256+j*8+5)) + } + if b&0x2 == 0x2 { + nsec = append(nsec, uint16(window*256+j*8+6)) + } + if b&0x1 == 0x1 { + nsec = append(nsec, uint16(window*256+j*8+7)) + } + } + off += length + lastwindow = window + } + return nsec, off, nil +} + +func packDataNsec(bitmap []uint16, msg []byte, off int) (int, error) { + if len(bitmap) == 0 { + return off, nil + } + var lastwindow, lastlength uint16 + for j := 0; j < len(bitmap); j++ { + t := bitmap[j] + window := t / 256 + length := (t-window*256)/8 + 1 + if window > lastwindow && lastlength != 0 { // New window, jump to the new offset + off += int(lastlength) + 2 + lastlength = 0 + } + if window < lastwindow || length < lastlength { + return len(msg), &Error{err: "nsec bits out of order"} + } + if off+2+int(length) > len(msg) { + return len(msg), &Error{err: "overflow packing nsec"} + } + // Setting the window # + msg[off] = byte(window) + // Setting the octets length + msg[off+1] = byte(length) + // Setting the bit value for the type in the right octet + msg[off+1+int(length)] |= byte(1 << (7 - (t % 8))) + lastwindow, lastlength = window, length + } + off += int(lastlength) + 2 + return off, nil +} + +func unpackDataDomainNames(msg []byte, off, end int) ([]string, int, error) { + var ( + servers []string + s string + err error + ) + if end > len(msg) { + return nil, len(msg), &Error{err: "overflow unpacking domain names"} + } + for off < end { + s, off, err = UnpackDomainName(msg, off) + if err != nil { + return servers, len(msg), err + } + servers = append(servers, s) + } + return servers, off, nil +} + +func packDataDomainNames(names []string, msg []byte, off int, compression map[string]int, compress bool) (int, error) { + var err error + for j := 0; j < len(names); j++ { + off, err = PackDomainName(names[j], msg, off, compression, false && compress) + if err != nil { + return len(msg), err + } + } + return off, nil +} diff --git a/privaterr.go b/privaterr.go index 7db26f43..6b08e6e9 100644 --- a/privaterr.go +++ b/privaterr.go @@ -66,11 +66,17 @@ func (r *PrivateRR) copy() RR { return rr } func (r *PrivateRR) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { + off, err := r.Hdr.pack(msg, off, compression, compress) + if err != nil { + return off, err + } + headerEnd := off n, err := r.Data.Pack(msg[off:]) if err != nil { return len(msg), err } off += n + r.Header().Rdlength = uint16(off - headerEnd) return off, nil } @@ -83,19 +89,36 @@ func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata) TypeToString[rtype] = rtypestr StringToType[rtypestr] = rtype + typeToUnpack[rtype] = func(h RR_Header, msg []byte, off int) (RR, int, error) { + if noRdata(h) { + return &h, off, nil + } + var err error + + rr := mkPrivateRR(h.Rrtype) + rr.Hdr = h + + off1, err := rr.Data.Unpack(msg[off:]) + off += off1 + if err != nil { + return rr, off, err + } + return rr, off, err + } + setPrivateRR := func(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { rr := mkPrivateRR(h.Rrtype) rr.Hdr = h var l lex text := make([]string, 0, 2) // could be 0..N elements, median is probably 1 - FETCH: + Fetch: for { // TODO(miek): we could also be returning _QUOTE, this might or might not // be an issue (basically parsing TXT becomes hard) switch l = <-c; l.value { case zNewline, zEOF: - break FETCH + break Fetch case zString: text = append(text, l.token) } @@ -120,6 +143,7 @@ func PrivateHandleRemove(rtype uint16) { delete(TypeToString, rtype) delete(typeToparserFunc, rtype) delete(StringToType, rtypestr) + delete(typeToUnpack, rtype) } return } diff --git a/privaterr_test.go b/privaterr_test.go index 1d99dc93..5f177aa4 100644 --- a/privaterr_test.go +++ b/privaterr_test.go @@ -87,6 +87,7 @@ func TestPrivateByteSlice(t *testing.T) { rr1, off1, err := dns.UnpackRR(buf[:off], 0) if err != nil { t.Errorf("got error unpacking ISBN: %v", err) + return } if off1 != off { diff --git a/zmsg.go b/zmsg.go index fad3b569..115c34ca 100644 --- a/zmsg.go +++ b/zmsg.go @@ -75,6 +75,62 @@ func (rr *CAA) pack(msg []byte, off int, compression map[string]int, compress bo if err != nil { return off, err } + off, err = packStringOctet(rr.Value, msg, off) + if err != nil { + return off, err + } + rr.Header().Rdlength = uint16(off - headerEnd) + return off, nil +} + +func (rr *CDNSKEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { + off, err := rr.Hdr.pack(msg, off, compression, compress) + if err != nil { + return off, err + } + headerEnd := off + off, err = packUint16(rr.Flags, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Protocol, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packStringBase64(rr.PublicKey, msg, off) + if err != nil { + return off, err + } + rr.Header().Rdlength = uint16(off - headerEnd) + return off, nil +} + +func (rr *CDS) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { + off, err := rr.Hdr.pack(msg, off, compression, compress) + if err != nil { + return off, err + } + headerEnd := off + off, err = packUint16(rr.KeyTag, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.DigestType, msg, off) + if err != nil { + return off, err + } + off, err = packStringHex(rr.Digest, msg, off) + if err != nil { + return off, err + } rr.Header().Rdlength = uint16(off - headerEnd) return off, nil } @@ -133,6 +189,32 @@ func (rr *DHCID) pack(msg []byte, off int, compression map[string]int, compress return off, nil } +func (rr *DLV) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { + off, err := rr.Hdr.pack(msg, off, compression, compress) + if err != nil { + return off, err + } + headerEnd := off + off, err = packUint16(rr.KeyTag, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.DigestType, msg, off) + if err != nil { + return off, err + } + off, err = packStringHex(rr.Digest, msg, off) + if err != nil { + return off, err + } + rr.Header().Rdlength = uint16(off - headerEnd) + return off, nil +} + func (rr *DNAME) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { @@ -191,6 +273,10 @@ func (rr *DS) pack(msg []byte, off int, compression map[string]int, compress boo if err != nil { return off, err } + off, err = packStringHex(rr.Digest, msg, off) + if err != nil { + return off, err + } rr.Header().Rdlength = uint16(off - headerEnd) return off, nil } @@ -201,6 +287,10 @@ func (rr *EID) pack(msg []byte, off int, compression map[string]int, compress bo return off, err } headerEnd := off + off, err = packStringHex(rr.Endpoint, msg, off) + if err != nil { + return off, err + } rr.Header().Rdlength = uint16(off - headerEnd) return off, nil } @@ -305,10 +395,18 @@ func (rr *HIP) pack(msg []byte, off int, compression map[string]int, compress bo if err != nil { return off, err } + off, err = packStringHex(rr.Hit, msg, off) + if err != nil { + return off, err + } off, err = packStringBase64(rr.PublicKey, msg, off) if err != nil { return off, err } + off, err = packDataDomainNames(rr.RendezvousServers, msg, off, compression, compress) + if err != nil { + return off, err + } rr.Header().Rdlength = uint16(off - headerEnd) return off, nil } @@ -351,6 +449,32 @@ func (rr *IPSECKEY) pack(msg []byte, off int, compression map[string]int, compre return off, nil } +func (rr *KEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { + off, err := rr.Hdr.pack(msg, off, compression, compress) + if err != nil { + return off, err + } + headerEnd := off + off, err = packUint16(rr.Flags, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Protocol, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packStringBase64(rr.PublicKey, msg, off) + if err != nil { + return off, err + } + rr.Header().Rdlength = uint16(off - headerEnd) + return off, nil +} + func (rr *KX) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { @@ -625,6 +749,10 @@ func (rr *NIMLOC) pack(msg []byte, off int, compression map[string]int, compress return off, err } headerEnd := off + off, err = packStringHex(rr.Locator, msg, off) + if err != nil { + return off, err + } rr.Header().Rdlength = uint16(off - headerEnd) return off, nil } @@ -681,6 +809,10 @@ func (rr *NSEC) pack(msg []byte, off int, compression map[string]int, compress b if err != nil { return off, err } + off, err = packDataNsec(rr.TypeBitMap, msg, off) + if err != nil { + return off, err + } rr.Header().Rdlength = uint16(off - headerEnd) return off, nil } @@ -711,6 +843,10 @@ func (rr *NSEC3) pack(msg []byte, off int, compression map[string]int, compress if err != nil { return off, err } + off, err = packDataNsec(rr.TypeBitMap, msg, off) + if err != nil { + return off, err + } rr.Header().Rdlength = uint16(off - headerEnd) return off, nil } @@ -737,6 +873,10 @@ func (rr *NSEC3PARAM) pack(msg []byte, off int, compression map[string]int, comp if err != nil { return off, err } + off, err = packStringHex(rr.Salt, msg, off) + if err != nil { + return off, err + } rr.Header().Rdlength = uint16(off - headerEnd) return off, nil } @@ -761,6 +901,10 @@ func (rr *OPT) pack(msg []byte, off int, compression map[string]int, compress bo return off, err } headerEnd := off + off, err = packDataOpt(rr.Option, msg, off) + if err != nil { + return off, err + } rr.Header().Rdlength = uint16(off - headerEnd) return off, nil } @@ -807,6 +951,10 @@ func (rr *RFC3597) pack(msg []byte, off int, compression map[string]int, compres return off, err } headerEnd := off + off, err = packStringHex(rr.Rdata, msg, off) + if err != nil { + return off, err + } rr.Header().Rdlength = uint16(off - headerEnd) return off, nil } @@ -919,6 +1067,52 @@ func (rr *RT) pack(msg []byte, off int, compression map[string]int, compress boo return off, nil } +func (rr *SIG) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { + off, err := rr.Hdr.pack(msg, off, compression, compress) + if err != nil { + return off, err + } + headerEnd := off + off, err = packUint16(rr.TypeCovered, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Labels, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(rr.OrigTtl, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(rr.Expiration, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(rr.Inception, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.KeyTag, msg, off) + if err != nil { + return off, err + } + off, err = PackDomainName(rr.SignerName, msg, off, compression, compress) + if err != nil { + return off, err + } + off, err = packStringBase64(rr.Signature, msg, off) + if err != nil { + return off, err + } + rr.Header().Rdlength = uint16(off - headerEnd) + return off, nil +} + func (rr *SOA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { @@ -1011,6 +1205,10 @@ func (rr *SSHFP) pack(msg []byte, off int, compression map[string]int, compress if err != nil { return off, err } + off, err = packStringHex(rr.FingerPrint, msg, off) + if err != nil { + return off, err + } rr.Header().Rdlength = uint16(off - headerEnd) return off, nil } @@ -1033,6 +1231,10 @@ func (rr *TA) pack(msg []byte, off int, compression map[string]int, compress boo if err != nil { return off, err } + off, err = packStringHex(rr.Digest, msg, off) + if err != nil { + return off, err + } rr.Header().Rdlength = uint16(off - headerEnd) return off, nil } @@ -1119,6 +1321,10 @@ func (rr *TLSA) pack(msg []byte, off int, compression map[string]int, compress b if err != nil { return off, err } + off, err = packStringHex(rr.Certificate, msg, off) + if err != nil { + return off, err + } rr.Header().Rdlength = uint16(off - headerEnd) return off, nil } @@ -1217,6 +1423,10 @@ func (rr *URI) pack(msg []byte, off int, compression map[string]int, compress bo if err != nil { return off, err } + off, err = packStringOctet(rr.Target, msg, off) + if err != nil { + return off, err + } rr.Header().Rdlength = uint16(off - headerEnd) return off, nil } @@ -1239,7 +1449,7 @@ func (rr *X25) pack(msg []byte, off int, compression map[string]int, compress bo func unpackA(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1257,7 +1467,7 @@ func unpackA(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackAAAA(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1275,7 +1485,7 @@ func unpackAAAA(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackAFSDB(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1300,7 +1510,7 @@ func unpackAFSDB(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackANY(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1314,7 +1524,7 @@ func unpackANY(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackCAA(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1337,12 +1547,94 @@ func unpackCAA(h RR_Header, msg []byte, off int) (RR, int, error) { if off == len(msg) { return rr, off, nil } + rr.Value, off, err = unpackStringOctet(msg, off) + if err != nil { + return rr, off, err + } + return rr, off, err +} + +func unpackCDNSKEY(h RR_Header, msg []byte, off int) (RR, int, error) { + if noRdata(h) { + return &h, off, nil + } + var err error + rdStart := off + _ = rdStart + + rr := new(CDNSKEY) + rr.Hdr = h + + rr.Flags, off, err = unpackUint16(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.Protocol, off, err = unpackUint8(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.Algorithm, off, err = unpackUint8(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return rr, off, err + } + return rr, off, err +} + +func unpackCDS(h RR_Header, msg []byte, off int) (RR, int, error) { + if noRdata(h) { + return &h, off, nil + } + var err error + rdStart := off + _ = rdStart + + rr := new(CDS) + rr.Hdr = h + + rr.KeyTag, off, err = unpackUint16(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.Algorithm, off, err = unpackUint8(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.DigestType, off, err = unpackUint8(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return rr, off, err + } return rr, off, err } func unpackCERT(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1381,7 +1673,7 @@ func unpackCERT(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackCNAME(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1399,7 +1691,7 @@ func unpackCNAME(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackDHCID(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1415,9 +1707,48 @@ func unpackDHCID(h RR_Header, msg []byte, off int) (RR, int, error) { return rr, off, err } +func unpackDLV(h RR_Header, msg []byte, off int) (RR, int, error) { + if noRdata(h) { + return &h, off, nil + } + var err error + rdStart := off + _ = rdStart + + rr := new(DLV) + rr.Hdr = h + + rr.KeyTag, off, err = unpackUint16(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.Algorithm, off, err = unpackUint8(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.DigestType, off, err = unpackUint8(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return rr, off, err + } + return rr, off, err +} + func unpackDNAME(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1435,7 +1766,7 @@ func unpackDNAME(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackDNSKEY(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1474,7 +1805,7 @@ func unpackDNSKEY(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackDS(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1504,12 +1835,16 @@ func unpackDS(h RR_Header, msg []byte, off int) (RR, int, error) { if off == len(msg) { return rr, off, nil } + rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return rr, off, err + } return rr, off, err } func unpackEID(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1518,12 +1853,16 @@ func unpackEID(h RR_Header, msg []byte, off int) (RR, int, error) { rr := new(EID) rr.Hdr = h + rr.Endpoint, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return rr, off, err + } return rr, off, err } func unpackEUI48(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1541,7 +1880,7 @@ func unpackEUI48(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackEUI64(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1559,7 +1898,7 @@ func unpackEUI64(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackGID(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1577,7 +1916,7 @@ func unpackGID(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackGPOS(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1609,7 +1948,7 @@ func unpackGPOS(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackHINFO(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1634,7 +1973,7 @@ func unpackHINFO(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackHIP(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1664,6 +2003,10 @@ func unpackHIP(h RR_Header, msg []byte, off int) (RR, int, error) { if off == len(msg) { return rr, off, nil } + rr.Hit, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return rr, off, err + } if off == len(msg) { return rr, off, nil } @@ -1674,12 +2017,16 @@ func unpackHIP(h RR_Header, msg []byte, off int) (RR, int, error) { if off == len(msg) { return rr, off, nil } + rr.RendezvousServers, off, err = unpackDataDomainNames(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return rr, off, err + } return rr, off, err } func unpackIPSECKEY(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1737,9 +2084,48 @@ func unpackIPSECKEY(h RR_Header, msg []byte, off int) (RR, int, error) { return rr, off, err } +func unpackKEY(h RR_Header, msg []byte, off int) (RR, int, error) { + if noRdata(h) { + return &h, off, nil + } + var err error + rdStart := off + _ = rdStart + + rr := new(KEY) + rr.Hdr = h + + rr.Flags, off, err = unpackUint16(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.Protocol, off, err = unpackUint8(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.Algorithm, off, err = unpackUint8(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return rr, off, err + } + return rr, off, err +} + func unpackKX(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1764,7 +2150,7 @@ func unpackKX(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackL32(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1789,7 +2175,7 @@ func unpackL32(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackL64(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1814,7 +2200,7 @@ func unpackL64(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackLOC(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1874,7 +2260,7 @@ func unpackLOC(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackLP(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1899,7 +2285,7 @@ func unpackLP(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackMB(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1917,7 +2303,7 @@ func unpackMB(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackMD(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1935,7 +2321,7 @@ func unpackMD(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackMF(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1953,7 +2339,7 @@ func unpackMF(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackMG(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1971,7 +2357,7 @@ func unpackMG(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackMINFO(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -1996,7 +2382,7 @@ func unpackMINFO(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackMR(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2014,7 +2400,7 @@ func unpackMR(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackMX(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2039,7 +2425,7 @@ func unpackMX(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackNAPTR(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2092,7 +2478,7 @@ func unpackNAPTR(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackNID(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2117,7 +2503,7 @@ func unpackNID(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackNIMLOC(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2126,12 +2512,16 @@ func unpackNIMLOC(h RR_Header, msg []byte, off int) (RR, int, error) { rr := new(NIMLOC) rr.Hdr = h + rr.Locator, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return rr, off, err + } return rr, off, err } func unpackNINFO(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2149,7 +2539,7 @@ func unpackNINFO(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackNS(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2167,7 +2557,7 @@ func unpackNS(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackNSAPPTR(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2185,7 +2575,7 @@ func unpackNSAPPTR(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackNSEC(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2201,12 +2591,16 @@ func unpackNSEC(h RR_Header, msg []byte, off int) (RR, int, error) { if off == len(msg) { return rr, off, nil } + rr.TypeBitMap, off, err = unpackDataNsec(msg, off) + if err != nil { + return rr, off, err + } return rr, off, err } func unpackNSEC3(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2256,12 +2650,16 @@ func unpackNSEC3(h RR_Header, msg []byte, off int) (RR, int, error) { if off == len(msg) { return rr, off, nil } + rr.TypeBitMap, off, err = unpackDataNsec(msg, off) + if err != nil { + return rr, off, err + } return rr, off, err } func unpackNSEC3PARAM(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2298,12 +2696,16 @@ func unpackNSEC3PARAM(h RR_Header, msg []byte, off int) (RR, int, error) { if off == len(msg) { return rr, off, nil } + rr.Salt, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return rr, off, err + } return rr, off, err } func unpackOPENPGPKEY(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2321,7 +2723,7 @@ func unpackOPENPGPKEY(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackOPT(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2330,12 +2732,16 @@ func unpackOPT(h RR_Header, msg []byte, off int) (RR, int, error) { rr := new(OPT) rr.Hdr = h + rr.Option, off, err = unpackDataOpt(msg, off) + if err != nil { + return rr, off, err + } return rr, off, err } func unpackPTR(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2353,7 +2759,7 @@ func unpackPTR(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackPX(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2385,7 +2791,7 @@ func unpackPX(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackRFC3597(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2394,12 +2800,16 @@ func unpackRFC3597(h RR_Header, msg []byte, off int) (RR, int, error) { rr := new(RFC3597) rr.Hdr = h + rr.Rdata, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return rr, off, err + } return rr, off, err } func unpackRKEY(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2438,7 +2848,7 @@ func unpackRKEY(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackRP(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2463,7 +2873,7 @@ func unpackRP(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackRRSIG(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2537,7 +2947,7 @@ func unpackRRSIG(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackRT(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2560,9 +2970,83 @@ func unpackRT(h RR_Header, msg []byte, off int) (RR, int, error) { return rr, off, err } +func unpackSIG(h RR_Header, msg []byte, off int) (RR, int, error) { + if noRdata(h) { + return &h, off, nil + } + var err error + rdStart := off + _ = rdStart + + rr := new(SIG) + rr.Hdr = h + + rr.TypeCovered, off, err = unpackUint16(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.Algorithm, off, err = unpackUint8(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.Labels, off, err = unpackUint8(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.OrigTtl, off, err = unpackUint32(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.Expiration, off, err = unpackUint32(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.Inception, off, err = unpackUint32(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.KeyTag, off, err = unpackUint16(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.SignerName, off, err = UnpackDomainName(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.Signature, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return rr, off, err + } + return rr, off, err +} + func unpackSOA(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2622,7 +3106,7 @@ func unpackSOA(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackSPF(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2640,7 +3124,7 @@ func unpackSPF(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackSRV(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2679,7 +3163,7 @@ func unpackSRV(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackSSHFP(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2702,12 +3186,16 @@ func unpackSSHFP(h RR_Header, msg []byte, off int) (RR, int, error) { if off == len(msg) { return rr, off, nil } + rr.FingerPrint, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return rr, off, err + } return rr, off, err } func unpackTA(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2737,12 +3225,16 @@ func unpackTA(h RR_Header, msg []byte, off int) (RR, int, error) { if off == len(msg) { return rr, off, nil } + rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return rr, off, err + } return rr, off, err } func unpackTALINK(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2767,7 +3259,7 @@ func unpackTALINK(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackTKEY(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2841,7 +3333,7 @@ func unpackTKEY(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackTLSA(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2871,12 +3363,16 @@ func unpackTLSA(h RR_Header, msg []byte, off int) (RR, int, error) { if off == len(msg) { return rr, off, nil } + rr.Certificate, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return rr, off, err + } return rr, off, err } func unpackTSIG(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2942,7 +3438,7 @@ func unpackTSIG(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackTXT(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2960,7 +3456,7 @@ func unpackTXT(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackUID(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2978,7 +3474,7 @@ func unpackUID(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackUINFO(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -2996,7 +3492,7 @@ func unpackUINFO(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackURI(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -3019,12 +3515,16 @@ func unpackURI(h RR_Header, msg []byte, off int) (RR, int, error) { if off == len(msg) { return rr, off, nil } + rr.Target, off, err = unpackStringOctet(msg, off) + if err != nil { + return rr, off, err + } return rr, off, err } func unpackX25(h RR_Header, msg []byte, off int) (RR, int, error) { if noRdata(h) { - return nil, off, nil + return &h, off, nil } var err error rdStart := off @@ -3039,3 +3539,73 @@ func unpackX25(h RR_Header, msg []byte, off int) (RR, int, error) { } return rr, off, err } + +var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){ + TypeA: unpackA, + TypeAAAA: unpackAAAA, + TypeAFSDB: unpackAFSDB, + TypeANY: unpackANY, + TypeCAA: unpackCAA, + TypeCDNSKEY: unpackCDNSKEY, + TypeCDS: unpackCDS, + TypeCERT: unpackCERT, + TypeCNAME: unpackCNAME, + TypeDHCID: unpackDHCID, + TypeDLV: unpackDLV, + TypeDNAME: unpackDNAME, + TypeDNSKEY: unpackDNSKEY, + TypeDS: unpackDS, + TypeEID: unpackEID, + TypeEUI48: unpackEUI48, + TypeEUI64: unpackEUI64, + TypeGID: unpackGID, + TypeGPOS: unpackGPOS, + TypeHINFO: unpackHINFO, + TypeHIP: unpackHIP, + TypeIPSECKEY: unpackIPSECKEY, + TypeKEY: unpackKEY, + TypeKX: unpackKX, + TypeL32: unpackL32, + TypeL64: unpackL64, + TypeLOC: unpackLOC, + TypeLP: unpackLP, + TypeMB: unpackMB, + TypeMD: unpackMD, + TypeMF: unpackMF, + TypeMG: unpackMG, + TypeMINFO: unpackMINFO, + TypeMR: unpackMR, + TypeMX: unpackMX, + TypeNAPTR: unpackNAPTR, + TypeNID: unpackNID, + TypeNIMLOC: unpackNIMLOC, + TypeNINFO: unpackNINFO, + TypeNS: unpackNS, + TypeNSAPPTR: unpackNSAPPTR, + TypeNSEC: unpackNSEC, + TypeNSEC3: unpackNSEC3, + TypeNSEC3PARAM: unpackNSEC3PARAM, + TypeOPENPGPKEY: unpackOPENPGPKEY, + TypeOPT: unpackOPT, + TypePTR: unpackPTR, + TypePX: unpackPX, + TypeRKEY: unpackRKEY, + TypeRP: unpackRP, + TypeRRSIG: unpackRRSIG, + TypeRT: unpackRT, + TypeSIG: unpackSIG, + TypeSOA: unpackSOA, + TypeSPF: unpackSPF, + TypeSRV: unpackSRV, + TypeSSHFP: unpackSSHFP, + TypeTA: unpackTA, + TypeTALINK: unpackTALINK, + TypeTKEY: unpackTKEY, + TypeTLSA: unpackTLSA, + TypeTSIG: unpackTSIG, + TypeTXT: unpackTXT, + TypeUID: unpackUID, + TypeUINFO: unpackUINFO, + TypeURI: unpackURI, + TypeX25: unpackX25, +}