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.13 2007/08/13 00:56:30 rjongbloed
28 * Fixed compile on DevStudio 2003
30 * Revision 1.12 2007/08/10 10:07:29 dsandras
31 * Fixed DNS support thanks to Vincent Luba <luba novacom be>.
33 * Revision 1.11 2006/02/26 11:51:20 csoutheren
34 * Extended DNS test program to include URL based SRV lookups
35 * Re-arranged SRV lookup code to allow access to internal routine
38 * Revision 1.10 2006/02/26 09:26:17 shorne
39 * Added DNS SRV record lookups
41 * Revision 1.9 2005/11/30 12:47:37 csoutheren
42 * Removed tabs, reformatted some code, and changed tags for Doxygen
44 * Revision 1.8 2004/06/24 07:36:24 csoutheren
45 * Added definitions of T_SRV and T_NAPTR for hosts that do not have these
47 * Revision 1.7 2004/05/31 12:49:47 csoutheren
48 * Added handling of unknown DNS types
50 * Revision 1.6 2004/05/28 06:50:42 csoutheren
51 * Reorganised DNS functions to use templates, and exposed more internals to allow new DNS lookup types to be added
53 * Revision 1.5 2003/07/22 23:52:20 dereksmithies
54 * Fix from Fabrizio Ammollo to cope with when P_DNS is disabled. Thanks!
56 * Revision 1.4 2003/04/16 07:02:55 robertj
59 * Revision 1.3 2003/04/15 08:14:06 craigs
60 * Added single string form of GetSRVRecords
62 * Revision 1.2 2003/04/15 08:06:24 craigs
63 * Added Unix implementation
65 * Revision 1.1 2003/04/15 04:06:56 craigs
78 #include <ptlib/sockets.h>
80 #include <ptclib/random.h>
81 #include <ptclib/url.h>
86 # pragma comment(lib, P_DNS_LIBRARY)
88 // Accommodate spelling error in windns.h
89 enum { DnsSectionAdditional
= DnsSectionAddtional
};
93 # define P_HAS_RESOLVER 1 // set if using Unix-style DNS routines
94 # include <arpa/nameser.h>
96 # if defined(P_MACOSX) && (P_MACOSX >= 700)
97 # include <arpa/nameser_compat.h>
102 #ifdef P_HAS_RESOLVER
104 //////////////////////////////////////////////////////////////////////////
106 // these classes provide an emulation of the Microsoft DNS API
107 // on non-Window systems
119 #define DNS_STATUS int
120 #define DNS_TYPE_SRV T_SRV
121 #define DNS_TYPE_MX T_MX
122 #define DNS_TYPE_A T_A
123 #define DNS_TYPE_NAPTR T_NAPTR
124 #define DnsFreeRecordList 0
125 #define DNS_QUERY_STANDARD 0
126 #define DNS_QUERY_BYPASS_CACHE 0
128 typedef struct _DnsAData
{
133 char pNameExchange
[MAXDNAME
];
138 char pNameHost
[MAXDNAME
];
141 typedef struct _DnsSRVData
{
142 char pNameTarget
[MAXDNAME
];
148 typedef struct _DnsNULLData
{
153 typedef struct _DnsRecordFlags
155 unsigned Section
: 2;
157 unsigned CharSet
: 2;
159 unsigned Reserved
: 24;
162 typedef enum _DnsSection
167 DnsSectionAdditional
,
174 char pName
[MAXDNAME
];
179 DWORD DW
; ///< flags as DWORD
180 DNS_RECORD_FLAGS S
; ///< flags as structure
192 typedef DnsRecord
* PDNS_RECORD
;
194 extern void DnsRecordListFree(PDNS_RECORD rec
, int FreeType
);
196 extern DNS_STATUS
DnsQuery_A(const char * service
,
200 PDNS_RECORD
* results
,
204 #endif // P_HAS_RESOLVER
208 //////////////////////////////////////////////////////////////////////////
210 // this template automates the creation of a list of records for
211 // a specific type of DNS lookup
214 template <unsigned type
, class RecordListType
, class RecordType
>
215 BOOL
Lookup(const PString
& name
, RecordListType
& recordList
)
220 recordList
.RemoveAll();
222 PDNS_RECORD results
= NULL
;
223 DNS_STATUS status
= DnsQuery_A((const char *)name
,
232 // find records matching the correct type
233 PDNS_RECORD dnsRecord
= results
;
234 while (dnsRecord
!= NULL
) {
235 RecordType
* record
= recordList
.HandleDNSRecord(dnsRecord
, results
);
237 recordList
.Append(record
);
238 dnsRecord
= dnsRecord
->pNext
;
242 DnsRecordListFree(results
, DnsFreeRecordList
);
244 return recordList
.GetSize() != 0;
247 /////////////////////////////////////////////////////////////
249 class SRVRecord
: public PObject
251 PCLASSINFO(SRVRecord
, PObject
);
256 Comparison
Compare(const PObject
& obj
) const;
257 void PrintOn(ostream
& strm
) const;
260 PIPSocket::Address hostAddress
;
267 PDECLARE_SORTED_LIST(SRVRecordList
, PDNS::SRVRecord
)
269 void PrintOn(ostream
& strm
) const;
271 SRVRecord
* GetFirst();
272 SRVRecord
* GetNext();
274 PDNS::SRVRecord
* HandleDNSRecord(PDNS_RECORD dnsRecord
, PDNS_RECORD results
);
282 * return a list of DNS SRV record with the specified service type
285 inline BOOL
GetRecords(const PString
& service
, SRVRecordList
& serviceList
)
286 { return Lookup
<DNS_TYPE_SRV
, SRVRecordList
, SRVRecord
>(service
, serviceList
); }
289 * provided for backwards compatibility
291 inline BOOL
GetSRVRecords(
292 const PString
& service
,
293 SRVRecordList
& serviceList
295 { return GetRecords(service
, serviceList
); }
298 * return a list of DNS SRV record with the specified service, type and domain
302 const PString
& service
,
303 const PString
& type
,
304 const PString
& domain
,
305 SRVRecordList
& serviceList
309 * Perform a DNS lookup of the specified service
310 * @return TRUE if the service could be resolved, else FALSE
314 const PString
& domain
, ///< domain to lookup
315 const PString
& service
, ///< service to use
316 WORD defaultPort
, ///< default por to use
317 PIPSocketAddressAndPortVector
& addrList
///< returned list of sockets and ports
321 const PURL
& url
, ///< URL to lookup
322 const PString
& service
, ///< service to use
323 PStringList
& returnStr
///< resolved addresses, if return value is TRUE
326 ////////////////////////////////////////////////////////////////
328 class MXRecord
: public PObject
330 PCLASSINFO(MXRecord
, PObject
);
334 Comparison
Compare(const PObject
& obj
) const;
335 void PrintOn(ostream
& strm
) const;
338 PIPSocket::Address hostAddress
;
343 PDECLARE_SORTED_LIST(MXRecordList
, PDNS::MXRecord
)
345 void PrintOn(ostream
& strm
) const;
347 MXRecord
* GetFirst();
348 MXRecord
* GetNext();
350 PDNS::MXRecord
* HandleDNSRecord(PDNS_RECORD dnsRecord
, PDNS_RECORD results
);
357 * return a list of MX records for the specified domain
359 inline BOOL
GetRecords(
360 const PString
& domain
,
361 MXRecordList
& serviceList
363 { return Lookup
<DNS_TYPE_MX
, MXRecordList
, MXRecord
>(domain
, serviceList
); }
366 * provided for backwards compatibility
368 inline BOOL
GetMXRecords(
369 const PString
& domain
,
370 MXRecordList
& serviceList
373 return GetRecords(domain
, serviceList
);
376 ///////////////////////////////////////////////////////////////////////////
383 // End Of File ///////////////////////////////////////////////////////////////