dns/types.go

1644 lines
45 KiB
Go
Raw Normal View History

2010-08-04 07:57:59 +10:00
package dns
import (
2012-02-20 01:24:26 +11:00
"encoding/base64"
"fmt"
2010-08-04 07:57:59 +10:00
"net"
"strconv"
2010-12-30 02:11:23 +11:00
"strings"
"time"
2010-08-04 07:57:59 +10:00
)
type (
Type uint16 // Type is a DNS type.
Class uint16 // Class is a DNS class.
Name string // Name is a DNS domain name.
)
2010-08-04 07:57:59 +10:00
// Packet formats
2011-01-27 19:29:11 +11:00
// Wire constants and supported types.
2010-08-04 07:57:59 +10:00
const (
// valid RR_Header.Rrtype and Question.qtype
TypeNone uint16 = 0
2012-02-19 06:07:25 +11:00
TypeA uint16 = 1
TypeNS uint16 = 2
TypeMD uint16 = 3
TypeMF uint16 = 4
TypeCNAME uint16 = 5
TypeSOA uint16 = 6
TypeMB uint16 = 7
TypeMG uint16 = 8
TypeMR uint16 = 9
TypeNULL uint16 = 10
TypeWKS uint16 = 11
TypePTR uint16 = 12
TypeHINFO uint16 = 13
TypeMINFO uint16 = 14
TypeMX uint16 = 15
TypeTXT uint16 = 16
2012-05-02 06:57:22 +10:00
TypeRP uint16 = 17
2012-06-01 21:34:14 +10:00
TypeAFSDB uint16 = 18
2012-11-21 00:32:06 +11:00
TypeX25 uint16 = 19
2012-11-21 00:14:00 +11:00
TypeISDN uint16 = 20
2012-08-10 17:22:50 +10:00
TypeRT uint16 = 21
2013-10-13 22:25:08 +11:00
TypeNSAP uint16 = 22
TypeNSAPPTR uint16 = 23
2011-08-22 22:11:41 +10:00
TypeSIG uint16 = 24
TypeKEY uint16 = 25
2013-10-13 23:23:02 +11:00
TypePX uint16 = 26
2013-10-13 23:01:33 +11:00
TypeGPOS uint16 = 27
2012-02-19 06:07:25 +11:00
TypeAAAA uint16 = 28
TypeLOC uint16 = 29
2011-08-22 22:11:41 +10:00
TypeNXT uint16 = 30
2013-10-20 07:31:12 +11:00
TypeEID uint16 = 31
TypeNIMLOC uint16 = 32
2012-02-19 06:07:25 +11:00
TypeSRV uint16 = 33
2012-11-21 00:32:06 +11:00
TypeATMA uint16 = 34
2012-02-19 06:07:25 +11:00
TypeNAPTR uint16 = 35
TypeKX uint16 = 36
TypeCERT uint16 = 37
TypeDNAME uint16 = 39
TypeOPT uint16 = 41 // EDNS
2011-08-22 22:11:41 +10:00
TypeDS uint16 = 43
TypeSSHFP uint16 = 44
TypeIPSECKEY uint16 = 45
2011-08-22 22:11:41 +10:00
TypeRRSIG uint16 = 46
TypeNSEC uint16 = 47
TypeDNSKEY uint16 = 48
TypeDHCID uint16 = 49
TypeNSEC3 uint16 = 50
TypeNSEC3PARAM uint16 = 51
2012-04-14 18:44:32 +10:00
TypeTLSA uint16 = 52
2012-02-19 06:07:25 +11:00
TypeHIP uint16 = 55
2012-11-21 02:42:16 +11:00
TypeNINFO uint16 = 56
2012-11-21 02:48:28 +11:00
TypeRKEY uint16 = 57
2011-08-22 22:11:41 +10:00
TypeTALINK uint16 = 58
2012-11-21 02:52:18 +11:00
TypeCDS uint16 = 59
2014-08-14 18:18:08 +10:00
TypeOPENPGPKEY uint16 = 61
2011-08-22 22:11:41 +10:00
TypeSPF uint16 = 99
TypeUINFO uint16 = 100
TypeUID uint16 = 101
TypeGID uint16 = 102
TypeUNSPEC uint16 = 103
2012-11-18 07:26:48 +11:00
TypeNID uint16 = 104
TypeL32 uint16 = 105
TypeL64 uint16 = 106
TypeLP uint16 = 107
TypeEUI48 uint16 = 108
TypeEUI64 uint16 = 109
2011-08-22 22:11:41 +10:00
TypeTKEY uint16 = 249
TypeTSIG uint16 = 250
2011-03-25 21:19:35 +11:00
// valid Question.Qtype only
2011-08-22 22:11:41 +10:00
TypeIXFR uint16 = 251
TypeAXFR uint16 = 252
TypeMAILB uint16 = 253
TypeMAILA uint16 = 254
TypeANY uint16 = 255
2012-09-02 01:06:24 +10:00
2013-10-13 23:27:50 +11:00
TypeURI uint16 = 256
TypeCAA uint16 = 257
TypeTA uint16 = 32768
TypeDLV uint16 = 32769
TypeReserved uint16 = 65535
2011-02-21 23:16:07 +11:00
2011-03-25 21:19:35 +11:00
// valid Question.Qclass
2010-08-04 07:57:59 +10:00
ClassINET = 1
ClassCSNET = 2
ClassCHAOS = 3
ClassHESIOD = 4
2011-07-23 17:21:24 +10:00
ClassNONE = 254
2010-08-04 07:57:59 +10:00
ClassANY = 255
// Msg.rcode
RcodeSuccess = 0
RcodeFormatError = 1
RcodeServerFailure = 2
RcodeNameError = 3
RcodeNotImplemented = 4
RcodeRefused = 5
2011-01-10 06:46:21 +11:00
RcodeYXDomain = 6
RcodeYXRrset = 7
RcodeNXRrset = 8
RcodeNotAuth = 9
RcodeNotZone = 10
2011-01-27 01:13:06 +11:00
RcodeBadSig = 16 // TSIG
RcodeBadVers = 16 // EDNS0
2011-01-27 01:13:06 +11:00
RcodeBadKey = 17
RcodeBadTime = 18
RcodeBadMode = 19 // TKEY
RcodeBadName = 20
RcodeBadAlg = 21
RcodeBadTrunc = 22 // TSIG
2011-01-02 05:51:25 +11:00
// Opcode
OpcodeQuery = 0
OpcodeIQuery = 1
OpcodeStatus = 2
// There is no 3
OpcodeNotify = 4
2011-01-02 06:51:34 +11:00
OpcodeUpdate = 5
2010-08-04 07:57:59 +10:00
)
// The wire format for the DNS packet header.
type Header struct {
Id uint16
Bits uint16
Qdcount, Ancount, Nscount, Arcount uint16
}
const (
// Header.Bits
_QR = 1 << 15 // query/response (response=1)
_AA = 1 << 10 // authoritative
_TC = 1 << 9 // truncated
_RD = 1 << 8 // recursion desired
_RA = 1 << 7 // recursion available
_Z = 1 << 6 // Z
_AD = 1 << 5 // authticated data
_CD = 1 << 4 // checking disabled
_LOC_EQUATOR = 1 << 31 // RFC 1876, Section 2.
2010-08-04 07:57:59 +10:00
)
// DNS queries.
type Question struct {
Name string `dns:"cdomain-name"` // "cdomain-name" specifies encoding (and may be compressed)
2010-08-04 07:57:59 +10:00
Qtype uint16
Qclass uint16
}
2011-12-20 22:53:47 +11:00
func (q *Question) String() (s string) {
2010-08-04 07:57:59 +10:00
// prefix with ; (as in dig)
s = ";" + sprintName(q.Name) + "\t"
s += Class(q.Qclass).String() + "\t"
s += " " + Type(q.Qtype).String()
2010-08-04 07:57:59 +10:00
return s
}
func (q *Question) len() int {
l := len(q.Name) + 1
return l + 4
}
type ANY struct {
2011-11-03 09:06:54 +11:00
Hdr RR_Header
// Does not have any rdata
2011-08-22 22:13:43 +10:00
}
func (rr *ANY) Header() *RR_Header { return &rr.Hdr }
func (rr *ANY) copy() RR { return &ANY{*rr.Hdr.copyHeader()} }
2013-05-01 00:56:30 +10:00
func (rr *ANY) String() string { return rr.Hdr.String() }
func (rr *ANY) len() int { return rr.Hdr.len() }
type CNAME struct {
Hdr RR_Header
Target string `dns:"cdomain-name"`
2010-08-04 07:57:59 +10:00
}
func (rr *CNAME) Header() *RR_Header { return &rr.Hdr }
func (rr *CNAME) copy() RR { return &CNAME{*rr.Hdr.copyHeader(), sprintName(rr.Target)} }
2013-05-01 00:56:30 +10:00
func (rr *CNAME) String() string { return rr.Hdr.String() + rr.Target }
func (rr *CNAME) len() int { return rr.Hdr.len() + len(rr.Target) + 1 }
type HINFO struct {
2010-08-04 07:57:59 +10:00
Hdr RR_Header
Cpu string
Os string
}
func (rr *HINFO) Header() *RR_Header { return &rr.Hdr }
func (rr *HINFO) copy() RR { return &HINFO{*rr.Hdr.copyHeader(), rr.Cpu, rr.Os} }
2013-05-01 00:56:30 +10:00
func (rr *HINFO) String() string { return rr.Hdr.String() + rr.Cpu + " " + rr.Os }
func (rr *HINFO) len() int { return rr.Hdr.len() + len(rr.Cpu) + len(rr.Os) }
type MB struct {
2010-08-04 07:57:59 +10:00
Hdr RR_Header
Mb string `dns:"cdomain-name"`
2010-08-04 07:57:59 +10:00
}
func (rr *MB) Header() *RR_Header { return &rr.Hdr }
func (rr *MB) copy() RR { return &MB{*rr.Hdr.copyHeader(), sprintName(rr.Mb)} }
2010-08-04 07:57:59 +10:00
2013-05-01 00:56:30 +10:00
func (rr *MB) String() string { return rr.Hdr.String() + rr.Mb }
func (rr *MB) len() int { return rr.Hdr.len() + len(rr.Mb) + 1 }
type MG struct {
2010-08-04 07:57:59 +10:00
Hdr RR_Header
Mg string `dns:"cdomain-name"`
2010-08-04 07:57:59 +10:00
}
func (rr *MG) Header() *RR_Header { return &rr.Hdr }
func (rr *MG) copy() RR { return &MG{*rr.Hdr.copyHeader(), rr.Mg} }
func (rr *MG) len() int { l := len(rr.Mg) + 1; return rr.Hdr.len() + l }
func (rr *MG) String() string { return rr.Hdr.String() + sprintName(rr.Mg) }
type MINFO struct {
2010-08-04 07:57:59 +10:00
Hdr RR_Header
Rmail string `dns:"cdomain-name"`
Email string `dns:"cdomain-name"`
2010-08-04 07:57:59 +10:00
}
func (rr *MINFO) Header() *RR_Header { return &rr.Hdr }
func (rr *MINFO) copy() RR { return &MINFO{*rr.Hdr.copyHeader(), rr.Rmail, rr.Email} }
2010-08-04 07:57:59 +10:00
func (rr *MINFO) String() string {
return rr.Hdr.String() + sprintName(rr.Rmail) + " " + sprintName(rr.Email)
2010-08-04 07:57:59 +10:00
}
func (rr *MINFO) len() int {
l := len(rr.Rmail) + 1
n := len(rr.Email) + 1
return rr.Hdr.len() + l + n
}
type MR struct {
2010-08-04 07:57:59 +10:00
Hdr RR_Header
Mr string `dns:"cdomain-name"`
2010-08-04 07:57:59 +10:00
}
func (rr *MR) Header() *RR_Header { return &rr.Hdr }
func (rr *MR) copy() RR { return &MR{*rr.Hdr.copyHeader(), rr.Mr} }
func (rr *MR) len() int { l := len(rr.Mr) + 1; return rr.Hdr.len() + l }
2010-08-04 07:57:59 +10:00
func (rr *MR) String() string {
return rr.Hdr.String() + sprintName(rr.Mr)
2010-08-04 07:57:59 +10:00
}
type MF struct {
2012-06-01 21:25:54 +10:00
Hdr RR_Header
2012-06-01 21:34:14 +10:00
Mf string `dns:"cdomain-name"`
2012-06-01 21:25:54 +10:00
}
func (rr *MF) Header() *RR_Header { return &rr.Hdr }
func (rr *MF) copy() RR { return &MF{*rr.Hdr.copyHeader(), rr.Mf} }
func (rr *MF) len() int { return rr.Hdr.len() + len(rr.Mf) + 1 }
2012-06-01 21:25:54 +10:00
func (rr *MF) String() string {
return rr.Hdr.String() + " " + sprintName(rr.Mf)
2012-06-01 21:25:54 +10:00
}
type MD struct {
2012-06-01 21:25:54 +10:00
Hdr RR_Header
2012-06-01 21:34:14 +10:00
Md string `dns:"cdomain-name"`
2012-06-01 21:25:54 +10:00
}
func (rr *MD) Header() *RR_Header { return &rr.Hdr }
func (rr *MD) copy() RR { return &MD{*rr.Hdr.copyHeader(), rr.Md} }
func (rr *MD) len() int { return rr.Hdr.len() + len(rr.Md) + 1 }
2012-06-01 21:25:54 +10:00
func (rr *MD) String() string {
return rr.Hdr.String() + " " + sprintName(rr.Md)
2012-06-01 21:25:54 +10:00
}
type MX struct {
2012-11-21 00:32:06 +11:00
Hdr RR_Header
Preference uint16
2012-11-21 00:32:06 +11:00
Mx string `dns:"cdomain-name"`
2010-08-04 07:57:59 +10:00
}
func (rr *MX) Header() *RR_Header { return &rr.Hdr }
func (rr *MX) copy() RR { return &MX{*rr.Hdr.copyHeader(), rr.Preference, rr.Mx} }
func (rr *MX) len() int { l := len(rr.Mx) + 1; return rr.Hdr.len() + l + 2 }
2010-08-04 07:57:59 +10:00
func (rr *MX) String() string {
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Mx)
2010-08-04 07:57:59 +10:00
}
type AFSDB struct {
2012-06-01 21:35:52 +10:00
Hdr RR_Header
Subtype uint16
Hostname string `dns:"cdomain-name"`
2012-06-01 21:34:14 +10:00
}
func (rr *AFSDB) Header() *RR_Header { return &rr.Hdr }
func (rr *AFSDB) copy() RR { return &AFSDB{*rr.Hdr.copyHeader(), rr.Subtype, rr.Hostname} }
func (rr *AFSDB) len() int { l := len(rr.Hostname) + 1; return rr.Hdr.len() + l + 2 }
2012-06-01 21:34:14 +10:00
func (rr *AFSDB) String() string {
return rr.Hdr.String() + strconv.Itoa(int(rr.Subtype)) + " " + sprintName(rr.Hostname)
2012-06-01 21:34:14 +10:00
}
type X25 struct {
2012-11-21 00:32:06 +11:00
Hdr RR_Header
2012-11-21 00:07:16 +11:00
PSDNAddress string
}
func (rr *X25) Header() *RR_Header { return &rr.Hdr }
func (rr *X25) copy() RR { return &X25{*rr.Hdr.copyHeader(), rr.PSDNAddress} }
func (rr *X25) len() int { return rr.Hdr.len() + len(rr.PSDNAddress) + 1 }
2012-11-21 00:07:16 +11:00
func (rr *X25) String() string {
2012-11-21 00:07:16 +11:00
return rr.Hdr.String() + rr.PSDNAddress
}
type RT struct {
2012-08-10 17:22:50 +10:00
Hdr RR_Header
Preference uint16
Host string `dns:"cdomain-name"`
}
func (rr *RT) Header() *RR_Header { return &rr.Hdr }
func (rr *RT) copy() RR { return &RT{*rr.Hdr.copyHeader(), rr.Preference, rr.Host} }
func (rr *RT) len() int { l := len(rr.Host) + 1; return rr.Hdr.len() + l + 2 }
2012-08-10 17:22:50 +10:00
func (rr *RT) String() string {
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Host)
2012-08-10 17:22:50 +10:00
}
type NS struct {
2010-08-04 07:57:59 +10:00
Hdr RR_Header
Ns string `dns:"cdomain-name"`
2010-08-04 07:57:59 +10:00
}
func (rr *NS) Header() *RR_Header { return &rr.Hdr }
func (rr *NS) len() int { l := len(rr.Ns) + 1; return rr.Hdr.len() + l }
func (rr *NS) copy() RR { return &NS{*rr.Hdr.copyHeader(), rr.Ns} }
2010-08-04 07:57:59 +10:00
func (rr *NS) String() string {
return rr.Hdr.String() + sprintName(rr.Ns)
2010-08-04 07:57:59 +10:00
}
type PTR struct {
2010-08-04 07:57:59 +10:00
Hdr RR_Header
Ptr string `dns:"cdomain-name"`
2010-08-04 07:57:59 +10:00
}
func (rr *PTR) Header() *RR_Header { return &rr.Hdr }
func (rr *PTR) copy() RR { return &PTR{*rr.Hdr.copyHeader(), rr.Ptr} }
func (rr *PTR) len() int { l := len(rr.Ptr) + 1; return rr.Hdr.len() + l }
2010-08-04 07:57:59 +10:00
func (rr *PTR) String() string {
return rr.Hdr.String() + sprintName(rr.Ptr)
2010-08-04 07:57:59 +10:00
}
type RP struct {
2012-05-02 06:57:22 +10:00
Hdr RR_Header
Mbox string `dns:"domain-name"`
Txt string `dns:"domain-name"`
}
func (rr *RP) Header() *RR_Header { return &rr.Hdr }
func (rr *RP) copy() RR { return &RP{*rr.Hdr.copyHeader(), rr.Mbox, rr.Txt} }
func (rr *RP) len() int { return rr.Hdr.len() + len(rr.Mbox) + 1 + len(rr.Txt) + 1 }
2012-05-02 06:57:22 +10:00
func (rr *RP) String() string {
return rr.Hdr.String() + rr.Mbox + " " + sprintTxt([]string{rr.Txt})
2012-05-02 06:57:22 +10:00
}
type SOA struct {
2010-08-04 07:57:59 +10:00
Hdr RR_Header
Ns string `dns:"cdomain-name"`
Mbox string `dns:"cdomain-name"`
2010-08-04 07:57:59 +10:00
Serial uint32
Refresh uint32
Retry uint32
Expire uint32
Minttl uint32
}
func (rr *SOA) Header() *RR_Header { return &rr.Hdr }
func (rr *SOA) copy() RR {
return &SOA{*rr.Hdr.copyHeader(), rr.Ns, rr.Mbox, rr.Serial, rr.Refresh, rr.Retry, rr.Expire, rr.Minttl}
2010-08-04 07:57:59 +10:00
}
func (rr *SOA) String() string {
return rr.Hdr.String() + sprintName(rr.Ns) + " " + sprintName(rr.Mbox) +
2012-02-20 04:36:59 +11:00
" " + strconv.FormatInt(int64(rr.Serial), 10) +
" " + strconv.FormatInt(int64(rr.Refresh), 10) +
" " + strconv.FormatInt(int64(rr.Retry), 10) +
" " + strconv.FormatInt(int64(rr.Expire), 10) +
" " + strconv.FormatInt(int64(rr.Minttl), 10)
2010-08-04 07:57:59 +10:00
}
func (rr *SOA) len() int {
l := len(rr.Ns) + 1
n := len(rr.Mbox) + 1
return rr.Hdr.len() + l + n + 20
}
type TXT struct {
2010-08-04 07:57:59 +10:00
Hdr RR_Header
Txt []string `dns:"txt"`
2010-08-04 07:57:59 +10:00
}
func (rr *TXT) Header() *RR_Header { return &rr.Hdr }
func (rr *TXT) copy() RR {
cp := make([]string, len(rr.Txt), cap(rr.Txt))
copy(cp, rr.Txt)
return &TXT{*rr.Hdr.copyHeader(), cp}
}
2010-08-04 07:57:59 +10:00
func (rr *TXT) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
func sprintName(s string) string {
src := []byte(s)
dst := make([]byte, 0, len(src))
for i := 0; i < len(src); {
if i+1 < len(src) && src[i] == '\\' && src[i+1] == '.' {
dst = append(dst, src[i:i+2]...)
i += 2
2012-02-19 06:07:25 +11:00
} else {
b, n := nextByte(src, i)
if n == 0 {
i++ // dangling back slash
} else if b == '.' {
dst = append(dst, b)
} else {
dst = appendDomainNameByte(dst, b)
}
i += n
2012-02-19 06:07:25 +11:00
}
}
return string(dst)
}
func sprintTxt(txt []string) string {
var out []byte
for i, s := range txt {
if i > 0 {
out = append(out, ` "`...)
} else {
out = append(out, '"')
}
bs := []byte(s)
for j := 0; j < len(bs); {
b, n := nextByte(bs, j)
if n == 0 {
break
}
out = appendTXTStringByte(out, b)
j += n
}
out = append(out, '"')
}
return string(out)
}
func appendDomainNameByte(s []byte, b byte) []byte {
if b == '.' || b == '(' || b == ')' || b == ';' || b == ' ' || b == '\'' || b == '@' {
return append(s, '\\', b)
}
return appendTXTStringByte(s, b)
}
func appendTXTStringByte(s []byte, b byte) []byte {
if b == '"' {
return append(s, `\"`...)
} else if b == '\\' {
return append(s, `\\`...)
} else if b == '\t' {
return append(s, `\t`...)
} else if b == '\r' {
return append(s, `\r`...)
} else if b == '\n' {
return append(s, `\n`...)
} else if b < ' ' || b > '~' {
return append(s, fmt.Sprintf("\\%03d", b)...)
}
return append(s, b)
}
func nextByte(b []byte, offset int) (byte, int) {
2014-03-01 13:37:10 +11:00
if offset >= len(b) {
return 0, 0
}
if b[offset] != '\\' {
// not an escape sequence
return b[offset], 1
}
switch len(b) - offset {
case 1: // dangling escape
return 0, 0
case 2, 3: // too short to be \ddd
default: // maybe \ddd
if isDigit(b[offset+1]) && isDigit(b[offset+2]) && isDigit(b[offset+3]) {
return dddToByte(b[offset+1:]), 4
}
}
// not \ddd, maybe a control char
switch b[offset+1] {
case 't':
return '\t', 2
case 'r':
return '\r', 2
case 'n':
return '\n', 2
default:
return b[offset+1], 2
}
2010-08-04 07:57:59 +10:00
}
func (rr *TXT) len() int {
l := rr.Hdr.len()
for _, t := range rr.Txt {
l += len(t) + 1
2012-02-19 06:07:25 +11:00
}
return l
}
type SPF struct {
2012-02-19 04:59:19 +11:00
Hdr RR_Header
Txt []string `dns:"txt"`
2012-02-19 04:59:19 +11:00
}
func (rr *SPF) Header() *RR_Header { return &rr.Hdr }
func (rr *SPF) copy() RR {
cp := make([]string, len(rr.Txt), cap(rr.Txt))
copy(cp, rr.Txt)
return &SPF{*rr.Hdr.copyHeader(), cp}
}
2012-02-19 04:59:19 +11:00
func (rr *SPF) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
2012-02-19 04:59:19 +11:00
func (rr *SPF) len() int {
l := rr.Hdr.len()
2012-02-19 06:07:25 +11:00
for _, t := range rr.Txt {
l += len(t) + 1
2012-02-19 06:07:25 +11:00
}
return l
2012-02-19 04:59:19 +11:00
}
type SRV struct {
2010-08-04 07:57:59 +10:00
Hdr RR_Header
Priority uint16
Weight uint16
Port uint16
Target string `dns:"domain-name"`
2010-08-04 07:57:59 +10:00
}
func (rr *SRV) Header() *RR_Header { return &rr.Hdr }
func (rr *SRV) len() int { l := len(rr.Target) + 1; return rr.Hdr.len() + l + 6 }
func (rr *SRV) copy() RR {
return &SRV{*rr.Hdr.copyHeader(), rr.Priority, rr.Weight, rr.Port, rr.Target}
2010-08-04 07:57:59 +10:00
}
func (rr *SRV) String() string {
2010-08-04 07:57:59 +10:00
return rr.Hdr.String() +
strconv.Itoa(int(rr.Priority)) + " " +
strconv.Itoa(int(rr.Weight)) + " " +
strconv.Itoa(int(rr.Port)) + " " + sprintName(rr.Target)
2010-08-04 07:57:59 +10:00
}
type NAPTR struct {
2010-12-31 06:50:31 +11:00
Hdr RR_Header
Order uint16
2012-11-21 00:32:06 +11:00
Preference uint16
2010-12-31 06:50:31 +11:00
Flags string
Service string
Regexp string
Replacement string `dns:"domain-name"`
2010-12-31 06:50:31 +11:00
}
func (rr *NAPTR) Header() *RR_Header { return &rr.Hdr }
func (rr *NAPTR) copy() RR {
return &NAPTR{*rr.Hdr.copyHeader(), rr.Order, rr.Preference, rr.Flags, rr.Service, rr.Regexp, rr.Replacement}
2010-12-31 06:50:31 +11:00
}
func (rr *NAPTR) String() string {
2011-01-18 02:03:06 +11:00
return rr.Hdr.String() +
2011-01-17 20:30:20 +11:00
strconv.Itoa(int(rr.Order)) + " " +
strconv.Itoa(int(rr.Preference)) + " " +
2011-01-17 20:30:20 +11:00
"\"" + rr.Flags + "\" " +
"\"" + rr.Service + "\" " +
"\"" + rr.Regexp + "\" " +
rr.Replacement
2010-12-31 06:50:31 +11:00
}
func (rr *NAPTR) len() int {
return rr.Hdr.len() + 4 + len(rr.Flags) + 1 + len(rr.Service) + 1 +
len(rr.Regexp) + 1 + len(rr.Replacement) + 1
}
2011-02-25 02:13:23 +11:00
// See RFC 4398.
type CERT struct {
Hdr RR_Header
Type uint16
KeyTag uint16
Algorithm uint8
Certificate string `dns:"base64"`
}
func (rr *CERT) Header() *RR_Header { return &rr.Hdr }
func (rr *CERT) copy() RR {
return &CERT{*rr.Hdr.copyHeader(), rr.Type, rr.KeyTag, rr.Algorithm, rr.Certificate}
}
func (rr *CERT) String() string {
return rr.Hdr.String() + strconv.Itoa(int(rr.Type)) +
" " + strconv.Itoa(int(rr.KeyTag)) +
" " + strconv.Itoa(int(rr.Algorithm)) +
" " + rr.Certificate
}
func (rr *CERT) len() int {
return rr.Hdr.len() + 5 +
2012-02-20 01:24:26 +11:00
base64.StdEncoding.DecodedLen(len(rr.Certificate))
}
2011-01-27 19:29:11 +11:00
// See RFC 2672.
type DNAME struct {
Hdr RR_Header
Target string `dns:"domain-name"`
2011-01-25 23:47:12 +11:00
}
func (rr *DNAME) Header() *RR_Header { return &rr.Hdr }
func (rr *DNAME) copy() RR { return &DNAME{*rr.Hdr.copyHeader(), rr.Target} }
func (rr *DNAME) len() int { l := len(rr.Target) + 1; return rr.Hdr.len() + l }
2011-01-25 23:47:12 +11:00
func (rr *DNAME) String() string {
return rr.Hdr.String() + sprintName(rr.Target)
2011-01-25 23:47:12 +11:00
}
type A struct {
2010-08-04 07:57:59 +10:00
Hdr RR_Header
A net.IP `dns:"a"`
2010-08-04 07:57:59 +10:00
}
func (rr *A) Header() *RR_Header { return &rr.Hdr }
func (rr *A) copy() RR { return &A{*rr.Hdr.copyHeader(), copyIP(rr.A)} }
2013-05-01 00:42:04 +10:00
func (rr *A) len() int { return rr.Hdr.len() + net.IPv4len }
func (rr *A) String() string {
if rr.A == nil {
return rr.Hdr.String()
}
return rr.Hdr.String() + rr.A.String()
}
type AAAA struct {
2010-08-04 07:57:59 +10:00
Hdr RR_Header
AAAA net.IP `dns:"aaaa"`
2010-08-04 07:57:59 +10:00
}
func (rr *AAAA) Header() *RR_Header { return &rr.Hdr }
func (rr *AAAA) copy() RR { return &AAAA{*rr.Hdr.copyHeader(), copyIP(rr.AAAA)} }
2013-05-01 00:42:04 +10:00
func (rr *AAAA) len() int { return rr.Hdr.len() + net.IPv6len }
func (rr *AAAA) String() string {
if rr.AAAA == nil {
return rr.Hdr.String()
}
return rr.Hdr.String() + rr.AAAA.String()
}
2013-10-13 23:23:02 +11:00
type PX struct {
Hdr RR_Header
Preference uint16
Map822 string `dns:"domain-name"`
Mapx400 string `dns:"domain-name"`
}
func (rr *PX) Header() *RR_Header { return &rr.Hdr }
func (rr *PX) copy() RR { return &PX{*rr.Hdr.copyHeader(), rr.Preference, rr.Map822, rr.Mapx400} }
func (rr *PX) String() string {
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Map822) + " " + sprintName(rr.Mapx400)
2013-10-13 23:23:02 +11:00
}
func (rr *PX) len() int { return rr.Hdr.len() + 2 + len(rr.Map822) + 1 + len(rr.Mapx400) + 1 }
2013-10-13 23:23:02 +11:00
2013-10-13 23:01:33 +11:00
type GPOS struct {
Hdr RR_Header
Longitude string
Latitude string
Altitude string
}
func (rr *GPOS) Header() *RR_Header { return &rr.Hdr }
func (rr *GPOS) copy() RR { return &GPOS{*rr.Hdr.copyHeader(), rr.Longitude, rr.Latitude, rr.Altitude} }
func (rr *GPOS) len() int {
return rr.Hdr.len() + len(rr.Longitude) + len(rr.Latitude) + len(rr.Altitude) + 3
}
func (rr *GPOS) String() string {
return rr.Hdr.String() + rr.Longitude + " " + rr.Latitude + " " + rr.Altitude
}
type LOC struct {
Hdr RR_Header
Version uint8
Size uint8
HorizPre uint8
VertPre uint8
Latitude uint32
Longitude uint32
Altitude uint32
2010-12-31 06:55:25 +11:00
}
func (rr *LOC) Header() *RR_Header { return &rr.Hdr }
func (rr *LOC) len() int { return rr.Hdr.len() + 4 + 12 }
func (rr *LOC) copy() RR {
return &LOC{*rr.Hdr.copyHeader(), rr.Version, rr.Size, rr.HorizPre, rr.VertPre, rr.Latitude, rr.Longitude, rr.Altitude}
2010-12-31 06:55:25 +11:00
}
func (rr *LOC) String() string {
s := rr.Hdr.String()
// Copied from ldns
// Latitude
lat := rr.Latitude
north := "N"
if lat > _LOC_EQUATOR {
lat = lat - _LOC_EQUATOR
} else {
north = "S"
lat = _LOC_EQUATOR - lat
}
h := lat / (1000 * 60 * 60)
lat = lat % (1000 * 60 * 60)
m := lat / (1000 * 60)
lat = lat % (1000 * 60)
s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, (float32(lat) / 1000), north)
// Longitude
lon := rr.Longitude
east := "E"
if lon > _LOC_EQUATOR {
lon = lon - _LOC_EQUATOR
} else {
east = "W"
lon = _LOC_EQUATOR - lon
}
h = lon / (1000 * 60 * 60)
lon = lon % (1000 * 60 * 60)
m = lon / (1000 * 60)
lon = lon % (1000 * 60)
s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, (float32(lon) / 1000), east)
s1 := rr.Altitude / 100.00
s1 -= 100000
if rr.Altitude%100 == 0 {
s += fmt.Sprintf("%.2fm ", float32(s1))
} else {
s += fmt.Sprintf("%.0fm ", float32(s1))
}
2012-05-01 00:54:02 +10:00
s += cmToString((rr.Size&0xf0)>>4, rr.Size&0x0f) + "m "
s += cmToString((rr.HorizPre&0xf0)>>4, rr.HorizPre&0x0f) + "m "
s += cmToString((rr.VertPre&0xf0)>>4, rr.VertPre&0x0f) + "m"
return s
2010-12-31 06:55:25 +11:00
}
type RRSIG struct {
2010-12-23 21:02:01 +11:00
Hdr RR_Header
TypeCovered uint16
Algorithm uint8
Labels uint8
OrigTtl uint32
Expiration uint32
Inception uint32
KeyTag uint16
SignerName string `dns:"domain-name"`
Signature string `dns:"base64"`
2010-08-04 07:57:59 +10:00
}
func (rr *RRSIG) Header() *RR_Header { return &rr.Hdr }
func (rr *RRSIG) copy() RR {
return &RRSIG{*rr.Hdr.copyHeader(), rr.TypeCovered, rr.Algorithm, rr.Labels, rr.OrigTtl, rr.Expiration, rr.Inception, rr.KeyTag, rr.SignerName, rr.Signature}
2010-08-04 07:57:59 +10:00
}
func (rr *RRSIG) String() string {
s := rr.Hdr.String()
s += Type(rr.TypeCovered).String()
s += " " + strconv.Itoa(int(rr.Algorithm)) +
2010-12-21 08:20:13 +11:00
" " + strconv.Itoa(int(rr.Labels)) +
2012-02-20 04:36:59 +11:00
" " + strconv.FormatInt(int64(rr.OrigTtl), 10) +
2012-09-12 05:45:21 +10:00
" " + TimeToString(rr.Expiration) +
" " + TimeToString(rr.Inception) +
2010-12-21 08:20:13 +11:00
" " + strconv.Itoa(int(rr.KeyTag)) +
" " + sprintName(rr.SignerName) +
" " + rr.Signature
return s
2010-08-04 07:57:59 +10:00
}
func (rr *RRSIG) len() int {
return rr.Hdr.len() + len(rr.SignerName) + 1 +
2012-02-20 01:24:26 +11:00
base64.StdEncoding.DecodedLen(len(rr.Signature)) + 18
}
type NSEC struct {
Hdr RR_Header
NextDomain string `dns:"domain-name"`
TypeBitMap []uint16 `dns:"nsec"`
2010-08-04 07:57:59 +10:00
}
func (rr *NSEC) Header() *RR_Header { return &rr.Hdr }
func (rr *NSEC) copy() RR {
cp := make([]uint16, len(rr.TypeBitMap), cap(rr.TypeBitMap))
copy(cp, rr.TypeBitMap)
return &NSEC{*rr.Hdr.copyHeader(), rr.NextDomain, cp}
}
2010-08-04 07:57:59 +10:00
func (rr *NSEC) String() string {
s := rr.Hdr.String() + sprintName(rr.NextDomain)
2011-01-17 20:30:20 +11:00
for i := 0; i < len(rr.TypeBitMap); i++ {
s += " " + Type(rr.TypeBitMap[i]).String()
2011-01-17 20:30:20 +11:00
}
return s
2010-08-04 07:57:59 +10:00
}
func (rr *NSEC) len() int {
l := rr.Hdr.len() + len(rr.NextDomain) + 1
lastwindow := uint32(2 ^ 32 + 1)
for _, t := range rr.TypeBitMap {
window := t / 256
if uint32(window) != lastwindow {
l += 1 + 32
}
lastwindow = uint32(window)
}
return l
}
type DS struct {
2010-08-04 07:57:59 +10:00
Hdr RR_Header
KeyTag uint16
Algorithm uint8
DigestType uint8
Digest string `dns:"hex"`
2010-08-04 07:57:59 +10:00
}
func (rr *DS) Header() *RR_Header { return &rr.Hdr }
func (rr *DS) len() int { return rr.Hdr.len() + 4 + len(rr.Digest)/2 }
func (rr *DS) copy() RR {
return &DS{*rr.Hdr.copyHeader(), rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
2010-08-04 07:57:59 +10:00
}
func (rr *DS) String() string {
2011-01-18 02:03:06 +11:00
return rr.Hdr.String() + strconv.Itoa(int(rr.KeyTag)) +
" " + strconv.Itoa(int(rr.Algorithm)) +
2010-08-04 07:57:59 +10:00
" " + strconv.Itoa(int(rr.DigestType)) +
" " + strings.ToUpper(rr.Digest)
2010-08-04 07:57:59 +10:00
}
type CDS struct {
2012-11-21 02:52:18 +11:00
Hdr RR_Header
KeyTag uint16
Algorithm uint8
DigestType uint8
Digest string `dns:"hex"`
}
func (rr *CDS) Header() *RR_Header { return &rr.Hdr }
func (rr *CDS) len() int { return rr.Hdr.len() + 4 + len(rr.Digest)/2 }
func (rr *CDS) copy() RR {
return &CDS{*rr.Hdr.copyHeader(), rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
2012-11-21 02:52:18 +11:00
}
func (rr *CDS) String() string {
2012-11-21 02:52:18 +11:00
return rr.Hdr.String() + strconv.Itoa(int(rr.KeyTag)) +
" " + strconv.Itoa(int(rr.Algorithm)) +
" " + strconv.Itoa(int(rr.DigestType)) +
" " + strings.ToUpper(rr.Digest)
}
type DLV struct {
2011-02-21 23:16:07 +11:00
Hdr RR_Header
KeyTag uint16
Algorithm uint8
DigestType uint8
Digest string `dns:"hex"`
2011-02-21 23:16:07 +11:00
}
func (rr *DLV) Header() *RR_Header { return &rr.Hdr }
func (rr *DLV) len() int { return rr.Hdr.len() + 4 + len(rr.Digest)/2 }
func (rr *DLV) copy() RR {
return &DLV{*rr.Hdr.copyHeader(), rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
2011-02-21 23:16:07 +11:00
}
func (rr *DLV) String() string {
2011-02-21 23:16:07 +11:00
return rr.Hdr.String() + strconv.Itoa(int(rr.KeyTag)) +
" " + strconv.Itoa(int(rr.Algorithm)) +
" " + strconv.Itoa(int(rr.DigestType)) +
" " + strings.ToUpper(rr.Digest)
}
type KX struct {
2012-11-21 00:32:06 +11:00
Hdr RR_Header
Preference uint16
Exchanger string `dns:"domain-name"`
2011-03-13 23:04:54 +11:00
}
func (rr *KX) Header() *RR_Header { return &rr.Hdr }
func (rr *KX) len() int { return rr.Hdr.len() + 2 + len(rr.Exchanger) + 1 }
func (rr *KX) copy() RR { return &KX{*rr.Hdr.copyHeader(), rr.Preference, rr.Exchanger} }
2011-03-13 23:04:54 +11:00
func (rr *KX) String() string {
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) +
" " + sprintName(rr.Exchanger)
2011-03-13 23:04:54 +11:00
}
type TA struct {
2011-02-21 23:16:07 +11:00
Hdr RR_Header
KeyTag uint16
Algorithm uint8
DigestType uint8
Digest string `dns:"hex"`
2011-02-21 23:16:07 +11:00
}
func (rr *TA) Header() *RR_Header { return &rr.Hdr }
func (rr *TA) len() int { return rr.Hdr.len() + 4 + len(rr.Digest)/2 }
func (rr *TA) copy() RR {
return &TA{*rr.Hdr.copyHeader(), rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
2011-02-21 23:16:07 +11:00
}
func (rr *TA) String() string {
2011-02-21 23:16:07 +11:00
return rr.Hdr.String() + strconv.Itoa(int(rr.KeyTag)) +
" " + strconv.Itoa(int(rr.Algorithm)) +
" " + strconv.Itoa(int(rr.DigestType)) +
" " + strings.ToUpper(rr.Digest)
}
2011-01-17 20:30:20 +11:00
type TALINK struct {
2011-02-21 23:24:45 +11:00
Hdr RR_Header
PreviousName string `dns:"domain-name"`
NextName string `dns:"domain-name"`
2011-02-21 23:24:45 +11:00
}
func (rr *TALINK) Header() *RR_Header { return &rr.Hdr }
func (rr *TALINK) copy() RR { return &TALINK{*rr.Hdr.copyHeader(), rr.PreviousName, rr.NextName} }
func (rr *TALINK) len() int { return rr.Hdr.len() + len(rr.PreviousName) + len(rr.NextName) + 2 }
2011-02-21 23:24:45 +11:00
func (rr *TALINK) String() string {
2011-02-21 23:24:45 +11:00
return rr.Hdr.String() +
" " + sprintName(rr.PreviousName) + " " + sprintName(rr.NextName)
2011-02-21 23:24:45 +11:00
}
type SSHFP struct {
2011-01-17 20:30:20 +11:00
Hdr RR_Header
Algorithm uint8
Type uint8
FingerPrint string `dns:"hex"`
2011-01-17 20:30:20 +11:00
}
func (rr *SSHFP) Header() *RR_Header { return &rr.Hdr }
func (rr *SSHFP) len() int { return rr.Hdr.len() + 2 + len(rr.FingerPrint)/2 }
func (rr *SSHFP) copy() RR {
return &SSHFP{*rr.Hdr.copyHeader(), rr.Algorithm, rr.Type, rr.FingerPrint}
2011-01-17 20:30:20 +11:00
}
func (rr *SSHFP) String() string {
2011-01-18 02:03:06 +11:00
return rr.Hdr.String() + strconv.Itoa(int(rr.Algorithm)) +
2011-01-17 20:30:20 +11:00
" " + strconv.Itoa(int(rr.Type)) +
" " + strings.ToUpper(rr.FingerPrint)
}
type IPSECKEY struct {
2012-02-19 06:07:25 +11:00
Hdr RR_Header
Precedence uint8
GatewayType uint8
Algorithm uint8
Gateway string `dns:"ipseckey"`
PublicKey string `dns:"base64"`
}
func (rr *IPSECKEY) Header() *RR_Header { return &rr.Hdr }
func (rr *IPSECKEY) copy() RR {
return &IPSECKEY{*rr.Hdr.copyHeader(), rr.Precedence, rr.GatewayType, rr.Algorithm, rr.Gateway, rr.PublicKey}
}
func (rr *IPSECKEY) String() string {
2012-02-19 06:07:25 +11:00
return rr.Hdr.String() + strconv.Itoa(int(rr.Precedence)) +
" " + strconv.Itoa(int(rr.GatewayType)) +
" " + strconv.Itoa(int(rr.Algorithm)) +
" " + rr.Gateway +
" " + rr.PublicKey
}
func (rr *IPSECKEY) len() int {
return rr.Hdr.len() + 3 + len(rr.Gateway) + 1 +
2012-02-20 01:24:26 +11:00
base64.StdEncoding.DecodedLen(len(rr.PublicKey))
}
type DNSKEY struct {
2010-08-04 07:57:59 +10:00
Hdr RR_Header
Flags uint16
Protocol uint8
Algorithm uint8
PublicKey string `dns:"base64"`
2010-08-04 07:57:59 +10:00
}
func (rr *DNSKEY) Header() *RR_Header { return &rr.Hdr }
func (rr *DNSKEY) len() int {
return rr.Hdr.len() + 4 + base64.StdEncoding.DecodedLen(len(rr.PublicKey))
}
func (rr *DNSKEY) copy() RR {
return &DNSKEY{*rr.Hdr.copyHeader(), rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey}
2010-08-04 07:57:59 +10:00
}
func (rr *DNSKEY) String() string {
2012-02-19 06:07:25 +11:00
return rr.Hdr.String() + strconv.Itoa(int(rr.Flags)) +
2010-08-04 07:57:59 +10:00
" " + strconv.Itoa(int(rr.Protocol)) +
2010-12-21 08:20:13 +11:00
" " + strconv.Itoa(int(rr.Algorithm)) +
" " + rr.PublicKey
2010-08-04 07:57:59 +10:00
}
type RKEY struct {
2012-11-21 02:48:28 +11:00
Hdr RR_Header
Flags uint16
Protocol uint8
Algorithm uint8
PublicKey string `dns:"base64"`
}
func (rr *RKEY) Header() *RR_Header { return &rr.Hdr }
func (rr *RKEY) len() int { return rr.Hdr.len() + 4 + base64.StdEncoding.DecodedLen(len(rr.PublicKey)) }
func (rr *RKEY) copy() RR {
return &RKEY{*rr.Hdr.copyHeader(), rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey}
2012-11-21 02:48:28 +11:00
}
func (rr *RKEY) String() string {
2012-11-21 02:48:28 +11:00
return rr.Hdr.String() + strconv.Itoa(int(rr.Flags)) +
" " + strconv.Itoa(int(rr.Protocol)) +
" " + strconv.Itoa(int(rr.Algorithm)) +
" " + rr.PublicKey
}
2013-10-13 22:25:08 +11:00
type NSAP struct {
Hdr RR_Header
Length uint8
Nsap string
}
func (rr *NSAP) Header() *RR_Header { return &rr.Hdr }
func (rr *NSAP) copy() RR { return &NSAP{*rr.Hdr.copyHeader(), rr.Length, rr.Nsap} }
func (rr *NSAP) String() string { return rr.Hdr.String() + strconv.Itoa(int(rr.Length)) + " " + rr.Nsap }
func (rr *NSAP) len() int { return rr.Hdr.len() + 1 + len(rr.Nsap) + 1 }
2013-10-13 22:25:08 +11:00
type NSAPPTR struct {
Hdr RR_Header
Ptr string `dns:"domain-name"`
}
func (rr *NSAPPTR) Header() *RR_Header { return &rr.Hdr }
func (rr *NSAPPTR) copy() RR { return &NSAPPTR{*rr.Hdr.copyHeader(), rr.Ptr} }
func (rr *NSAPPTR) String() string { return rr.Hdr.String() + sprintName(rr.Ptr) }
func (rr *NSAPPTR) len() int { return rr.Hdr.len() + len(rr.Ptr) }
2013-10-13 22:25:08 +11:00
type NSEC3 struct {
Hdr RR_Header
Hash uint8
Flags uint8
Iterations uint16
SaltLength uint8
Salt string `dns:"size-hex"`
HashLength uint8
NextDomain string `dns:"size-base32"`
TypeBitMap []uint16 `dns:"nsec"`
2010-08-04 07:57:59 +10:00
}
func (rr *NSEC3) Header() *RR_Header { return &rr.Hdr }
func (rr *NSEC3) copy() RR {
cp := make([]uint16, len(rr.TypeBitMap), cap(rr.TypeBitMap))
copy(cp, rr.TypeBitMap)
return &NSEC3{*rr.Hdr.copyHeader(), rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt, rr.HashLength, rr.NextDomain, cp}
2010-08-04 07:57:59 +10:00
}
func (rr *NSEC3) String() string {
2011-01-17 20:30:20 +11:00
s := rr.Hdr.String()
2011-01-18 02:03:06 +11:00
s += strconv.Itoa(int(rr.Hash)) +
2011-01-17 20:30:20 +11:00
" " + strconv.Itoa(int(rr.Flags)) +
" " + strconv.Itoa(int(rr.Iterations)) +
" " + saltToString(rr.Salt) +
2011-02-22 02:21:16 +11:00
" " + rr.NextDomain
2011-01-17 20:30:20 +11:00
for i := 0; i < len(rr.TypeBitMap); i++ {
s += " " + Type(rr.TypeBitMap[i]).String()
2011-01-17 20:30:20 +11:00
}
return s
2010-08-04 07:57:59 +10:00
}
func (rr *NSEC3) len() int {
l := rr.Hdr.len() + 6 + len(rr.Salt)/2 + 1 + len(rr.NextDomain) + 1
lastwindow := uint32(2 ^ 32 + 1)
for _, t := range rr.TypeBitMap {
window := t / 256
if uint32(window) != lastwindow {
l += 1 + 32
}
lastwindow = uint32(window)
}
return l
}
type NSEC3PARAM struct {
Hdr RR_Header
Hash uint8
Flags uint8
Iterations uint16
SaltLength uint8
2012-08-27 06:40:00 +10:00
Salt string `dns:"hex"`
2010-08-04 07:57:59 +10:00
}
func (rr *NSEC3PARAM) Header() *RR_Header { return &rr.Hdr }
func (rr *NSEC3PARAM) len() int { return rr.Hdr.len() + 2 + 4 + 1 + len(rr.Salt)/2 }
func (rr *NSEC3PARAM) copy() RR {
return &NSEC3PARAM{*rr.Hdr.copyHeader(), rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt}
2010-08-04 07:57:59 +10:00
}
func (rr *NSEC3PARAM) String() string {
2011-01-18 02:03:06 +11:00
s := rr.Hdr.String()
s += strconv.Itoa(int(rr.Hash)) +
" " + strconv.Itoa(int(rr.Flags)) +
" " + strconv.Itoa(int(rr.Iterations)) +
" " + saltToString(rr.Salt)
return s
2010-08-04 07:57:59 +10:00
}
type TKEY struct {
Hdr RR_Header
Algorithm string `dns:"domain-name"`
Inception uint32
Expiration uint32
Mode uint16
Error uint16
KeySize uint16
Key string
2012-06-21 01:12:10 +10:00
OtherLen uint16
OtherData string
}
func (rr *TKEY) Header() *RR_Header { return &rr.Hdr }
func (rr *TKEY) copy() RR {
return &TKEY{*rr.Hdr.copyHeader(), rr.Algorithm, rr.Inception, rr.Expiration, rr.Mode, rr.Error, rr.KeySize, rr.Key, rr.OtherLen, rr.OtherData}
}
func (rr *TKEY) String() string {
2011-01-10 06:46:21 +11:00
// It has no presentation format
return ""
}
func (rr *TKEY) len() int {
return rr.Hdr.len() + len(rr.Algorithm) + 1 + 4 + 4 + 6 +
len(rr.Key) + 2 + len(rr.OtherData)
}
// RFC3597 represents an unknown/generic RR.
type RFC3597 struct {
2011-02-25 02:22:14 +11:00
Hdr RR_Header
Rdata string `dns:"hex"`
2011-02-22 01:19:52 +11:00
}
func (rr *RFC3597) Header() *RR_Header { return &rr.Hdr }
func (rr *RFC3597) copy() RR { return &RFC3597{*rr.Hdr.copyHeader(), rr.Rdata} }
func (rr *RFC3597) len() int { return rr.Hdr.len() + len(rr.Rdata)/2 + 2 }
2011-02-22 01:19:52 +11:00
func (rr *RFC3597) String() string {
2011-02-25 02:22:14 +11:00
s := rr.Hdr.String()
s += "\\# " + strconv.Itoa(len(rr.Rdata)/2) + " " + rr.Rdata
return s
2011-02-22 01:19:52 +11:00
}
type URI struct {
2011-02-25 02:22:14 +11:00
Hdr RR_Header
Priority uint16
Weight uint16
2013-01-21 01:43:40 +11:00
Target []string `dns:"txt"`
}
func (rr *URI) Header() *RR_Header { return &rr.Hdr }
func (rr *URI) copy() RR {
cp := make([]string, len(rr.Target), cap(rr.Target))
copy(cp, rr.Target)
return &URI{*rr.Hdr.copyHeader(), rr.Weight, rr.Priority, cp}
}
func (rr *URI) String() string {
return rr.Hdr.String() + strconv.Itoa(int(rr.Priority)) +
" " + strconv.Itoa(int(rr.Weight)) + sprintTxt(rr.Target)
}
func (rr *URI) len() int {
l := rr.Hdr.len() + 4
for _, t := range rr.Target {
l += len(t) + 1
}
return l
}
type DHCID struct {
2011-07-23 17:21:24 +10:00
Hdr RR_Header
Digest string `dns:"base64"`
2011-03-13 23:11:11 +11:00
}
func (rr *DHCID) Header() *RR_Header { return &rr.Hdr }
func (rr *DHCID) copy() RR { return &DHCID{*rr.Hdr.copyHeader(), rr.Digest} }
func (rr *DHCID) String() string { return rr.Hdr.String() + rr.Digest }
func (rr *DHCID) len() int { return rr.Hdr.len() + base64.StdEncoding.DecodedLen(len(rr.Digest)) }
type TLSA struct {
2012-01-16 20:11:05 +11:00
Hdr RR_Header
Usage uint8
Selector uint8
MatchingType uint8
Certificate string `dns:"hex"`
2012-01-16 20:06:21 +11:00
}
func (rr *TLSA) Header() *RR_Header { return &rr.Hdr }
func (rr *TLSA) len() int { return rr.Hdr.len() + 3 + len(rr.Certificate)/2 }
func (rr *TLSA) copy() RR {
return &TLSA{*rr.Hdr.copyHeader(), rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate}
2012-01-16 20:06:21 +11:00
}
func (rr *TLSA) String() string {
2012-01-16 20:06:21 +11:00
return rr.Hdr.String() +
" " + strconv.Itoa(int(rr.Usage)) +
" " + strconv.Itoa(int(rr.Selector)) +
" " + strconv.Itoa(int(rr.MatchingType)) +
" " + rr.Certificate
}
type HIP struct {
2012-02-19 06:07:25 +11:00
Hdr RR_Header
HitLength uint8
PublicKeyAlgorithm uint8
PublicKeyLength uint16
Hit string `dns:"hex"`
PublicKey string `dns:"base64"`
RendezvousServers []string `dns:"domain-name"`
2012-02-19 06:07:25 +11:00
}
func (rr *HIP) Header() *RR_Header { return &rr.Hdr }
func (rr *HIP) copy() RR {
cp := make([]string, len(rr.RendezvousServers), cap(rr.RendezvousServers))
copy(cp, rr.RendezvousServers)
return &HIP{*rr.Hdr.copyHeader(), rr.HitLength, rr.PublicKeyAlgorithm, rr.PublicKeyLength, rr.Hit, rr.PublicKey, cp}
2012-02-19 06:07:25 +11:00
}
func (rr *HIP) String() string {
2012-02-20 01:24:26 +11:00
s := rr.Hdr.String() +
2012-02-19 06:07:25 +11:00
" " + strconv.Itoa(int(rr.PublicKeyAlgorithm)) +
" " + rr.Hit +
" " + rr.PublicKey
2012-02-20 01:24:26 +11:00
for _, d := range rr.RendezvousServers {
s += " " + sprintName(d)
2012-02-20 01:24:26 +11:00
}
return s
2012-02-19 06:07:25 +11:00
}
func (rr *HIP) len() int {
l := rr.Hdr.len() + 4 +
2012-02-20 01:24:26 +11:00
len(rr.Hit)/2 +
base64.StdEncoding.DecodedLen(len(rr.PublicKey))
for _, d := range rr.RendezvousServers {
l += len(d) + 1
2012-02-20 01:24:26 +11:00
}
return l
2012-02-19 06:07:25 +11:00
}
type NINFO struct {
2012-11-21 02:52:18 +11:00
Hdr RR_Header
ZSData []string `dns:"txt"`
2012-11-21 02:42:16 +11:00
}
func (rr *NINFO) Header() *RR_Header { return &rr.Hdr }
func (rr *NINFO) copy() RR {
cp := make([]string, len(rr.ZSData), cap(rr.ZSData))
copy(cp, rr.ZSData)
return &NINFO{*rr.Hdr.copyHeader(), cp}
}
2012-11-21 02:42:16 +11:00
func (rr *NINFO) String() string { return rr.Hdr.String() + sprintTxt(rr.ZSData) }
2012-11-21 02:42:16 +11:00
func (rr *NINFO) len() int {
l := rr.Hdr.len()
2012-11-21 02:42:16 +11:00
for _, t := range rr.ZSData {
l += len(t) + 1
2012-11-21 02:42:16 +11:00
}
return l
}
type WKS struct {
2012-06-02 06:23:21 +10:00
Hdr RR_Header
Address net.IP `dns:"a"`
Protocol uint8
2012-06-03 01:33:49 +10:00
BitMap []uint16 `dns:"wks"`
2012-06-02 02:29:07 +10:00
}
func (rr *WKS) Header() *RR_Header { return &rr.Hdr }
func (rr *WKS) len() int { return rr.Hdr.len() + net.IPv4len + 1 }
func (rr *WKS) copy() RR {
cp := make([]uint16, len(rr.BitMap), cap(rr.BitMap))
copy(cp, rr.BitMap)
return &WKS{*rr.Hdr.copyHeader(), copyIP(rr.Address), rr.Protocol, cp}
}
2012-06-02 02:29:07 +10:00
func (rr *WKS) String() (s string) {
s = rr.Hdr.String()
if rr.Address != nil {
s += rr.Address.String()
}
2012-06-03 01:33:49 +10:00
for i := 0; i < len(rr.BitMap); i++ {
// should lookup the port
s += " " + strconv.Itoa(int(rr.BitMap[i]))
2012-06-02 06:23:21 +10:00
}
return s
2012-06-02 02:29:07 +10:00
}
type NID struct {
2012-11-18 07:26:48 +11:00
Hdr RR_Header
Preference uint16
NodeID uint64
}
func (rr *NID) Header() *RR_Header { return &rr.Hdr }
func (rr *NID) copy() RR { return &NID{*rr.Hdr.copyHeader(), rr.Preference, rr.NodeID} }
func (rr *NID) len() int { return rr.Hdr.len() + 2 + 8 }
2012-11-18 07:26:48 +11:00
func (rr *NID) String() string {
2012-11-18 07:26:48 +11:00
s := rr.Hdr.String() + strconv.Itoa(int(rr.Preference))
2012-11-18 09:01:35 +11:00
node := fmt.Sprintf("%0.16x", rr.NodeID)
s += " " + node[0:4] + ":" + node[4:8] + ":" + node[8:12] + ":" + node[12:16]
2012-11-18 07:26:48 +11:00
return s
}
type L32 struct {
2012-11-18 07:32:02 +11:00
Hdr RR_Header
Preference uint16
Locator32 net.IP `dns:"a"`
}
func (rr *L32) Header() *RR_Header { return &rr.Hdr }
func (rr *L32) copy() RR { return &L32{*rr.Hdr.copyHeader(), rr.Preference, copyIP(rr.Locator32)} }
func (rr *L32) len() int { return rr.Hdr.len() + net.IPv4len }
2012-11-18 07:32:02 +11:00
func (rr *L32) String() string {
if rr.Locator32 == nil {
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference))
}
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) +
" " + rr.Locator32.String()
2012-11-18 07:32:02 +11:00
}
type L64 struct {
2012-11-18 07:37:15 +11:00
Hdr RR_Header
Preference uint16
Locator64 uint64
}
func (rr *L64) Header() *RR_Header { return &rr.Hdr }
func (rr *L64) copy() RR { return &L64{*rr.Hdr.copyHeader(), rr.Preference, rr.Locator64} }
func (rr *L64) len() int { return rr.Hdr.len() + 2 + 8 }
2012-11-18 07:37:15 +11:00
func (rr *L64) String() string {
2012-11-18 07:37:15 +11:00
s := rr.Hdr.String() + strconv.Itoa(int(rr.Preference))
2012-11-18 19:10:28 +11:00
node := fmt.Sprintf("%0.16X", rr.Locator64)
s += " " + node[0:4] + ":" + node[4:8] + ":" + node[8:12] + ":" + node[12:16]
2012-11-18 07:37:15 +11:00
return s
}
type LP struct {
2012-11-18 07:43:09 +11:00
Hdr RR_Header
Preference uint16
Fqdn string `dns:"domain-name"`
}
func (rr *LP) Header() *RR_Header { return &rr.Hdr }
func (rr *LP) copy() RR { return &LP{*rr.Hdr.copyHeader(), rr.Preference, rr.Fqdn} }
func (rr *LP) len() int { return rr.Hdr.len() + 2 + len(rr.Fqdn) + 1 }
func (rr *LP) String() string {
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Fqdn)
2012-11-18 07:43:09 +11:00
}
type EUI48 struct {
Hdr RR_Header
Address uint64 `dns:"uint48"`
}
func (rr *EUI48) Header() *RR_Header { return &rr.Hdr }
func (rr *EUI48) copy() RR { return &EUI48{*rr.Hdr.copyHeader(), rr.Address} }
2013-05-01 00:56:30 +10:00
func (rr *EUI48) String() string { return rr.Hdr.String() + euiToString(rr.Address, 48) }
func (rr *EUI48) len() int { return rr.Hdr.len() + 6 }
type EUI64 struct {
Hdr RR_Header
Address uint64
}
func (rr *EUI64) Header() *RR_Header { return &rr.Hdr }
func (rr *EUI64) copy() RR { return &EUI64{*rr.Hdr.copyHeader(), rr.Address} }
2013-05-01 00:56:30 +10:00
func (rr *EUI64) String() string { return rr.Hdr.String() + euiToString(rr.Address, 64) }
func (rr *EUI64) len() int { return rr.Hdr.len() + 8 }
// Support in incomplete - just handle it as unknown record
/*
2013-04-30 23:04:07 +10:00
type CAA struct {
Hdr RR_Header
Flag uint8
Tag string
2013-09-27 18:51:20 +10:00
Value string `dns:"octet"`
2013-04-30 23:04:07 +10:00
}
func (rr *CAA) Header() *RR_Header { return &rr.Hdr }
func (rr *CAA) copy() RR { return &CAA{*rr.Hdr.copyHeader(), rr.Flag, rr.Tag, rr.Value} }
func (rr *CAA) len() int { return rr.Hdr.len() + 1 + len(rr.Tag) + 1 + len(rr.Value) }
2013-04-30 23:04:07 +10:00
func (rr *CAA) String() string {
s := rr.Hdr.String() + strconv.FormatInt(int64(rr.Flag), 10) + " " + rr.Tag
2013-09-27 18:51:20 +10:00
s += strconv.QuoteToASCII(rr.Value)
2013-04-30 23:04:07 +10:00
return s
}
*/
2013-04-30 23:04:07 +10:00
2013-05-01 00:42:04 +10:00
type UID struct {
Hdr RR_Header
Uid uint32
}
func (rr *UID) Header() *RR_Header { return &rr.Hdr }
func (rr *UID) copy() RR { return &UID{*rr.Hdr.copyHeader(), rr.Uid} }
func (rr *UID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Uid), 10) }
func (rr *UID) len() int { return rr.Hdr.len() + 4 }
type GID struct {
Hdr RR_Header
Gid uint32
}
func (rr *GID) Header() *RR_Header { return &rr.Hdr }
func (rr *GID) copy() RR { return &GID{*rr.Hdr.copyHeader(), rr.Gid} }
func (rr *GID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Gid), 10) }
func (rr *GID) len() int { return rr.Hdr.len() + 4 }
type UINFO struct {
Hdr RR_Header
Uinfo string
}
func (rr *UINFO) Header() *RR_Header { return &rr.Hdr }
func (rr *UINFO) copy() RR { return &UINFO{*rr.Hdr.copyHeader(), rr.Uinfo} }
func (rr *UINFO) String() string { return rr.Hdr.String() + sprintTxt([]string{rr.Uinfo}) }
2013-05-01 00:56:30 +10:00
func (rr *UINFO) len() int { return rr.Hdr.len() + len(rr.Uinfo) + 1 }
2013-05-01 00:42:04 +10:00
2013-10-20 07:31:12 +11:00
type EID struct {
Hdr RR_Header
Endpoint string `dns:"hex"`
}
func (rr *EID) Header() *RR_Header { return &rr.Hdr }
func (rr *EID) copy() RR { return &EID{*rr.Hdr.copyHeader(), rr.Endpoint} }
func (rr *EID) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Endpoint) }
func (rr *EID) len() int { return rr.Hdr.len() + len(rr.Endpoint)/2 }
type NIMLOC struct {
Hdr RR_Header
Locator string `dns:"hex"`
}
func (rr *NIMLOC) Header() *RR_Header { return &rr.Hdr }
func (rr *NIMLOC) copy() RR { return &NIMLOC{*rr.Hdr.copyHeader(), rr.Locator} }
func (rr *NIMLOC) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Locator) }
func (rr *NIMLOC) len() int { return rr.Hdr.len() + len(rr.Locator)/2 }
2014-07-24 18:29:42 +10:00
type OPENPGPKEY struct {
Hdr RR_Header
PublicKey string `dns:"base64"`
}
func (rr *OPENPGPKEY) Header() *RR_Header { return &rr.Hdr }
func (rr *OPENPGPKEY) copy() RR { return &OPENPGPKEY{*rr.Hdr.copyHeader(), rr.PublicKey} }
func (rr *OPENPGPKEY) String() string { return rr.Hdr.String() + rr.PublicKey }
func (rr *OPENPGPKEY) len() int {
return rr.Hdr.len() + base64.StdEncoding.DecodedLen(len(rr.PublicKey))
}
2012-09-12 05:45:21 +10:00
// TimeToString translates the RRSIG's incep. and expir. times to the
2012-04-11 23:13:17 +10:00
// string representation used when printing the record.
2012-05-15 20:27:40 +10:00
// It takes serial arithmetic (RFC 1982) into account.
2012-09-12 05:45:21 +10:00
func TimeToString(t uint32) string {
2012-08-17 16:29:45 +10:00
mod := ((int64(t) - time.Now().Unix()) / year68) - 1
2012-05-15 20:24:57 +10:00
if mod < 0 {
mod = 0
}
2012-08-17 16:29:45 +10:00
ti := time.Unix(int64(t)-(mod*year68), 0).UTC()
2011-07-25 05:29:16 +10:00
return ti.Format("20060102150405")
}
// StringToTime translates the RRSIG's incep. and expir. times from
2012-04-11 23:13:17 +10:00
// string values like "20110403154150" to an 32 bit integer.
2012-05-15 20:24:57 +10:00
// It takes serial arithmetic (RFC 1982) into account.
2012-09-12 05:45:21 +10:00
func StringToTime(s string) (uint32, error) {
2011-12-17 00:48:30 +11:00
t, e := time.Parse("20060102150405", s)
if e != nil {
return 0, e
}
2012-08-17 16:29:45 +10:00
mod := (t.Unix() / year68) - 1
2012-05-15 20:24:57 +10:00
if mod < 0 {
mod = 0
}
2012-08-17 16:29:45 +10:00
return uint32(t.Unix() - (mod * year68)), nil
}
// saltToString converts a NSECX salt to uppercase and
// returns "-" when it is empty
func saltToString(s string) string {
if len(s) == 0 {
return "-"
}
return strings.ToUpper(s)
}
2012-05-01 00:54:02 +10:00
func cmToString(mantissa, exponent uint8) string {
switch exponent {
case 0, 1:
if exponent == 1 {
mantissa *= 10
}
2012-04-30 23:36:04 +10:00
return fmt.Sprintf("%.02f", float32(mantissa))
default:
s := fmt.Sprintf("%d", mantissa)
for i := uint8(0); i < exponent-2; i++ {
s += "0"
}
return s
}
panic("dns: not reached")
}
func euiToString(eui uint64, bits int) (hex string) {
switch bits {
case 64:
2013-04-16 03:42:07 +10:00
hex = fmt.Sprintf("%16.16x", eui)
hex = hex[0:2] + "-" + hex[2:4] + "-" + hex[4:6] + "-" + hex[6:8] +
"-" + hex[8:10] + "-" + hex[10:12] + "-" + hex[12:14] + "-" + hex[14:16]
case 48:
2013-04-16 03:42:07 +10:00
hex = fmt.Sprintf("%12.12x", eui)
hex = hex[0:2] + "-" + hex[2:4] + "-" + hex[4:6] + "-" + hex[6:8] +
"-" + hex[8:10] + "-" + hex[10:12]
}
return
}
2014-01-12 21:11:23 +11:00
// copyIP returns a copy of ip.
func copyIP(ip net.IP) net.IP {
p := make(net.IP, len(ip))
copy(p, ip)
return p
}
2010-08-04 07:57:59 +10:00
// Map of constructors for each RR wire type.
2012-06-30 22:49:37 +10:00
var rr_mk = map[uint16]func() RR{
TypeA: func() RR { return new(A) },
TypeAAAA: func() RR { return new(AAAA) },
TypeAFSDB: func() RR { return new(AFSDB) },
// TypeCAA: func() RR { return new(CAA) },
2013-10-13 23:01:33 +11:00
TypeCDS: func() RR { return new(CDS) },
TypeCERT: func() RR { return new(CERT) },
TypeCNAME: func() RR { return new(CNAME) },
2013-10-13 23:01:33 +11:00
TypeDHCID: func() RR { return new(DHCID) },
TypeDLV: func() RR { return new(DLV) },
TypeDNAME: func() RR { return new(DNAME) },
TypeDNSKEY: func() RR { return new(DNSKEY) },
TypeDS: func() RR { return new(DS) },
TypeEUI48: func() RR { return new(EUI48) },
TypeEUI64: func() RR { return new(EUI64) },
TypeGID: func() RR { return new(GID) },
TypeGPOS: func() RR { return new(GPOS) },
2013-10-20 07:31:12 +11:00
TypeEID: func() RR { return new(EID) },
TypeHINFO: func() RR { return new(HINFO) },
2013-10-13 23:01:33 +11:00
TypeHIP: func() RR { return new(HIP) },
TypeKX: func() RR { return new(KX) },
TypeL32: func() RR { return new(L32) },
TypeL64: func() RR { return new(L64) },
TypeLOC: func() RR { return new(LOC) },
TypeLP: func() RR { return new(LP) },
TypeMB: func() RR { return new(MB) },
TypeMD: func() RR { return new(MD) },
TypeMF: func() RR { return new(MF) },
2013-10-13 23:01:33 +11:00
TypeMG: func() RR { return new(MG) },
TypeMINFO: func() RR { return new(MINFO) },
TypeMR: func() RR { return new(MR) },
TypeMX: func() RR { return new(MX) },
2013-10-13 23:01:33 +11:00
TypeNAPTR: func() RR { return new(NAPTR) },
TypeNID: func() RR { return new(NID) },
TypeNINFO: func() RR { return new(NINFO) },
2013-10-20 07:31:12 +11:00
TypeNIMLOC: func() RR { return new(NIMLOC) },
TypeNS: func() RR { return new(NS) },
2013-10-13 23:01:33 +11:00
TypeNSAP: func() RR { return new(NSAP) },
TypeNSAPPTR: func() RR { return new(NSAPPTR) },
TypeNSEC3: func() RR { return new(NSEC3) },
TypeNSEC3PARAM: func() RR { return new(NSEC3PARAM) },
TypeNSEC: func() RR { return new(NSEC) },
2014-08-14 18:18:08 +10:00
TypeOPENPGPKEY: func() RR { return new(OPENPGPKEY) },
TypeOPT: func() RR { return new(OPT) },
TypePTR: func() RR { return new(PTR) },
TypeRKEY: func() RR { return new(RKEY) },
TypeRP: func() RR { return new(RP) },
TypePX: func() RR { return new(PX) },
TypeRRSIG: func() RR { return new(RRSIG) },
TypeRT: func() RR { return new(RT) },
TypeSOA: func() RR { return new(SOA) },
TypeSPF: func() RR { return new(SPF) },
TypeSRV: func() RR { return new(SRV) },
TypeSSHFP: func() RR { return new(SSHFP) },
TypeTA: func() RR { return new(TA) },
TypeTALINK: func() RR { return new(TALINK) },
TypeTKEY: func() RR { return new(TKEY) },
TypeTLSA: func() RR { return new(TLSA) },
TypeTSIG: func() RR { return new(TSIG) },
TypeTXT: func() RR { return new(TXT) },
TypeUID: func() RR { return new(UID) },
TypeUINFO: func() RR { return new(UINFO) },
TypeURI: func() RR { return new(URI) },
TypeWKS: func() RR { return new(WKS) },
TypeX25: func() RR { return new(X25) },
2010-08-04 07:57:59 +10:00
}