c语言实现域名解析

来源:互联网 发布:相机特效软件 编辑:程序博客网 时间:2024/05/01 15:30

来源:c语言实现域名解析

对原文进行了一点小修改,原文可能是在C++环境编译的,比如“.cpp”后缀的文件编译的,“.cpp”文件默认以C++方式编译,所以原文如果复制保存为“.c”后缀的,编译是通不过的,很多错误。以下是修改过后的代码,DNS请修改为自己所在区域的DNS地址,经测试,直接使用路由IP也可。域名输入例如:“www.baidu.net”,不含引号。测试“www.csdn.net”得到的IP在浏览器打开不是csdn,不知道为什么,其他域名未测试。

c语言实现域名解析:

#include   <stdio.h>#include   <Winsock2.h>#include   <windows.h>typedef enum {false = 0, true = !false}bool;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 sendtoint MySendto(SOCKET sockTo, const char FAR * buf,int len,char *addr,USHORT port);//TCP 连接bool MyConnect(SOCKET s, char *addr,USHORT );// UDP recvfromint MyRecvFrom(SOCKET s, char FAR * buf,int len,char *addr,USHORT port);//设置DNS 头部bool SetDNSHead(char *name,char *buf);int main(int arg,char *are[]){    int Result=0;    char buf[1024]={0};    char addr[16] = "192.168.1.1";// dns 服务器地址    char *name = 0; //要查询的域名    SOCKET sockTo;    int len;    DnsHead *DnsH;    char *getIP;    //int i;        if ( !initWSA() )//初始化    {        displayErrWSA("initWSA err!");        return 1;    }        //创建套接字    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);                //发送出去的请求数据长度        len = sizeof(DnsHead)+sizeof(DnsQuery)+strlen(name)+2;                //      for (int  i =0;i<50;i+=2)        //      {        //          printf("x",(UCHAR)buf[i]);        //          printf("x ",(UCHAR)buf[i+1]);        //      }        //发送DNS 请求        if ( ( Result =MySendto(sockTo,buf,len,addr,53) ) <= 0)        {            displayErrWSA("sendto err!");            continue;        }                //接收应答        if ( (Result =MyRecvFrom(sockTo,buf,1024,addr,53) ) <=  0)        {            displayErrWSA("recvfrom err!");            continue;        }                //简单的取得返回的 IP 地址( 收到的最后4字节 )        DnsH = (DnsHead *)buf;        if (DnsH->numA == 0)        {            printf("无法解析 %s 的IP 地址。\n",name);            continue;        }        getIP =(char *)buf +Result - 4;        printf("%s 的IP地址为: ",name);        for (Result= 0 ;Result<4 ;Result++)        {            printf("%u.",(UCHAR )getIP[Result]);        }        printf("\n");    }    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;}int MySendto(SOCKET sockTo, const char FAR * buf,int len,char *addr,USHORT port){    //设置发送数据到的 套接字及地址结构    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,        (struct sockaddr *)&addrTo, sizeof(struct sockaddr)  );}bool MyConnect(SOCKET sockTo, char *addr,USHORT port){        int   Result;        //设置连接到的 套接字及地址结构    SOCKADDR_IN   addrTo;    addrTo.sin_addr.S_un.S_addr=(inet_addr(addr));    addrTo.sin_family=AF_INET;    addrTo.sin_port=htons(port);        //连接    Result = connect(sockTo,(struct sockaddr *)&addrTo,sizeof(SOCKADDR_IN));    if(SOCKET_ERROR == Result)    {        return false;    }    return true;}int MyRecvFrom(SOCKET s, char FAR * buf,int len,char *addr,USHORT port){        //设置发送数据到的 套接字及地址结构    int addrlen;    SOCKADDR_IN   addrFrom;    addrFrom.sin_addr.S_un.S_addr=inet_addr(addr);    addrFrom.sin_family=AF_INET;    addrFrom.sin_port=htons(port);    addrlen = sizeof(SOCKADDR_IN);    return recvfrom( s, buf, len, 0, (SOCKADDR *)&addrFrom, &addrlen);}int  ChName(char *fname,char *tname);//域名转化bool SetDNSHead(char *name,char *buf){    DnsHead *DnsH;    DnsQuery *DnsQ;    int NameLen;    memset(buf,0,sizeof(DnsHead));        //设置头部    DnsH = (DnsHead *)buf;    DnsH->ID = (USHORT)1;    DnsH->tag = htons(0x0100);    DnsH->numQ = htons(1);    DnsH->numA = 0;        DnsQ =(DnsQuery *) ( buf+ sizeof(DnsHead) );    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;    int k = i+1;    tname[i+2] = 0;    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;}