1package magna
2
3import (
4 "fmt"
5 "net"
6)
7
8type (
9 // An OPCode specifies the kind of query.
10 OPCode int
11
12 // A RCode specifies the response code.
13 RCode int
14
15 // A DNSType specifies the type of the query.
16 DNSType uint16
17
18 // A DNSClass specifies the class of the query.
19 DNSClass uint16
20)
21
22const (
23 QUERY OPCode = iota
24 IQUERY
25 STATUS
26)
27
28func (op OPCode) String() string {
29 switch op {
30 case QUERY:
31 return "QUERY"
32 case IQUERY:
33 return "IQUERY"
34 case STATUS:
35 return "STATUS"
36 default:
37 return fmt.Sprintf("RESERVED(%d)", int(op))
38 }
39}
40
41const (
42 NOERROR RCode = iota
43 FORMERR
44 SERVFAIL
45 NXDOMAIN
46 NOTIMP
47 REFUSED
48)
49
50func (r RCode) String() string {
51 switch r {
52 case NOERROR:
53 return "NOERROR"
54 case FORMERR:
55 return "FORMERR"
56 case SERVFAIL:
57 return "SERVFAIL"
58 case NXDOMAIN:
59 return "NXDOMAIN"
60 case NOTIMP:
61 return "NOTIMP"
62 case REFUSED:
63 return "REFUSED"
64 default:
65 return fmt.Sprintf("RESERVED(%d)", int(r))
66 }
67}
68
69const (
70 AType DNSType = iota + 1
71 NSType
72 MDType
73 MFType
74 CNAMEType
75 SOAType
76 MBType
77 MGType
78 MRType
79 NULLType
80 WKSType
81 PTRType
82 HINFOType
83 MINFOType
84 MXType
85 TXTType
86
87 AXFRType = 252
88 MAILBType = 253
89 MAILAType = 254
90 AllType = 255
91)
92
93func (t DNSType) String() string {
94 switch t {
95 case AType:
96 return "A"
97 case NSType:
98 return "NS"
99 case MDType:
100 return "MD"
101 case MFType:
102 return "MF"
103 case CNAMEType:
104 return "CNAME"
105 case SOAType:
106 return "SOA"
107 case MBType:
108 return "MB"
109 case MGType:
110 return "MG"
111 case MRType:
112 return "MR"
113 case NULLType:
114 return "NULL"
115 case WKSType:
116 return "WKS"
117 case PTRType:
118 return "PTR"
119 case HINFOType:
120 return "HINFO"
121 case MINFOType:
122 return "MINFO"
123 case MXType:
124 return "MX"
125 case TXTType:
126 return "TXT"
127 case AXFRType:
128 return "AXFR"
129 case MAILBType:
130 return "MAILB"
131 case MAILAType:
132 return "MAILA"
133 case AllType:
134 return "All"
135 default:
136 return fmt.Sprintf("RESERVED(%d)", int(t))
137 }
138}
139
140const (
141 IN DNSClass = iota + 1
142 CS
143 CH
144 HS
145
146 ANY = 255
147)
148
149func (c DNSClass) String() string {
150 switch c {
151 case IN:
152 return "IN"
153 case CS:
154 return "CS"
155 case CH:
156 return "CH"
157 case HS:
158 return "HS"
159 case ANY:
160 return "*"
161 default:
162 return fmt.Sprintf("RESERVED(%d)", int(c))
163 }
164}
165
166// A Message represents the single format supported by the DNS protocol.
167type Message struct {
168 Header Header // Header contains metadata about the message.
169 Question []Question // Question contains a slice of questions.
170 Answer []ResourceRecord // Answer contains a slice of resource records.
171 Authority []ResourceRecord // Authority contains a slice of resource records.
172 Additional []ResourceRecord // Additional contains a slice of resource records.
173
174 // offsets is a map of domains pointing to the seen offset used
175 // in domain compression.
176 offsets map[string]uint16
177}
178
179// A Header represents the metadata information of a DNS packet.
180type Header struct {
181 ID uint16 // ID is a 16 bit identifier.
182 QR bool // QR (query response) specifies if the packet is a query (false) or response (true).
183 OPCode OPCode // OPCode is a 4bit value that specifies the kind of the query.
184 AA bool // AA (Authoritative Answer) specifies if the responding name server is the authoritative server.
185 TC bool // TC (Truncation) specifies if the packet was truncated due to length.
186 RD bool // RD (Recursion Desired) specifies that the client wants to recurse.
187 RA bool // RA (Recursion Available) specifies that the server is available to recurse.
188 Z uint8 // Z Reserved for future use
189 RCode RCode // RCode is a 4 bit field representing the response error.
190 QDCount uint16 // QDCount specifies number of entries in the Question slice.
191 ANCount uint16 // ANCount specifies number of entries in the Answer slice.
192 NSCount uint16 // NSCount specifies number of entries in the Authority slice.
193 ARCount uint16 // ARCount specifies number of entries in the Additional slice.
194}
195
196// A Question represent a question in the DNS packet.
197type Question struct {
198 QName string // QName domain name being questioned.
199 QType DNSType // QType specifies the type of the question.
200 QClass DNSClass // QClass specifies the class of the question.
201}
202
203// A ResourceRecordData represents the RDATA field of the resource record.
204// Decode:
205//
206// []byte - DNS packet
207// int - offset in []byte to start parsing resource record data
208// int - length of the resource record field
209//
210// Encode:
211//
212// []byte - DNS Packet
213// *map[string]uint8 - map containing labels and offsets for domain name compression
214type ResourceRecordData interface {
215 Decode([]byte, int, int) (int, error)
216 Encode([]byte, *map[string]uint16) ([]byte, error)
217 String() string
218}
219
220// ResourceRecord represents DNS records.
221type ResourceRecord struct {
222 Name string // a domain label
223 RType DNSType // the type of the record
224 RClass DNSClass // the class of the record
225 TTL uint32 // the time to live of the record in seconds
226 RDLength uint16 // the length of the record in number of bytes
227 RData ResourceRecordData // the data of the record
228}
229
230// A represents a 32 bit Internet Address.
231type A struct {
232 Address net.IP
233}
234
235// NS represents
236type NS struct {
237 NSDName string
238}
239
240// MD represents the mail agent for a domain.
241// XXX: Obsolete
242type MD struct {
243 MADName string
244}
245
246// MF represents a host which has a mail agent for a domain.
247// XXX: Obsolete
248type MF struct {
249 MADName string
250}
251
252// CNAME represents the canonical name for the owner.
253type CNAME struct {
254 CName string
255}
256
257// SOA represents
258type SOA struct {
259 MName string // MName represents the name server that was the original source of data for a zone.
260 RName string // RName represents a mailbox of the person responsible for this zone.
261 Serial uint32 // Serial is a 32 bit version number of the original copy of the zone.
262 Refresh uint32 // Refresh is a 32 bit time interval before the zone should be refreshed.
263 Retry uint32 // Retry is a 32 bit time interval that should elapse before a failed refresh is retried.
264 Expire uint32 // Expire is the upper limit on the time interval that can elapse before the zone is no longer authoritative.
265 Minimum uint32 // Minimum is the minimum TTL field that should be exported with any RR from this zone.
266}
267
268// MB represents the host with a specified mailbox.
269type MB struct {
270 MADName string
271}
272
273// MG represents a mailbox which is configured for MGMName.
274type MG struct {
275 MGMName string
276}
277
278// MR specifies the proper rename of a mailbox.
279type MR struct {
280 NEWName string
281}
282
283// NULL can be anything as long as its under 65535 octets.
284type NULL struct {
285 Anything []byte
286}
287
288// WKS specifies well known services supported by a protocol.
289type WKS struct {
290 Address net.IP // Address is a 32 bit Internet address.
291 Protocol uint8 // Protocol is a 8 bit IP protocol number.
292 BitMap []byte // BitMap is a variable length bit map must be multiple of 8 bits.
293}
294
295// PTR specifies to a location in the domain name space.
296type PTR struct {
297 PTRDName string
298}
299
300// HINFO represents the general information about a server.
301type HINFO struct {
302 CPU string // CPU specifies the CPU type.
303 OS string // OS specifies the operating system.
304}
305
306// MINFO represents mailing list information.
307type MINFO struct {
308 RMailBx string // RMailBx specifies the mailbox for a mailing list.
309 EMailBx string // EMailBx specifes a mailbox for receiving errors.
310}
311
312// MX represents a host acting as a mail exchange.
313type MX struct {
314 Preference uint16 // Preference specifies the preference with lower values being prefered.
315 Exchange string // Exchange specifies host acting for the name.
316}
317
318// TXT represents one or more character strings.
319type TXT struct {
320 TxtData []string
321}
322
323// Reserved represents a record that is not yet implemented.
324type Reserved struct {
325 Bytes []byte
326}