4 * PWLib library for DNS lookup services
6 * Portable Windows Library
8 * Copyright (c) 2003 Equivalence Pty. Ltd.
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/
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
20 * The Original Code is Portable Windows Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Contributor(s): ______________________________________.
27 * Revision 1.8 2004/06/24 07:36:24 csoutheren
28 * Added definitions of T_SRV and T_NAPTR for hosts that do not have these
30 * Revision 1.7 2004/05/31 12:49:47 csoutheren
31 * Added handling of unknown DNS types
33 * Revision 1.6 2004/05/28 06:50:42 csoutheren
34 * Reorganised DNS functions to use templates, and exposed more internals to allow new DNS lookup types to be added
36 * Revision 1.5 2003/07/22 23:52:20 dereksmithies
37 * Fix from Fabrizio Ammollo to cope with when P_DNS is disabled. Thanks!
39 * Revision 1.4 2003/04/16 07:02:55 robertj
42 * Revision 1.3 2003/04/15 08:14:06 craigs
43 * Added single string form of GetSRVRecords
45 * Revision 1.2 2003/04/15 08:06:24 craigs
46 * Added Unix implementation
48 * Revision 1.1 2003/04/15 04:06:56 craigs
61 #include <ptlib/sockets.h>
63 #include <ptclib/random.h>
68 # pragma comment(lib, P_DNS_LIBRARY)
72 # define P_HAS_RESOLVER 1 // set if using Unix-style DNS routines
73 # include <arpa/nameser.h>
75 # if defined(P_MACOSX) && (P_MACOSX >= 700)
76 # include <arpa/nameser_compat.h>
83 //////////////////////////////////////////////////////////////////////////
85 // these classes provide an emulation of the Microsoft DNS API
86 // on non-Window systems
98 #define DNS_STATUS int
99 #define DNS_TYPE_SRV T_SRV
100 #define DNS_TYPE_MX T_MX
101 #define DNS_TYPE_A T_A
102 #define DNS_TYPE_NAPTR T_NAPTR
103 #define DnsFreeRecordList 0
104 #define DNS_QUERY_STANDARD 0
105 #define DNS_QUERY_BYPASS_CACHE 0
107 typedef struct _DnsAData
{
112 char pNameExchange
[MAXDNAME
];
117 char pNameHost
[MAXDNAME
];
120 typedef struct _DnsSRVData
{
121 char pNameTarget
[MAXDNAME
];
127 typedef struct _DnsNULLData
{
132 typedef struct _DnsRecordFlags
134 unsigned Section
: 2;
136 unsigned CharSet
: 2;
138 unsigned Reserved
: 24;
141 typedef enum _DnsSection
153 char pName
[MAXDNAME
];
158 DWORD DW
; // flags as DWORD
159 DNS_RECORD_FLAGS S
; // flags as structure
171 typedef DnsRecord
* PDNS_RECORD
;
173 extern void DnsRecordListFree(PDNS_RECORD rec
, int FreeType
);
175 extern DNS_STATUS
DnsQuery_A(const char * service
,
179 PDNS_RECORD
* results
,
183 #endif // P_HAS_RESOLVER
187 //////////////////////////////////////////////////////////////////////////
189 // this template automates the creation of a list of records for
190 // a specific type of DNS lookup
193 template <unsigned type
, class RecordListType
, class RecordType
>
194 BOOL
Lookup(const PString
& name
, RecordListType
& recordList
)
199 recordList
.RemoveAll();
201 PDNS_RECORD results
= NULL
;
202 DNS_STATUS status
= DnsQuery_A((const char *)name
,
211 // find records matching the correct type
212 PDNS_RECORD dnsRecord
= results
;
213 while (dnsRecord
!= NULL
) {
214 RecordType
* record
= recordList
.HandleDNSRecord(dnsRecord
, results
);
216 recordList
.Append(record
);
217 dnsRecord
= dnsRecord
->pNext
;
221 DnsRecordListFree(results
, DnsFreeRecordList
);
223 return recordList
.GetSize() != 0;
226 /////////////////////////////////////////////////////////////
228 class SRVRecord
: public PObject
230 PCLASSINFO(SRVRecord
, PObject
);
235 Comparison
Compare(const PObject
& obj
) const;
236 void PrintOn(ostream
& strm
) const;
239 PIPSocket::Address hostAddress
;
246 PDECLARE_SORTED_LIST(SRVRecordList
, PDNS::SRVRecord
)
248 void PrintOn(ostream
& strm
) const;
250 SRVRecord
* GetFirst();
251 SRVRecord
* GetNext();
253 PDNS::SRVRecord
* HandleDNSRecord(PDNS_RECORD dnsRecord
, PDNS_RECORD results
);
261 * return a list of DNS SRV record with the specified service type
264 inline BOOL
GetRecords(const PString
& service
, SRVRecordList
& serviceList
)
265 { return Lookup
<DNS_TYPE_SRV
, SRVRecordList
, SRVRecord
>(service
, serviceList
); }
268 * provided for backwards compatibility
270 inline BOOL
GetSRVRecords(
271 const PString
& service
,
272 SRVRecordList
& serviceList
274 { return GetRecords(service
, serviceList
); }
277 * return a list of DNS SRV record with the specified service, type and domain
281 const PString
& service
,
282 const PString
& type
,
283 const PString
& domain
,
284 SRVRecordList
& serviceList
287 ////////////////////////////////////////////////////////////////
289 class MXRecord
: public PObject
291 PCLASSINFO(MXRecord
, PObject
);
295 Comparison
Compare(const PObject
& obj
) const;
296 void PrintOn(ostream
& strm
) const;
299 PIPSocket::Address hostAddress
;
304 PDECLARE_SORTED_LIST(MXRecordList
, PDNS::MXRecord
)
306 void PrintOn(ostream
& strm
) const;
308 MXRecord
* GetFirst();
309 MXRecord
* GetNext();
311 PDNS::MXRecord
* HandleDNSRecord(PDNS_RECORD dnsRecord
, PDNS_RECORD results
);
318 * return a list of MX records for the specified domain
320 inline BOOL
GetRecords(
321 const PString
& domain
,
322 MXRecordList
& serviceList
324 { return Lookup
<DNS_TYPE_MX
, MXRecordList
, MXRecord
>(domain
, serviceList
); }
327 * provided for backwards compatibility
329 inline BOOL
GetMXRecords(
330 const PString
& domain
,
331 MXRecordList
& serviceList
334 return GetRecords(domain
, serviceList
);
337 ///////////////////////////////////////////////////////////////////////////
344 // End Of File ///////////////////////////////////////////////////////////////