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

Generated on Fri Oct 14 01:44:09 2011 for PTLib by  doxygen 1.4.7