Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

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  * $Log: pdns.h,v $
00027  * Revision 1.8  2004/06/24 07:36:24  csoutheren
00028  * Added definitions of T_SRV and T_NAPTR for hosts that do not have these
00029  *
00030  * Revision 1.7  2004/05/31 12:49:47  csoutheren
00031  * Added handling of unknown DNS types
00032  *
00033  * Revision 1.6  2004/05/28 06:50:42  csoutheren
00034  * Reorganised DNS functions to use templates, and exposed more internals to allow new DNS lookup types to be added
00035  *
00036  * Revision 1.5  2003/07/22 23:52:20  dereksmithies
00037  * Fix from Fabrizio Ammollo to cope with when P_DNS is disabled. Thanks!
00038  *
00039  * Revision 1.4  2003/04/16 07:02:55  robertj
00040  * Cleaned up source.
00041  *
00042  * Revision 1.3  2003/04/15 08:14:06  craigs
00043  * Added single string form of GetSRVRecords
00044  *
00045  * Revision 1.2  2003/04/15 08:06:24  craigs
00046  * Added Unix implementation
00047  *
00048  * Revision 1.1  2003/04/15 04:06:56  craigs
00049  * Initial version
00050  *
00051  */
00052 
00053 #if P_DNS
00054 #ifndef _PDNS_H
00055 #define _PDNS_H
00056 
00057 #ifdef P_USE_PRAGMA
00058 #pragma interface
00059 #endif
00060 
00061 #include <ptlib/sockets.h>
00062 
00063 #include <ptclib/random.h>
00064 
00065 #if defined(_WIN32)
00066 
00067 #  include <windns.h>
00068 #  pragma comment(lib, P_DNS_LIBRARY)
00069 
00070 #else
00071 
00072 #  define  P_HAS_RESOLVER 1         // set if using Unix-style DNS routines
00073 #  include <arpa/nameser.h>
00074 #  include <resolv.h>
00075 #  if defined(P_MACOSX) && (P_MACOSX >= 700)
00076 #    include <arpa/nameser_compat.h>
00077 #  endif
00078 
00079 #endif  // _WIN32
00080 
00081 #ifdef P_HAS_RESOLVER
00082 
00084 //
00085 // these classes provide an emulation of the Microsoft DNS API 
00086 // on non-Window systems
00087 //
00088 
00089 #ifndef T_SRV
00090 #define T_SRV   33
00091 #endif
00092 
00093 #ifndef T_NAPTR
00094 #define T_NAPTR   35
00095 #endif
00096 
00097 
00098 #define DNS_STATUS              int
00099 #define DNS_TYPE_SRV            T_SRV
00100 #define DNS_TYPE_MX             T_MX
00101 #define DNS_TYPE_A              T_A
00102 #define DNS_TYPE_NAPTR          T_NAPTR
00103 #define DnsFreeRecordList       0
00104 #define DNS_QUERY_STANDARD      0
00105 #define DNS_QUERY_BYPASS_CACHE  0
00106 
00107 typedef struct _DnsAData {
00108   DWORD IpAddress;
00109 } DNS_A_DATA;
00110 
00111 typedef struct {
00112   char   pNameExchange[MAXDNAME];
00113   WORD   wPreference;
00114 } DNS_MX_DATA;
00115 
00116 typedef struct {
00117   char pNameHost[MAXDNAME];
00118 } DNS_PTR_DATA;
00119 
00120 typedef struct _DnsSRVData {
00121   char   pNameTarget[MAXDNAME];
00122   WORD   wPriority;
00123   WORD   wWeight;
00124   WORD   wPort;
00125 } DNS_SRV_DATA;
00126 
00127 typedef struct _DnsNULLData {
00128   DWORD  dwByteCount;
00129   char   data[1];
00130 } DNS_NULL_DATA;
00131 
00132 typedef struct _DnsRecordFlags
00133 {
00134   unsigned   Section     : 2;
00135   unsigned   Delete      : 1;
00136   unsigned   CharSet     : 2;
00137   unsigned   Unused      : 3;
00138   unsigned   Reserved    : 24;
00139 } DNS_RECORD_FLAGS;
00140 
00141 typedef enum _DnsSection
00142 {
00143   DnsSectionQuestion,
00144   DnsSectionAnswer,
00145   DnsSectionAuthority,
00146   DnsSectionAddtional,
00147 } DNS_SECTION;
00148 
00149 
00150 class DnsRecord {
00151   public:
00152     DnsRecord * pNext;
00153     char        pName[MAXDNAME];
00154     WORD        wType;
00155     WORD        wDataLength;
00156 
00157     union {
00158       DWORD               DW;     // flags as DWORD
00159       DNS_RECORD_FLAGS    S;      // flags as structure
00160     } Flags;
00161 
00162     union {
00163       DNS_A_DATA     A;
00164       DNS_MX_DATA    MX;
00165       DNS_PTR_DATA   NS;
00166       DNS_SRV_DATA   SRV;
00167       DNS_NULL_DATA  Null;
00168     } Data;
00169 };
00170 
00171 typedef DnsRecord * PDNS_RECORD;
00172 
00173 extern void DnsRecordListFree(PDNS_RECORD rec, int FreeType);
00174 
00175 extern DNS_STATUS DnsQuery_A(const char * service,
00176                       WORD requestType,
00177                       DWORD options,
00178                       void *,
00179                       PDNS_RECORD * results,
00180                       void *);
00181 
00182 
00183 #endif // P_HAS_RESOLVER
00184 
00185 namespace PDNS {
00186 
00188 //
00189 //  this template automates the creation of a list of records for
00190 //  a specific type of DNS lookup
00191 //
00192 
00193 template <unsigned type, class RecordListType, class RecordType>
00194 BOOL Lookup(const PString & name, RecordListType & recordList)
00195 {
00196   if (name.IsEmpty())
00197     return FALSE;
00198 
00199   recordList.RemoveAll();
00200 
00201   PDNS_RECORD results = NULL;
00202   DNS_STATUS status = DnsQuery_A((const char *)name, 
00203                                  type,
00204                                  DNS_QUERY_STANDARD, 
00205                                  NULL, 
00206                                  &results, 
00207                                  NULL);
00208   if (status != 0)
00209     return FALSE;
00210 
00211   // find records matching the correct type
00212   PDNS_RECORD dnsRecord = results;
00213   while (dnsRecord != NULL) {
00214     RecordType * record = recordList.HandleDNSRecord(dnsRecord, results);
00215     if (record != NULL)
00216       recordList.Append(record);
00217     dnsRecord = dnsRecord->pNext;
00218   }
00219 
00220   if (results != NULL)
00221     DnsRecordListFree(results, DnsFreeRecordList);
00222 
00223   return recordList.GetSize() != 0;
00224 }
00225 
00227 
00228 class SRVRecord : public PObject
00229 {
00230   PCLASSINFO(SRVRecord, PObject);
00231   public:
00232     SRVRecord()
00233     { used = FALSE; }
00234 
00235     Comparison Compare(const PObject & obj) const;
00236     void PrintOn(ostream & strm) const;
00237 
00238     PString            hostName;
00239     PIPSocket::Address hostAddress;
00240     BOOL               used;
00241     WORD port;
00242     WORD priority;
00243     WORD weight;
00244 };
00245 
00246 PDECLARE_SORTED_LIST(SRVRecordList, PDNS::SRVRecord)
00247   public:
00248     void PrintOn(ostream & strm) const;
00249 
00250     SRVRecord * GetFirst();
00251     SRVRecord * GetNext();
00252 
00253     PDNS::SRVRecord * HandleDNSRecord(PDNS_RECORD dnsRecord, PDNS_RECORD results);
00254 
00255   protected:
00256     PINDEX     priPos;
00257     PWORDArray priList;
00258 };
00259 
00264 inline BOOL GetRecords(const PString & service, SRVRecordList & serviceList)
00265 { return Lookup<DNS_TYPE_SRV, SRVRecordList, SRVRecord>(service, serviceList); }
00266 
00270 inline BOOL GetSRVRecords(
00271       const PString & service,
00272       SRVRecordList & serviceList
00273 )
00274 { return GetRecords(service, serviceList); }
00275 
00280 BOOL GetSRVRecords(
00281       const PString & service,
00282       const PString & type,
00283       const PString & domain,
00284       SRVRecordList & serviceList
00285 );
00286 
00288 
00289 class MXRecord : public PObject
00290 {
00291   PCLASSINFO(MXRecord, PObject);
00292   public:
00293     MXRecord()
00294     { used = FALSE; }
00295     Comparison Compare(const PObject & obj) const;
00296     void PrintOn(ostream & strm) const;
00297 
00298     PString            hostName;
00299     PIPSocket::Address hostAddress;
00300     BOOL               used;
00301     WORD               preference;
00302 };
00303 
00304 PDECLARE_SORTED_LIST(MXRecordList, PDNS::MXRecord)
00305   public:
00306     void PrintOn(ostream & strm) const;
00307 
00308     MXRecord * GetFirst();
00309     MXRecord * GetNext();
00310 
00311     PDNS::MXRecord * HandleDNSRecord(PDNS_RECORD dnsRecord, PDNS_RECORD results);
00312 
00313   protected:
00314     PINDEX lastIndex;
00315 };
00316 
00320 inline BOOL GetRecords(
00321       const PString & domain,
00322       MXRecordList & serviceList
00323 )
00324 { return Lookup<DNS_TYPE_MX, MXRecordList, MXRecord>(domain, serviceList); }
00325 
00329 inline BOOL GetMXRecords(
00330       const PString & domain,
00331       MXRecordList & serviceList
00332 )
00333 {
00334   return GetRecords(domain, serviceList);
00335 }
00336 
00338 
00339 }; // namespace PDNS
00340 
00341 #endif // _PDNS_H
00342 #endif // P_DNS
00343 
00344 // End Of File ///////////////////////////////////////////////////////////////

Generated on Wed Sep 28 10:27:33 2005 for PWLib by  doxygen 1.4.4