📄 dns_v1.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 + -