Add NULL record (#840)
Sorely missing from this library. Add it. As there is no presentation format the String method for this type puts a comment in front of it. Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
parent
5f5f2380fc
commit
56516cf4de
|
@ -153,7 +153,8 @@ if rr.%s != "-" {
|
|||
fallthrough
|
||||
case st.Tag(i) == `dns:"hex"`:
|
||||
o("off, err = packStringHex(rr.%s, msg, off)\n")
|
||||
|
||||
case st.Tag(i) == `dns:"any"`:
|
||||
o("off, err = packStringAny(rr.%s, msg, off)\n")
|
||||
case st.Tag(i) == `dns:"octet"`:
|
||||
o("off, err = packStringOctet(rr.%s, msg, off)\n")
|
||||
case st.Tag(i) == "":
|
||||
|
@ -261,6 +262,8 @@ return rr, off, err
|
|||
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:"any"`:
|
||||
o("rr.%s, off, err = unpackStringAny(msg, off, rdStart + int(rr.Hdr.Rdlength))\n")
|
||||
case `dns:"octet"`:
|
||||
o("rr.%s, off, err = unpackStringOctet(msg, off)\n")
|
||||
case "":
|
||||
|
|
|
@ -363,6 +363,22 @@ func packStringHex(s string, msg []byte, off int) (int, error) {
|
|||
return off, nil
|
||||
}
|
||||
|
||||
func unpackStringAny(msg []byte, off, end int) (string, int, error) {
|
||||
if end > len(msg) {
|
||||
return "", len(msg), &Error{err: "overflow unpacking anything"}
|
||||
}
|
||||
return string(msg[off:end]), end, nil
|
||||
}
|
||||
|
||||
func packStringAny(s string, msg []byte, off int) (int, error) {
|
||||
if off+len(s) > len(msg) {
|
||||
return len(msg), &Error{err: "overflow packing anything"}
|
||||
}
|
||||
copy(msg[off:off+len(s)], s)
|
||||
off += len(s)
|
||||
return off, nil
|
||||
}
|
||||
|
||||
func unpackStringTxt(msg []byte, off int) ([]string, int, error) {
|
||||
txt, off, err := unpackTxt(msg, off)
|
||||
if err != nil {
|
||||
|
|
|
@ -341,7 +341,7 @@ func TestParseDirectiveMisc(t *testing.T) {
|
|||
|
||||
func TestNSEC(t *testing.T) {
|
||||
nsectests := map[string]string{
|
||||
"nl. IN NSEC3PARAM 1 0 5 30923C44C6CBBB8F": "nl.\t3600\tIN\tNSEC3PARAM\t1 0 5 30923C44C6CBBB8F",
|
||||
"nl. IN NSEC3PARAM 1 0 5 30923C44C6CBBB8F": "nl.\t3600\tIN\tNSEC3PARAM\t1 0 5 30923C44C6CBBB8F",
|
||||
"p2209hipbpnm681knjnu0m1febshlv4e.nl. IN NSEC3 1 1 5 30923C44C6CBBB8F P90DG1KE8QEAN0B01613LHQDG0SOJ0TA NS SOA TXT RRSIG DNSKEY NSEC3PARAM": "p2209hipbpnm681knjnu0m1febshlv4e.nl.\t3600\tIN\tNSEC3\t1 1 5 30923C44C6CBBB8F P90DG1KE8QEAN0B01613LHQDG0SOJ0TA NS SOA TXT RRSIG DNSKEY NSEC3PARAM",
|
||||
"localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSEC": "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC",
|
||||
"localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSEC TYPE65534": "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC TYPE65534",
|
||||
|
@ -398,16 +398,16 @@ func TestQuotes(t *testing.T) {
|
|||
`t.example.com. IN TXT "a bc"`: "t.example.com.\t3600\tIN\tTXT\t\"a bc\"",
|
||||
`t.example.com. IN TXT "a
|
||||
bc"`: "t.example.com.\t3600\tIN\tTXT\t\"a\\010 bc\"",
|
||||
`t.example.com. IN TXT ""`: "t.example.com.\t3600\tIN\tTXT\t\"\"",
|
||||
`t.example.com. IN TXT "a"`: "t.example.com.\t3600\tIN\tTXT\t\"a\"",
|
||||
`t.example.com. IN TXT "aa"`: "t.example.com.\t3600\tIN\tTXT\t\"aa\"",
|
||||
`t.example.com. IN TXT "aaa" ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"",
|
||||
`t.example.com. IN TXT "abc" "DEF"`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"",
|
||||
`t.example.com. IN TXT "abc" ( "DEF" )`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"",
|
||||
`t.example.com. IN TXT aaa ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"",
|
||||
`t.example.com. IN TXT aaa aaa;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\" \"aaa\"",
|
||||
`t.example.com. IN TXT aaa aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\" \"aaa\"",
|
||||
`t.example.com. IN TXT aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"",
|
||||
`t.example.com. IN TXT ""`: "t.example.com.\t3600\tIN\tTXT\t\"\"",
|
||||
`t.example.com. IN TXT "a"`: "t.example.com.\t3600\tIN\tTXT\t\"a\"",
|
||||
`t.example.com. IN TXT "aa"`: "t.example.com.\t3600\tIN\tTXT\t\"aa\"",
|
||||
`t.example.com. IN TXT "aaa" ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"",
|
||||
`t.example.com. IN TXT "abc" "DEF"`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"",
|
||||
`t.example.com. IN TXT "abc" ( "DEF" )`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"",
|
||||
`t.example.com. IN TXT aaa ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"",
|
||||
`t.example.com. IN TXT aaa aaa;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\" \"aaa\"",
|
||||
`t.example.com. IN TXT aaa aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\" \"aaa\"",
|
||||
`t.example.com. IN TXT aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"",
|
||||
"cid.urn.arpa. NAPTR 100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.",
|
||||
"cid.urn.arpa. NAPTR 100 50 \"s\" \"rcds+I2C\" \"\" _rcds._udp.gatech.edu.": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"rcds+I2C\" \"\" _rcds._udp.gatech.edu.",
|
||||
"cid.urn.arpa. NAPTR 100 50 \"s\" \"http+I2L+I2C+I2R\" \"\" _http._tcp.gatech.edu.": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"http+I2L+I2C+I2R\" \"\" _http._tcp.gatech.edu.",
|
||||
|
@ -1567,3 +1567,17 @@ func TestBad(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNULLRecord(t *testing.T) {
|
||||
// packet captured from iodine
|
||||
packet := `8116840000010001000000000569627a6c700474657374046d69656b026e6c00000a0001c00c000a0001000000000005497f000001`
|
||||
data, _ := hex.DecodeString(packet)
|
||||
msg := new(Msg)
|
||||
err := msg.Unpack(data)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to unpack NULL record")
|
||||
}
|
||||
if _, ok := msg.Answer[0].(*NULL); !ok {
|
||||
t.Fatalf("Expected packet to contain NULL record")
|
||||
}
|
||||
}
|
||||
|
|
11
types.go
11
types.go
|
@ -241,6 +241,17 @@ type ANY struct {
|
|||
|
||||
func (rr *ANY) String() string { return rr.Hdr.String() }
|
||||
|
||||
// NULL RR. See RFC 1035.
|
||||
type NULL struct {
|
||||
Hdr RR_Header
|
||||
Anything string `dns:"any"`
|
||||
}
|
||||
|
||||
func (rr *NULL) String() string {
|
||||
// There is no presentation format; prefix string with a comment.
|
||||
return ";" + rr.Hdr.String() + rr.Anything
|
||||
}
|
||||
|
||||
// CNAME RR. See RFC 1034.
|
||||
type CNAME struct {
|
||||
Hdr RR_Header
|
||||
|
|
|
@ -193,6 +193,8 @@ func main() {
|
|||
fallthrough
|
||||
case st.Tag(i) == `dns:"hex"`:
|
||||
o("l += len(rr.%s)/2 + 1\n")
|
||||
case st.Tag(i) == `dns:"any"`:
|
||||
o("l += len(rr.%s)\n")
|
||||
case st.Tag(i) == `dns:"a"`:
|
||||
o("l += net.IPv4len // %s\n")
|
||||
case st.Tag(i) == `dns:"aaaa"`:
|
||||
|
|
|
@ -85,6 +85,8 @@ func isDuplicateRdata(r1, r2 RR) bool {
|
|||
return isDuplicateNSEC3(r1.(*NSEC3), r2.(*NSEC3))
|
||||
case TypeNSEC3PARAM:
|
||||
return isDuplicateNSEC3PARAM(r1.(*NSEC3PARAM), r2.(*NSEC3PARAM))
|
||||
case TypeNULL:
|
||||
return isDuplicateNULL(r1.(*NULL), r2.(*NULL))
|
||||
case TypeOPENPGPKEY:
|
||||
return isDuplicateOPENPGPKEY(r1.(*OPENPGPKEY), r2.(*OPENPGPKEY))
|
||||
case TypePTR:
|
||||
|
@ -616,6 +618,13 @@ func isDuplicateNSEC3PARAM(r1, r2 *NSEC3PARAM) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func isDuplicateNULL(r1, r2 *NULL) bool {
|
||||
if r1.Anything != r2.Anything {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateOPENPGPKEY(r1, r2 *OPENPGPKEY) bool {
|
||||
if r1.PublicKey != r2.PublicKey {
|
||||
return false
|
||||
|
|
30
zmsg.go
30
zmsg.go
|
@ -802,6 +802,18 @@ func (rr *NSEC3PARAM) pack(msg []byte, off int, compression compressionMap, comp
|
|||
return headerEnd, off, nil
|
||||
}
|
||||
|
||||
func (rr *NULL) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) {
|
||||
headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress)
|
||||
if err != nil {
|
||||
return headerEnd, off, err
|
||||
}
|
||||
off, err = packStringAny(rr.Anything, msg, off)
|
||||
if err != nil {
|
||||
return headerEnd, off, err
|
||||
}
|
||||
return headerEnd, off, nil
|
||||
}
|
||||
|
||||
func (rr *OPENPGPKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) {
|
||||
headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress)
|
||||
if err != nil {
|
||||
|
@ -2549,6 +2561,23 @@ func unpackNSEC3PARAM(h RR_Header, msg []byte, off int) (RR, int, error) {
|
|||
return rr, off, err
|
||||
}
|
||||
|
||||
func unpackNULL(h RR_Header, msg []byte, off int) (RR, int, error) {
|
||||
rr := new(NULL)
|
||||
rr.Hdr = h
|
||||
if noRdata(h) {
|
||||
return rr, off, nil
|
||||
}
|
||||
var err error
|
||||
rdStart := off
|
||||
_ = rdStart
|
||||
|
||||
rr.Anything, off, err = unpackStringAny(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) {
|
||||
rr := new(OPENPGPKEY)
|
||||
rr.Hdr = h
|
||||
|
@ -3448,6 +3477,7 @@ var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){
|
|||
TypeNSEC: unpackNSEC,
|
||||
TypeNSEC3: unpackNSEC3,
|
||||
TypeNSEC3PARAM: unpackNSEC3PARAM,
|
||||
TypeNULL: unpackNULL,
|
||||
TypeOPENPGPKEY: unpackOPENPGPKEY,
|
||||
TypeOPT: unpackOPT,
|
||||
TypePTR: unpackPTR,
|
||||
|
|
10
ztypes.go
10
ztypes.go
|
@ -54,6 +54,7 @@ var TypeToRR = map[uint16]func() RR{
|
|||
TypeNSEC: func() RR { return new(NSEC) },
|
||||
TypeNSEC3: func() RR { return new(NSEC3) },
|
||||
TypeNSEC3PARAM: func() RR { return new(NSEC3PARAM) },
|
||||
TypeNULL: func() RR { return new(NULL) },
|
||||
TypeOPENPGPKEY: func() RR { return new(OPENPGPKEY) },
|
||||
TypeOPT: func() RR { return new(OPT) },
|
||||
TypePTR: func() RR { return new(PTR) },
|
||||
|
@ -209,6 +210,7 @@ func (rr *NSAPPTR) Header() *RR_Header { return &rr.Hdr }
|
|||
func (rr *NSEC) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *NSEC3) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *NSEC3PARAM) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *NULL) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *OPENPGPKEY) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *OPT) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *PTR) Header() *RR_Header { return &rr.Hdr }
|
||||
|
@ -473,6 +475,11 @@ func (rr *NSEC3PARAM) len(off int, compression map[string]struct{}) int {
|
|||
l += len(rr.Salt) / 2
|
||||
return l
|
||||
}
|
||||
func (rr *NULL) len(off int, compression map[string]struct{}) int {
|
||||
l := rr.Hdr.len(off, compression)
|
||||
l += len(rr.Anything)
|
||||
return l
|
||||
}
|
||||
func (rr *OPENPGPKEY) len(off int, compression map[string]struct{}) int {
|
||||
l := rr.Hdr.len(off, compression)
|
||||
l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
|
||||
|
@ -783,6 +790,9 @@ func (rr *NSEC3) copy() RR {
|
|||
func (rr *NSEC3PARAM) copy() RR {
|
||||
return &NSEC3PARAM{rr.Hdr, rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt}
|
||||
}
|
||||
func (rr *NULL) copy() RR {
|
||||
return &NULL{rr.Hdr, rr.Anything}
|
||||
}
|
||||
func (rr *OPENPGPKEY) copy() RR {
|
||||
return &OPENPGPKEY{rr.Hdr, rr.PublicKey}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue