c语言修改windows dns,c语言winsock 实现简单的域名解析功能(DNS. v 1.0)

/**************************************

** 实现简单的DNS 学习、测试之用

** VC6.0 winXP 编译通过

** 20100406  v1.0

** from http://blog.csdn.net/jxfgh

************************************/

#include  

#include  

#include  

typedef struct _DNSHEAD{   //dns 头部

USHORT ID;

USHORT tag;   // dns 标志(参数)

USHORT numQ;  // 问题数

USHORT numA;  // 答案数

USHORT numA1;  // 权威答案数

USHORT numA2;  // 附加答案数

}DnsHead;

typedef struct _DNSQUERY //dns 查询结构

{

//    char   name[64];

//   //查询的域名,这是一个大小在0到63之间的字符串;

USHORT type;

//查询类型,大约有20个不同的类型

USHORT classes;

//查询类,通常是A类既查询IP地址。

}DnsQuery;

#pragma comment(lib,"ws2_32.lib")

// 初始化操作

bool initWSA();

//显示错误

void displayErrWSA(char *str);

//创建套接字

SOCKET CreateSocket(int type);

//UDP sendto

int MySendto(SOCKET sockTo, const char FAR * buf,int len,char *addr,USHORT port);

// UDP recvfrom

int MyRecvFrom(SOCKET s, char FAR * buf,int len);

//设置DNS 头部

bool SetDNSHead(char *name,char *buf);

int main(int arg,char *are[])

{

int Result=0;

char buf[1024]={0};

char addr[16] = "61.187.72.8";// dns 服务器地址

char *name = 0; //要查询的域名

if ( !initWSA() )//初始化

{

displayErrWSA("initWSA err!");

return 1;

}

//创建套接字

SOCKET sockTo ;

if ( (sockTo = CreateSocket(SOCK_DGRAM)) == 0)

{

displayErrWSA("CreatSocket err!");

return 1;

}

while (1)

{

if (arg < 2)

{

char temp[1024]={0};

printf("/n请输入要查询的域名:");

scanf("%s",temp);

if (temp[0] == 'q' ||temp[0] == 'Q')

{

break;

}

name =  temp;

}

else

{

arg = 1;

name =  are[1];

}

//设置dns 头部

SetDNSHead(name,buf);

//发送出去的请求数据长度

int len = sizeof(DnsHead)+sizeof(DnsQuery)+strlen(name)+2;

//发送DNS 请求

if ( ( Result =MySendto(sockTo,buf,len,addr,53) ) <= 0)

{

displayErrWSA("sendto err!");

continue;

}

//接收应答

if ( (Result =MyRecvFrom(sockTo,buf,1024) ) <=  0)

{

displayErrWSA("recvfrom err!");

continue;

}

//简单的取得返回的 IP 地址( 收到的最后4字节 )

DnsHead *DnsH = (DnsHead *)buf;

if (DnsH->numA == 0)

{

printf("无法解析 %s 的IP 地址。/n",name);

continue;

}

char *getIP =(char *)buf +Result - 4;

printf("%s 的IP地址为: ",name);

for (int Result= 0 ;Result<4 ;Result++)

{

printf("%u.",(UCHAR )getIP[Result]);

}

printf("/n");

}

closesocket(sockTo);

return 0;

}

// 初始化操作

bool initWSA()

{

WORD   wVersionRequested;

WSADATA   wsaData;

int Result;

wVersionRequested = MAKEWORD( 2, 2 );

Result = WSAStartup( wVersionRequested, &wsaData );

if(Result   !=   0 )

{

return false;

}

if( LOBYTE( wsaData.wVersion) != 2 ||

HIBYTE(wsaData.wVersion)!= 2 )

{

WSACleanup();

return false;

}

return true;

}

//*********************************************/

/****************         创建套接字 */

SOCKET CreateSocket(int type)

{

SOCKET sock=socket(AF_INET,type,0);

if (sock == INVALID_SOCKET )

{

return 0;

}

return sock;

}

//*********************************************/

/*****************         UDP sendto*/

int MySendto(SOCKET sockTo, const char FAR * buf,int len,char *addr,USHORT port)

{

if (addr[0]'9') //addr 中不是IP 地址,域名解析

{

struct   sockaddr_in   addr_in;

HOSTENT *host = NULL;

host = gethostbyname(addr);//域名解析函数

if ( host->h_addr_list[0]!=NULL )

{

memcpy  ( &addr_in.sin_addr.s_addr,

host->h_addr_list[0], host->h_length);

addr = inet_ntoa(addr_in.sin_addr);

}

}

//设置发送数据到的 套接字及地址结构

SOCKADDR_IN   addrTo;

addrTo.sin_addr.S_un.S_addr=inet_addr(addr);

addrTo.sin_family=AF_INET;

addrTo.sin_port=htons(port);

return sendto(  sockTo, buf, len, 0,

(sockaddr*)&addrTo, sizeof(sockaddr)  );

}

//*********************************************/

/*********************** UDP recvform*/

int MyRecvFrom(SOCKET s, char FAR * buf,int len)

{

//设置发送数据到的 套接字及地址结构

SOCKADDR_IN   addrFrom;

int addrlen = sizeof(SOCKADDR_IN);

return recvfrom( s, buf, len, 0, (SOCKADDR *)&addrFrom, &addrlen);

}

//*********************************************/

/********************** 设置DNS 头部 */

int  ChName(char *fname,char *tname);//域名转化

bool SetDNSHead(char *name,char *buf)

{

memset(buf,0,sizeof(DnsHead));

//设置头部

DnsHead *DnsH = (DnsHead *)buf;

DnsH->ID = (USHORT)1;

DnsH->tag = htons(0x0100);

DnsH->numQ = htons(1);

DnsH->numA = 0;

DnsQuery *DnsQ =(DnsQuery *) ( buf+ sizeof(DnsHead) );

int NameLen = ChName(name,(char *)DnsQ);

//设置查询信息

DnsQ = (DnsQuery *)( (char *)DnsQ + NameLen );

DnsQ->classes = htons(1);

DnsQ->type = htons(1);

return true;

}

//显示错误信息

void displayErrWSA(char *str)

{

printf("/n%s,err = %d/n",str,WSAGetLastError());

getchar();

}

//域名转化 int  ChName(char *fname,char *tname) {    int j =0;  int i =strlen(fname)-1;  tname[i+2] = 0;  int k = i+1;  for (; i>=0;i--,k--)  {   if (fname[i] == '.')   {    tname[k] = j;    j=0;   }   else   {    tname[k] = fname[i];    j++;   }  }  tname[k] = j;  return strlen(tname)+1; }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值