xref: /haiku/src/preferences/mail/DNSQuery.h (revision 68ea01249e1e2088933cb12f9c28d4e5c5d1c9ef)
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