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

📄 dns_v1.cpp

📁 我自己用C写的客户端组包发送DNS报文的小程序
💻 CPP
字号:

/*   
 *   DNSCore.cpp   
 *   Function:     
 *   input   domain 、DNSSERVER,  output   IP   
 *   input("www.8080.net")        output("61.155.107.46")   
 *   Author: inc075481   
 *   Data:   2008-5-9   
*/   

	#include "stdafx.h"
	#include "dns_v1.h"


	char strDomain[50] = {0};
	char outputip[50] = {0};
	char dwDNSServerIP[50] = {0};
	int  arraystr_length = 0;
    char arrayStr[10][50] ={0};
	HANDLE m_pThreadRecvData = 0;
	HANDLE m_hSynEvent = CreateEvent(NULL, FALSE, TRUE, NULL);

	struct CDNSCore
	{
		SOCKADDR_IN m_saDNSServer;        //目标DNS地址
		SOCKET m_sockLocal;   
		int m_iRecvDataLen;  
		char m_szRecvBuf[RecvBufSize]; 
	};
	
	struct CDNSCore *a;
    
	 int  main()
	{
		printf("please send the URL which you want to search:\n");
		scanf("%s",strDomain);
		printf("please send the DNSSERVER IP:\n");
		scanf("%s",dwDNSServerIP);
		a = (struct CDNSCore *)malloc(sizeof(CDNSCore));
	    memset(a, 0, sizeof(CDNSCore));
		unsigned int addr = inet_addr(dwDNSServerIP);  
		a->m_saDNSServer.sin_family = AF_INET;
		a->m_saDNSServer.sin_addr.s_addr = addr;
		a->m_saDNSServer.sin_port = htons(53);
		a->m_sockLocal = INVALID_SOCKET;
		a->m_iRecvDataLen = 0;
		memset(a->m_szRecvBuf,0,RecvBufSize);
		initLocalSocket();
		getDomainIP(strDomain, outputip, arraystr_length);
		return 0;
	}

	void getArrayByDomainStr(const char* strDomain, int &length)
	{
		char byChar = 0;   
		char strTemp[50] = {0};
		int num = strlen(strDomain);
		int fir = 0;
		int sec = 0;

		for(int w = 0; w < num; w++)   
		{   
			byChar = strDomain[w];   
			if('.' == byChar)   
			{ 
				int t = strlen(strTemp);
				memcpy(arrayStr[sec], strTemp, t); 
				sec++;
				memset(strTemp,0,50);
				fir = 0;
			}   
			else   
			{   
				strTemp[fir]= byChar;
				fir++;
			}   
		} 
		if (strTemp[0] != 0)
		{
			memcpy(arrayStr[sec], strTemp, strlen(strTemp)); 
		    sec++;
		}		
		length = sec;
	}

	void getPackageRequestIP(SEND_PACKAGE &sendPkg, const char* strDomain, int &length)
	{
		char byBuf[526] = {0};
		char byTemp = 0;   
		int  pDataPtr = 0;
		int  iLastLen = 0;                     //最终查询报文长度 
		char strElement[50] = {0};   	
		DNS_REQUEST_HEAD dnsHead;
		//DNS_REQUEST_TAIL   
		DNS_REQUEST_TAIL dnsTail;

		//head(12字节)   初始化报头字段
		dnsHead.usSessionID = htons(0X0305);   
		dnsHead.usFlag = htons(DNS_FLAG_RD);   
		dnsHead.usQuestions = htons(0X0001);   
		dnsHead.usAnswer = 0X0000;   
		dnsHead.usAuthority = 0X0000;   
		dnsHead.usAdditional = 0X0000;   
		memcpy(byBuf+pDataPtr, &dnsHead, DNS_HEAD_SIZE);   
		pDataPtr = pDataPtr + DNS_HEAD_SIZE;   
		//构造报文身体   
		getArrayByDomainStr(strDomain, length);
		for(int i = 0; i < length; i++)   
		{   
			memcpy(strElement, arrayStr[i], strlen(arrayStr[i]));   
			//写长度   
			byTemp = strlen(strElement);   
			byBuf[pDataPtr] = byTemp;     
			++pDataPtr;   
			//写内容   
			memcpy(byBuf+pDataPtr,strElement,byTemp); 
			memset(strElement,0,50);
			pDataPtr = pDataPtr + byTemp;   
		}   
		//标识DomainStr已经完了   
		byBuf[pDataPtr] = 0X00;
		++pDataPtr;   
	 		
   
		//根据域名查找IP   
		dnsTail.usRequestType = htons(DNS_RRTYPE_A);    
		dnsTail.usRequestClass = htons(DNS_RRTYPE_A);   
		memcpy(byBuf+pDataPtr, &dnsTail, DNS_TAIL_SIZE);   
		pDataPtr = pDataPtr + 4;   
    
		iLastLen = pDataPtr;    
		sendPkg.pData = (char *)malloc(iLastLen);
		assert(sendPkg.pData != NULL);
		memcpy(sendPkg.pData, byBuf, iLastLen);   
		sendPkg.iDataLen = iLastLen;   
	} 

	bool sendDestPackage(const SOCKET sockLocal,   
						 const SOCKADDR_IN saDest,   
						 SEND_PACKAGE &sendPackage,   
						 const USHORT usSendTimes   /*   =   1   */   
						)
	{
		bool bRet = true;
		if (INVALID_SOCKET == sockLocal || sendPackage.iDataLen < 1 || NULL == sendPackage.pData)   
		{   
			return false;   
		}
		for(USHORT i = 0; i < usSendTimes; ++i)   
		{   
			if(SOCKET_ERROR == sendto(sockLocal, (const char*)sendPackage.pData, sendPackage.iDataLen, 0, (sockaddr*)&(saDest), sizeof(saDest)))   
			{   
				printf("sendPackage   Fail::::::::%d\n",WSAGetLastError());   
				bRet = false;   
			}   
			else   
			{   
				bRet = true;   
				printf("sendPackage IP %s Port %d DataLength %d Success\n",   
					   inet_ntoa(saDest.sin_addr),   
					   ntohs(saDest.sin_port),   
					   sendPackage.iDataLen   
					  );   
				//show   
				HexDump((const unsigned char *)sendPackage.pData,sendPackage.iDataLen);   
				//idle   
				Sleep(13);   
			}  
		} 
		free(sendPackage.pData);   
		sendPackage.pData = NULL;   
		return bRet;   
	}

	void HexDump(const unsigned char *buf, int nBufLen) 
	{
		int i;   
		for(i = 0; i < nBufLen; i++)   
		{   
			printf("%02X", buf[i]);   
			if(i%16 == 15)   
			{   
			   printf("\n");   
			}     
		}   
	}  

	bool getDomainIP(const char* strDomain, char* outputip, int &length)
	{
		SEND_PACKAGE sendPkg;     
		getPackageRequestIP(sendPkg, strDomain, length);   
		//send a package   
		sendDestPackage(a->m_sockLocal,a->m_saDNSServer,sendPkg);   
		//wait for event   
		//如果超时了   
		if(WAIT_TIMEOUT == WaitForSingleObject(m_hSynEvent,5000))   
		{   
			printf("DNSServer超时没有响应");   
			return   false;   
		}   
		//得到数据   
		else   
		{   
			//show   
			HexDump((const unsigned char*)a->m_szRecvBuf,a->m_iRecvDataLen);   
			//解析一个RequestReply的包
			processRequestReply(outputip);   
		}   
		return   true;
	}

	bool initLocalSocket()
	{
		WSADATA wsaData;   
		WSAStartup(MAKEWORD(2,2), &wsaData);   
		//初始化  
		a->m_sockLocal = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);   
		if(INVALID_SOCKET == a->m_sockLocal)   
		{   
			printf("WSASocket Error\n");   
			return false;   
		}   
		//绑定localport   
		SOCKADDR_IN saLocal;   
		saLocal.sin_family = AF_INET;   
		saLocal.sin_port = htons(0X0305);   
		saLocal.sin_addr.s_addr = INADDR_ANY;   
		if(SOCKET_ERROR == bind(a->m_sockLocal,(sockaddr *)&saLocal,sizeof(saLocal)))   
		{   
			printf("bind Error\n");   
		}   
		//create   new   thread   
		m_pThreadRecvData = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE)ThreadRecvData, a, 0, NULL);     
		return true;   
	}  

	static UINT ThreadRecvData(LPVOID pParam) 
	{
		struct CDNSCore *b;
		b = (CDNSCore*)(pParam);
		SOCKADDR_IN saTemp;   
		int iFromLen = sizeof(saTemp);
		while(1)   
		{   
			b->m_iRecvDataLen = recvfrom(b->m_sockLocal, b->m_szRecvBuf, RecvBufSize, 0, (sockaddr*)&(saTemp), &iFromLen);   
			if(b->m_iRecvDataLen > 0)   
			{   
				printf("\n\nRecv Something from DNSServer::::::::::%d\n",b->m_iRecvDataLen);   
				SetEvent(m_hSynEvent);   
			}   
			//空闲   
			Sleep(1024);   
		}   
		return 322; 
	}

	void processRequestReply(char* outputip)
	{
	  int pDataPtr = 0;
	  DNS_REQUEST_HEAD dnsHead;
	  DNS_REQUEST_TAIL dnsTail;
	  USHORT usRedirectPtr = 0;   
	  USHORT usRecordType = 0;   
	  USHORT usRecordClass = 0;   
	  USHORT usTrueDataLen = 0;   
	  UINT iTrueIP = 0;   
	  in_addr userIP;   
	  int iTempIndex = 0;   
	  char strElement[50] = {0};   
	  //初始化数组
	  memset(outputip, 0, 50);   
	  char* pData = (char *)(a->m_szRecvBuf);      
	  //DNS报头的装载   
	  memcpy((void*)&dnsHead, pData+pDataPtr, DNS_HEAD_SIZE);   
	  pDataPtr = pDataPtr + DNS_HEAD_SIZE;   
	  //body,temporary jump to End '\0'   
	  while(pDataPtr < a->m_iRecvDataLen && 0X00 != *(pData + pDataPtr))   
	  {   
		  ++pDataPtr;   
	  }   
	  ++pDataPtr;   
	  //报文身体   
	  memcpy((void*)&dnsTail, pData + pDataPtr, DNS_TAIL_SIZE);   
	  pDataPtr = pDataPtr + DNS_TAIL_SIZE;   
	  //RR记录   
	  printf("\n\n");   
	  while(pDataPtr < a->m_iRecvDataLen)   
	  {   
		  //DomainStr,重定向报文域名 2个字节   
		  //一般为C00C,二进制为1100000000001100
		  //最开始2Bit为11,剩下的Bit构成一个指针,指向DomainStr     
		  memcpy(&usRedirectPtr, pData+pDataPtr, 2);   
		  pDataPtr = pDataPtr + 2;   
		  usRedirectPtr = ntohs(usRedirectPtr);   
		  if(0X00 == usRedirectPtr)   
		  {   
		  printf("域名未得到IP,可能是非法域名");   
		  return ;   
		  }   
		  //类型,2 BYTES   
		  memcpy(&usRecordType, pData+pDataPtr, 2);   
		  pDataPtr = pDataPtr + 2;   
		  usRecordType = ntohs(usRecordType);   
		  //类,2 BYTES   
		  memcpy(&usRecordClass, pData+pDataPtr, 2);   
		  pDataPtr = pDataPtr + 2;   
		  usRecordClass = ntohs(usRecordClass);   
		  //TTL,4 BYTES   
		  pDataPtr = pDataPtr + 4;   
		  //后续真实数据长度,2 BYTES   
		  memcpy(&usTrueDataLen, pData+pDataPtr, 2);   
		  pDataPtr = pDataPtr + 2;   
		  usTrueDataLen = ntohs(usTrueDataLen);   
		  //下面的就是IP地址,4 BYTES  
		  if(DNS_RRTYPE_A == usRecordType)   
		  {   
			  memcpy(&iTrueIP, pData+pDataPtr, 4);
			  userIP.S_un.S_addr = iTrueIP;
			  memcpy(strElement, inet_ntoa(userIP), strlen(inet_ntoa(userIP)));
			  printf("%s",strElement);
			  memcpy(outputip, strElement, strlen(strElement));
			  memset(strElement, 0, 50);   
		  }   
		  pDataPtr = pDataPtr + usTrueDataLen;   
	  }    
	}   
 

⌨️ 快捷键说明

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