PWLib
1.10.10
|
00001 /* 00002 * pdns.h 00003 * 00004 * PWLib library for DNS lookup services 00005 * 00006 * Portable Windows Library 00007 * 00008 * Copyright (c) 2003 Equivalence Pty. Ltd. 00009 * 00010 * The contents of this file are subject to the Mozilla Public License 00011 * Version 1.0 (the "License"); you may not use this file except in 00012 * compliance with the License. You may obtain a copy of the License at 00013 * http://www.mozilla.org/MPL/ 00014 * 00015 * Software distributed under the License is distributed on an "AS IS" 00016 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 00017 * the License for the specific language governing rights and limitations 00018 * under the License. 00019 * 00020 * The Original Code is Portable Windows Library. 00021 * 00022 * The Initial Developer of the Original Code is Equivalence Pty. Ltd. 00023 * 00024 * Contributor(s): ______________________________________. 00025 * 00026 * $Log: pdns.h,v $ 00027 * Revision 1.9.2.2 2007/08/10 10:08:01 dsandras 00028 * Fixed DNS support thanks to Vincent Luba <luba novacom be>. 00029 * 00030 * Revision 1.9.2.1 2006/03/12 21:14:47 dsandras 00031 * Backports from HEAD. 00032 * 00033 * Revision 1.11 2006/02/26 11:51:20 csoutheren 00034 * Extended DNS test program to include URL based SRV lookups 00035 * Re-arranged SRV lookup code to allow access to internal routine 00036 * Reformatted code 00037 * 00038 * Revision 1.10 2006/02/26 09:26:17 shorne 00039 * Added DNS SRV record lookups 00040 * 00041 * Revision 1.9 2005/11/30 12:47:37 csoutheren 00042 * Removed tabs, reformatted some code, and changed tags for Doxygen 00043 * 00044 * Revision 1.8 2004/06/24 07:36:24 csoutheren 00045 * Added definitions of T_SRV and T_NAPTR for hosts that do not have these 00046 * 00047 * Revision 1.7 2004/05/31 12:49:47 csoutheren 00048 * Added handling of unknown DNS types 00049 * 00050 * Revision 1.6 2004/05/28 06:50:42 csoutheren 00051 * Reorganised DNS functions to use templates, and exposed more internals to allow new DNS lookup types to be added 00052 * 00053 * Revision 1.5 2003/07/22 23:52:20 dereksmithies 00054 * Fix from Fabrizio Ammollo to cope with when P_DNS is disabled. Thanks! 00055 * 00056 * Revision 1.4 2003/04/16 07:02:55 robertj 00057 * Cleaned up source. 00058 * 00059 * Revision 1.3 2003/04/15 08:14:06 craigs 00060 * Added single string form of GetSRVRecords 00061 * 00062 * Revision 1.2 2003/04/15 08:06:24 craigs 00063 * Added Unix implementation 00064 * 00065 * Revision 1.1 2003/04/15 04:06:56 craigs 00066 * Initial version 00067 * 00068 */ 00069 00070 #if P_DNS 00071 #ifndef _PDNS_H 00072 #define _PDNS_H 00073 00074 #ifdef P_USE_PRAGMA 00075 #pragma interface 00076 #endif 00077 00078 #include <ptlib/sockets.h> 00079 00080 #include <ptclib/random.h> 00081 #include <ptclib/url.h> 00082 00083 #if defined(_WIN32) 00084 00085 # include <windns.h> 00086 # pragma comment(lib, P_DNS_LIBRARY) 00087 00088 #else 00089 00090 # define P_HAS_RESOLVER 1 // set if using Unix-style DNS routines 00091 # include <arpa/nameser.h> 00092 # include <resolv.h> 00093 # if defined(P_MACOSX) && (P_MACOSX >= 700) 00094 # include <arpa/nameser_compat.h> 00095 # endif 00096 00097 #endif // _WIN32 00098 00099 #ifdef P_HAS_RESOLVER 00100 00102 // 00103 // these classes provide an emulation of the Microsoft DNS API 00104 // on non-Window systems 00105 // 00106 00107 #ifndef T_SRV 00108 #define T_SRV 33 00109 #endif 00110 00111 #ifndef T_NAPTR 00112 #define T_NAPTR 35 00113 #endif 00114 00115 00116 #define DNS_STATUS int 00117 #define DNS_TYPE_SRV T_SRV 00118 #define DNS_TYPE_MX T_MX 00119 #define DNS_TYPE_A T_A 00120 #define DNS_TYPE_NAPTR T_NAPTR 00121 #define DnsFreeRecordList 0 00122 #define DNS_QUERY_STANDARD 0 00123 #define DNS_QUERY_BYPASS_CACHE 0 00124 00125 typedef struct _DnsAData { 00126 DWORD IpAddress; 00127 } DNS_A_DATA; 00128 00129 typedef struct { 00130 char pNameExchange[MAXDNAME]; 00131 WORD wPreference; 00132 } DNS_MX_DATA; 00133 00134 typedef struct { 00135 char pNameHost[MAXDNAME]; 00136 } DNS_PTR_DATA; 00137 00138 typedef struct _DnsSRVData { 00139 char pNameTarget[MAXDNAME]; 00140 WORD wPriority; 00141 WORD wWeight; 00142 WORD wPort; 00143 } DNS_SRV_DATA; 00144 00145 typedef struct _DnsNULLData { 00146 DWORD dwByteCount; 00147 char data[1]; 00148 } DNS_NULL_DATA; 00149 00150 typedef struct _DnsRecordFlags 00151 { 00152 unsigned Section : 2; 00153 unsigned Delete : 1; 00154 unsigned CharSet : 2; 00155 unsigned Unused : 3; 00156 unsigned Reserved : 24; 00157 } DNS_RECORD_FLAGS; 00158 00159 typedef enum _DnsSection 00160 { 00161 DnsSectionQuestion, 00162 DnsSectionAnswer, 00163 DnsSectionAuthority, 00164 DnsSectionAdditional, 00165 } DNS_SECTION; 00166 00167 00168 class DnsRecord { 00169 public: 00170 DnsRecord * pNext; 00171 char pName[MAXDNAME]; 00172 WORD wType; 00173 WORD wDataLength; 00174 00175 union { 00176 DWORD DW; 00177 DNS_RECORD_FLAGS S; 00178 } Flags; 00179 00180 union { 00181 DNS_A_DATA A; 00182 DNS_MX_DATA MX; 00183 DNS_PTR_DATA NS; 00184 DNS_SRV_DATA SRV; 00185 DNS_NULL_DATA Null; 00186 } Data; 00187 }; 00188 00189 typedef DnsRecord * PDNS_RECORD; 00190 00191 extern void DnsRecordListFree(PDNS_RECORD rec, int FreeType); 00192 00193 extern DNS_STATUS DnsQuery_A(const char * service, 00194 WORD requestType, 00195 DWORD options, 00196 void *, 00197 PDNS_RECORD * results, 00198 void *); 00199 00200 00201 #endif // P_HAS_RESOLVER 00202 00203 namespace PDNS { 00204 00206 // 00207 // this template automates the creation of a list of records for 00208 // a specific type of DNS lookup 00209 // 00210 00211 template <unsigned type, class RecordListType, class RecordType> 00212 BOOL Lookup(const PString & name, RecordListType & recordList) 00213 { 00214 if (name.IsEmpty()) 00215 return FALSE; 00216 00217 recordList.RemoveAll(); 00218 00219 PDNS_RECORD results = NULL; 00220 DNS_STATUS status = DnsQuery_A((const char *)name, 00221 type, 00222 DNS_QUERY_STANDARD, 00223 NULL, 00224 &results, 00225 NULL); 00226 if (status != 0) 00227 return FALSE; 00228 00229 // find records matching the correct type 00230 PDNS_RECORD dnsRecord = results; 00231 while (dnsRecord != NULL) { 00232 RecordType * record = recordList.HandleDNSRecord(dnsRecord, results); 00233 if (record != NULL) 00234 recordList.Append(record); 00235 dnsRecord = dnsRecord->pNext; 00236 } 00237 00238 if (results != NULL) 00239 DnsRecordListFree(results, DnsFreeRecordList); 00240 00241 return recordList.GetSize() != 0; 00242 } 00243 00245 00246 class SRVRecord : public PObject 00247 { 00248 PCLASSINFO(SRVRecord, PObject); 00249 public: 00250 SRVRecord() 00251 { used = FALSE; } 00252 00253 Comparison Compare(const PObject & obj) const; 00254 void PrintOn(ostream & strm) const; 00255 00256 PString hostName; 00257 PIPSocket::Address hostAddress; 00258 BOOL used; 00259 WORD port; 00260 WORD priority; 00261 WORD weight; 00262 }; 00263 00264 PDECLARE_SORTED_LIST(SRVRecordList, PDNS::SRVRecord) 00265 public: 00266 void PrintOn(ostream & strm) const; 00267 00268 SRVRecord * GetFirst(); 00269 SRVRecord * GetNext(); 00270 00271 PDNS::SRVRecord * HandleDNSRecord(PDNS_RECORD dnsRecord, PDNS_RECORD results); 00272 00273 protected: 00274 PINDEX priPos; 00275 PWORDArray priList; 00276 }; 00277 00282 inline BOOL GetRecords(const PString & service, SRVRecordList & serviceList) 00283 { return Lookup<DNS_TYPE_SRV, SRVRecordList, SRVRecord>(service, serviceList); } 00284 00288 inline BOOL GetSRVRecords( 00289 const PString & service, 00290 SRVRecordList & serviceList 00291 ) 00292 { return GetRecords(service, serviceList); } 00293 00298 BOOL GetSRVRecords( 00299 const PString & service, 00300 const PString & type, 00301 const PString & domain, 00302 SRVRecordList & serviceList 00303 ); 00304 00310 BOOL LookupSRV( 00311 const PString & domain, 00312 const PString & service, 00313 WORD defaultPort, 00314 PIPSocketAddressAndPortVector & addrList 00315 ); 00316 00317 BOOL LookupSRV( 00318 const PURL & url, 00319 const PString & service, 00320 PStringList & returnStr 00321 ); 00322 00324 00325 class MXRecord : public PObject 00326 { 00327 PCLASSINFO(MXRecord, PObject); 00328 public: 00329 MXRecord() 00330 { used = FALSE; } 00331 Comparison Compare(const PObject & obj) const; 00332 void PrintOn(ostream & strm) const; 00333 00334 PString hostName; 00335 PIPSocket::Address hostAddress; 00336 BOOL used; 00337 WORD preference; 00338 }; 00339 00340 PDECLARE_SORTED_LIST(MXRecordList, PDNS::MXRecord) 00341 public: 00342 void PrintOn(ostream & strm) const; 00343 00344 MXRecord * GetFirst(); 00345 MXRecord * GetNext(); 00346 00347 PDNS::MXRecord * HandleDNSRecord(PDNS_RECORD dnsRecord, PDNS_RECORD results); 00348 00349 protected: 00350 PINDEX lastIndex; 00351 }; 00352 00356 inline BOOL GetRecords( 00357 const PString & domain, 00358 MXRecordList & serviceList 00359 ) 00360 { return Lookup<DNS_TYPE_MX, MXRecordList, MXRecord>(domain, serviceList); } 00361 00365 inline BOOL GetMXRecords( 00366 const PString & domain, 00367 MXRecordList & serviceList 00368 ) 00369 { 00370 return GetRecords(domain, serviceList); 00371 } 00372 00374 00375 }; // namespace PDNS 00376 00377 #endif // _PDNS_H 00378 #endif // P_DNS 00379 00380 // End Of File ///////////////////////////////////////////////////////////////