Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
22
Добавлен:
11.05.2015
Размер:
6.83 Кб
Скачать
// DNSClient.cpp : implementation file
//

#include "stdafx.h"
#include "UDPClient.h"
#include "DNSClient.h"


// CDNSClient
//-----------------------------------------------
CDNSClient::CDNSClient()
{
	m_ServerPort=53;
	m_State=dnsClear;
	m_TransID=0;
}
//-----------------------------------------------
CDNSClient::~CDNSClient()
{
}
//-----------------------------------------------
BOOL CDNSClient::InitInstance(void)
{
	BOOL Res=FALSE;
	if(Create(0,SOCK_DGRAM))
	{
		Res=Connect(CString(m_ServerAddress.c_str()),m_ServerPort);
		m_TransID=0;
	}
	return Res;
}
//-----------------------------------------------
int CDNSClient::ExitInstance(void)
{
	return 0;
}
//-----------------------------------------------
void CDNSClient::SetServer(const string& _Address,UINT _Port)
{
	if(m_State==dnsClear)
	{
		m_ServerAddress=_Address;
		m_ServerPort=_Port;
	}
	else
	{
		//Нельзя изменять адрес сервера
	}
}
//-----------------------------------------------
bool CDNSClient::QueryServer(const string& _Name,const string& _Type)
{
	char OutBuf[1000];
	int Offset=0;

	//Идентификатор запроса
	m_TransID++;
	memcpy(OutBuf+Offset,&m_TransID,sizeof(m_TransID));
	swap(OutBuf[Offset],OutBuf[Offset+1]);
	Offset+=sizeof(m_TransID);

	//Параметры
	__int16 Flags=0;
	Flags|=(0x0000&0x0080);		//Query
	Flags|=(0x0000&0x0078);		//Opcode
	Flags|=(0x0000&0x0002);		//Truncation
	Flags|=(0xFFFF&0x0001);		//Recursion
	memcpy(OutBuf+Offset,&Flags,sizeof(Flags));
	Offset+=sizeof(Flags);

	//Количество запросов
	__int16 QueryCount=1;
	memcpy(OutBuf+Offset,&QueryCount,sizeof(QueryCount));
	swap(OutBuf[Offset],OutBuf[Offset+1]);
	Offset+=sizeof(QueryCount);
	
	//Количество ответов (только в ответах)
	__int16 AnswerRRs=0;
	memcpy(OutBuf+Offset,&AnswerRRs,sizeof(AnswerRRs));
	swap(OutBuf[Offset],OutBuf[Offset+1]);
	Offset+=sizeof(AnswerRRs);

	//Количество записей серверов имен (только в ответах)
	__int16 AuthorityRRs=0;
	memcpy(OutBuf+Offset,&AuthorityRRs,sizeof(AuthorityRRs));
	swap(OutBuf[Offset],OutBuf[Offset+1]);
	Offset+=sizeof(AuthorityRRs);

	//Количество дополнительных записей (только в ответах)
	__int16 AdditionalRRs=0;
	memcpy(OutBuf+Offset,&AdditionalRRs,sizeof(AdditionalRRs));
	swap(OutBuf[Offset],OutBuf[Offset+1]);
	Offset+=sizeof(AdditionalRRs);

	//Запрашиваемый адрес
	char Address[1000]="\0";
	strcpy(Address+1,_Name.c_str());
	char* Cur=Address;
	char* Next=strchr(Address+1,'.');
	while(Next)
	{
		*Cur=(char)(Next-Cur-1);
		Cur=Next;
		Next=strchr(Cur,'.');
	}
	*Cur=(char)(_Name.length()-(Cur-Address));
	memcpy(OutBuf+Offset,Address,_Name.length()+2);
	Offset+=(int)_Name.length()+2;
	
	//Тип запроса
	__int16 Type=0;
	if(!_Type.compare("A"))
		Type=1;
	else if(!_Type.compare("NS"))
		Type=2;
//	else 
	memcpy(OutBuf+Offset,&Type,sizeof(Type));
	swap(OutBuf[Offset],OutBuf[Offset+1]);
	Offset+=sizeof(Type);

	//Класс адреса
	__int16 Class=1;
	memcpy(OutBuf+Offset,&Class,sizeof(Class));
	swap(OutBuf[Offset],OutBuf[Offset+1]);
	Offset+=sizeof(Class);

	//Отправляем запрос
	if(Send(OutBuf,Offset)==Offset)
	{
		m_State=dnsQuery;
		cout << "##DNS query sended" << endl;	
		return true;
	}
	else
	{
		cout << "##Couldn't send receive file query. Error code:" << GetLastError() << endl;
		return false;
	}
}
//-----------------------------------------------
void CDNSClient::OnReceive(int nErrorCode)
{
	if(m_State==dnsQuery)
	{
		char InBuf[10000];
		int InLen;

		InLen=Receive(InBuf,10000);
		if(InLen==SOCKET_ERROR || InLen==0)
		{
			cout << "##Error while receive" << endl;
		}
		else
		{
			cout << "##Received packet" << endl;

			int Offset=0;

			//Идентификатор транзакции
			__int16 TransID;
			swap(InBuf[Offset],InBuf[Offset+1]);
			memcpy(&TransID,InBuf+Offset,sizeof(TransID));
			Offset+=sizeof(TransID);
			cout << "Trasaction ID: " << TransID << endl;
			cout << "Flags:" << endl;

			//Параметры
			__int16 Flags;
			memcpy(&Flags,InBuf+Offset,sizeof(Flags));
			Offset+=sizeof(Flags);
			cout << " Response: " << (Flags&0x0080 ? "1" : "0") << endl;
			cout << " OpCode: " << (Flags&0x0078) << endl;
			cout << " Authoritative: " << (Flags&0x0004 ? "1" : "0") << endl;
			cout << " Truncated: " << (Flags&0x0002 ? "1" : "0") << endl;
			cout << " Recursion desired: " << (Flags&0x0001 ? "1" : "0") << endl;
			cout << " Recursion available: " << (Flags&0x8000 ? "1" : "0") << endl;
			cout << " Answer authenticated: " << (Flags&0x2000 ? "1" : "0") << endl;
			cout << " Error code: " << (Flags&0x0F00) << endl;

			//Количество запросов
			__int16 QueryCount;
			swap(InBuf[Offset],InBuf[Offset+1]);
			memcpy(&QueryCount,InBuf+Offset,sizeof(QueryCount));
			Offset+=sizeof(QueryCount);
			cout << "Query count: " << QueryCount << endl;

			//Количество ответов
			__int16 AnswerCount;
			swap(InBuf[Offset],InBuf[Offset+1]);
			memcpy(&AnswerCount,InBuf+Offset,sizeof(AnswerCount));
			Offset+=sizeof(AnswerCount);
			cout << "Answer count: " << AnswerCount << endl;

			//Количество записей серверов имен
			__int16 NSCount;
			swap(InBuf[Offset],InBuf[Offset+1]);
			memcpy(&NSCount,InBuf+Offset,sizeof(NSCount));
			Offset+=sizeof(NSCount);
			cout << "Name server count: " << NSCount << endl;

			//Количество дополнительных записей
			__int16 AdditionalCount;
			swap(InBuf[Offset],InBuf[Offset+1]);
			memcpy(&AdditionalCount,InBuf+Offset,sizeof(AdditionalCount));
			Offset+=sizeof(AdditionalCount);
			cout << "Additional count: " << AdditionalCount << endl;

			//Запросы
			cout << "Queries: " << endl;
			for(int i=0;i<QueryCount;i++)
			{
				cout << " " << (i+1) << ". ";

				//Разбираем имя сервера
				unsigned char Len=InBuf[Offset];
				char Buf[1000];
				int BufOffset=0;
				Offset++;
				while(Len>0)
				{
					memcpy(Buf+BufOffset,InBuf+Offset,Len);
					BufOffset+=Len;
					Buf[BufOffset]='.';
					BufOffset++;
					Offset+=Len;
					Len=InBuf[Offset];
					Offset++;
				}
				Buf[BufOffset-1]='\0';
				cout << Buf;

				//Тип запроса
				__int16 Type;
				swap(InBuf[Offset],InBuf[Offset+1]);
				memcpy(&Type,InBuf+Offset,sizeof(Type));
				Offset+=sizeof(Type);
				cout << " Type: " << Type;

				//Класс адреса
				__int16 Class;
				swap(InBuf[Offset],InBuf[Offset+1]);
				memcpy(&Class,InBuf+Offset,sizeof(Class));
				Offset+=sizeof(Class);
				cout << " Class: " << Class;

				cout << endl;
			}

			//Ответы
			cout << "Answers: " << endl;

			//Записи серверов имен
			cout << "Name servers: " << endl;

			//Дополнительные записи
			cout << "Additional: " << endl;
		}
	}
	else
	{
		cout << "##Unexpected data from server" << endl;
	}
}
//-----------------------------------------------
Соседние файлы в папке UDPClient