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