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

Generated on Fri Mar 7 06:25:02 2008 for PTLib by  doxygen 1.5.1