/* * pdns.h * * PWLib library for DNS lookup services * * Portable Windows Library * * Copyright (c) 2003 Equivalence Pty. Ltd. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Contributor(s): ______________________________________. * * $Log: pdns.h,v $ * Revision 1.9.2.1 2006/03/12 21:14:47 dsandras * Backports from HEAD. * * Revision 1.11 2006/02/26 11:51:20 csoutheren * Extended DNS test program to include URL based SRV lookups * Re-arranged SRV lookup code to allow access to internal routine * Reformatted code * * Revision 1.10 2006/02/26 09:26:17 shorne * Added DNS SRV record lookups * * Revision 1.9 2005/11/30 12:47:37 csoutheren * Removed tabs, reformatted some code, and changed tags for Doxygen * * Revision 1.8 2004/06/24 07:36:24 csoutheren * Added definitions of T_SRV and T_NAPTR for hosts that do not have these * * Revision 1.7 2004/05/31 12:49:47 csoutheren * Added handling of unknown DNS types * * Revision 1.6 2004/05/28 06:50:42 csoutheren * Reorganised DNS functions to use templates, and exposed more internals to allow new DNS lookup types to be added * * Revision 1.5 2003/07/22 23:52:20 dereksmithies * Fix from Fabrizio Ammollo to cope with when P_DNS is disabled. Thanks! * * Revision 1.4 2003/04/16 07:02:55 robertj * Cleaned up source. * * Revision 1.3 2003/04/15 08:14:06 craigs * Added single string form of GetSRVRecords * * Revision 1.2 2003/04/15 08:06:24 craigs * Added Unix implementation * * Revision 1.1 2003/04/15 04:06:56 craigs * Initial version * */ #if P_DNS #ifndef _PDNS_H #define _PDNS_H #ifdef P_USE_PRAGMA #pragma interface #endif #include #include #include #if defined(_WIN32) # include # pragma comment(lib, P_DNS_LIBRARY) #else # define P_HAS_RESOLVER 1 // set if using Unix-style DNS routines # include # include # if defined(P_MACOSX) && (P_MACOSX >= 700) # include # endif #endif // _WIN32 #ifdef P_HAS_RESOLVER ////////////////////////////////////////////////////////////////////////// // // these classes provide an emulation of the Microsoft DNS API // on non-Window systems // #ifndef T_SRV #define T_SRV 33 #endif #ifndef T_NAPTR #define T_NAPTR 35 #endif #define DNS_STATUS int #define DNS_TYPE_SRV T_SRV #define DNS_TYPE_MX T_MX #define DNS_TYPE_A T_A #define DNS_TYPE_NAPTR T_NAPTR #define DnsFreeRecordList 0 #define DNS_QUERY_STANDARD 0 #define DNS_QUERY_BYPASS_CACHE 0 typedef struct _DnsAData { DWORD IpAddress; } DNS_A_DATA; typedef struct { char pNameExchange[MAXDNAME]; WORD wPreference; } DNS_MX_DATA; typedef struct { char pNameHost[MAXDNAME]; } DNS_PTR_DATA; typedef struct _DnsSRVData { char pNameTarget[MAXDNAME]; WORD wPriority; WORD wWeight; WORD wPort; } DNS_SRV_DATA; typedef struct _DnsNULLData { DWORD dwByteCount; char data[1]; } DNS_NULL_DATA; typedef struct _DnsRecordFlags { unsigned Section : 2; unsigned Delete : 1; unsigned CharSet : 2; unsigned Unused : 3; unsigned Reserved : 24; } DNS_RECORD_FLAGS; typedef enum _DnsSection { DnsSectionQuestion, DnsSectionAnswer, DnsSectionAuthority, DnsSectionAddtional, } DNS_SECTION; class DnsRecord { public: DnsRecord * pNext; char pName[MAXDNAME]; WORD wType; WORD wDataLength; union { DWORD DW; ///< flags as DWORD DNS_RECORD_FLAGS S; ///< flags as structure } Flags; union { DNS_A_DATA A; DNS_MX_DATA MX; DNS_PTR_DATA NS; DNS_SRV_DATA SRV; DNS_NULL_DATA Null; } Data; }; typedef DnsRecord * PDNS_RECORD; extern void DnsRecordListFree(PDNS_RECORD rec, int FreeType); extern DNS_STATUS DnsQuery_A(const char * service, WORD requestType, DWORD options, void *, PDNS_RECORD * results, void *); #endif // P_HAS_RESOLVER namespace PDNS { ////////////////////////////////////////////////////////////////////////// // // this template automates the creation of a list of records for // a specific type of DNS lookup // template BOOL Lookup(const PString & name, RecordListType & recordList) { if (name.IsEmpty()) return FALSE; recordList.RemoveAll(); PDNS_RECORD results = NULL; DNS_STATUS status = DnsQuery_A((const char *)name, type, DNS_QUERY_STANDARD, NULL, &results, NULL); if (status != 0) return FALSE; // find records matching the correct type PDNS_RECORD dnsRecord = results; while (dnsRecord != NULL) { RecordType * record = recordList.HandleDNSRecord(dnsRecord, results); if (record != NULL) recordList.Append(record); dnsRecord = dnsRecord->pNext; } if (results != NULL) DnsRecordListFree(results, DnsFreeRecordList); return recordList.GetSize() != 0; } ///////////////////////////////////////////////////////////// class SRVRecord : public PObject { PCLASSINFO(SRVRecord, PObject); public: SRVRecord() { used = FALSE; } Comparison Compare(const PObject & obj) const; void PrintOn(ostream & strm) const; PString hostName; PIPSocket::Address hostAddress; BOOL used; WORD port; WORD priority; WORD weight; }; PDECLARE_SORTED_LIST(SRVRecordList, PDNS::SRVRecord) public: void PrintOn(ostream & strm) const; SRVRecord * GetFirst(); SRVRecord * GetNext(); PDNS::SRVRecord * HandleDNSRecord(PDNS_RECORD dnsRecord, PDNS_RECORD results); protected: PINDEX priPos; PWORDArray priList; }; /** * return a list of DNS SRV record with the specified service type */ inline BOOL GetRecords(const PString & service, SRVRecordList & serviceList) { return Lookup(service, serviceList); } /** * provided for backwards compatibility */ inline BOOL GetSRVRecords( const PString & service, SRVRecordList & serviceList ) { return GetRecords(service, serviceList); } /** * return a list of DNS SRV record with the specified service, type and domain */ BOOL GetSRVRecords( const PString & service, const PString & type, const PString & domain, SRVRecordList & serviceList ); /** * Perform a DNS lookup of the specified service * @return TRUE if the service could be resolved, else FALSE */ BOOL LookupSRV( const PString & domain, ///< domain to lookup const PString & service, ///< service to use WORD defaultPort, ///< default por to use PIPSocketAddressAndPortVector & addrList ///< returned list of sockets and ports ); BOOL LookupSRV( const PURL & url, ///< URL to lookup const PString & service, ///< service to use PStringList & returnStr ///< resolved addresses, if return value is TRUE ); //////////////////////////////////////////////////////////////// class MXRecord : public PObject { PCLASSINFO(MXRecord, PObject); public: MXRecord() { used = FALSE; } Comparison Compare(const PObject & obj) const; void PrintOn(ostream & strm) const; PString hostName; PIPSocket::Address hostAddress; BOOL used; WORD preference; }; PDECLARE_SORTED_LIST(MXRecordList, PDNS::MXRecord) public: void PrintOn(ostream & strm) const; MXRecord * GetFirst(); MXRecord * GetNext(); PDNS::MXRecord * HandleDNSRecord(PDNS_RECORD dnsRecord, PDNS_RECORD results); protected: PINDEX lastIndex; }; /** * return a list of MX records for the specified domain */ inline BOOL GetRecords( const PString & domain, MXRecordList & serviceList ) { return Lookup(domain, serviceList); } /** * provided for backwards compatibility */ inline BOOL GetMXRecords( const PString & domain, MXRecordList & serviceList ) { return GetRecords(domain, serviceList); } /////////////////////////////////////////////////////////////////////////// }; // namespace PDNS #endif // _PDNS_H #endif // P_DNS // End Of File ///////////////////////////////////////////////////////////////