Add the NAPTR record

This commit is contained in:
Miek Gieben 2010-12-30 20:50:31 +01:00
parent bccabeaeda
commit 2decd91cb4
3 changed files with 92 additions and 67 deletions

96
dns.go
View File

@ -7,7 +7,9 @@
// Supported RFCs and features include: // Supported RFCs and features include:
// * 1982 - Serial Arithmetic // * 1982 - Serial Arithmetic
// * 1034/1035 // * 1034/1035
// * 1876 - LOC record (incomplete)
// * 2671 - EDNS // * 2671 - EDNS
// * 2915 - NAPTR record (incomplete)
// * 3225 - DO bit (DNSSEC OK) // * 3225 - DO bit (DNSSEC OK)
// * 4033/4034/4035 - DNSSEC + validation functions // * 4033/4034/4035 - DNSSEC + validation functions
// * 5011 - NSID // * 5011 - NSID
@ -16,13 +18,15 @@
// //
package dns package dns
import ( "strconv") import (
"strconv"
)
const Year68 = 2 << (32 - 1) const Year68 = 2 << (32 - 1)
type RR interface { type RR interface {
Header() *RR_Header Header() *RR_Header
String() string String() string
} }
// An RRset is a slice of RRs. // An RRset is a slice of RRs.
@ -36,69 +40,69 @@ func (r RRset) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
// There are many types of messages, // There are many types of messages,
// but they all share the same header. // but they all share the same header.
type RR_Header struct { type RR_Header struct {
Name string "domain-name" Name string "domain-name"
Rrtype uint16 Rrtype uint16
Class uint16 Class uint16
Ttl uint32 Ttl uint32
Rdlength uint16 // length of data after header Rdlength uint16 // length of data after header
} }
func (h *RR_Header) Header() *RR_Header { func (h *RR_Header) Header() *RR_Header {
return h return h
} }
func (h *RR_Header) String() string { func (h *RR_Header) String() string {
var s string var s string
if h.Rrtype == TypeOPT { if h.Rrtype == TypeOPT {
s = ";" s = ";"
// and maybe other things // and maybe other things
} }
if len(h.Name) == 0 { if len(h.Name) == 0 {
s += ".\t" s += ".\t"
} else { } else {
s += h.Name + "\t" s += h.Name + "\t"
} }
s = s + strconv.Itoa(int(h.Ttl)) + "\t" s = s + strconv.Itoa(int(h.Ttl)) + "\t"
s = s + Class_str[h.Class] + "\t" s = s + Class_str[h.Class] + "\t"
s = s + Rr_str[h.Rrtype] + "\t" s = s + Rr_str[h.Rrtype] + "\t"
return s return s
} }
// Or expose the pack/unpack functions?? // Or expose the pack/unpack functions??
// Return the wiredata of rdata portion of a RR. // Return the wiredata of rdata portion of a RR.
func WireRdata(r RR) ([]byte, bool) { func WireRdata(r RR) ([]byte, bool) {
buf := make([]byte, 4096) // Too large, need to FIX TODO(mg) buf := make([]byte, 4096) // Too large, need to FIX TODO(mg)
off1, ok := packRR(r, buf, 0) off1, ok := packRR(r, buf, 0)
if !ok { if !ok {
return nil, false return nil, false
} }
start := off1 - int(r.Header().Rdlength) start := off1 - int(r.Header().Rdlength)
end := start + int(r.Header().Rdlength) end := start + int(r.Header().Rdlength)
buf = buf[start:end] buf = buf[start:end]
return buf, true return buf, true
} }
// Return the wiredata of a domainname (sans compressions). // Return the wiredata of a domainname (sans compressions).
func WireDomainName(s string) ([]byte, bool) { func WireDomainName(s string) ([]byte, bool) {
buf := make([]byte, 255) buf := make([]byte, 255)
off, ok := packDomainName(s, buf, 0) off, ok := packDomainName(s, buf, 0)
if !ok { if !ok {
return nil, ok return nil, ok
} }
buf = buf[:off] buf = buf[:off]
return buf, ok return buf, ok
} }
// Return the wiredata of a complete Resource Record. // Return the wiredata of a complete Resource Record.
func WireRR(r RR) ([]byte, bool) { func WireRR(r RR) ([]byte, bool) {
buf := make([]byte, 4096) buf := make([]byte, 4096)
off, ok := packRR(r, buf, 0) off, ok := packRR(r, buf, 0)
if !ok { if !ok {
return nil, false return nil, false
} }
buf = buf[:off] buf = buf[:off]
return buf, ok return buf, ok
} }

1
msg.go
View File

@ -49,6 +49,7 @@ var Rr_str = map[uint16]string{
TypeSOA: "SOA", TypeSOA: "SOA",
TypeTXT: "TXT", TypeTXT: "TXT",
TypeSRV: "SRV", TypeSRV: "SRV",
TypeNAPTR: "NAPTR",
TypeA: "A", TypeA: "A",
TypeAAAA: "AAAA", TypeAAAA: "AAAA",
TypeOPT: "OPT", TypeOPT: "OPT",

View File

@ -41,6 +41,7 @@ const (
TypeTXT = 16 TypeTXT = 16
TypeAAAA = 28 TypeAAAA = 28
TypeSRV = 33 TypeSRV = 33
TypeNAPTR = 35
// EDNS // EDNS
TypeOPT = 41 TypeOPT = 41
@ -289,6 +290,24 @@ func (rr *RR_SRV) String() string {
strconv.Itoa(int(rr.Port)) + " " + rr.Target strconv.Itoa(int(rr.Port)) + " " + rr.Target
} }
type RR_NAPTR struct {
Hdr RR_Header
Order uint16
Preference uint16
Flags string
Service string
Regexp string
Replacement string
}
func (rr *RR_NAPTR) Header() *RR_Header {
return &rr.Hdr
}
func (rr *RR_NAPTR) String() string {
return rr.Hdr.String() + "TODO"
}
type RR_A struct { type RR_A struct {
Hdr RR_Header Hdr RR_Header
A net.IP "A" A net.IP "A"
@ -452,25 +471,26 @@ func timeToDate(t uint32) string {
// Map of constructors for each RR wire type. // Map of constructors for each RR wire type.
var rr_mk = map[int]func() RR{ var rr_mk = map[int]func() RR{
TypeCNAME: func() RR { return new(RR_CNAME) }, TypeCNAME: func() RR { return new(RR_CNAME) },
TypeHINFO: func() RR { return new(RR_HINFO) }, TypeHINFO: func() RR { return new(RR_HINFO) },
TypeMB: func() RR { return new(RR_MB) }, TypeMB: func() RR { return new(RR_MB) },
TypeMG: func() RR { return new(RR_MG) }, TypeMG: func() RR { return new(RR_MG) },
TypeMINFO: func() RR { return new(RR_MINFO) }, TypeMINFO: func() RR { return new(RR_MINFO) },
TypeMR: func() RR { return new(RR_MR) }, TypeMR: func() RR { return new(RR_MR) },
TypeMX: func() RR { return new(RR_MX) }, TypeMX: func() RR { return new(RR_MX) },
TypeNS: func() RR { return new(RR_NS) }, TypeNS: func() RR { return new(RR_NS) },
TypePTR: func() RR { return new(RR_PTR) }, TypePTR: func() RR { return new(RR_PTR) },
TypeSOA: func() RR { return new(RR_SOA) }, TypeSOA: func() RR { return new(RR_SOA) },
TypeTXT: func() RR { return new(RR_TXT) }, TypeTXT: func() RR { return new(RR_TXT) },
TypeSRV: func() RR { return new(RR_SRV) }, TypeSRV: func() RR { return new(RR_SRV) },
TypeA: func() RR { return new(RR_A) }, TypeNAPTR: func() RR { return new(RR_NAPTR) },
TypeAAAA: func() RR { return new(RR_AAAA) }, TypeA: func() RR { return new(RR_A) },
TypeOPT: func() RR { return new(RR_OPT) }, TypeAAAA: func() RR { return new(RR_AAAA) },
TypeDS: func() RR { return new(RR_DS) }, TypeOPT: func() RR { return new(RR_OPT) },
TypeRRSIG: func() RR { return new(RR_RRSIG) }, TypeDS: func() RR { return new(RR_DS) },
TypeNSEC: func() RR { return new(RR_NSEC) }, TypeRRSIG: func() RR { return new(RR_RRSIG) },
TypeDNSKEY: func() RR { return new(RR_DNSKEY) }, TypeNSEC: func() RR { return new(RR_NSEC) },
TypeNSEC3: func() RR { return new(RR_NSEC3) }, TypeDNSKEY: func() RR { return new(RR_DNSKEY) },
TypeNSEC3PARAM: func() RR { return new(RR_NSEC3PARAM) }, TypeNSEC3: func() RR { return new(RR_NSEC3) },
TypeNSEC3PARAM: func() RR { return new(RR_NSEC3PARAM) },
} }