# 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 ///////////////////////////////////////////////////////////////