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: 21788 $
00027  * $Author: rjongbloed $
00028  * $Date: 2008-12-11 23:42:13 -0600 (Thu, 11 Dec 2008) $
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 #  pragma comment(lib, P_DNS_LIBRARY)
00049 
00050 // Accommodate spelling error in windns.h
00051 #ifndef __MINGW32__
00052 enum { DnsSectionAdditional = DnsSectionAddtional };
00053 #endif
00054 
00055 #else /* _WIN32 */
00056 
00057 #  define  P_HAS_RESOLVER 1         // set if using Unix-style DNS routines
00058 #  include <arpa/nameser.h>
00059 #  include <resolv.h>
00060 #  if defined(P_MACOSX) && (P_MACOSX >= 700)
00061 #    include <arpa/nameser_compat.h>
00062 #  endif
00063 
00064 #endif  // _WIN32
00065 
00066 #ifdef P_HAS_RESOLVER
00067 
00069 //
00070 // these classes provide an emulation of the Microsoft DNS API 
00071 // on non-Window systems
00072 //
00073 
00074 #ifndef T_SRV
00075 #define T_SRV   33
00076 #endif
00077 
00078 #ifndef T_NAPTR
00079 #define T_NAPTR   35
00080 #endif
00081 
00082 
00083 #define DNS_STATUS  int
00084 #define DNS_TYPE_SRV  T_SRV
00085 #define DNS_TYPE_MX  T_MX
00086 #define DNS_TYPE_A  T_A
00087 #define DNS_TYPE_NAPTR  T_NAPTR
00088 #define DnsFreeRecordList 0
00089 #define DNS_QUERY_STANDARD 0
00090 #define DNS_QUERY_BYPASS_CACHE 0
00091 
00092 typedef struct _DnsAData {
00093   DWORD IpAddress;
00094 } DNS_A_DATA;
00095 
00096 typedef struct {
00097   char   pNameExchange[MAXDNAME];
00098   WORD   wPreference;
00099 } DNS_MX_DATA;
00100 
00101 typedef struct {
00102   char pNameHost[MAXDNAME];
00103 } DNS_PTR_DATA;
00104 
00105 typedef struct _DnsSRVData {
00106   char   pNameTarget[MAXDNAME];
00107   WORD   wPriority;
00108   WORD   wWeight;
00109   WORD   wPort;
00110 } DNS_SRV_DATA;
00111 
00112 typedef struct _DnsNULLData {
00113   DWORD  dwByteCount;
00114   char   data[1];
00115 } DNS_NULL_DATA;
00116 
00117 typedef struct _DnsRecordFlags
00118 {
00119   unsigned   Section     : 2;
00120   unsigned   Delete      : 1;
00121   unsigned   CharSet     : 2;
00122   unsigned   Unused      : 3;
00123   unsigned   Reserved    : 24;
00124 } DNS_RECORD_FLAGS;
00125 
00126 typedef enum _DnsSection
00127 {
00128   DnsSectionQuestion,
00129   DnsSectionAnswer,
00130   DnsSectionAuthority,
00131   DnsSectionAdditional,
00132 } DNS_SECTION;
00133 
00134 
00135 class DnsRecord {
00136   public:
00137     DnsRecord * pNext;
00138     char        pName[MAXDNAME];
00139     WORD        wType;
00140     WORD        wDataLength;
00141 
00142     union {
00143       DWORD               DW;     
00144       DNS_RECORD_FLAGS    S;      
00145     } Flags;
00146 
00147     union {
00148       DNS_A_DATA     A;
00149       DNS_MX_DATA    MX;
00150       DNS_PTR_DATA   NS;
00151       DNS_SRV_DATA   SRV;
00152       DNS_NULL_DATA  Null;
00153     } Data;
00154 };
00155 
00156 typedef DnsRecord * PDNS_RECORD;
00157 
00158 
00159 typedef DWORD   IP4_ADDRESS, *PIP4_ADDRESS;
00160 
00161 typedef struct  _IP4_ARRAY
00162 {
00163     DWORD           AddrCount;
00164     IP4_ADDRESS     AddrArray[1];
00165 }
00166 IP4_ARRAY, *PIP4_ARRAY;
00167 
00168 
00169 extern void DnsRecordListFree(PDNS_RECORD rec, int FreeType);
00170 
00171 extern DNS_STATUS DnsQuery_A(const char * service,
00172           WORD requestType,
00173           DWORD options,
00174           PIP4_ARRAY,
00175           PDNS_RECORD * results,
00176           void *);
00177 
00178 
00179 #endif // P_HAS_RESOLVER
00180 
00181 namespace PDNS {
00182 
00184 //
00185 //  this template automates the creation of a list of records for
00186 //  a specific type of DNS lookup
00187 //
00188 
00189 template <unsigned type, class RecordListType, class RecordType>
00190 PBoolean Lookup(const PString & name, RecordListType & recordList)
00191 {
00192   if (name.IsEmpty())
00193     return PFalse;
00194 
00195   recordList.RemoveAll();
00196 
00197   PDNS_RECORD results = NULL;
00198   DNS_STATUS status = DnsQuery_A((const char *)name, 
00199                                  type,
00200                                  DNS_QUERY_STANDARD, 
00201                                  (PIP4_ARRAY)NULL, 
00202                                  &results, 
00203                                  NULL);
00204   if (status != 0)
00205     return PFalse;
00206 
00207   // find records matching the correct type
00208   PDNS_RECORD dnsRecord = results;
00209   while (dnsRecord != NULL) {
00210     RecordType * record = recordList.HandleDNSRecord(dnsRecord, results);
00211     if (record != NULL)
00212       recordList.Append(record);
00213     dnsRecord = dnsRecord->pNext;
00214   }
00215 
00216   if (results != NULL)
00217     DnsRecordListFree(results, DnsFreeRecordList);
00218 
00219   return recordList.GetSize() != 0;
00220 }
00221 
00223 
00224 class SRVRecord : public PObject
00225 {
00226   PCLASSINFO(SRVRecord, PObject);
00227   public:
00228     SRVRecord()
00229     { used = PFalse; }
00230 
00231     Comparison Compare(const PObject & obj) const;
00232     void PrintOn(ostream & strm) const;
00233 
00234     PString            hostName;
00235     PIPSocket::Address hostAddress;
00236     PBoolean               used;
00237     WORD port;
00238     WORD priority;
00239     WORD weight;
00240 };
00241 
00242 PDECLARE_SORTED_LIST(SRVRecordList, PDNS::SRVRecord)
00243   public:
00244     void PrintOn(ostream & strm) const;
00245 
00246     SRVRecord * GetFirst();
00247     SRVRecord * GetNext();
00248 
00249     PDNS::SRVRecord * HandleDNSRecord(PDNS_RECORD dnsRecord, PDNS_RECORD results);
00250 
00251   protected:
00252     PINDEX     priPos;
00253     PWORDArray priList;
00254 };
00255 
00260 inline PBoolean GetRecords(const PString & service, SRVRecordList & serviceList)
00261 { return Lookup<DNS_TYPE_SRV, SRVRecordList, SRVRecord>(service, serviceList); }
00262 
00266 inline PBoolean GetSRVRecords(
00267       const PString & service,
00268       SRVRecordList & serviceList
00269 )
00270 { return GetRecords(service, serviceList); }
00271 
00276 PBoolean GetSRVRecords(
00277       const PString & service,
00278       const PString & type,
00279       const PString & domain,
00280       SRVRecordList & serviceList
00281 );
00282 
00288 PBoolean LookupSRV(
00289          const PString & srvQuery,
00290          WORD defaultPort,
00291          PIPSocketAddressAndPortVector & addrList
00292 );
00293 
00294 PBoolean LookupSRV( 
00295          const PString & domain,                  
00296          const PString & service,                 
00297          WORD defaultPort,                        
00298          PIPSocketAddressAndPortVector & addrList 
00299 ); 
00300 
00301 PBoolean LookupSRV( 
00302          const PURL & url,          
00303          const PString & service,   
00304          PStringList & returnStr    
00305 );  
00306 
00308 
00309 class MXRecord : public PObject
00310 {
00311   PCLASSINFO(MXRecord, PObject);
00312   public:
00313     MXRecord()
00314     { used = PFalse; }
00315     Comparison Compare(const PObject & obj) const;
00316     void PrintOn(ostream & strm) const;
00317 
00318     PString            hostName;
00319     PIPSocket::Address hostAddress;
00320     PBoolean               used;
00321     WORD               preference;
00322 };
00323 
00324 PDECLARE_SORTED_LIST(MXRecordList, PDNS::MXRecord)
00325   public:
00326     void PrintOn(ostream & strm) const;
00327 
00328     MXRecord * GetFirst();
00329     MXRecord * GetNext();
00330 
00331     PDNS::MXRecord * HandleDNSRecord(PDNS_RECORD dnsRecord, PDNS_RECORD results);
00332 
00333   protected:
00334     PINDEX lastIndex;
00335 };
00336 
00340 inline PBoolean GetRecords(
00341       const PString & domain,
00342       MXRecordList & serviceList
00343 )
00344 { return Lookup<DNS_TYPE_MX, MXRecordList, MXRecord>(domain, serviceList); }
00345 
00349 inline PBoolean GetMXRecords(
00350       const PString & domain,
00351       MXRecordList & serviceList
00352 )
00353 {
00354   return GetRecords(domain, serviceList);
00355 }
00356 
00358 
00359 }; // namespace PDNS
00360 
00361 #endif // P_DNS
00362 
00363 #endif // PTLIB_PDNS_H
00364 
00365 
00366 // End Of File ///////////////////////////////////////////////////////////////

Generated on Thu May 27 01:36:48 2010 for PTLib by  doxygen 1.4.7