关于dns报文的填写与发送 请问:dns报文怎么填写啊? 还有该如何发送呢? 有源码更好谢谢! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 /** DNSCore.h* Function: * ◎1,input domain, output IP eg, input("www.163.com") output("202.108.42.72")* Author: wim* Data: 2005-1-18*/#pragma once#include <winsock2.h>class CDNSCore{ public: //构造函数 CDNSCore(const DWORD dwDNSServerIP); //析够函数 ~CDNSCore(); //公共接口 //根据输入的Domain,返回IP,失败就返回false,【同步返回】 bool getDomainIP(const CString &strDomain, CString &strOutIP); protected: private: //目标DNS的地址 SOCKADDR_IN m_saDNSServer; //本地的Socket SOCKET m_sockLocal; //初始化本地socket,并开启新线程接收数据 bool initLocalSocket(); //接收数据,缓冲区 static const int RecvBufSize = 4086; char m_szRecvBuf[RecvBufSize]; int m_iRecvDataLen; //用来在析够的时候,终止Recv线程 CWinThread* m_pThreadRecvData; //接收数据的线程 static UINT ThreadRecvData(LPVOID pParam); //收到数据,就产生一个事件 CEvent m_eventRecvData; struct SEND_PACKAGE { //new ,must be delete PBYTE pData; int iDataLen; SEND_PACKAGE() { memset(this,0,sizeof(SEND_PACKAGE)); } }; static const USHORT DNS_FLAG_QR = 0x8000; static const USHORT DNS_FLAG_AA = 0x0400; static const USHORT DNS_FLAG_TC = 0x0200; static const USHORT DNS_FLAG_RD = 0x0100; static const USHORT DNS_FLAG_RA = 0x0080; static const USHORT DNS_HEAD_SIZE = 12; static const USHORT DNS_RRTYPE_A = 1; static const USHORT DNS_RRTYPE_NS = 2; static const USHORT DNS_RRTYPE_CNAME = 5; static const USHORT DNS_RRTYPE_SOA = 6; static const USHORT DNS_RRTYPE_WKS = 11; static const USHORT DNS_RRTYPE_PTR = 12; static const USHORT DNS_RRTYPE_HINFO = 13; static const USHORT DNS_RRTYPE_MX = 15; static const USHORT DNS_TAIL_SIZE = 4; struct DNS_REQUEST_HEAD { /* client query ID number */ USHORT usSessionID; /* qualify contents <see below> */ USHORT usFlag; /* number of questions */ USHORT usQuestions; /* number of answer RRs */ USHORT usAnswer; /* number of authority RRs */ USHORT usAuthority; /* number of additional RRs */ USHORT usAdditional; DNS_REQUEST_HEAD() { memset(this,0,DNS_HEAD_SIZE); } }; struct DNS_REQUEST_TAIL { //Request Type USHORT usRequestType; //Request Class USHORT usRequestClass; DNS_REQUEST_TAIL() { memset(this,0,DNS_TAIL_SIZE); } }; //根据输入的DomainStr 得到一个StrArray void getArrayByDomainStr(const CString &strDomain,CStringArray &arrayStr); //组织一个请求Domain IP的包包 void getPackageRequestIP(SEND_PACKAGE &sendPkg,const CString &strDomain); //解析一个RequestReply的包包 void processRequestReply(CString &strOutIP); //发送一个包包,删除包包的内容 bool sendDestPackage( const SOCKET sockLocal, const SOCKADDR_IN saDest, SEND_PACKAGE &sendPackage, const USHORT usSendTimes = 1 ); //sigh,show void HexDump(const unsigned char *buf,int nBufLen); }; /** DNSCore.cpp* Function: * ◎1,input domain, output IPeg, input("www.163.com") output("202.108.42.72")* Author: wim* Data: 2005-1-18*/#include "stdafx.h"#include "DNSCorer.h"//构造函数CDNSCore::CDNSCore(const DWORD dwDNSServerIP){ //建立DNSServer的sa m_saDNSServer.sin_family = AF_INET; m_saDNSServer.sin_addr.s_addr = htonl(dwDNSServerIP); m_saDNSServer.sin_port = htons(53); //53 DNSService //7 Echo //赋初值 m_sockLocal = INVALID_SOCKET; m_pThreadRecvData = NULL; memset(m_szRecvBuf,0,RecvBufSize); m_iRecvDataLen = 0; //初始化本地socket,并开启新线程接收数据 initLocalSocket();}//析够函数CDNSCore::~CDNSCore(){ if(m_pThreadRecvData) { TerminateThread(m_pThreadRecvData->m_hThread,519); }}//初始化本地socket,并开启新线程接收数据bool CDNSCore::initLocalSocket(){ WSADATA wsaData; WSAStartup(MAKEWORD(2,2),&wsaData); //Init m_sockLocal = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); if(INVALID_SOCKET == m_sockLocal) { TRACE("WSASocket Error\n"); return false; } //SetTimeOut /* long lTimeOut = 1000; if( SOCKET_ERROR == setsockopt(m_sockToQQServer,SOL_SOCKET, SO_RCVTIMEO, (char*)&lTimeOut, sizeof(long))) { //TRACE("Set Timeout Error\n"); return false; }*/ //bind 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(m_sockLocal,(sockaddr *)&saLocal,sizeof(saLocal) ) ) { TRACE("bind Error\n"); //return false; } //create new thread m_pThreadRecvData = AfxBeginThread(ThreadRecvData,this); return true;}//根据输入的Domain,返回IP,失败就返回false,【同步返回】bool CDNSCore::getDomainIP(const CString &strDomain, CString &strOutIP){ //clean out param strOutIP.Empty(); //temp //strOutIP.Format("202.108.42.72"); SEND_PACKAGE sendPkg; //get a package getPackageRequestIP(sendPkg,strDomain); //send a package sendDestPackage(m_sockLocal,m_saDNSServer,sendPkg); //wait for event //如果超时了 if(WAIT_TIMEOUT == WaitForSingleObject(m_eventRecvData.m_hObject,5000)) { strOutIP.Format("DNSServer超时没有响应"); return false; } //得到数据 else { //show HexDump((const unsigned char*)m_szRecvBuf,m_iRecvDataLen); //解析一个RequestReply的包包 processRequestReply(strOutIP); } return true;} //解析一个RequestReply的包包void CDNSCore::processRequestReply(CString &strOutIP){ //clean Out Param strOutIP.Empty(); //strOutIP.Format("域名或许是非法的"); PBYTE pData = PBYTE(m_szRecvBuf); int pDataPtr = 0; //head DNS_REQUEST_HEAD dnsHead; memcpy((void*)&dnsHead,pData+pDataPtr,DNS_HEAD_SIZE); pDataPtr = pDataPtr + DNS_HEAD_SIZE; //body,temporary jump to End '\0' while( pDataPtr < m_iRecvDataLen && 0X00 != *(pData+pDataPtr) ) { ++pDataPtr; } ++pDataPtr; //Tail DNS_REQUEST_TAIL dnsTail; memcpy((void*)&dnsTail,pData+pDataPtr,DNS_TAIL_SIZE); pDataPtr = pDataPtr + DNS_TAIL_SIZE; //RR记录 USHORT usRedirectPtr = 0; USHORT usRecordType = 0; USHORT usRecordClass = 0; USHORT usTrueDataLen = 0; UINT iTrueIP = 0; in_addr userIP; int iTempIndex = 0; CString strElement; TRACE("\n\n"); while(pDataPtr < m_iRecvDataLen) { // DomainStr 重定向 (2) //C0 0C //最首2Bit为11 , 剩下的Bit构成一个指针,指向DomainStr memcpy(&usRedirectPtr,pData+pDataPtr,2); pDataPtr = pDataPtr + 2; usRedirectPtr = ntohs(usRedirectPtr); if(0X00 == usRedirectPtr) { strOutIP.Format("域名未得到IP,可能是非法域名"); return ; } //类型(2) memcpy(&usRecordType,pData+pDataPtr,2); pDataPtr = pDataPtr + 2; usRecordType = ntohs(usRecordType); //类(2) memcpy(&usRecordClass,pData+pDataPtr,2); pDataPtr = pDataPtr + 2; usRecordClass = ntohs(usRecordClass); //TTL (4) pDataPtr = pDataPtr + 4; //后续数据长度(2) memcpy(&usTrueDataLen,pData+pDataPtr,2); pDataPtr = pDataPtr + 2; usTrueDataLen = ntohs(usTrueDataLen); //一般来说,就是IP地址 if(DNS_RRTYPE_A == usRecordType) { memcpy(&iTrueIP,pData+pDataPtr,4); userIP.S_un.S_addr = iTrueIP; TRACE("Index %d IP [%s]\n",iTempIndex++,inet_ntoa(userIP)); strElement.Format("%s\r\n",inet_ntoa(userIP)); strOutIP += strElement; } pDataPtr = pDataPtr + usTrueDataLen; }}//组织一个请求Domain IP的包包void CDNSCore::getPackageRequestIP(SEND_PACKAGE &sendPkg,const CString &strDomain){ BYTE byBuf[526] = { /*//www.baidu.com 0X28, 0X30, 0X01, 0X00, 0X00, 0X01, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X03, 0X77, 0X77, 0X77, 0X05, 0X62, 0X61, 0X69, 0X64, 0X75, 0X03, 0X63, 0X6F, 0X6D, 0X00, 0X00, 0X01, 0X00, 0X01 */ 0 }; BYTE byTemp = 0; int pDataPtr = 0; //head(12) DNS_REQUEST_HEAD dnsHead; dnsHead.usSessionID = htons(0X0305); dnsHead.usFlag = htons(DNS_FLAG_RD /*| DNS_FLAG_AA*/); 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; //body(?) { CStringArray arrayStr; CString strElement; //get array getArrayByDomainStr(strDomain,arrayStr); //loop for(int i = 0 ; i < arrayStr.GetCount() ; ++i) { strElement = arrayStr.GetAt(i); //写长度 byTemp = strElement.GetLength(); byBuf[pDataPtr] = byTemp; ++pDataPtr; //写内容 memcpy(byBuf+pDataPtr,strElement.GetBuffer(),byTemp); pDataPtr = pDataPtr + byTemp; } //标识DomainStr已经完了 byBuf[pDataPtr] = 0X00; ++pDataPtr; } //DNS_REQUEST_TAIL DNS_REQUEST_TAIL dnsTail; //根据域名查找IP dnsTail.usRequestType = htons(DNS_RRTYPE_A); //根据IP查找域名 //dnsTail.usRequestType = htons(DNS_RRTYPE_PTR); //都是一样的 dnsTail.usRequestClass = htons(DNS_RRTYPE_A); memcpy(byBuf+pDataPtr,&dnsTail,DNS_TAIL_SIZE); pDataPtr = pDataPtr + 4; int iLastLen = pDataPtr; //return sendPkg.pData = new BYTE[iLastLen]; memcpy(sendPkg.pData,byBuf,iLastLen); sendPkg.iDataLen = iLastLen;}//根据输入的DomainStr 得到一个StrArrayvoid CDNSCore::getArrayByDomainStr(const CString &strDomain,CStringArray &arrayStr){ //temp //218.6.168.225 => www.konlink.net //CString strDomain; //strDomain.Format("225.6.168.218.in-addr.arpa"); ////clean out param //arrayStr.RemoveAll(); //local BYTE byChar = 0; CString strTemp; for(int i = 0 ; i < strDomain.GetLength() ; ++i) { byChar = strDomain.GetAt(i); if('.' == byChar) { arrayStr.Add(strTemp); //reset strTemp.Empty(); } else { strTemp += byChar; } } //heihei, 差点忘了 if(!(strTemp.IsEmpty())) { arrayStr.Add(strTemp); }}//发送一个包包,删除包包的内容bool CDNSCore::sendDestPackage( const SOCKET sockLocal, const SOCKADDR_IN saDest, SEND_PACKAGE &sendPackage, const USHORT usSendTimes /* = 1 */ ){ if ( INVALID_SOCKET == m_sockLocal || sendPackage.iDataLen < 1 || NULL == sendPackage.pData ) { return false; } bool bRet = true; for(USHORT i = 0 ; i < usSendTimes; ++i) { if(SOCKET_ERROR == sendto( sockLocal, (const char*)sendPackage.pData, sendPackage.iDataLen, 0, (sockaddr* )&(saDest), sizeof(saDest)) ) { TRACE("sendPackage Fail::::::::%d\n",WSAGetLastError()); bRet = false; } else { bRet = true; TRACE("sendPackage IP %s Port %d DataLength %d Success\n", inet_ntoa(saDest.sin_addr), ntohs(saDest.sin_port), sendPackage.iDataLen ); //show HexDump(sendPackage.pData,sendPackage.iDataLen); //idle Sleep(13); } } delete[] sendPackage.pData; sendPackage.pData = NULL; return bRet;}//sigh,showvoid CDNSCore::HexDump(const unsigned char *buf,int nBufLen){ int i ; for(i = 0; i < nBufLen; i++) { TRACE("%02X ",buf[i]); if(i%16 == 15) { TRACE("\n"); } } TRACE("\n");}//接收数据的线程UINT CDNSCore::ThreadRecvData(LPVOID pParam){ CDNSCore* pThis = (CDNSCore*)(pParam); SOCKADDR_IN saTemp; int iFromLen = sizeof(saTemp); while(true) { pThis->m_iRecvDataLen = recvfrom( pThis->m_sockLocal, pThis->m_szRecvBuf, RecvBufSize, 0, (sockaddr* )&(saTemp), &iFromLen ); if(pThis->m_iRecvDataLen > 0) { TRACE("\n\nRecv Something from DNSServer::::::::::%d\n",pThis->m_iRecvDataLen); pThis->m_eventRecvData.SetEvent(); } //Idle Sleep(1024); } return 322;} http://www.vckbase.com/document/viewdoc/?id=753 熟悉DNS数据包的格式,然后对应的结构体构造 EXE程序替换图标后不能运行,怎么办?是不是程序有什么保密措施?检测无壳。 碰到一个设置问题,不知道怎么解决! pcap_next_ex函数为什么执行不了?求助高手们 VC+++如何备份与还原Access数据库? 大家请看过来,一个简单的鼠标钩子问题! 如何将.res链接到EXE文件中? 怎么用程序杀掉所有的用户进程? <<Windows高级程序设计>>(清华)哪里有下载? IDL问题:如何生成类型库TLB文件 默认的单文档窗口样式改为分割样式 请问谁知道类似msn messager里的树型控件是怎么做的? 截获某个窗口的WM_TIMER消息
* DNSCore.h
* Function:
* ◎1,input domain, output IP
eg, input("www.163.com") output("202.108.42.72")
* Author: wim
* Data: 2005-1-18
*/
#pragma once
#include <winsock2.h>
class CDNSCore
{
public:
//构造函数
CDNSCore(const DWORD dwDNSServerIP);
//析够函数
~CDNSCore();
//公共接口
//根据输入的Domain,返回IP,失败就返回false,【同步返回】
bool getDomainIP(const CString &strDomain, CString &strOutIP); protected:
private:
//目标DNS的地址
SOCKADDR_IN m_saDNSServer;
//本地的Socket
SOCKET m_sockLocal; //初始化本地socket,并开启新线程接收数据
bool initLocalSocket(); //接收数据,缓冲区
static const int RecvBufSize = 4086;
char m_szRecvBuf[RecvBufSize];
int m_iRecvDataLen; //用来在析够的时候,终止Recv线程
CWinThread* m_pThreadRecvData; //接收数据的线程
static UINT ThreadRecvData(LPVOID pParam); //收到数据,就产生一个事件
CEvent m_eventRecvData; struct SEND_PACKAGE
{
//new ,must be delete
PBYTE pData;
int iDataLen;
SEND_PACKAGE()
{
memset(this,0,sizeof(SEND_PACKAGE));
}
}; static const USHORT DNS_FLAG_QR = 0x8000;
static const USHORT DNS_FLAG_AA = 0x0400;
static const USHORT DNS_FLAG_TC = 0x0200;
static const USHORT DNS_FLAG_RD = 0x0100;
static const USHORT DNS_FLAG_RA = 0x0080;
static const USHORT DNS_HEAD_SIZE = 12; static const USHORT DNS_RRTYPE_A = 1;
static const USHORT DNS_RRTYPE_NS = 2;
static const USHORT DNS_RRTYPE_CNAME = 5;
static const USHORT DNS_RRTYPE_SOA = 6;
static const USHORT DNS_RRTYPE_WKS = 11;
static const USHORT DNS_RRTYPE_PTR = 12;
static const USHORT DNS_RRTYPE_HINFO = 13;
static const USHORT DNS_RRTYPE_MX = 15;
static const USHORT DNS_TAIL_SIZE = 4; struct DNS_REQUEST_HEAD
{
/* client query ID number */
USHORT usSessionID;
/* qualify contents <see below> */
USHORT usFlag;
/* number of questions */
USHORT usQuestions;
/* number of answer RRs */
USHORT usAnswer;
/* number of authority RRs */
USHORT usAuthority;
/* number of additional RRs */
USHORT usAdditional;
DNS_REQUEST_HEAD()
{
memset(this,0,DNS_HEAD_SIZE);
}
};
struct DNS_REQUEST_TAIL
{
//Request Type
USHORT usRequestType;
//Request Class
USHORT usRequestClass; DNS_REQUEST_TAIL()
{
memset(this,0,DNS_TAIL_SIZE);
}
}; //根据输入的DomainStr 得到一个StrArray
void getArrayByDomainStr(const CString &strDomain,CStringArray &arrayStr); //组织一个请求Domain IP的包包
void getPackageRequestIP(SEND_PACKAGE &sendPkg,const CString &strDomain); //解析一个RequestReply的包包
void processRequestReply(CString &strOutIP); //发送一个包包,删除包包的内容
bool sendDestPackage(
const SOCKET sockLocal,
const SOCKADDR_IN saDest,
SEND_PACKAGE &sendPackage,
const USHORT usSendTimes = 1
);
//sigh,show
void HexDump(const unsigned char *buf,int nBufLen);
};
* DNSCore.cpp
* Function:
* ◎1,input domain, output IP
eg, input("www.163.com") output("202.108.42.72")
* Author: wim
* Data: 2005-1-18
*/
#include "stdafx.h"
#include "DNSCorer.h"
//构造函数
CDNSCore::CDNSCore(const DWORD dwDNSServerIP)
{
//建立DNSServer的sa
m_saDNSServer.sin_family = AF_INET;
m_saDNSServer.sin_addr.s_addr = htonl(dwDNSServerIP);
m_saDNSServer.sin_port = htons(53);
//53 DNSService
//7 Echo
//赋初值
m_sockLocal = INVALID_SOCKET;
m_pThreadRecvData = NULL;
memset(m_szRecvBuf,0,RecvBufSize);
m_iRecvDataLen = 0;
//初始化本地socket,并开启新线程接收数据
initLocalSocket();
}
//析够函数
CDNSCore::~CDNSCore()
{
if(m_pThreadRecvData)
{
TerminateThread(m_pThreadRecvData->m_hThread,519);
}
}
//初始化本地socket,并开启新线程接收数据
bool CDNSCore::initLocalSocket()
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2),&wsaData); //Init
m_sockLocal = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(INVALID_SOCKET == m_sockLocal)
{
TRACE("WSASocket Error\n");
return false;
} //SetTimeOut
/*
long lTimeOut = 1000;
if( SOCKET_ERROR == setsockopt(m_sockToQQServer,SOL_SOCKET, SO_RCVTIMEO, (char*)&lTimeOut, sizeof(long)))
{
//TRACE("Set Timeout Error\n");
return false;
}*/
//bind 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(m_sockLocal,(sockaddr *)&saLocal,sizeof(saLocal) ) )
{
TRACE("bind Error\n");
//return false;
} //create new thread
m_pThreadRecvData = AfxBeginThread(ThreadRecvData,this); return true;
}
//根据输入的Domain,返回IP,失败就返回false,【同步返回】
bool CDNSCore::getDomainIP(const CString &strDomain, CString &strOutIP)
{
//clean out param
strOutIP.Empty();
//temp
//strOutIP.Format("202.108.42.72"); SEND_PACKAGE sendPkg;
//get a package
getPackageRequestIP(sendPkg,strDomain);
//send a package
sendDestPackage(m_sockLocal,m_saDNSServer,sendPkg); //wait for event
//如果超时了
if(WAIT_TIMEOUT == WaitForSingleObject(m_eventRecvData.m_hObject,5000))
{
strOutIP.Format("DNSServer超时没有响应");
return false;
}
//得到数据
else
{
//show
HexDump((const unsigned char*)m_szRecvBuf,m_iRecvDataLen);
//解析一个RequestReply的包包
processRequestReply(strOutIP);
} return true;
}
void CDNSCore::processRequestReply(CString &strOutIP)
{
//clean Out Param
strOutIP.Empty();
//strOutIP.Format("域名或许是非法的"); PBYTE pData = PBYTE(m_szRecvBuf);
int pDataPtr = 0;
//head
DNS_REQUEST_HEAD dnsHead;
memcpy((void*)&dnsHead,pData+pDataPtr,DNS_HEAD_SIZE);
pDataPtr = pDataPtr + DNS_HEAD_SIZE;
//body,temporary jump to End '\0'
while(
pDataPtr < m_iRecvDataLen &&
0X00 != *(pData+pDataPtr)
)
{
++pDataPtr;
}
++pDataPtr;
//Tail
DNS_REQUEST_TAIL dnsTail;
memcpy((void*)&dnsTail,pData+pDataPtr,DNS_TAIL_SIZE);
pDataPtr = pDataPtr + DNS_TAIL_SIZE;
//RR记录
USHORT usRedirectPtr = 0;
USHORT usRecordType = 0;
USHORT usRecordClass = 0;
USHORT usTrueDataLen = 0;
UINT iTrueIP = 0;
in_addr userIP;
int iTempIndex = 0;
CString strElement;
TRACE("\n\n");
while(pDataPtr < m_iRecvDataLen)
{
// DomainStr 重定向 (2)
//C0 0C
//最首2Bit为11 , 剩下的Bit构成一个指针,指向DomainStr
memcpy(&usRedirectPtr,pData+pDataPtr,2);
pDataPtr = pDataPtr + 2;
usRedirectPtr = ntohs(usRedirectPtr);
if(0X00 == usRedirectPtr)
{
strOutIP.Format("域名未得到IP,可能是非法域名");
return ;
}
//类型(2)
memcpy(&usRecordType,pData+pDataPtr,2);
pDataPtr = pDataPtr + 2;
usRecordType = ntohs(usRecordType);
//类(2)
memcpy(&usRecordClass,pData+pDataPtr,2);
pDataPtr = pDataPtr + 2;
usRecordClass = ntohs(usRecordClass);
//TTL (4)
pDataPtr = pDataPtr + 4;
//后续数据长度(2)
memcpy(&usTrueDataLen,pData+pDataPtr,2);
pDataPtr = pDataPtr + 2;
usTrueDataLen = ntohs(usTrueDataLen);
//一般来说,就是IP地址
if(DNS_RRTYPE_A == usRecordType)
{
memcpy(&iTrueIP,pData+pDataPtr,4);
userIP.S_un.S_addr = iTrueIP;
TRACE("Index %d IP [%s]\n",iTempIndex++,inet_ntoa(userIP));
strElement.Format("%s\r\n",inet_ntoa(userIP));
strOutIP += strElement;
}
pDataPtr = pDataPtr + usTrueDataLen;
}}
//组织一个请求Domain IP的包包
void CDNSCore::getPackageRequestIP(SEND_PACKAGE &sendPkg,const CString &strDomain)
{
BYTE byBuf[526] = {
/*//www.baidu.com
0X28, 0X30, 0X01, 0X00, 0X00, 0X01, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X03, 0X77, 0X77, 0X77,
0X05, 0X62, 0X61, 0X69, 0X64, 0X75, 0X03, 0X63,
0X6F, 0X6D, 0X00, 0X00, 0X01, 0X00, 0X01
*/
0
};
BYTE byTemp = 0;
int pDataPtr = 0;
//head(12)
DNS_REQUEST_HEAD dnsHead;
dnsHead.usSessionID = htons(0X0305);
dnsHead.usFlag = htons(DNS_FLAG_RD /*| DNS_FLAG_AA*/);
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;
//body(?)
{
CStringArray arrayStr;
CString strElement;
//get array
getArrayByDomainStr(strDomain,arrayStr);
//loop
for(int i = 0 ; i < arrayStr.GetCount() ; ++i)
{
strElement = arrayStr.GetAt(i);
//写长度
byTemp = strElement.GetLength();
byBuf[pDataPtr] = byTemp;
++pDataPtr;
//写内容
memcpy(byBuf+pDataPtr,strElement.GetBuffer(),byTemp);
pDataPtr = pDataPtr + byTemp;
}
//标识DomainStr已经完了
byBuf[pDataPtr] = 0X00; ++pDataPtr;
}
//DNS_REQUEST_TAIL
DNS_REQUEST_TAIL dnsTail;
//根据域名查找IP
dnsTail.usRequestType = htons(DNS_RRTYPE_A);
//根据IP查找域名
//dnsTail.usRequestType = htons(DNS_RRTYPE_PTR); //都是一样的
dnsTail.usRequestClass = htons(DNS_RRTYPE_A);
memcpy(byBuf+pDataPtr,&dnsTail,DNS_TAIL_SIZE);
pDataPtr = pDataPtr + 4;
int iLastLen = pDataPtr;
//return
sendPkg.pData = new BYTE[iLastLen];
memcpy(sendPkg.pData,byBuf,iLastLen);
sendPkg.iDataLen = iLastLen;
}
//根据输入的DomainStr 得到一个StrArray
void CDNSCore::getArrayByDomainStr(const CString &strDomain,CStringArray &arrayStr)
{
//temp
//218.6.168.225 => www.konlink.net
//CString strDomain;
//strDomain.Format("225.6.168.218.in-addr.arpa");
////clean out param
//arrayStr.RemoveAll();
//local
BYTE byChar = 0;
CString strTemp;
for(int i = 0 ; i < strDomain.GetLength() ; ++i)
{
byChar = strDomain.GetAt(i);
if('.' == byChar)
{
arrayStr.Add(strTemp);
//reset
strTemp.Empty();
}
else
{
strTemp += byChar;
}
}
//heihei, 差点忘了
if(!(strTemp.IsEmpty()))
{
arrayStr.Add(strTemp);
}}
//发送一个包包,删除包包的内容
bool CDNSCore::sendDestPackage(
const SOCKET sockLocal,
const SOCKADDR_IN saDest,
SEND_PACKAGE &sendPackage,
const USHORT usSendTimes /* = 1 */
)
{
if (
INVALID_SOCKET == m_sockLocal ||
sendPackage.iDataLen < 1 ||
NULL == sendPackage.pData
)
{
return false;
} bool bRet = true;
for(USHORT i = 0 ; i < usSendTimes; ++i)
{
if(SOCKET_ERROR ==
sendto(
sockLocal,
(const char*)sendPackage.pData,
sendPackage.iDataLen,
0,
(sockaddr* )&(saDest),
sizeof(saDest))
)
{
TRACE("sendPackage Fail::::::::%d\n",WSAGetLastError());
bRet = false;
}
else
{
bRet = true;
TRACE("sendPackage IP %s Port %d DataLength %d Success\n",
inet_ntoa(saDest.sin_addr),
ntohs(saDest.sin_port),
sendPackage.iDataLen
);
//show
HexDump(sendPackage.pData,sendPackage.iDataLen);
//idle
Sleep(13);
}
} delete[] sendPackage.pData;
sendPackage.pData = NULL;
return bRet;
}
//sigh,show
void CDNSCore::HexDump(const unsigned char *buf,int nBufLen)
{
int i ;
for(i = 0; i < nBufLen; i++)
{
TRACE("%02X ",buf[i]);
if(i%16 == 15)
{
TRACE("\n");
}
}
TRACE("\n");}
//接收数据的线程
UINT CDNSCore::ThreadRecvData(LPVOID pParam)
{
CDNSCore* pThis = (CDNSCore*)(pParam);
SOCKADDR_IN saTemp;
int iFromLen = sizeof(saTemp);
while(true)
{
pThis->m_iRecvDataLen =
recvfrom(
pThis->m_sockLocal,
pThis->m_szRecvBuf,
RecvBufSize,
0,
(sockaddr* )&(saTemp),
&iFromLen
);
if(pThis->m_iRecvDataLen > 0)
{
TRACE("\n\nRecv Something from DNSServer::::::::::%d\n",pThis->m_iRecvDataLen);
pThis->m_eventRecvData.SetEvent();
}
//Idle
Sleep(1024);
} return 322;
}