📄 dns.h
字号:
#if(!defined(__NEURO__DNS__CLIENT__))
#define __NEURO__DNS__CLIENT__
#include "SocketClient.h"
#include "NeuroBuffer.h"
#include <afxtempl.h>
/***********************************************************************
LICENSE AGREEMENT AND POLICY
The following code is provided on AS IS basis, no claim should be made
if the code does any damage, the user using and modifying this code will
be responsible for any kind of damange this code produces.
You can freely distribute, use this code as long as you insert this
Agreement with each distribution.
The code should not be sold at any cases.
-Akash Kava
ackava@hotmail.com
************************************************************************/
/************************************************************************
Name : CDnsBuffer
Type : Class
------------------------------------------------------------------------
Author : Akash Kava
Purpose: Dns Results come in a binary format, length followed
by the data buffer. Complete data buffer is needed
to search Compressed Domain Names in buffer
Dns protocol uses pointers in response to represent
repeated data, by expanding this pointers you will
get full names
************************************************************************/
class CDnsBuffer : public CNeuroBuffer {
public:
// Buffer Pointer Management
void Reset()
{
m_nPointer = 0;
}
int GetPointer()
{
return m_nPointer;
}
int Reset(int n)
{
int nOld = m_nPointer;
m_nPointer = n;
return nOld;
}
void operator = (CDnsBuffer & Buffer)
{
UnsafeClear();
Allocate(Buffer.GetSize());
Copy(Buffer.GetBuffer(),Buffer.GetSize());
}
// Appending Buffer Functions
void operator << (unsigned __int8 c)
{
Append((BYTE *)&c,1);
}
void operator << (unsigned __int16 c)
{
c = htons(c);
Append((BYTE *)&c,2);
}
void operator << (unsigned __int32 c)
{
c = htonl(c);
Append((BYTE*)&c,4);
}
// Extracting Buffer Data, pointer moves ahead
// Throws DNS Exception if pointer out of range
void operator >> (unsigned __int8 & c)
{
Get(&c,1);
}
void operator >> (unsigned __int16 & c)
{
Get(&c,2);
c = ntohs(c);
}
void operator >> (unsigned __int32 & c)
{
Get(&c,4);
c = ntohl(c);
}
void operator ++()
{
m_nPointer ++;
}
void operator += (int n)
{
m_nPointer += n;
}
void Get(LPVOID Buffer,int size)
{
if(m_nPointer+size > m_nSize)
{
CString Text;
Text.Format("Insufficient Data Pointer:%d Size:%d Total:%d",m_nPointer,size,m_nSize);
throw new CSocketException (Text,NULL);
}
memcpy(Buffer,m_pBuffer+m_nPointer,size);
m_nPointer += size;
}
void operator += (CDnsBuffer & Buffer)
{
Append(Buffer.GetBuffer(),Buffer.GetSize());
}
// DNS Name Extraction from buffer , Message Pointer Expansion
// Call this member function with nPointer=0 while reading buffer
// to get domain name.
// This function calls same function recursively to extract message
// from pointers and also sets pointer to next resource data to be read
// This function is carefully designed and implemented, its tested
// perfectly, use it without modifying single line
virtual CString GetName(int nPointer)
{
CString Name;
unsigned __int8 nLen8;
unsigned __int16 nLen16;
int nOldPointer = GetPointer();
if(nPointer!=0)
Reset(nPointer);
do
{
(*this) >> nLen8;
if(nLen8==0)
{
break;
}
// Is this octate message pointer????
if(nLen8 & 0xC0)
{
// YES
nLen8 = nLen8 & 0x3F;
nLen16 = nLen8;
nLen16 <<= 8;
(*this) >> nLen8;
nLen16 |= nLen8;
Name += GetName(nLen16);
if(nPointer != 0)
Reset(nOldPointer);
return Name;
}
else
{
// NO
char * cname = new char [nLen8+1];
memset(cname,0,nLen8+1);
Get(cname,nLen8);
Name += cname;
Name += ".";
}
}while(true);
if(nPointer!=0)
Reset(nOldPointer);
if(!Name.IsEmpty())
{
if(Name.Right(1)==".")
Name = Name.Left(Name.GetLength()-1);
}
return Name;
}
};
/************************************************************************
Name : DnsHeaderFlags
Type : Union
------------------------------------------------------------------------
Author : Akash Kava
Purpose: DNS Header Flags, its 16 bit value
Every bit field is explained below
************************************************************************/
union DnsHeaderFlags{
unsigned __int16 Flag;
struct{
int QR : 1 ;
int OPCODE : 4 ;
int AA : 1 ;
int TC : 1 ;
int RD : 1 ;
int RA : 1 ;
int Z : 3 ;
int RCODE : 4 ;
}Flags;
};
/************************************************************************
Name : CDnsHeader
Type : Class
------------------------------------------------------------------------
Author : Akash Kava
Purpose: DNS Header Class which holds initial
header information
The pack and unpack method interacts with CDnsBuffer
and exchanges data according to protocol in every class
defined below
pack and unpack methods moves buffer pointer as well,
make sure you never write function which passes copy of
buffer rather then reference of buffer, always pass
reference of buffer to maintain integrity
************************************************************************/
class CDnsHeader{
public:
unsigned __int16 ID;
DnsHeaderFlags Flags;
unsigned __int16 QDCount;
unsigned __int16 ANCount;
unsigned __int16 NSCount;
unsigned __int16 ARCount;
void operator = ( CDnsHeader & Header )
{
ID = Header.ID;
Flags.Flag = Header.Flags.Flag;
QDCount = Header.QDCount;
ANCount = Header.ANCount;
NSCount = Header.NSCount;
ARCount = Header.ARCount;
}
CDnsHeader()
{
ID = GetTickCount();
Flags.Flag = 0;
QDCount = 1;
ANCount = 0;
NSCount = 0;
ARCount = 0;
}
CDnsBuffer Pack()
{
CDnsBuffer Buffer;
Buffer << ID;
Buffer << Flags.Flag;
Buffer << QDCount;
Buffer << ANCount;
Buffer << NSCount;
Buffer << ARCount;
return Buffer;
}
void Unpack( CDnsBuffer & Buffer )
{
Buffer >> ID;
Buffer >> Flags.Flag;
Buffer >> QDCount;
Buffer >> ANCount;
Buffer >> NSCount;
Buffer >> ARCount;
}
CString ToString()
{
CString Text;
Text.Format("ID=%d\nQDCount=%d\nANCount=%d\nNSCount=%d\nARCount=%d\n",ID,QDCount,ANCount,NSCount,ARCount);
return Text;
}
};
/************************************************************************
Name : CDnsRR
Type : Class
------------------------------------------------------------------------
Author : Akash Kava
Purpose: DNS Response's Resource Record
This class holds Name,Type,Class,TTL and
Length of RData, RData is Type dependent
which then appears in every derived class
from CDnsRR
The pack and unpack method interacts with CDnsBuffer
and exchanges data according to protocol in every class
defined below.
Please note, pack and unpack methods of all derived
classes of CDnsRR does not call pack and unpack method
of CDnsRR anytime, its your responsibility to first
make object of CDnsRR and then process it with buffer,
make type dependent class of Resource Record and then
process it again for only RData.
Such complex method is designed only to get the
compressed domain names in RData section of Resource
Record
************************************************************************/
class CDnsRR{
public:
CString Name;
unsigned __int16 Type;
unsigned __int16 Class;
unsigned __int32 TTL;
unsigned __int16 Length;
CDnsRR()
{
}
CDnsRR(CDnsRR * pRR)
{
Name = pRR->Name;
Type = pRR->Type;
Class = pRR->Class;
TTL = pRR->TTL;
Length = pRR->Length;
}
CString GetString(int Number)
{
CString strNumber;
strNumber.Format("%d",Number);
return strNumber;
}
virtual void Unpack(CDnsBuffer & Buffer)
{
Name = Buffer.GetName(0);
Buffer >> Type;
Buffer >> Class;
Buffer >> TTL;
Buffer >> Length;
}
virtual CString ToString()
{
CString Text;
Text = "Name=" + Name + "\n";
Text += "TTL=" + GetString(TTL) + "\n";
Text += "TYPE=" + GetString(Type) + "\n";
return Text;
}
virtual void CopyRData(CDnsRR* pRR){
};
};
/************************************************************************
Name : CDnsRRDefault
Type : Class
------------------------------------------------------------------------
Author : Akash Kava
Purpose: All Resource Record types are not programmed here
thats why This class serves as substitute for non-implemented
class types.
************************************************************************/
class CDnsRRDefault: public CDnsRR{
public:
BYTE * pRData;
CDnsRRDefault()
{
pRData = NULL;
}
CDnsRRDefault(CDnsRR * pRR)
: CDnsRR(pRR)
{
pRData = NULL;
}
~CDnsRRDefault()
{
if(pRData)
delete pRData;
}
virtual void Unpack(CDnsBuffer & Buffer)
{
pRData = new BYTE [Length];
Buffer.Get(pRData,Length);
}
virtual void CopyRData(CDnsRR* pRR){
CDnsRRDefault * pRRD = (CDnsRRDefault *)pRR;
pRData = new BYTE[Length];
memcpy(pRData,pRRD->pRData,Length);
};
};
/************************************************************************
Name : CDnsRRMX
Type : Class
------------------------------------------------------------------------
Author : Akash Kava
Purpose: Most widely used DNS class type, for mail exchange
************************************************************************/
class CDnsRRMX : public CDnsRR {
public:
unsigned __int16 Preference;
CString Exchange;
CDnsRRMX(CDnsRR * pRR)
: CDnsRR(pRR)
{
}
void Unpack(CDnsBuffer & Buffer)
{
int nPointer = Buffer.GetPointer();
Buffer >> Preference;
Exchange = Buffer.GetName(0);
Buffer.Reset(nPointer + Length);
}
virtual CString ToString()
{
CString Text;
Text += "MX Record\n";
Text += CDnsRR::ToString();
Text += "Preference=" + GetString(Preference) + "\n";
Text += "Exchange=" + Exchange + "\n\n";
return Text;
}
virtual void CopyRData(CDnsRR* pRR){
CDnsRRMX * pRRMX = (CDnsRRMX*) pRR;
Preference = pRRMX->Preference;
Exchange = pRRMX->Exchange;
}
};
/************************************************************************
Name : CDnsRRCNAME
Type : Class
------------------------------------------------------------------------
Author : Akash Kava
Purpose: Encapsulates Resource Record for Type CNAME
************************************************************************/
class CDnsRRCNAME : public CDnsRR {
public:
CString Name;
CDnsRRCNAME(CDnsRR * pRR)
: CDnsRR(pRR)
{
}
void Unpack(CDnsBuffer & Buffer)
{
Name = Buffer.GetName(0);
}
virtual CString ToString()
{
CString Text;
Text = "CNAME Record:\n";
Text += CDnsRR::ToString();
Text += "CName=" + Name+ "\n\n";
return Text;
}
virtual void CopyRData(CDnsRR* pRR){
CDnsRRCNAME * pRRCNAME = (CDnsRRCNAME*) pRR;
Name = pRRCNAME->Name;
}
};
/************************************************************************
Name : CDnsRRA
Type : Class
------------------------------------------------------------------------
Author : Akash Kava
Purpose: Encapsulates Resource Record for Type A
CString A of this class holds text
representation of IP address like 127.0.0.1
************************************************************************/
class CDnsRRA : public CDnsRR {
public:
CString A;
CDnsRRA(CDnsRR * pRR)
: CDnsRR(pRR)
{
}
void Unpack(CDnsBuffer & Buffer)
{
unsigned __int8 byte1;
unsigned __int8 byte2;
unsigned __int8 byte3;
unsigned __int8 byte4;
Buffer>>byte1;
Buffer>>byte2;
Buffer>>byte3;
Buffer>>byte4;
A.Format("%d.%d.%d.%d",byte1,byte2,byte3,byte4);
}
virtual CString ToString()
{
CString Text;
Text = "A Record:\n";
Text += CDnsRR::ToString();
Text += "A=" + A + "\n\n";
return Text;
}
BOOL operator == (LPCTSTR lpszName) const
{
return (Name.CompareNoCase(lpszName)==0);
}
virtual void CopyRData(CDnsRR* pRR){
CDnsRRA * pRRA = (CDnsRRA*) pRR;
A = pRRA->A;
}
};
/************************************************************************
Name : CDnsRRNS
Type : Class
------------------------------------------------------------------------
Author : Akash Kava
Purpose: Encapsulates Resource Record for Type NS
CString NS of this class holds domain
name of Authorized Name Server
************************************************************************/
class CDnsRRNS : public CDnsRR {
public:
CString NS;
CDnsRRNS( CDnsRR * pRR )
: CDnsRR(pRR)
{
}
void Unpack(CDnsBuffer & Buffer)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -