Example #1
0
BOOL DecodeDotStr(char *szEncodedStr, USHORT *pusEncodedStrLen, char *szDotStr, USHORT nDotStrSize,char *szPacketStartPos = NULL)
{
	if (szEncodedStr == NULL || pusEncodedStrLen == NULL || szDotStr == NULL)
	{
		return FALSE;
	}

	char *pDecodePos = szEncodedStr;
	USHORT usPlainStrLen = 0;
	BYTE nLabelDataLen = 0;    
	*pusEncodedStrLen = 0;

	while ((nLabelDataLen = *pDecodePos) != 0x00)
	{
		if ((nLabelDataLen & 0xc0) == 0) //普通格式,LabelDataLen + Label
		{
			if (usPlainStrLen + nLabelDataLen + 1 > nDotStrSize)
			{
				return FALSE;
			}
			memcpy(szDotStr + usPlainStrLen, pDecodePos + 1, nLabelDataLen);
			memcpy(szDotStr + usPlainStrLen + nLabelDataLen, ".", 1);
			pDecodePos += (nLabelDataLen + 1);
			usPlainStrLen += (nLabelDataLen + 1);
			*pusEncodedStrLen += (nLabelDataLen + 1);
		}
		else //消息压缩格式,11000000 00000000,两个字节,前2位为跳转标志,后14位为跳转的偏移
		{
			if (szPacketStartPos == NULL)
			{
				return FALSE;
			}
			USHORT usJumpPos = ntohs(*(USHORT*)(pDecodePos)) & 0x3fff;
			USHORT nEncodeStrLen = 0;
			if (!DecodeDotStr(szPacketStartPos + usJumpPos, &nEncodeStrLen, szDotStr + usPlainStrLen, nDotStrSize - usPlainStrLen, szPacketStartPos))
			{
				return FALSE;
			}
			else
			{
				*pusEncodedStrLen += 2;
				return TRUE;
			}
		}
	}

	szDotStr[usPlainStrLen - 1] = '\0';
	*pusEncodedStrLen += 1;

	return TRUE;
}
Example #2
0
BOOL DecodeDNSResponse( char *pRecvBuf,int nBufLen )
{
	USHORT nEncodedNameLen = 0;
	char szDotName[128] = {'\0'};
	DNSHeader *pDNSHeader = (DNSHeader*)pRecvBuf;
	USHORT usQuestionCount = 0;
	USHORT usAnswerCount = 0;

	if ( 
		//pDNSHeader->usTransID == 0
		//&& 
		(ntohs(pDNSHeader->usFlags) & 0xfb7f) == 0x8100 //RFC1035 4.1.1(Header section format)
		&& (usQuestionCount = ntohs(pDNSHeader->usQuestionCount)) >= 0
		&& (usAnswerCount = ntohs(pDNSHeader->usAnswerCount)) > 0)
	{
		CStringA strHostName;

		char *pDNSData = pRecvBuf + sizeof(DNSHeader);

		//解析Question字段
		for (int q = 0; q != usQuestionCount; ++q)
		{
			if (!DecodeDotStr(pDNSData, &nEncodedNameLen, szDotName, sizeof(szDotName)))
			{
				return FALSE;
			}
			pDNSData += (nEncodedNameLen + DNS_TYPE_SIZE + DNS_CLASS_SIZE);
		}

		strHostName = szDotName;

		OutputDebugStringA(szDotName);

		//解析Answer字段
		for (int a = 0; a != usAnswerCount; ++a)
		{
			if (!DecodeDotStr(pDNSData, &nEncodedNameLen, szDotName, sizeof(szDotName), pRecvBuf))
			{
				return FALSE;
			}

			pDNSData += nEncodedNameLen;

			USHORT usAnswerType = ntohs(*(USHORT*)(pDNSData));
			USHORT usAnswerClass = ntohs(*(USHORT*)(pDNSData + DNS_TYPE_SIZE));
			ULONG usAnswerTTL = ntohl(*(ULONG*)(pDNSData + DNS_TYPE_SIZE + DNS_CLASS_SIZE));
			USHORT usAnswerDataLen = ntohs(*(USHORT*)(pDNSData + DNS_TYPE_SIZE + DNS_CLASS_SIZE + DNS_TTL_SIZE));
			pDNSData += (DNS_TYPE_SIZE + DNS_CLASS_SIZE + DNS_TTL_SIZE + DNS_DATALEN_SIZE);

			if (usAnswerType == DNS_TYPE_A /*&& pveculIPList != NULL*/)
			{
				if (FastMatchRecord(strHostName))
				{
					ULONG ulIP = *(ULONG*)(pDNSData);
					in_addr ia;
					ia.s_addr=ulIP;
					OutputDebugStringA(inet_ntoa(ia));

					*(ULONG*)(pDNSData) = inet_addr("127.0.0.1");
				}
			}
// 			else if (usAnswerType == DNS_TYPE_CNAME && pvecstrCNameList != NULL)
// 			{
// 				if (!DecodeDotStr(pDNSData, &nEncodedNameLen, szDotName, sizeof(szDotName), recvbuf))
// 				{
// 					return FALSE;
// 				}
// 				pvecstrCNameList->push_back(szDotName);
// 			}

			pDNSData += (usAnswerDataLen);
		}

	}

	return FALSE;
}
Example #3
0
BOOL CDNSLookup::RecvDNSResponse(sockaddr_in sockAddrDNSServer, ULONG ulTimeout, std::vector<ULONG> *pveculIPList, std::vector<std::string> *pvecstrCNameList, ULONG *pulTimeSpent)
{
	ULONG ulSendTimestamp = GetTickCountCalibrate();

	if (pveculIPList != NULL)
	{
		pveculIPList->clear();
	}
	if (pvecstrCNameList != NULL)
	{
		pvecstrCNameList->clear();
	}

	char recvbuf[1024] = { '\0' };
	char szDotName[128] = { '\0' };
	USHORT nEncodedNameLen = 0;

	while (TRUE)
	{
		if (WSAWaitForMultipleEvents(1, &m_event, FALSE, 100, FALSE) != WSA_WAIT_TIMEOUT)
		{
			WSANETWORKEVENTS netEvent;
			WSAEnumNetworkEvents(m_sock, m_event, &netEvent);

			if (netEvent.lNetworkEvents & FD_READ)
			{
				ULONG ulRecvTimestamp = GetTickCountCalibrate();
				int nSockaddrDestSize = sizeof(sockAddrDNSServer);

				//接收响应报文
				if (recvfrom(m_sock, recvbuf, 1024, 0, (struct sockaddr*)&sockAddrDNSServer, &nSockaddrDestSize) != SOCKET_ERROR)
				{
					DNSHeader *pDNSHeader = (DNSHeader*)recvbuf;
					USHORT usQuestionCount = 0;
					USHORT usAnswerCount = 0;

					if (pDNSHeader->usTransID == m_usCurrentProcID
						&& (ntohs(pDNSHeader->usFlags) & 0xfb7f) == 0x8100 //RFC1035 4.1.1(Header section format)
						&& (usQuestionCount = ntohs(pDNSHeader->usQuestionCount)) >= 0
						&& (usAnswerCount = ntohs(pDNSHeader->usAnswerCount)) > 0)
					{
						char *pDNSData = recvbuf + sizeof(DNSHeader);

						//解析Question字段
						for (int q = 0; q != usQuestionCount; ++q)
						{
							if (!DecodeDotStr(pDNSData, &nEncodedNameLen, szDotName, sizeof(szDotName)))
							{
								return FALSE;
							}
							pDNSData += (nEncodedNameLen + DNS_TYPE_SIZE + DNS_CLASS_SIZE);
						}

						//解析Answer字段
						for (int a = 0; a != usAnswerCount; ++a)
						{
							if (!DecodeDotStr(pDNSData, &nEncodedNameLen, szDotName, sizeof(szDotName), recvbuf))
							{
								return FALSE;
							}
							pDNSData += nEncodedNameLen;

							USHORT usAnswerType = ntohs(*(USHORT*)(pDNSData));
							USHORT usAnswerClass = ntohs(*(USHORT*)(pDNSData + DNS_TYPE_SIZE));
							ULONG usAnswerTTL = ntohl(*(ULONG*)(pDNSData + DNS_TYPE_SIZE + DNS_CLASS_SIZE));
							USHORT usAnswerDataLen = ntohs(*(USHORT*)(pDNSData + DNS_TYPE_SIZE + DNS_CLASS_SIZE + DNS_TTL_SIZE));
							pDNSData += (DNS_TYPE_SIZE + DNS_CLASS_SIZE + DNS_TTL_SIZE + DNS_DATALEN_SIZE);

							if (usAnswerType == DNS_TYPE_A && pveculIPList != NULL)
							{
								ULONG ulIP = *(ULONG*)(pDNSData);
								pveculIPList->push_back(ulIP);
							}
							else if (usAnswerType == DNS_TYPE_CNAME && pvecstrCNameList != NULL)
							{
								if (!DecodeDotStr(pDNSData, &nEncodedNameLen, szDotName, sizeof(szDotName), recvbuf))
								{
									return FALSE;
								}
								pvecstrCNameList->push_back(szDotName);
							}

							pDNSData += (usAnswerDataLen);
						}

						//计算DNS查询所用时间
						if (pulTimeSpent != NULL)
						{
							*pulTimeSpent = ulRecvTimestamp - ulSendTimestamp;
						}

						break;
					}
				}
			}
		}

		//超时退出
		if (GetTickCountCalibrate() - ulSendTimestamp > ulTimeout)
		{
			*pulTimeSpent = ulTimeout + 1;
			return FALSE;
		}
	}

	return TRUE;
}