package magna import ( "fmt" "net" ) type ( // An OPCode specifies the kind of query. OPCode int // A RCode specifies the response code. RCode int // A DNSType specifies the type of the query. DNSType uint16 // A DNSClass specifies the class of the query. DNSClass uint16 ) const ( QUERY OPCode = iota IQUERY STATUS ) func (op OPCode) String() string { switch op { case QUERY: return "QUERY" case IQUERY: return "IQUERY" case STATUS: return "STATUS" default: return fmt.Sprintf("RESERVED(%d)", int(op)) } } const ( NOERROR RCode = iota FORMERR SERVFAIL NXDOMAIN NOTIMP REFUSED ) func (r RCode) String() string { switch r { case NOERROR: return "NOERROR" case FORMERR: return "FORMERR" case SERVFAIL: return "SERVFAIL" case NXDOMAIN: return "NXDOMAIN" case NOTIMP: return "NOTIMP" case REFUSED: return "REFUSED" default: return fmt.Sprintf("RESERVED(%d)", int(r)) } } const ( AType DNSType = iota + 1 NSType MDType MFType CNAMEType SOAType MBType MGType MRType NULLType WKSType PTRType HINFOType MINFOType MXType TXTType AXFRType = 252 MAILBType = 253 MAILAType = 254 AllType = 255 ) func (t DNSType) String() string { switch t { case AType: return "A" case NSType: return "NS" case MDType: return "MD" case MFType: return "MF" case CNAMEType: return "CNAME" case SOAType: return "SOA" case MBType: return "MB" case MGType: return "MG" case MRType: return "MR" case NULLType: return "NULL" case WKSType: return "WKS" case PTRType: return "PTR" case HINFOType: return "HINFO" case MINFOType: return "MINFO" case MXType: return "MX" case TXTType: return "TXT" case AXFRType: return "AXFR" case MAILBType: return "MAILB" case MAILAType: return "MAILA" case AllType: return "All" default: return fmt.Sprintf("RESERVED(%d)", int(t)) } } const ( IN DNSClass = iota + 1 CS CH HS ANY = 255 ) func (c DNSClass) String() string { switch c { case IN: return "IN" case CS: return "CS" case CH: return "CH" case HS: return "HS" case ANY: return "*" default: return fmt.Sprintf("RESERVED(%d)", int(c)) } } // A Message represents the single format supported by the DNS protocol. type Message struct { Header Header // Header contains metadata about the message. Question []Question // Question contains a slice of questions. Answer []ResourceRecord // Answer contains a slice of resource records. Authority []ResourceRecord // Authority contains a slice of resource records. Additional []ResourceRecord // Additional contains a slice of resource records. // offsets is a map of domains pointing to the seen offset used // in domain compression. offsets map[string]uint16 } // A Header represents the metadata information of a DNS packet. type Header struct { ID uint16 // ID is a 16 bit identifier. QR bool // QR (query response) specifies if the packet is a query (false) or response (true). OPCode OPCode // OPCode is a 4bit value that specifies the kind of the query. AA bool // AA (Authoritative Answer) specifies if the responding name server is the authoritative server. TC bool // TC (Truncation) specifies if the packet was truncated due to length. RD bool // RD (Recursion Desired) specifies that the client wants to recurse. RA bool // RA (Recursion Available) specifies that the server is available to recurse. Z uint8 // Z Reserved for future use RCode RCode // RCode is a 4 bit field representing the response error. QDCount uint16 // QDCount specifies number of entries in the Question slice. ANCount uint16 // ANCount specifies number of entries in the Answer slice. NSCount uint16 // NSCount specifies number of entries in the Authority slice. ARCount uint16 // ARCount specifies number of entries in the Additional slice. } // A Question represent a question in the DNS packet. type Question struct { QName string // QName domain name being questioned. QType DNSType // QType specifies the type of the question. QClass DNSClass // QClass specifies the class of the question. } // A ResourceRecordData represents the RDATA field of the resource record. // Decode: // // []byte - DNS packet // int - offset in []byte to start parsing resource record data // int - length of the resource record field // // Encode: // // []byte - DNS Packet // *map[string]uint8 - map containing labels and offsets for domain name compression type ResourceRecordData interface { Decode([]byte, int, int) (int, error) Encode([]byte, *map[string]uint16) []byte String() string } // ResourceRecord represents DNS records. type ResourceRecord struct { Name string // a domain label RType DNSType // the type of the record RClass DNSClass // the class of the record TTL uint32 // the time to live of the record in seconds RDLength uint16 // the length of the record in number of bytes RData ResourceRecordData // the data of the record } // A represents a 32 bit Internet Address. type A struct { Address net.IP } // NS represents type NS struct { NSDName string } // MD represents the mail agent for a domain. // XXX: Obsolete type MD struct { MADName string } // MF represents a host which has a mail agent for a domain. // XXX: Obsolete type MF struct { MADName string } // CNAME represents the canonical name for the owner. type CNAME struct { CName string } // SOA represents type SOA struct { MName string // MName represents the name server that was the original source of data for a zone. RName string // RName represents a mailbox of the person responsible for this zone. Serial uint32 // Serial is a 32 bit version number of the original copy of the zone. Refresh uint32 // Refresh is a 32 bit time interval before the zone should be refreshed. Retry uint32 // Retry is a 32 bit time interval that should elapse before a failed refresh is retried. Expire uint32 // Expire is the upper limit on the time interval that can elapse before the zone is no longer authoritative. Minimum uint32 // Minimum is the minimum TTL field that should be exported with any RR from this zone. } // MB represents the host with a specified mailbox. type MB struct { MADName string } // MG represents a mailbox which is configured for MGMName. type MG struct { MGMName string } // MR specifies the proper rename of a mailbox. type MR struct { NEWName string } // NULL can be anything as long as its under 65535 octets. type NULL struct { Anything []byte } // WKS specifies well known services supported by a protocol. type WKS struct { Address net.IP // Address is a 32 bit Internet address. Protocol uint8 // Protocol is a 8 bit IP protocol number. BitMap []byte // BitMap is a variable length bit map must be multiple of 8 bits. } // PTR specifies to a location in the domain name space. type PTR struct { PTRDName string } // HINFO represents the general information about a server. type HINFO struct { CPU string // CPU specifies the CPU type. OS string // OS specifies the operating system. } // MINFO represents mailing list information. type MINFO struct { RMailBx string // RMailBx specifies the mailbox for a mailing list. EMailBx string // EMailBx specifes a mailbox for receiving errors. } // MX represents a host acting as a mail exchange. type MX struct { Preference uint16 // Preference specifies the preference with lower values being prefered. Exchange string // Exchange specifies host acting for the name. } // TXT represents one or more character strings. type TXT struct { TxtData []string } // Reserved represents a record that is not yet implemented. type Reserved struct { Bytes []byte }