// // File: hzDNS.h // // Legal Notice: This file is part of the HadronZoo C++ Class Library. // // Copyright 2025 HadronZoo Project (http://www.hadronzoo.com) // // The HadronZoo C++ Class Library is free software: You can redistribute it, and/or modify it under the terms of the GNU Lesser General Public License, as published by the Free // Software Foundation, either version 3 of the License, or any later version. // // The HadronZoo C++ Class Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR // A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with the HadronZoo C++ Class Library. If not, see http://www.gnu.org/licenses. //
// // The primary purpose for the hzDNS class is too facilitate DNS lookup //
#ifndef hzDNS_h #define hzDNS_h
#include "hzChain.h" #include "hzTmplList.h" #include "hzIpaddr.h"
enum DnsType { // Category: Internet // // Main types (from RFC 1035)
DNSTYPE_A = 1, // a host address DNSTYPE_NS = 2, // an authoritative name server DNSTYPE_MD = 3, // a mail destination (Obsolete - use MX) DNSTYPE_MF = 4, // a mail forwarder (Obsolete - use MX) DNSTYPE_CNAME = 5, // the canonical name for an alias DNSTYPE_SOA = 6, // marks the start of a zone of authority DNSTYPE_MB = 7, // a mailbox domain name (EXPERIMENTAL) DNSTYPE_MG = 8, // a mail group member (EXPERIMENTAL) DNSTYPE_MR = 9, // a mail rename domain name (EXPERIMENTAL) DNSTYPE_NULL = 10, // a null RR (EXPERIMENTAL) DNSTYPE_WKS = 11, // a well known service description DNSTYPE_PTR = 12, // a domain name pointer DNSTYPE_HINFO = 13, // host information DNSTYPE_MINFO = 14, // mailbox or mail list information DNSTYPE_MX = 15, // mail exchange DNSTYPE_TXT = 16, // text strings
// From RFC 1183 DNSTYPE_RP = 17, // for Responsible Person DNSTYPE_AFSDB = 18, // for AFS Data Base location DNSTYPE_X25 = 19, // for X.25 PSDN address DNSTYPE_ISDN = 20, // for ISDN address DNSTYPE_RT = 21, // for Route Through
// Others DNSTYPE_NSAP = 22, // for NSAP address, NSAP style A record (RFC1706) DNSTYPE_NSAP_PTR = 23, // Not sure! DNSTYPE_SIG = 24, // for security signature (RFC2535, RFC3755, RFC4034) DNSTYPE_KEY = 25, // for security key (RFC2535, RFC3755, RFC4034) DNSTYPE_PX = 26, // X.400 mail mapping information (RFC2163) DNSTYPE_GPOS = 27, // Geographical Position (RFC1712) DNSTYPE_AAAA = 28, // IP6 Address (RFC3596) DNSTYPE_LOC = 29, // Location Information (RFC1876) DNSTYPE_NXT = 30, // Next Domain - OBSOLETE (RFC2535, RFC3755) DNSTYPE_EID = 31, // Endpoint Identifier (Patton) DNSTYPE_NIMLOC = 32, // Nimrod Locator (Patton) DNSTYPE_SRV = 33, // Server Selection (RFC2782) DNSTYPE_ATMA = 34, // ATM Address (Dobrowski) DNSTYPE_NAPTR = 35, // Naming Authority Pointer (RFC2168, RFC2915) DNSTYPE_KX = 36, // Key Exchanger (RFC2230) DNSTYPE_CERT = 37, // CERT (RFC2538) DNSTYPE_A6 = 38, // IPV6 (RFC2874, RFC3226) DNSTYPE_DNAME = 39, // DNAME (RFC2672) DNSTYPE_SINK = 40, // SINK (Eastlake) DNSTYPE_OPT = 41, // OPT (RFC2671) DNSTYPE_APL = 42, // APL (RFC3123) DNSTYPE_DS = 43, // Delegation Signer (RFC3658) DNSTYPE_SSHFP = 44, // SSH Key Fingerprint (RFC4255) DNSTYPE_IPSECKEY = 45, // IPSECKEY (RFC4025) DNSTYPE_RRSIG = 46, // RRSIG (RFC3755) DNSTYPE_NSEC = 47, // NSEC (RFC3755) DNSTYPE_DNSKEY = 48, // DNSKEY (RFC3755) DNSTYPE_DHCID = 49, // DHCID (RFC4701) DNSTYPE_HIP = 55, // Host Identity Protocol (RFC-ietf-hip-dns-09.txt) DNSTYPE_SPF = 99, // Oh no, not these! (RFC4408) DNSTYPE_UINFO = 100, // IANA-Reserved DNSTYPE_UID = 101, // IANA-Reserved DNSTYPE_GID = 102, // IANA-Reserved DNSTYPE_UNSPEC = 103, // IANA-Reserved DNSTYPE_TKEY = 249, // Transaction Key (RFC2930) DNSTYPE_TSIG = 250, // Transaction Signature (RFC2845) DNSTYPE_IXFR = 251, // incremental transfer (RFC1995) DNSTYPE_AXFR = 252, // transfer of an entire zone (RFC1035) DNSTYPE_MAILB = 253, // mailbox-related RRs (MB, MG or MR) (RFC1035) DNSTYPE_MAILA = 254, // mail agent RRs (Obsolete - see MX) (RFC1035) DNSTYPE_GLOBAL = 255, // A request for all records (RFC1035) DNSTYPE_TA = 32768, // DNSSEC Trust Authorities (Weiler) DNSTYPE_DLV = 32769, // DNSSEC Lookaside Validation (RFC4431) } ;
/* ** DNS Header */
struct DnsHdr { // Category: Internet // // Used in the interpretation of a DNS query
uint16_t m_nQueryID ; // Useful only if set of records require more than one UDP packet. We send this with next request. uint16_t m_nDNACode ; // Flags for interpretation - currently ignored uint16_t m_nNoQuestions ; // Question count uint16_t m_nNoAnswers ; // Answer count uint16_t m_nNoAuth ; // Name server record count uint16_t m_nNoAdditional ; // Name server record count
void _clear (void) { m_nQueryID = 0 ; m_nDNACode = 0 ; m_nNoQuestions = 0 ; m_nNoAnswers = 0 ; m_nNoAuth = 0 ; m_nNoAdditional = 0 ; }
bool QueryResponse (void) { return m_nDNACode & 0x8000 ? true : false ; } uint32_t OpCode (void) { return (m_nDNACode & 0x7800) >> 11 ; } bool Authoritative (void) { return m_nDNACode & 0x0400 ? true : false ; } bool Truncation (void) { return m_nDNACode & 0x0200 ? true : false ; } bool RecursionDesire (void) { return m_nDNACode & 0x0100 ? true : false ; } bool RecursionAvail (void) { return m_nDNACode & 0x0080 ? true : false ; } uint32_t ResponseCode (void) { return m_nDNACode & 0x000F ; } } ;
/* ** DNS Record */
struct DnsRec { // Category: Internet // // DNS Record - Used in the interpretation of a DNS query
hzString m_Domain ; // Domain name hzString m_Server ; // Server name
hzIpaddr m_Ipa ; // IP address (V4) uint32_t m_anorakA ; // Part of IVP6 uint32_t m_anorakB ; // Part of IVP6 uint32_t m_anorakC ; // Part of IVP6 uint32_t m_anorakD ; // Part of IVP6
uint32_t m_nTTL ; // Time to live uint16_t m_nType ; // Type of record, eg IN uint16_t m_nClass ; // Class of record, eg MX uint16_t m_nLen ; // Record length uint16_t m_nValue ; // Eg MX value
DnsRec (void) { Clear() ; }
~DnsRec (void) { }
void Clear (void) { m_Ipa.Clear() ; m_anorakA = m_anorakB = m_anorakC = m_anorakD = 0 ; m_nTTL = 0 ; m_nType = 0 ; m_nClass = 0 ; m_nLen = 0 ; m_nValue = 0 ; } } ;
struct hzResServer { // Category: Internet // // Cut-down version of a DNS record as used by applications
hzString m_Servername ; // Name of server being queried hzIpaddr m_Ipa ; // IP address (V4) uint32_t m_nTTL ; // Time to live uint16_t m_nValue ; // MX records only uint16_t m_nMisc ; // Reserved
hzResServer (void) { m_nTTL = 0 ; m_nValue = 0 ; m_nMisc = 0 ; } } ;
class hzDNS { // Category: Internet // // The DnsQuery class
uchar* m_cpDns ; // Buffer for DNS output
uint16_t m_qID ; // So we can check this against ID of query uint16_t m_DNA ; // Exactly uint32_t m_Resv ; // Reserved
hzString _procraw (uchar** cpPtr) ; void _clear (void) ;
public: hzList<DnsRec> m_arQus ; // Question section hzList<DnsRec> m_arAns ; // Answer section hzList<DnsRec> m_arAut ; // Authorative section hzList<DnsRec> m_arAdd ; // Additional section hzChain m_Error ; // For error reporting
hzDNS (void) { m_cpDns = 0 ; }
~hzDNS (void) { m_arQus.Clear() ; m_arAns.Clear() ; m_arAut.Clear() ; m_arAdd.Clear() ; delete [] m_cpDns ; }
hzEcode Query (const char* dom, DnsType eType) ; hzEcode SelectMX (hzList<hzResServer>& ServersMX, const char* dom) ;
hzEcode QueryA (const char* dom) { return Query(dom, DNSTYPE_A) ; } hzEcode QueryPTR (const char* dom) { return Query(dom, DNSTYPE_PTR) ; } hzEcode QueryTXT (const char* dom) { return Query(dom, DNSTYPE_TXT) ; } hzEcode QuerySPF (const char* dom) { return Query(dom, DNSTYPE_SPF) ; } hzEcode QueryMX (const char* dom) { return Query(dom, DNSTYPE_MX) ; }
void Show (hzChain& Result) const ;
uint32_t NoAnswers (void) const { return m_arAns.Count() ; } uint32_t NoAuth (void) const { return m_arAut.Count() ; } uint32_t NoAdditional (void) const { return m_arAdd.Count() ; } } ;
/* ** Prototypes */
hzEcode GetHostByAddr (hzString& Host, const char* cpIPAddr) ;
#endif // hzDNS_h