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]uint8
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]uint8) []byte
217}
218
219// ResourceRecord represents DNS records.
220type ResourceRecord struct {
221 Name string // a domain label
222 RType DNSType // the type of the record
223 RClass DNSClass // the class of the record
224 TTL uint32 // the time to live of the record in seconds
225 RDLength uint16 // the length of the record in number of bytes
226 RData ResourceRecordData // the data of the record
227}
228
229// A represents a 32 bit Internet Address.
230type A struct {
231 Address net.IP
232}
233
234// NS represents
235type NS struct {
236 NSDName string
237}
238
239// MD represents the mail agent for a domain.
240// XXX: Obsolete
241type MD struct {
242 MADName string
243}
244
245// MF represents a host which has a mail agent for a domain.
246// XXX: Obsolete
247type MF struct {
248 MADName string
249}
250
251// CNAME represents the canonical name for the owner.
252type CNAME struct {
253 CName string
254}
255
256// SOA represents
257type SOA struct {
258 MName string // MName represents the name server that was the original source of data for a zone.
259 RName string // RName represents a mailbox of the person responsible for this zone.
260 Serial uint32 // Serial is a 32 bit version number of the original copy of the zone.
261 Refresh uint32 // Refresh is a 32 bit time interval before the zone should be refreshed.
262 Retry uint32 // Retry is a 32 bit time interval that should elapse before a failed refresh is retried.
263 Expire uint32 // Expire is the upper limit on the time interval that can elapse before the zone is no longer authoritative.
264 Minimum uint32 // Minimum is the minimum TTL field that should be exported with any RR from this zone.
265}
266
267// MB represents the host with a specified mailbox.
268type MB struct {
269 MADName string
270}
271
272// MG represents a mailbox which is configured for MGMName.
273type MG struct {
274 MGMName string
275}
276
277// MR specifies the proper rename of a mailbox.
278type MR struct {
279 NEWName string
280}
281
282// NULL can be anything as long as its under 65535 octets.
283type NULL struct {
284 Anything []byte
285}
286
287// WKS specifies well known services supported by a protocol.
288type WKS struct {
289 Address net.IP // Address is a 32 bit Internet address.
290 Protocol uint8 // Protocol is a 8 bit IP protocol number.
291 BitMap []byte // BitMap is a variable length bit map must be multiple of 8 bits.
292}
293
294// PTR specifies to a location in the domain name space.
295type PTR struct {
296 PTRDName string
297}
298
299// HINFO represents the general information about a server.
300type HINFO struct {
301 CPU string // CPU specifies the CPU type.
302 OS string // OS specifies the operating system.
303}
304
305// MINFO represents mailing list information.
306type MINFO struct {
307 RMailBx string // RMailBx specifies the mailbox for a mailing list.
308 EMailBx string // EMailBx specifes a mailbox for receiving errors.
309}
310
311// MX represents a host acting as a mail exchange.
312type MX struct {
313 Preference uint16 // Preference specifies the preference with lower values being prefered.
314 Exchange string // Exchange specifies host acting for the name.
315}
316
317// TXT represents one or more character strings.
318type TXT struct {
319 TxtData string
320}
321
322// Reserved represents a record that is not yet implemented.
323type Reserved struct {
324 Bytes []byte
325}