1 #ifndef DNS_QUERY_H 2 #define DNS_QUERY_H 3 4 5 #include <DataIO.h> 6 #include <NetBuffer.h> 7 #include <ObjectList.h> 8 #include <String.h> 9 10 11 #include <arpa/inet.h> 12 13 #define MX_RECORD 15 14 15 struct mx_record { 16 uint16 priority; 17 BString serverName; 18 }; 19 20 21 class BRawNetBuffer { 22 public: 23 BRawNetBuffer(); 24 BRawNetBuffer(off_t size); 25 BRawNetBuffer(const void* buf, size_t size); 26 27 // functions like in BNetBuffer but no type and size info is writen. 28 // functions return B_NO_MEMORY or B_OK 29 status_t AppendUint16(uint16 value); 30 status_t AppendString(const char* string); 31 32 status_t ReadUint16(uint16& value); 33 status_t ReadUint32(uint32& value); 34 status_t ReadString(BString& string); 35 36 status_t SkipReading(off_t off); 37 38 void *Data(void) const { return (void*)fBuffer.Buffer(); } 39 size_t Size(void) const { return fBuffer.BufferLength(); } 40 size_t SetSize(off_t size) { return fBuffer.SetSize(size); } 41 void SetWritePosition(off_t pos) { fWritePosition = pos; } 42 43 private: 44 void _Init(const void* buf, size_t size); 45 ssize_t _ReadStringAt(BString& string, off_t pos); 46 47 off_t fWritePosition; 48 off_t fReadPosition; 49 BMallocIO fBuffer; 50 }; 51 52 53 class DNSTools { 54 public: 55 static status_t GetDNSServers(BObjectList<BString>* serverList); 56 static BString ConvertToDNSName(const BString& string); 57 static BString ConvertFromDNSName(const BString& string); 58 }; 59 60 // see also http://prasshhant.blogspot.com/2007/03/dns-query.html 61 struct dns_header { 62 dns_header() 63 { 64 q_count = 0; 65 ans_count = 0; 66 auth_count = 0; 67 add_count = 0; 68 } 69 70 uint16 id; // A 16 bit identifier 71 72 unsigned char qr :1; // query (0), or a response (1) 73 unsigned char opcode :4; // A four bit field 74 unsigned char aa :1; // Authoritative Answer 75 unsigned char tc :1; // Truncated Message 76 unsigned char rd :1; // Recursion Desired 77 unsigned char ra :1; // Recursion Available 78 unsigned char z :3; // Reserved for future use 79 unsigned char rcode :4; // Response code 80 81 uint16 q_count; // number of question entries 82 uint16 ans_count; // number of answer entries 83 uint16 auth_count; // number of authority entries 84 uint16 add_count; // number of resource entries 85 }; 86 87 // resource record without resource data 88 struct resource_record_head { 89 BString name; 90 uint16 type; 91 uint16 dataClass; 92 uint32 ttl; 93 uint16 dataLength; 94 }; 95 96 97 class DNSQuery { 98 public: 99 DNSQuery(); 100 ~DNSQuery(); 101 status_t ReadDNSServer(in_addr* add); 102 status_t GetMXRecords(const BString& serverName, 103 BObjectList<mx_record>* mxList, 104 bigtime_t timeout = 500000); 105 106 private: 107 uint16 _GetUniqueID(); 108 void _SetMXHeader(dns_header* header); 109 void _AppendQueryHeader(BRawNetBuffer& buffer, 110 const dns_header* header); 111 void _ReadQueryHeader(BRawNetBuffer& buffer, 112 dns_header* header); 113 void _ReadMXRecord(BRawNetBuffer& buffer, 114 mx_record* mxRecord); 115 116 void _ReadResourceRecord(BRawNetBuffer& buffer, 117 resource_record_head* rrHead); 118 }; 119 120 121 #endif // DNS_QUERY_H 122