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

Generated on Fri Feb 15 20:58:31 2013 for PTLib by  doxygen 1.4.7