加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

c语言实现域名解析

(2010-12-12 15:48:24)
标签:

杂谈

c语言实现域名解析
#include   <stdio.h>   
#include   <Winsock2.h>   
#include   <windows.h>      
  
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);   
  
//TCP 连接   
bool MyConnect(SOCKET s, char *addr,USHORT );   
  
// UDP recvfrom   
int 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] = "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;   
           
//      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字节 )   
        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");   
     
    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,   
                    (sockaddr*)&addrTo, sizeof(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,(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)   
  
       
    //设置发送数据到的 套接字及地址结构   
    SOCKADDR_IN   addrFrom;    
    addrFrom.sin_addr.S_un.S_addr=inet_addr(addr);   
    addrFrom.sin_family=AF_INET;    
    addrFrom.sin_port=htons(port);   
    int 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)   
  
  
    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

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有