c语言winsock 实现域名解析

c语言实现域名解析 

  1. #include   <stdio.h>   
  2. #include   <Winsock2.h>   
  3. #include   <windows.h>      
  4.   
  5. typedef struct _DNSHEAD{        //dns 头部   
  6.         USHORT ID;   
  7.         USHORT tag; // dns 标志(参数)   
  8.         USHORT numQ;        // 问题数   
  9.         USHORT numA;        // 答案数   
  10.         USHORT numA1;       // 权威答案数   
  11.         USHORT numA2;       // 附加答案数   
  12. }DnsHead;   
  13. typedef struct _DNSQUERY    //dns 查询结构   
  14. {   
  15. //    char   name[64];   
  16. //      //查询的域名,这是一个大小在0到63之间的字符串;   
  17.       USHORT type;   
  18.       //查询类型,大约有20个不同的类型   
  19.       USHORT classes;   
  20.       //查询类,通常是A类既查询IP地址。   
  21.   
  22. }DnsQuery;  
  23.  
  24. #pragma comment(lib,"ws2_32.lib")   
  25.   
  26. // 初始化操作   
  27. bool initWSA();   
  28.   
  29. //显示错误   
  30. void displayErrWSA(char *str);   
  31.   
  32. //创建套接字   
  33. SOCKET CreateSocket(int type);   
  34.   
  35. //UDP sendto   
  36. int MySendto(SOCKET sockTo, const char FAR * buf,int len,char *addr,USHORT port);   
  37.   
  38. //TCP 连接   
  39. bool MyConnect(SOCKET s, char *addr,USHORT );   
  40.   
  41. // UDP recvfrom   
  42. int MyRecvFrom(SOCKET s, char FAR * buf,int len,char *addr,USHORT port);   
  43.   
  44. //设置DNS 头部   
  45. bool SetDNSHead(char *name,char *buf);   
  46.   
  47. int main(int arg,char *are[])    
  48. {   
  49.     int Result=0;   
  50.     char buf[1024]={0};   
  51.     char addr[16] = "61.187.72.8";// dns 服务器地址   
  52.     char *name = 0; //要查询的域名   
  53.        
  54.     if ( !initWSA() )//初始化   
  55.     {   
  56.         displayErrWSA("initWSA err!");   
  57.         return 1;   
  58.     }   
  59.   
  60.     //创建套接字   
  61.     SOCKET sockTo ;   
  62.     if ( (sockTo = CreateSocket(SOCK_DGRAM)) == 0)   
  63.     {   
  64.         displayErrWSA("CreatSocket err!");   
  65.         return 1;   
  66.         }   
  67.     while (1)   
  68.     {   
  69.         if (arg < 2)   
  70.         {   
  71.             char temp[1024]={0};   
  72.             printf("\n请输入要查询的域名:");   
  73.             scanf("%s",temp);   
  74.             if (temp[0] == 'q' ||temp[0] == 'Q')   
  75.             {   
  76.                 break;   
  77.             }   
  78.             name =  temp;   
  79.         }   
  80.         else  
  81.         {   
  82.             arg = 1;   
  83.             name =  are[1];   
  84.         }   
  85.   
  86.         //设置dns 头部   
  87.         SetDNSHead(name,buf);   
  88.            
  89.         //发送出去的请求数据长度   
  90.         int len = sizeof(DnsHead)+sizeof(DnsQuery)+strlen(name)+2;   
  91.            
  92. //      for (int  i =0;i<50;i+=2)   
  93. //      {   
  94. //          printf("%02x",(UCHAR)buf[i]);   
  95. //          printf("%02x ",(UCHAR)buf[i+1]);   
  96. //      }   
  97.         //发送DNS 请求   
  98.         if ( ( Result =MySendto(sockTo,buf,len,addr,53) ) <= 0)   
  99.         {   
  100.             displayErrWSA("sendto err!");   
  101.             continue;   
  102.         }   
  103.            
  104.         //接收应答   
  105.         if ( (Result =MyRecvFrom(sockTo,buf,1024,addr,53) ) <=  0)   
  106.         {   
  107.             displayErrWSA("recvfrom err!");   
  108.             continue;   
  109.         }   
  110.            
  111.         //简单的取得返回的 IP 地址( 收到的最后4字节 )   
  112.         DnsHead *DnsH = (DnsHead *)buf;   
  113.         if (DnsH->numA == 0)   
  114.         {   
  115.             printf("无法解析 %s 的IP 地址。\n",name);   
  116.             continue;   
  117.         }   
  118.         char *getIP =(char *)buf +Result - 4;   
  119.         printf("%s 的IP地址为: ",name);   
  120.         for (int Result= 0 ;Result<4 ;Result++)   
  121.         {   
  122.             printf("%u.",(UCHAR )getIP[Result]);   
  123.         }   
  124.         printf("\n");   
  125.     }   
  126.     return 0;   
  127. }   
  128.   
  129. // 初始化操作   
  130. bool initWSA()   
  131. {   
  132.     WORD   wVersionRequested;    
  133.     WSADATA   wsaData;    
  134.     int Result;   
  135.     wVersionRequested = MAKEWORD( 2, 2 );    
  136.     Result = WSAStartup( wVersionRequested, &wsaData );    
  137.     if(Result   !=   0 )     
  138.     {   
  139.         return false;    
  140.     }    
  141.        
  142.     if( LOBYTE( wsaData.wVersion) != 2 ||    
  143.                 HIBYTE(wsaData.wVersion)!= 2 )   
  144.     {    
  145.         WSACleanup();   
  146.         return false;      
  147.     }    
  148.     return true;   
  149. }   
  150.   
  151. //*********************************************/   
  152. /****************         创建套接字 */  
  153. SOCKET CreateSocket(int type)   
  154. {   
  155.     SOCKET  sock=socket(AF_INET,type,0);   
  156.     if (sock == INVALID_SOCKET )   
  157.     {   
  158.         return 0;   
  159.     }   
  160.     return sock;   
  161. }   
  162.   
  163.   
  164.   
  165. //*********************************************/   
  166. /*****************         UDP sendto*/  
  167. int MySendto(SOCKET sockTo, const char FAR * buf,int len,char *addr,USHORT port)   
  168. {   
  169. //设置发送数据到的 套接字及地址结构   
  170.     SOCKADDR_IN   addrTo;    
  171.     addrTo.sin_addr.S_un.S_addr=inet_addr(addr);   
  172.     addrTo.sin_family=AF_INET;    
  173.     addrTo.sin_port=htons(port);   
  174.   
  175.     return sendto(  sockTo, buf, len, 0,   
  176.                     (sockaddr*)&addrTo, sizeof(sockaddr)  );   
  177.   
  178. }   
  179.   
  180.   
  181. //*********************************************/   
  182. /**************************  TCP 连接*/  
  183. bool MyConnect(SOCKET sockTo, char *addr,USHORT port)   
  184. {   
  185.   
  186.     int   Result;   
  187.   
  188.     //设置连接到的 套接字及地址结构   
  189.     SOCKADDR_IN   addrTo;    
  190.     addrTo.sin_addr.S_un.S_addr=(inet_addr(addr));   
  191.     addrTo.sin_family=AF_INET;    
  192.     addrTo.sin_port=htons(port);   
  193.        
  194.     //连接   
  195.     Result = connect(sockTo,(sockaddr *)&addrTo,sizeof(SOCKADDR_IN));    
  196.     if(SOCKET_ERROR == Result)   
  197.     {   
  198.         return false;   
  199.     }   
  200.     return true;   
  201. }   
  202.   
  203.   
  204.   
  205. //*********************************************/   
  206. /*********************** UDP recvform*/  
  207. int MyRecvFrom(SOCKET s, char FAR * buf,int len,char *addr,USHORT port)   
  208. {   
  209.        
  210.     //设置发送数据到的 套接字及地址结构   
  211.     SOCKADDR_IN   addrFrom;    
  212.     addrFrom.sin_addr.S_un.S_addr=inet_addr(addr);   
  213.     addrFrom.sin_family=AF_INET;    
  214.     addrFrom.sin_port=htons(port);   
  215.     int addrlen = sizeof(SOCKADDR_IN);   
  216.     return recvfrom( s, buf, len, 0, (SOCKADDR *)&addrFrom, &addrlen);   
  217. }   
  218.   
  219.   
  220.   
  221. //*********************************************/   
  222. /********************** 设置DNS 头部 */  
  223. int  ChName(char *fname,char *tname);//域名转化   
  224. bool SetDNSHead(char *name,char *buf)   
  225. {   
  226.   
  227.     memset(buf,0,sizeof(DnsHead));   
  228.   
  229.     //设置头部   
  230.     DnsHead *DnsH = (DnsHead *)buf;   
  231.     DnsH->ID = (USHORT)1;   
  232.     DnsH->tag = htons(0x0100);   
  233.     DnsH->numQ = htons(1);   
  234.     DnsH->numA = 0;   
  235.        
  236.     DnsQuery *DnsQ =(DnsQuery *) ( buf+ sizeof(DnsHead) );   
  237.     int NameLen = ChName(name,(char *)DnsQ);   
  238.        
  239.     //设置查询信息   
  240.     DnsQ = (DnsQuery *)( (char *)DnsQ + NameLen );   
  241.     DnsQ->classes = htons(1);   
  242.     DnsQ->type = htons(1);   
  243.     return true;   
  244. }   
  245.   
  246.   
  247.   
  248. //显示错误信息   
  249. void displayErrWSA(char *str)   
  250. {   
  251.     printf("\n%s,err = %d\n",str,WSAGetLastError());   
  252.     getchar();   
  253. }   
  254.   
  255.   
  256. //域名转化   
  257. int  ChName(char *fname,char *tname)   
  258. {   
  259.        
  260.     int j =0;   
  261.     int i =strlen(fname)-1;   
  262.     tname[i+2] = 0;   
  263.     int k = i+1;   
  264.     for (; i>=0;i--,k--)   
  265.     {   
  266.         if (fname[i] == '.')   
  267.         {   
  268.             tname[k] = j;   
  269.             j=0;   
  270.         }   
  271.         else  
  272.         {   
  273.             tname[k] = fname[i];   
  274.             j++;   
  275.         }   
  276.     }   
  277.     tname[k] = j;   
  278.     return strlen(tname)+1;   
  279. }  


文章来自: 本站原创
Tags:
评论: 0 | 查看次数: 12831