www.pudn.com > DSPSample.rar > DNS.h


#ifndef DNS_QUERY_PORT 
	#include "StdAfx.h" 
 
	#define DNS_QUERY_PORT		53				//DNS服务器的监听端口 
	#define DNSPACKET_BUFFSIZE	512				//DNSPACKET数据缓冲区的尺寸 
	#define DNS_SRV_ADDR		"202.96.128.68"	//DNS服务器的IP地址 
 
	 
class DNS 
{ 
private: 
	DNS(){}; 
public: 
	enum _DNSCLASS 
	{ 
		classIN = 1, 
		classCS, 
		classCH, 
		classHS, 
		classANY=255 
	}; 
 
	enum _DNSTYPE 
	{ 
		//定义DNS类型 
		typeA = 1, 
		typeNS, 
		typeMD, 
		typeMF, 
		typeCNAME, 
		typeSOA, 
		typeMB, 
		typeMG, 
		typeMR, 
		typeNULL, 
		typeWKS, 
		typePTR, 
		typeHINFO, 
		typeMINFO, 
		typeMX, 
		typeTXT, 
		typeAXFR = 252, 
		typeMAILB, 
		typeMAILA, 
		typeAll 
	}; 
 
	struct _DNSHEADER 
	{ 
		//DNS头 
		USHORT	id; 
		 
		USHORT	RD		: 1; 
		USHORT	TC		: 1; 
		USHORT	AA		: 1; 
		USHORT	Opcode	: 4; 
		USHORT	QR		: 1; 
		 
		USHORT	RCODE	: 4; 
		USHORT	Z		: 3; 
		USHORT	RA		: 1; 
		 
		USHORT	QDCOUNT;		//Count of Queryes 
		USHORT	ANCOUNT;		//Count of Answers 
		USHORT	NSCOUNT;		//Count of NameServer 
		USHORT	ARCOUNT;		//Count of Address Records(A记录) 
	public: 
		_DNSHEADER() 
		{ 
			memset(this, 0, sizeof(this)); 
		} 
		inline void Normalize() 
		{ 
			//从字节序转变成网络序或逆转 
			QDCOUNT = htons(QDCOUNT); 
			ANCOUNT = htons(ANCOUNT); 
			NSCOUNT = htons(NSCOUNT); 
			ARCOUNT = htons(ARCOUNT); 
		} 
	}; 
 
	struct _DNSRR; 
	struct _DNSQUESTION; 
	 
	struct _MXRECORD 
	{ 
		char			*lpSrvName; 
		char			*lpSrvAddr; 
		int				nSrvNameLen; 
		int				nSrvAddrLen; 
		unsigned long	ip; 
 
		_MXRECORD():lpSrvName(NULL),lpSrvAddr(NULL){}; 
		~_MXRECORD() 
		{ 
			Empty(); 
		}; 
		 
		inline void Empty() 
		{ 
			if(lpSrvName!=NULL) 
			{	 
				::free(lpSrvName); 
				lpSrvName	=NULL; 
			} 
			if(lpSrvAddr!=NULL) 
			{ 
				::free(lpSrvAddr); 
				lpSrvAddr	=NULL; 
			} 
		}; 
		inline bool Fill(_DNSRR& dr); 
	}; 
 
	struct _DNSPACKET 
	{ 
		//DNS包 
	public: 
		_DNSHEADER	Header; 
	private: 
		char		pvtData[DNSPACKET_BUFFSIZE-sizeof(_DNSHEADER)]; 
		char		mxName[DNSPACKET_BUFFSIZE-sizeof(_DNSHEADER)]; 
		USHORT		mxNameLen; 
		 
		inline bool	IsInMXName(const char* const lpSrv); 
	public: 
		USHORT Offset; 
		 
		_DNSPACKET()		{Header.id	= 0;Empty();}; 
		inline	void	Normalize()	{Header.Normalize();} 
		inline	int		Empty(); 
 
		inline	bool	QueryDNSServer(SOCKET sock,char* const lpHost,const struct sockaddr_in FAR * lphDnsSrv,_DNSTYPE type=typeAll,_DNSCLASS dnsClass=classIN); 
		inline	bool	WaitRecvFromDNSServer(SOCKET sock,struct sockaddr_in FAR* from,int nSeconds=2); 
		inline	bool	GetDNSQuestion(_DNSQUESTION& dq); 
		inline	bool	GetDNSRR(_DNSRR& dr); 
		inline	bool	GetMXHostSet(char* const lpSrvName,char* const lpDnsSrv=DNS_SRV_ADDR,int nCount=5); 
		inline	bool	GetMX(_MXRECORD& mr); 
		inline	struct hostent FAR * GetMXHost(); 
 
		//重载操作符BYTE*() 
		inline operator BYTE*()			{return (BYTE*)this;}; 
		inline USHORT	GetSize()const	{return DNSPACKET_BUFFSIZE;}; 
	}; 
 
	struct _QNAME 
	{ 
		//DNS字符串结构,保存名字 
		char	Data[DNSPACKET_BUFFSIZE]; 
	public: 
		USHORT		Offset; 
		 
		inline	void Empty() 
		{ 
			memset(Data, 0, sizeof(Data)); 
			Offset = 0; 
		} 
		 
		_QNAME()	{Empty();	}; 
		inline	USHORT GetSize()const {return Offset+1;	}; 
		 
		inline	int		Add(LPCSTR str); 
		inline	char*	Get(int& nLen); 
		inline	bool	Add(_DNSPACKET& dns, USHORT& nOffset); 
		inline	bool	Fill(_DNSPACKET& dns, USHORT& nOffset); 
	}; 
	 
	struct _DNSA 
	{ 
		//DNS地址 
		long	addr; 
 
		_DNSA() 
		{ 
			addr = 0; 
		} 
		inline	void _DNSA::Normalize() 
		{ 
			//将地址由字节序转换为网络序 
			addr = htonl(addr); 
		} 
		 
		inline	bool	Add(_DNSPACKET& dns, USHORT& nOffset); 
		inline	bool	Fill(_DNSPACKET& dns, USHORT& nOffset); 
	}; 
	 
	struct _DNSNS 
	{ 
		//DNS服务器的名字 
		_QNAME	Server; 
		 
	public: 
		inline void Empty() 
		{ 
			Server.Empty(); 
		} 
		 
		_DNSNS() 
		{ 
			Empty(); 
		} 
		 
		inline bool Fill(_DNSPACKET& dns, USHORT& nOffset) 
		{ 
			return Server.Fill(dns, nOffset); 
		} 
		 
		inline bool Add(_DNSPACKET& dns, USHORT& nOffset) 
		{ 
			return Server.Add(dns, nOffset); 
		} 
	}; 
	 
	struct _DNSMX 
	{ 
		//MX记录 
		USHORT	Reference; 
		_QNAME	Exchange; 
		 
	public: 
		_DNSMX() 
		{ 
			Empty(); 
		} 
		inline	void Empty() 
		{ 
			Reference = 0; 
			Exchange.Empty(); 
		} 
		inline	void Normalize() 
		{ 
			//转变字节序为网络序 
			Reference	= htons(Reference); 
		} 
		 
		inline	bool	Fill(_DNSPACKET& dns, USHORT& nOffset); 
		inline	bool	Add(_DNSPACKET& dns, USHORT& nOffset); 
	}; 
	 
	struct _DNSSOA 
	{ 
		_QNAME	mName; 
		_QNAME	rName; 
		long	Serial; 
		long	Refresh; 
		long	Retry; 
		long	Expire; 
		long	Minimum; 
		 
	public: 
		_DNSSOA() 
		{ 
			Empty(); 
		} 
		inline	void Empty() 
		{ 
			mName.Empty(); 
			rName.Empty(); 
			memset(&Serial, 0, 5*4); 
		} 
		inline	void Normalize() 
		{ 
			Serial	= htonl(Serial); 
			Refresh = htonl(Refresh); 
			Retry	= htonl(Retry); 
			Expire	= htonl(Expire); 
			Minimum	= htonl(Minimum); 
		} 
		 
		inline	bool	Fill(_DNSPACKET& dns, USHORT& nOffset); 
		inline	bool	Add(_DNSPACKET& dns, USHORT& nOffset); 
	}; 
	 
	struct _DNSQUESTION 
	{ 
	public: 
		_QNAME		qName; 
		_DNSTYPE	Type; 
		_DNSCLASS	Class; 
	public: 
		_DNSQUESTION() 
		{ 
			Empty(); 
		} 
		inline	void Empty() 
		{ 
			qName.Empty(); 
			Type	= typeAll; 
			Class	= classANY; 
		} 
		inline	void _DNSQUESTION::Normalize() 
		{ 
			Type  = (_DNSTYPE)htons(Type); 
			Class = (_DNSCLASS)htons(Class); 
		} 
		 
		inline	bool	Add(_DNSPACKET& dns, USHORT& nOffset); 
		inline	bool	Fill(_DNSPACKET& dns, USHORT& nOffset); 
		inline	USHORT	GetSize()const{return qName.GetSize() + 4;}; 
	}; 
	 
	struct _DNSRR 
	{ 
		_DNSQUESTION	q; 
		long			ttl; 
		USHORT			rDataLen; 
		BYTE*			rData; 
	public: 
		_DNSPACKET*		pDns; 
		USHORT			Offset; 
	public: 
		_DNSRR(_DNSPACKET& rDns) 
		{ 
			pDns		= &rDns; 
			rData		= NULL; 
			Empty(); 
		} 
		~_DNSRR() 
		{ 
			Empty(); 
		} 
		inline	void Normalize() 
		{ 
			q.Normalize(); 
			ttl		= htonl(ttl); 
			rDataLen= htons(rDataLen); 
		} 
		 
		inline	void	Empty(); 
		inline	bool	Add(_DNSPACKET& dns, USHORT& nOffset); 
		inline	bool	Fill(_DNSPACKET& dns, USHORT& nOffset); 
		inline	bool	GetDNSRecord(_DNSSOA& ds); 
		inline	bool	GetDNSRecord(_DNSNS& dn); 
		inline	bool	GetDNSRecord(_DNSMX& dm); 
		inline	bool	GetDNSRecord(_DNSA& da); 
 
		inline USHORT	GetSize()const{return rDataLen;}; 
	}; 
 
	static SOCKET CreateDNSSocket(char *lpDnsSrv,struct sockaddr_in& hDnsSrv); 
}; 
 
#endif