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
15struct mx_record {
16	uint16	priority;
17	BString	serverName;
18};
19
20
21class BRawNetBuffer {
22public:
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
43private:
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
53class DNSTools {
54public:
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
61struct 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
88struct resource_record_head {
89	BString	name;
90	uint16	type;
91	uint16	dataClass;
92	uint32	ttl;
93	uint16	dataLength;
94};
95
96
97class DNSQuery {
98public:
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
106private:
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