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

Generated on Mon Sep 15 01:21:35 2008 for PTLib by  doxygen 1.5.1