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