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

Generated on Thu Jun 15 15:24:28 2006 for PWLib by  doxygen 1.4.2