From 2decd91cb42a2ef8e80322f617e71d4fa33a90d7 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Thu, 30 Dec 2010 20:50:31 +0100 Subject: [PATCH] Add the NAPTR record --- dns.go | 96 +++++++++++++++++++++++++++++--------------------------- msg.go | 1 + types.go | 62 +++++++++++++++++++++++------------- 3 files changed, 92 insertions(+), 67 deletions(-) diff --git a/dns.go b/dns.go index c55e72fa..f5de0dc9 100644 --- a/dns.go +++ b/dns.go @@ -7,7 +7,9 @@ // Supported RFCs and features include: // * 1982 - Serial Arithmetic // * 1034/1035 +// * 1876 - LOC record (incomplete) // * 2671 - EDNS +// * 2915 - NAPTR record (incomplete) // * 3225 - DO bit (DNSSEC OK) // * 4033/4034/4035 - DNSSEC + validation functions // * 5011 - NSID @@ -16,13 +18,15 @@ // package dns -import ( "strconv") +import ( + "strconv" +) const Year68 = 2 << (32 - 1) type RR interface { - Header() *RR_Header - String() string + Header() *RR_Header + String() string } // 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, // but they all share the same header. type RR_Header struct { - Name string "domain-name" - Rrtype uint16 - Class uint16 - Ttl uint32 - Rdlength uint16 // length of data after header + Name string "domain-name" + Rrtype uint16 + Class uint16 + Ttl uint32 + Rdlength uint16 // length of data after header } func (h *RR_Header) Header() *RR_Header { - return h + return h } func (h *RR_Header) String() string { - var s string + var s string - if h.Rrtype == TypeOPT { - s = ";" - // and maybe other things - } + if h.Rrtype == TypeOPT { + s = ";" + // and maybe other things + } - if len(h.Name) == 0 { - s += ".\t" - } else { - s += h.Name + "\t" - } - s = s + strconv.Itoa(int(h.Ttl)) + "\t" - s = s + Class_str[h.Class] + "\t" - s = s + Rr_str[h.Rrtype] + "\t" - return s + if len(h.Name) == 0 { + s += ".\t" + } else { + s += h.Name + "\t" + } + s = s + strconv.Itoa(int(h.Ttl)) + "\t" + s = s + Class_str[h.Class] + "\t" + s = s + Rr_str[h.Rrtype] + "\t" + return s } // Or expose the pack/unpack functions?? // Return the wiredata of rdata portion of a RR. func WireRdata(r RR) ([]byte, bool) { - buf := make([]byte, 4096) // Too large, need to FIX TODO(mg) - off1, ok := packRR(r, buf, 0) - if !ok { - return nil, false - } - start := off1 - int(r.Header().Rdlength) - end := start + int(r.Header().Rdlength) - buf = buf[start:end] - return buf, true + buf := make([]byte, 4096) // Too large, need to FIX TODO(mg) + off1, ok := packRR(r, buf, 0) + if !ok { + return nil, false + } + start := off1 - int(r.Header().Rdlength) + end := start + int(r.Header().Rdlength) + buf = buf[start:end] + return buf, true } // Return the wiredata of a domainname (sans compressions). func WireDomainName(s string) ([]byte, bool) { - buf := make([]byte, 255) - off, ok := packDomainName(s, buf, 0) - if !ok { - return nil, ok - } - buf = buf[:off] - return buf, ok + buf := make([]byte, 255) + off, ok := packDomainName(s, buf, 0) + if !ok { + return nil, ok + } + buf = buf[:off] + return buf, ok } // Return the wiredata of a complete Resource Record. func WireRR(r RR) ([]byte, bool) { - buf := make([]byte, 4096) - off, ok := packRR(r, buf, 0) - if !ok { - return nil, false - } - buf = buf[:off] - return buf, ok + buf := make([]byte, 4096) + off, ok := packRR(r, buf, 0) + if !ok { + return nil, false + } + buf = buf[:off] + return buf, ok } diff --git a/msg.go b/msg.go index c2d0a01b..b25bfb45 100644 --- a/msg.go +++ b/msg.go @@ -49,6 +49,7 @@ var Rr_str = map[uint16]string{ TypeSOA: "SOA", TypeTXT: "TXT", TypeSRV: "SRV", + TypeNAPTR: "NAPTR", TypeA: "A", TypeAAAA: "AAAA", TypeOPT: "OPT", diff --git a/types.go b/types.go index 04de2eef..cb1f977d 100644 --- a/types.go +++ b/types.go @@ -41,6 +41,7 @@ const ( TypeTXT = 16 TypeAAAA = 28 TypeSRV = 33 + TypeNAPTR = 35 // EDNS TypeOPT = 41 @@ -289,6 +290,24 @@ func (rr *RR_SRV) String() string { 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 { Hdr RR_Header A net.IP "A" @@ -452,25 +471,26 @@ func timeToDate(t uint32) string { // Map of constructors for each RR wire type. var rr_mk = map[int]func() RR{ - TypeCNAME: func() RR { return new(RR_CNAME) }, - TypeHINFO: func() RR { return new(RR_HINFO) }, - TypeMB: func() RR { return new(RR_MB) }, - TypeMG: func() RR { return new(RR_MG) }, - TypeMINFO: func() RR { return new(RR_MINFO) }, - TypeMR: func() RR { return new(RR_MR) }, - TypeMX: func() RR { return new(RR_MX) }, - TypeNS: func() RR { return new(RR_NS) }, - TypePTR: func() RR { return new(RR_PTR) }, - TypeSOA: func() RR { return new(RR_SOA) }, - TypeTXT: func() RR { return new(RR_TXT) }, - TypeSRV: func() RR { return new(RR_SRV) }, - TypeA: func() RR { return new(RR_A) }, - TypeAAAA: func() RR { return new(RR_AAAA) }, - TypeOPT: func() RR { return new(RR_OPT) }, - TypeDS: func() RR { return new(RR_DS) }, - TypeRRSIG: func() RR { return new(RR_RRSIG) }, - TypeNSEC: func() RR { return new(RR_NSEC) }, - TypeDNSKEY: func() RR { return new(RR_DNSKEY) }, - TypeNSEC3: func() RR { return new(RR_NSEC3) }, - TypeNSEC3PARAM: func() RR { return new(RR_NSEC3PARAM) }, + TypeCNAME: func() RR { return new(RR_CNAME) }, + TypeHINFO: func() RR { return new(RR_HINFO) }, + TypeMB: func() RR { return new(RR_MB) }, + TypeMG: func() RR { return new(RR_MG) }, + TypeMINFO: func() RR { return new(RR_MINFO) }, + TypeMR: func() RR { return new(RR_MR) }, + TypeMX: func() RR { return new(RR_MX) }, + TypeNS: func() RR { return new(RR_NS) }, + TypePTR: func() RR { return new(RR_PTR) }, + TypeSOA: func() RR { return new(RR_SOA) }, + TypeTXT: func() RR { return new(RR_TXT) }, + TypeSRV: func() RR { return new(RR_SRV) }, + TypeNAPTR: func() RR { return new(RR_NAPTR) }, + TypeA: func() RR { return new(RR_A) }, + TypeAAAA: func() RR { return new(RR_AAAA) }, + TypeOPT: func() RR { return new(RR_OPT) }, + TypeDS: func() RR { return new(RR_DS) }, + TypeRRSIG: func() RR { return new(RR_RRSIG) }, + TypeNSEC: func() RR { return new(RR_NSEC) }, + TypeDNSKEY: func() RR { return new(RR_DNSKEY) }, + TypeNSEC3: func() RR { return new(RR_NSEC3) }, + TypeNSEC3PARAM: func() RR { return new(RR_NSEC3PARAM) }, }