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.11  2006/02/26 11:51:20  csoutheren
00028  * Extended DNS test program to include URL based SRV lookups
00029  * Re-arranged SRV lookup code to allow access to internal routine
00030  * Reformatted code
00031  *
00032  * Revision 1.10  2006/02/26 09:26:17  shorne
00033  * Added DNS SRV record lookups
00034  *
00035  * Revision 1.9  2005/11/30 12:47:37  csoutheren
00036  * Removed tabs, reformatted some code, and changed tags for Doxygen
00037  *
00038  * Revision 1.8  2004/06/24 07:36:24  csoutheren
00039  * Added definitions of T_SRV and T_NAPTR for hosts that do not have these
00040  *
00041  * Revision 1.7  2004/05/31 12:49:47  csoutheren
00042  * Added handling of unknown DNS types
00043  *
00044  * Revision 1.6  2004/05/28 06:50:42  csoutheren
00045  * Reorganised DNS functions to use templates, and exposed more internals to allow new DNS lookup types to be added
00046  *
00047  * Revision 1.5  2003/07/22 23:52:20  dereksmithies
00048  * Fix from Fabrizio Ammollo to cope with when P_DNS is disabled. Thanks!
00049  *
00050  * Revision 1.4  2003/04/16 07:02:55  robertj
00051  * Cleaned up source.
00052  *
00053  * Revision 1.3  2003/04/15 08:14:06  craigs
00054  * Added single string form of GetSRVRecords
00055  *
00056  * Revision 1.2  2003/04/15 08:06:24  craigs
00057  * Added Unix implementation
00058  *
00059  * Revision 1.1  2003/04/15 04:06:56  craigs
00060  * Initial version
00061  *
00062  */
00063 
00064 #if P_DNS
00065 #ifndef _PDNS_H
00066 #define _PDNS_H
00067 
00068 #ifdef P_USE_PRAGMA
00069 #pragma interface
00070 #endif
00071 
00072 #include <ptlib/sockets.h>
00073 
00074 #include <ptclib/random.h>
00075 #include <ptclib/url.h>
00076 
00077 #if defined(_WIN32)
00078 
00079 #  include <windns.h>
00080 #  pragma comment(lib, P_DNS_LIBRARY)
00081 
00082 #else
00083 
00084 #  define  P_HAS_RESOLVER 1         // set if using Unix-style DNS routines
00085 #  include <arpa/nameser.h>
00086 #  include <resolv.h>
00087 #  if defined(P_MACOSX) && (P_MACOSX >= 700)
00088 #    include <arpa/nameser_compat.h>
00089 #  endif
00090 
00091 #endif  // _WIN32
00092 
00093 #ifdef P_HAS_RESOLVER
00094 
00096 //
00097 // these classes provide an emulation of the Microsoft DNS API 
00098 // on non-Window systems
00099 //
00100 
00101 #ifndef T_SRV
00102 #define T_SRV   33
00103 #endif
00104 
00105 #ifndef T_NAPTR
00106 #define T_NAPTR   35
00107 #endif
00108 
00109 
00110 #define DNS_STATUS  int
00111 #define DNS_TYPE_SRV  T_SRV
00112 #define DNS_TYPE_MX  T_MX
00113 #define DNS_TYPE_A  T_A
00114 #define DNS_TYPE_NAPTR  T_NAPTR
00115 #define DnsFreeRecordList 0
00116 #define DNS_QUERY_STANDARD 0
00117 #define DNS_QUERY_BYPASS_CACHE 0
00118 
00119 typedef struct _DnsAData {
00120   DWORD IpAddress;
00121 } DNS_A_DATA;
00122 
00123 typedef struct {
00124   char   pNameExchange[MAXDNAME];
00125   WORD   wPreference;
00126 } DNS_MX_DATA;
00127 
00128 typedef struct {
00129   char pNameHost[MAXDNAME];
00130 } DNS_PTR_DATA;
00131 
00132 typedef struct _DnsSRVData {
00133   char   pNameTarget[MAXDNAME];
00134   WORD   wPriority;
00135   WORD   wWeight;
00136   WORD   wPort;
00137 } DNS_SRV_DATA;
00138 
00139 typedef struct _DnsNULLData {
00140   DWORD  dwByteCount;
00141   char   data[1];
00142 } DNS_NULL_DATA;
00143 
00144 typedef struct _DnsRecordFlags
00145 {
00146   unsigned   Section     : 2;
00147   unsigned   Delete      : 1;
00148   unsigned   CharSet     : 2;
00149   unsigned   Unused      : 3;
00150   unsigned   Reserved    : 24;
00151 } DNS_RECORD_FLAGS;
00152 
00153 typedef enum _DnsSection
00154 {
00155   DnsSectionQuestion,
00156   DnsSectionAnswer,
00157   DnsSectionAuthority,
00158   DnsSectionAddtional,
00159 } DNS_SECTION;
00160 
00161 
00162 class DnsRecord {
00163   public:
00164     DnsRecord * pNext;
00165     char        pName[MAXDNAME];
00166     WORD        wType;
00167     WORD        wDataLength;
00168 
00169     union {
00170       DWORD               DW;     
00171       DNS_RECORD_FLAGS    S;      
00172     } Flags;
00173 
00174     union {
00175       DNS_A_DATA     A;
00176       DNS_MX_DATA    MX;
00177       DNS_PTR_DATA   NS;
00178       DNS_SRV_DATA   SRV;
00179       DNS_NULL_DATA  Null;
00180     } Data;
00181 };
00182 
00183 typedef DnsRecord * PDNS_RECORD;
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           void *,
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 BOOL 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                                  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     BOOL               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 BOOL GetRecords(const PString & service, SRVRecordList & serviceList)
00277 { return Lookup<DNS_TYPE_SRV, SRVRecordList, SRVRecord>(service, serviceList); }
00278 
00282 inline BOOL GetSRVRecords(
00283       const PString & service,
00284       SRVRecordList & serviceList
00285 )
00286 { return GetRecords(service, serviceList); }
00287 
00292 BOOL GetSRVRecords(
00293       const PString & service,
00294       const PString & type,
00295       const PString & domain,
00296       SRVRecordList & serviceList
00297 );
00298 
00304 BOOL LookupSRV( 
00305          const PString & domain,                  
00306          const PString & service,                 
00307                     WORD defaultPort,             
00308          PIPSocketAddressAndPortVector & addrList 
00309 );  
00310 
00311 BOOL LookupSRV( 
00312          const PURL & url,          
00313          const PString & service,   
00314          PStringList & returnStr    
00315 );  
00316 
00318 
00319 class MXRecord : public PObject
00320 {
00321   PCLASSINFO(MXRecord, PObject);
00322   public:
00323     MXRecord()
00324     { used = FALSE; }
00325     Comparison Compare(const PObject & obj) const;
00326     void PrintOn(ostream & strm) const;
00327 
00328     PString            hostName;
00329     PIPSocket::Address hostAddress;
00330     BOOL               used;
00331     WORD               preference;
00332 };
00333 
00334 PDECLARE_SORTED_LIST(MXRecordList, PDNS::MXRecord)
00335   public:
00336     void PrintOn(ostream & strm) const;
00337 
00338     MXRecord * GetFirst();
00339     MXRecord * GetNext();
00340 
00341     PDNS::MXRecord * HandleDNSRecord(PDNS_RECORD dnsRecord, PDNS_RECORD results);
00342 
00343   protected:
00344     PINDEX lastIndex;
00345 };
00346 
00350 inline BOOL GetRecords(
00351       const PString & domain,
00352       MXRecordList & serviceList
00353 )
00354 { return Lookup<DNS_TYPE_MX, MXRecordList, MXRecord>(domain, serviceList); }
00355 
00359 inline BOOL GetMXRecords(
00360       const PString & domain,
00361       MXRecordList & serviceList
00362 )
00363 {
00364   return GetRecords(domain, serviceList);
00365 }
00366 
00368 
00369 }; // namespace PDNS
00370 
00371 #endif // _PDNS_H
00372 #endif // P_DNS
00373 
00374 // End Of File ///////////////////////////////////////////////////////////////

Generated on Mon Sep 1 09:41:07 2008 for PWLib by  doxygen 1.5.6