⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dnsquery.cpp

📁 通过这个程序你可以进行网络DNS的查询。希望能够让你得到方便
💻 CPP
字号:
// DNSQuery1.cpp: implementation of the CDNSQuery class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "dnsquery.h"
#include "DNSQuery.h"

#include "winsock2.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#pragma comment(lib,"ws2_32.lib")   //Winsock Library

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDNSQuery::CDNSQuery()
{

	WSADATA firstsock;
	
	RetrieveDnsServersFromRegistry();

	TRACE("\nInitialising Winsock...");
	if (WSAStartup(MAKEWORD(2,2),&firstsock) != 0)
	{
		TRACE("Failed. Error Code : %d",WSAGetLastError());
		return;
	} 
	TRACE("Initialised.");

}

CDNSQuery::~CDNSQuery()
{
	WSACleanup();
}

CString CDNSQuery::DNSQuery(unsigned char *host, char *dnsserver)
{
	unsigned char buf[65536],*qname,*reader;
	int i , j , stop;
	
	SOCKET s;
	struct sockaddr_in a;

	struct RES_RECORD answers[20],auth[20],addit[20];  //DNS服务器的回应
	struct sockaddr_in dest;
	
	struct DNS_HEADER *dns = NULL;
	struct QUESTION   *qinfo = NULL;

	CString sResult = "", sTemp;

	s = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);  //采用UDP进行DNS查询

	dest.sin_family=AF_INET;
	dest.sin_port=htons(53);                    //DNS端口
	dest.sin_addr.s_addr=inet_addr(dnsserver);  //DNS服务器

	//设置DNS标准查询结构
	dns = (struct DNS_HEADER *)&buf;
	
	dns->id = (unsigned short) (htons((unsigned short) GetCurrentProcessId()));
	dns->qr = 0;      //这是一个查询
	dns->opcode = 0;  //这是一个标准查询
	dns->aa = 0;      //不用认证
	dns->tc = 0;      //这是一个完整封包
	dns->rd = 1;      //希望递归查询
	dns->ra = 0;      
	dns->z  = 0;
	dns->ad = 0;
	dns->cd = 0;
	dns->rcode = 0;
	dns->q_count = htons(1);   //只有一个问题
	dns->ans_count  = 0;
	dns->auth_count = 0;
	dns->add_count  = 0;
	
	//指针指向查询部分
	qname =(unsigned char*)&buf[sizeof(struct DNS_HEADER)];
    //转换域名格式
	ChangetoDnsNameFormat(qname,host);
	qinfo =(struct QUESTION*)&buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname) + 1)]; //fill it

	qinfo->qtype = htons(1);  //只查询ipv4地址
	qinfo->qclass = htons(1); //这是internet网络

	TRACE("\nSending Packet...");
	if(sendto(s,(char*)buf,sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION),0,(struct sockaddr*)&dest,sizeof(dest))==SOCKET_ERROR)
	{
		TRACE("%d  error",WSAGetLastError());
	}
	TRACE("Sent");
	
	i = sizeof(dest);
	TRACE("\nReceiving answer...");
	if(recvfrom (s,(char*)buf,65536,0,(struct sockaddr*)&dest,&i)==SOCKET_ERROR)
	{
		TRACE("Failed. Error Code : %d",WSAGetLastError());
	}
	TRACE("Received.");
	
	dns=(struct DNS_HEADER*)buf;
	
	//指针越过DNS包头和查询问题部分
	reader=&buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION)];

    sTemp.Format("The response contains : ");
	sResult += sTemp;
	sTemp.Format("\r\n %d Questions.",ntohs(dns->q_count));
	sResult += sTemp;
	sTemp.Format("\r\n %d Answers.",ntohs(dns->ans_count));
	sResult += sTemp;
	sTemp.Format("\r\n %d Authoritative Servers.",ntohs(dns->auth_count));
	sResult += sTemp;
	sTemp.Format("\r\n %d Additional records.\r\n",ntohs(dns->add_count));
	sResult += sTemp;

	//读问题回答
	stop=0;
	
	for(i=0;i<ntohs(dns->ans_count);i++)
	{
		answers[i].name=ReadName(reader,buf,&stop);
		reader = reader + stop;
		
		answers[i].resource = (struct R_DATA*)(reader);
		reader = reader + sizeof(struct R_DATA);
	
		if(ntohs(answers[i].resource->type) == 1) //if its an ipv4 address
		{
			answers[i].rdata = (unsigned char*)malloc(ntohs(answers[i].resource->data_len));
			
			for(j=0 ; j<ntohs(answers[i].resource->data_len) ; j++)
				answers[i].rdata[j]=reader[j];
			
			answers[i].rdata[ntohs(answers[i].resource->data_len)] = '\0';
			
			reader = reader + ntohs(answers[i].resource->data_len);
		
		}
		else
		{
			answers[i].rdata = ReadName(reader,buf,&stop);
		    reader = reader + stop;
		}
	}
	
	//读认证回应
	for(i=0;i<ntohs(dns->auth_count);i++)
	{
		auth[i].name=ReadName(reader,buf,&stop);
		reader+=stop;
		
		auth[i].resource=(struct R_DATA*)(reader);
		reader+=sizeof(struct R_DATA);
	
		auth[i].rdata=ReadName(reader,buf,&stop);
		reader+=stop;
	}

	//读附加资源数据
	for(i=0;i<ntohs(dns->add_count);i++)
	{
		addit[i].name=ReadName(reader,buf,&stop);
		reader+=stop;
		
		addit[i].resource=(struct R_DATA*)(reader);
		reader+=sizeof(struct R_DATA);
	
		if(ntohs(addit[i].resource->type)==1)
		{
			addit[i].rdata = (unsigned char*)malloc(ntohs(addit[i].resource->data_len));
			for(j=0;j<ntohs(addit[i].resource->data_len);j++)
				addit[i].rdata[j]=reader[j];

			addit[i].rdata[ntohs(addit[i].resource->data_len)]='\0';
			reader+=ntohs(addit[i].resource->data_len);
		
		}
		else
		{
			addit[i].rdata=ReadName(reader,buf,&stop);
		    reader+=stop;
		}
	}

	
	//输出回答,即查询结果
	for(i=0;i<ntohs(dns->ans_count);i++)
	{
		sTemp.Format("Name : %s ",answers[i].name);
		sResult += sTemp;
			
		if(ntohs(answers[i].resource->type)==1)   //IPv4地址
		{
			
			long *p;
			p=(long*)answers[i].rdata;
			a.sin_addr.s_addr=(*p);    
			sTemp.Format("has \r\nIPv4 address :  %s",inet_ntoa(a.sin_addr));
			sResult += sTemp;
		}
		if(ntohs(answers[i].resource->type)==5)   //别名
		{
			sTemp.Format("has alias name : %s",answers[i].rdata);
			sResult += sTemp;
		}
				
		sTemp.Format("\r\n");
		sResult += sTemp;
	}

	//输出认证信息
	for(i=0;i<ntohs(dns->auth_count);i++)
	{
		sTemp.Format("Name : %s ",auth[i].name);
		sResult += sTemp;
		if(ntohs(auth[i].resource->type)==2)
		{
			sTemp.Format("has authoritative nameserver : %s",auth[i].rdata);
			sResult += sTemp;
		}
		sTemp.Format("\r\n");
		sResult += sTemp;
	}

	//输出附加资源数据
	for(i=0;i<ntohs(dns->add_count);i++)
	{
		sTemp.Format("Name : %s ",addit[i].name);
		sResult += sTemp;
		if(ntohs(addit[i].resource->type)==1)
		{
			long *p;
			p=(long*)addit[i].rdata;
			a.sin_addr.s_addr=(*p);    
			sTemp.Format("has \r\nIPv4 address :  %s",inet_ntoa(a.sin_addr));
			sResult += sTemp;
		}
		sTemp.Format("\r\n");
		sResult += sTemp;
	}

    return sResult;
}

unsigned char* CDNSQuery::ReadName(unsigned char* reader,unsigned char* buffer,int* count)
{
	unsigned char *name;
	unsigned int p=0,jumped=0,offset;
	int i , j;

	*count = 1;
	name   = (unsigned char*)malloc(256);
	
	name[0]='\0';

	//read the names in 3www6google3com format
	while(*reader!=0)
	{
		if(*reader>=192)
		{
			offset = (*reader)*256 + *(reader+1) - 49152; //49152 = 11000000 00000000  ;)
			reader = buffer + offset - 1;
			jumped = 1;  //we have jumped to another location so counting wont go up!
		}
		else 
			name[p++]=*reader;
		
		reader=reader+1;
		
		if(jumped==0) *count = *count + 1; //if we havent jumped to another location then we can count up
	}
	
	name[p]='\0';    //string complete
	if(jumped==1) *count = *count + 1;  //number of steps we actually moved forward in the packet
	
	//now convert 3www6google3com0 to www.google.com
	for(i=0;i<(int)strlen((const char*)name);i++)
	{
		p=name[i];
		for(j=0;j<(int)p;j++)
		{
			name[i]=name[i+1];
			i=i+1;
		}
		name[i]='.';
	}
	name[i-1]='\0';	  //remove the last dot
	return name;		
}


// 从注册表读出DNS服务器
void CDNSQuery::RetrieveDnsServersFromRegistry()
{
	HKEY hkey=0;
	char name[256];
	char *path="SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
	char *fullpath[256];
	unsigned long s=sizeof(name);
	int  dns_count=0 , err , i , j;
	HKEY inter;
	unsigned long count;


	//Open the registry folder
	RegOpenKeyEx(HKEY_LOCAL_MACHINE , path , 0 , KEY_READ , &hkey );
		
	
	
	//how many interfaces
	RegQueryInfoKey(hkey, 0 , 0 , 0 , &count , 0 , 0 , 0 , 0 , 0 , 0 , 0 );
	
	for(i=0;i<(int)count;i++)
	{
		s=256;
		//Get the interface subkey name
		RegEnumKeyEx(hkey , i , (char*)name , &s , 0 , 0 , 0 , 0 );
		
		//Make the full path
		strcpy((char*)fullpath,path);
		strcat((char*)fullpath,"\\");
		strcat((char*)fullpath,name);
				
		//Open the full path name
		RegOpenKeyEx(HKEY_LOCAL_MACHINE , (const char*)fullpath , 0 , KEY_READ , &inter );
				
		//Extract the value in Nameserver field
		s=256;
		err=RegQueryValueEx(inter , "NameServer" , 0 , 0 , (unsigned char*)name ,	&s );
		
		if(err==ERROR_SUCCESS && strlen(name)>0) strcpy(m_DnsServers[dns_count++],name);
	}

	for(i=0;i<dns_count;i++)
	{
		for(j=0;j<(int)strlen(m_DnsServers[i]);j++)
		{
			if(m_DnsServers[i][j]==',' || m_DnsServers[i][j]==' ')
			{
				strcpy(m_DnsServers[dns_count++],m_DnsServers[i]+j+1);
				m_DnsServers[i][j]=0;
			}
		}
	}

	TRACE("\nThe following DNS Servers were found on your system...");
	for(i=0;i<dns_count;i++)
	{
		TRACE("\n%d)  %s",i+1,m_DnsServers[i]);
	}
}


//转换格式: www.google.com -> www google com ;
void CDNSQuery::ChangetoDnsNameFormat(unsigned char* dns,unsigned char* host)
{
	int lock=0 , i;
	
	strcat((char*)host,".");
	
	for(i=0;i<(int)strlen((char*)host);i++)
	{
		if(host[i]=='.')
		{
			*dns++=i-lock;
			for(;lock<i;lock++)
			{
				*dns++=host[lock];
			}
			lock++; //or lock=i+1;
		}
	}
    *dns++='\0';
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -