PTLib  Version 2.10.4
pdns.h
Go to the documentation of this file.
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  * $Revision: 25959 $
00027  * $Author: rjongbloed $
00028  * $Date: 2011-06-02 00:33:14 -0500 (Thu, 02 Jun 2011) $
00029  */
00030 
00031 #ifndef PTLIB_PDNS_H
00032 #define PTLIB_PDNS_H
00033 
00034 #if P_DNS
00035 
00036 #ifdef P_USE_PRAGMA
00037 #pragma interface
00038 #endif
00039 
00040 #include <ptlib/sockets.h>
00041 
00042 #include <ptclib/random.h>
00043 #include <ptclib/url.h>
00044 
00045 #if defined(_WIN32)
00046 
00047   #include <windns.h>
00048 
00049   #ifndef __MINGW32__
00050 
00051     #include <ntverp.h>
00052 
00053     #pragma comment(lib, "dnsapi.lib")
00054 
00055     // Accommodate spelling error in windns.h
00056     enum { DnsSectionAdditional = DnsSectionAddtional };
00057 
00058   #endif
00059 
00060 #else /* _WIN32 */
00061 
00062   #define  P_HAS_RESOLVER 1         // set if using Unix-style DNS routines
00063   #include <arpa/nameser.h>
00064   #include <resolv.h>
00065   #if defined(P_MACOSX) && (P_MACOSX >= 700)
00066     #include <arpa/nameser_compat.h>
00067   #endif
00068 
00069 #endif  // _WIN32
00070 
00071 
00072 #if defined(_WIN32) && VER_PRODUCTBUILD < 6000
00073 typedef struct
00074 {
00075     WORD            wOrder;
00076     WORD            wPreference;
00077     PSTR            pFlags;
00078     PSTR            pService;
00079     PSTR            pRegularExpression;
00080     PSTR            pReplacement;
00081 }
00082 DNS_NAPTR_DATA;
00083 #endif
00084 
00085 
00086 #ifdef P_HAS_RESOLVER
00087 
00089 //
00090 // these classes provide an emulation of the Microsoft DNS API 
00091 // on non-Window systems
00092 //
00093 
00094 #define DnsRecordListFree  PDnsRecordListFree
00095 
00096 #ifndef T_SRV
00097 #define T_SRV   33
00098 #endif
00099 
00100 #ifndef T_NAPTR
00101 #define T_NAPTR   35
00102 #endif
00103 
00104 
00105 #define DNS_STATUS  int
00106 #define DNS_TYPE_SRV  T_SRV
00107 #define DNS_TYPE_MX  T_MX
00108 #define DNS_TYPE_A  T_A
00109 #define DNS_TYPE_NAPTR  T_NAPTR
00110 #define DnsFreeRecordList 0
00111 #define DNS_QUERY_STANDARD 0
00112 #define DNS_QUERY_BYPASS_CACHE 0
00113 
00114 typedef struct _DnsAData {
00115   DWORD IpAddress;
00116 } DNS_A_DATA;
00117 
00118 typedef struct {
00119   char   pNameExchange[MAXDNAME];
00120   WORD   wPreference;
00121 } DNS_MX_DATA;
00122 
00123 typedef struct {
00124   char pNameHost[MAXDNAME];
00125 } DNS_PTR_DATA;
00126 
00127 typedef struct _DnsSRVData {
00128   char   pNameTarget[MAXDNAME];
00129   WORD   wPriority;
00130   WORD   wWeight;
00131   WORD   wPort;
00132 } DNS_SRV_DATA;
00133 
00134 typedef struct _DnsNULLData {
00135   DWORD  dwByteCount;
00136   char   data[1];
00137 } DNS_NULL_DATA;
00138 
00139 typedef struct _DnsRecordFlags
00140 {
00141   unsigned   Section     : 2;
00142   unsigned   Delete      : 1;
00143   unsigned   CharSet     : 2;
00144   unsigned   Unused      : 3;
00145   unsigned   Reserved    : 24;
00146 } DNS_RECORD_FLAGS;
00147 
00148 typedef enum _DnsSection
00149 {
00150   DnsSectionQuestion,
00151   DnsSectionAnswer,
00152   DnsSectionAuthority,
00153   DnsSectionAdditional,
00154 } DNS_SECTION;
00155 
00156 
00157 class DnsRecord {
00158   public:
00159     DnsRecord * pNext;
00160     char        pName[MAXDNAME];
00161     WORD        wType;
00162     WORD        wDataLength;
00163 
00164     union {
00165       DWORD               DW;     
00166       DNS_RECORD_FLAGS    S;      
00167     } Flags;
00168 
00169     union {
00170       DNS_A_DATA     A;
00171       DNS_MX_DATA    MX;
00172       DNS_PTR_DATA   NS;
00173       DNS_SRV_DATA   SRV;
00174       DNS_NULL_DATA  Null;
00175     } Data;
00176 };
00177 
00178 typedef DnsRecord DNS_RECORD;
00179 typedef DnsRecord * PDNS_RECORD;
00180 
00181 
00182 typedef DWORD   IP4_ADDRESS, *PIP4_ADDRESS;
00183 
00184 typedef struct  _IP4_ARRAY
00185 {
00186     DWORD           AddrCount;
00187     IP4_ADDRESS     AddrArray[1];
00188 }
00189 IP4_ARRAY, *PIP4_ARRAY;
00190 
00191 
00192 extern void PDnsRecordListFree(PDNS_RECORD rec, int FreeType);
00193 
00194 extern DNS_STATUS DnsQuery_A(const char * service,
00195           WORD requestType,
00196           DWORD options,
00197           PIP4_ARRAY,
00198           PDNS_RECORD * results,
00199           void *);
00200 
00201 
00202 #endif // P_HAS_RESOLVER
00203 
00204 namespace PDNS {
00205 
00207 
00208 DNS_STATUS Cached_DnsQuery(
00209     const char * name,
00210     WORD       type,
00211     DWORD      options,
00212     void *     extra,
00213     PDNS_RECORD * queryResults,
00214     void * reserved
00215 );
00216 
00217 
00218 void Cached_DnsRecordListFree(PDNS_RECORD, int);
00219 
00221 //
00222 //  this template automates the creation of a list of records for
00223 //  a specific type of DNS lookup
00224 //
00225 
00226 template <unsigned type, class RecordListType, class RecordType>
00227 PBoolean Lookup(const PString & name, RecordListType & recordList)
00228 {
00229   if (name.IsEmpty())
00230     return false;
00231 
00232   recordList.RemoveAll();
00233 
00234   PDNS_RECORD results = NULL;
00235   DNS_STATUS status = Cached_DnsQuery((const char *)name, 
00236                                       type,
00237                                       DNS_QUERY_STANDARD, 
00238                                       (PIP4_ARRAY)NULL, 
00239                                       &results, 
00240                                       NULL);
00241   if (status != 0)
00242     return false;
00243 
00244   // find records matching the correct type
00245   PDNS_RECORD dnsRecord = results;
00246   while (dnsRecord != NULL) {
00247     RecordType * record = recordList.HandleDNSRecord(dnsRecord, results);
00248     if (record != NULL)
00249       recordList.Append(record);
00250     dnsRecord = dnsRecord->pNext;
00251   }
00252 
00253   if (results != NULL)
00254     Cached_DnsRecordListFree(results, DnsFreeRecordList);
00255 
00256   return recordList.GetSize() != 0;
00257 }
00258 
00260 
00261 class SRVRecord : public PObject
00262 {
00263   PCLASSINFO(SRVRecord, PObject);
00264   public:
00265     SRVRecord()
00266     { used = false; }
00267 
00268     Comparison Compare(const PObject & obj) const;
00269     void PrintOn(ostream & strm) const;
00270 
00271     PString            hostName;
00272     PIPSocket::Address hostAddress;
00273     PBoolean               used;
00274     WORD port;
00275     WORD priority;
00276     WORD weight;
00277 };
00278 
00279 PDECLARE_SORTED_LIST(SRVRecordList, PDNS::SRVRecord)
00280   public:
00281     void PrintOn(ostream & strm) const;
00282 
00283     SRVRecord * GetFirst();
00284     SRVRecord * GetNext();
00285 
00286     PDNS::SRVRecord * HandleDNSRecord(PDNS_RECORD dnsRecord, PDNS_RECORD results);
00287 
00288   protected:
00289     PINDEX     priPos;
00290     PWORDArray priList;
00291 };
00292 
00297 inline PBoolean GetRecords(const PString & service, SRVRecordList & serviceList)
00298 { return Lookup<DNS_TYPE_SRV, SRVRecordList, SRVRecord>(service, serviceList); }
00299 
00303 inline PBoolean GetSRVRecords(
00304       const PString & service,
00305       SRVRecordList & serviceList
00306 )
00307 { return GetRecords(service, serviceList); }
00308 
00313 PBoolean GetSRVRecords(
00314       const PString & service,
00315       const PString & type,
00316       const PString & domain,
00317       SRVRecordList & serviceList
00318 );
00319 
00325 PBoolean LookupSRV(
00326          const PString & srvQuery,
00327          WORD defaultPort,
00328          PIPSocketAddressAndPortVector & addrList
00329 );
00330 
00331 PBoolean LookupSRV( 
00332          const PString & domain,                  
00333          const PString & service,                 
00334          WORD defaultPort,                        
00335          PIPSocketAddressAndPortVector & addrList 
00336 ); 
00337 
00338 PBoolean LookupSRV( 
00339          const PURL & url,          
00340          const PString & service,   
00341          PStringList & returnStr    
00342 );  
00343 
00345 
00346 class MXRecord : public PObject
00347 {
00348   PCLASSINFO(MXRecord, PObject);
00349   public:
00350     MXRecord()
00351     { used = false; }
00352     Comparison Compare(const PObject & obj) const;
00353     void PrintOn(ostream & strm) const;
00354 
00355     PString            hostName;
00356     PIPSocket::Address hostAddress;
00357     PBoolean               used;
00358     WORD               preference;
00359 };
00360 
00361 PDECLARE_SORTED_LIST(MXRecordList, PDNS::MXRecord)
00362   public:
00363     void PrintOn(ostream & strm) const;
00364 
00365     MXRecord * GetFirst();
00366     MXRecord * GetNext();
00367 
00368     PDNS::MXRecord * HandleDNSRecord(PDNS_RECORD dnsRecord, PDNS_RECORD results);
00369 
00370   protected:
00371     PINDEX lastIndex;
00372 };
00373 
00377 inline PBoolean GetRecords(
00378       const PString & domain,
00379       MXRecordList & serviceList
00380 )
00381 { return Lookup<DNS_TYPE_MX, MXRecordList, MXRecord>(domain, serviceList); }
00382 
00386 inline PBoolean GetMXRecords(
00387       const PString & domain,
00388       MXRecordList & serviceList
00389 )
00390 {
00391   return GetRecords(domain, serviceList);
00392 }
00393 
00394 
00395 }; // namespace PDNS
00396 
00397 #endif // P_DNS
00398 
00399 #endif // PTLIB_PDNS_H
00400 
00401 
00402 // End Of File ///////////////////////////////////////////////////////////////
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines