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

Generated on Fri Sep 21 14:40:11 2007 for PWLib by  doxygen 1.5.3