a go dns packet parser
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 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}