PTLib  Version 2.10.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
pdns.h
Go to the documentation of this file.
1 /*
2  * pdns.h
3  *
4  * PWLib library for DNS lookup services
5  *
6  * Portable Windows Library
7  *
8  * Copyright (c) 2003 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Contributor(s): ______________________________________.
25  *
26  * $Revision: 25959 $
27  * $Author: rjongbloed $
28  * $Date: 2011-06-02 00:33:14 -0500 (Thu, 02 Jun 2011) $
29  */
30 
31 #ifndef PTLIB_PDNS_H
32 #define PTLIB_PDNS_H
33 
34 #if P_DNS
35 
36 #ifdef P_USE_PRAGMA
37 #pragma interface
38 #endif
39 
40 #include <ptlib/sockets.h>
41 
42 #include <ptclib/random.h>
43 #include <ptclib/url.h>
44 
45 #if defined(_WIN32)
46 
47  #include <windns.h>
48 
49  #ifndef __MINGW32__
50 
51  #include <ntverp.h>
52 
53  #pragma comment(lib, "dnsapi.lib")
54 
55  // Accommodate spelling error in windns.h
56  enum { DnsSectionAdditional = DnsSectionAddtional };
57 
58  #endif
59 
60 #else /* _WIN32 */
61 
62  #define P_HAS_RESOLVER 1 // set if using Unix-style DNS routines
63  #include <arpa/nameser.h>
64  #include <resolv.h>
65  #if defined(P_MACOSX) && (P_MACOSX >= 700)
66  #include <arpa/nameser_compat.h>
67  #endif
68 
69 #endif // _WIN32
70 
71 
72 #if defined(_WIN32) && VER_PRODUCTBUILD < 6000
73 typedef struct
74 {
75  WORD wOrder;
76  WORD wPreference;
77  PSTR pFlags;
78  PSTR pService;
79  PSTR pRegularExpression;
80  PSTR pReplacement;
81 }
82 DNS_NAPTR_DATA;
83 #endif
84 
85 
86 #ifdef P_HAS_RESOLVER
87 
89 //
90 // these classes provide an emulation of the Microsoft DNS API
91 // on non-Window systems
92 //
93 
94 #define DnsRecordListFree PDnsRecordListFree
95 
96 #ifndef T_SRV
97 #define T_SRV 33
98 #endif
99 
100 #ifndef T_NAPTR
101 #define T_NAPTR 35
102 #endif
103 
104 
105 #define DNS_STATUS int
106 #define DNS_TYPE_SRV T_SRV
107 #define DNS_TYPE_MX T_MX
108 #define DNS_TYPE_A T_A
109 #define DNS_TYPE_NAPTR T_NAPTR
110 #define DnsFreeRecordList 0
111 #define DNS_QUERY_STANDARD 0
112 #define DNS_QUERY_BYPASS_CACHE 0
113 
114 typedef struct _DnsAData {
115  DWORD IpAddress;
116 } DNS_A_DATA;
117 
118 typedef struct {
119  char pNameExchange[MAXDNAME];
121 } DNS_MX_DATA;
122 
123 typedef struct {
124  char pNameHost[MAXDNAME];
125 } DNS_PTR_DATA;
126 
127 typedef struct _DnsSRVData {
128  char pNameTarget[MAXDNAME];
129  WORD wPriority;
130  WORD wWeight;
131  WORD wPort;
132 } DNS_SRV_DATA;
133 
134 typedef struct _DnsNULLData {
135  DWORD dwByteCount;
136  char data[1];
137 } DNS_NULL_DATA;
138 
139 typedef struct _DnsRecordFlags
140 {
141  unsigned Section : 2;
142  unsigned Delete : 1;
143  unsigned CharSet : 2;
144  unsigned Unused : 3;
145  unsigned Reserved : 24;
147 
148 typedef enum _DnsSection
149 {
154 } DNS_SECTION;
155 
156 
157 class DnsRecord {
158  public:
160  char pName[MAXDNAME];
161  WORD wType;
163 
164  union {
165  DWORD DW;
167  } Flags;
168 
169  union {
175  } Data;
176 };
177 
180 
181 
182 typedef DWORD IP4_ADDRESS, *PIP4_ADDRESS;
183 
184 typedef struct _IP4_ARRAY
185 {
186  DWORD AddrCount;
187  IP4_ADDRESS AddrArray[1];
188 }
189 IP4_ARRAY, *PIP4_ARRAY;
190 
191 
192 extern void PDnsRecordListFree(PDNS_RECORD rec, int FreeType);
193 
194 extern DNS_STATUS DnsQuery_A(const char * service,
195  WORD requestType,
196  DWORD options,
197  PIP4_ARRAY,
198  PDNS_RECORD * results,
199  void *);
200 
201 
202 #endif // P_HAS_RESOLVER
203 
204 namespace PDNS {
205 
207 
209  const char * name,
210  WORD type,
211  DWORD options,
212  void * extra,
213  PDNS_RECORD * queryResults,
214  void * reserved
215 );
216 
217 
219 
221 //
222 // this template automates the creation of a list of records for
223 // a specific type of DNS lookup
224 //
225 
226 template <unsigned type, class RecordListType, class RecordType>
227 PBoolean Lookup(const PString & name, RecordListType & recordList)
228 {
229  if (name.IsEmpty())
230  return false;
231 
232  recordList.RemoveAll();
233 
234  PDNS_RECORD results = NULL;
235  DNS_STATUS status = Cached_DnsQuery((const char *)name,
236  type,
238  (PIP4_ARRAY)NULL,
239  &results,
240  NULL);
241  if (status != 0)
242  return false;
243 
244  // find records matching the correct type
245  PDNS_RECORD dnsRecord = results;
246  while (dnsRecord != NULL) {
247  RecordType * record = recordList.HandleDNSRecord(dnsRecord, results);
248  if (record != NULL)
249  recordList.Append(record);
250  dnsRecord = dnsRecord->pNext;
251  }
252 
253  if (results != NULL)
255 
256  return recordList.GetSize() != 0;
257 }
258 
260 
261 class SRVRecord : public PObject
262 {
263  PCLASSINFO(SRVRecord, PObject);
264  public:
266  { used = false; }
267 
268  Comparison Compare(const PObject & obj) const;
269  void PrintOn(ostream & strm) const;
270 
274  WORD port;
275  WORD priority;
276  WORD weight;
277 };
278 
280  public:
281  void PrintOn(ostream & strm) const;
282 
283  SRVRecord * GetFirst();
284  SRVRecord * GetNext();
285 
286  PDNS::SRVRecord * HandleDNSRecord(PDNS_RECORD dnsRecord, PDNS_RECORD results);
287 
288  protected:
289  PINDEX priPos;
291 };
292 
297 inline PBoolean GetRecords(const PString & service, SRVRecordList & serviceList)
298 { return Lookup<DNS_TYPE_SRV, SRVRecordList, SRVRecord>(service, serviceList); }
299 
304  const PString & service,
305  SRVRecordList & serviceList
306 )
307 { return GetRecords(service, serviceList); }
308 
314  const PString & service,
315  const PString & type,
316  const PString & domain,
317  SRVRecordList & serviceList
318 );
319 
326  const PString & srvQuery,
327  WORD defaultPort,
329 );
330 
332  const PString & domain,
333  const PString & service,
334  WORD defaultPort,
336 );
337 
339  const PURL & url,
340  const PString & service,
341  PStringList & returnStr
342 );
343 
345 
346 class MXRecord : public PObject
347 {
349  public:
351  { used = false; }
352  Comparison Compare(const PObject & obj) const;
353  void PrintOn(ostream & strm) const;
354 
359 };
360 
361 PDECLARE_SORTED_LIST(MXRecordList, PDNS::MXRecord)
362  public:
363  void PrintOn(ostream & strm) const;
364 
365  MXRecord * GetFirst();
366  MXRecord * GetNext();
367 
368  PDNS::MXRecord * HandleDNSRecord(PDNS_RECORD dnsRecord, PDNS_RECORD results);
369 
370  protected:
371  PINDEX lastIndex;
372 };
373 
378  const PString & domain,
379  MXRecordList & serviceList
380 )
381 { return Lookup<DNS_TYPE_MX, MXRecordList, MXRecord>(domain, serviceList); }
382 
387  const PString & domain,
388  MXRecordList & serviceList
389 )
390 {
391  return GetRecords(domain, serviceList);
392 }
393 
394 
395 }; // namespace PDNS
396 
397 #endif // P_DNS
398 
399 #endif // PTLIB_PDNS_H
400 
401 
402 // End Of File ///////////////////////////////////////////////////////////////