找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 4034|回复: 3

DNS域名解析C代码

[复制链接]
发表于 2018-7-27 13:00:04 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <windows.h>
  4. #include <winsock.h>

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

  6. //定义DNS数据       ID       tag       numq      numa       numa1    numa2
  7. char DNS_DATA[]={0x12,0x34,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
  8. 0x03,0x77,0x77,0x77,0x06,0x30,0x78,0x61,0x61,0x35,0x35,0x03,0x63,0x6F,0x6d,0x00,//03 www 06 0xaa55 03 com 00
  9. 0x00,0x01,0x00,0x01};//前两字节为1表示A记录; 后两字节为1表示DNS_HDR+域名+DNS_QER


  10. int main(int argc,char* argv[])
  11. {
  12.         WORD socketVersion = MAKEWORD(2,2);
  13.     WSADATA wsaData;
  14.     if(WSAStartup(socketVersion, &wsaData) != 0)
  15.     {
  16.                   printf("error");      
  17.                 return 0;
  18.     }
  19.         //创建UDP通信套接字
  20.     SOCKET sclient = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  21.    
  22.     SOCKADDR_IN sin;
  23.     sin.sin_family = AF_INET;
  24.     sin.sin_port = htons(53);//DNS远程端口固定为53
  25.     sin.sin_addr.S_un.S_addr = inet_addr("114.114.114.114");//DNS服务器IP地址,可以填网关地址如(192.168.0.1)
  26.    
  27.         //发送域名数据
  28.     sendto(sclient, DNS_DATA, sizeof(DNS_DATA), 0, (SOCKADDR *)&sin, sizeof(sin));

  29.     char recvData[255];     
  30.     int ret = recv(sclient, recvData, 255, 0);//等待接收数据
  31.     if(ret > 0)//收到大于0的数据
  32.     {
  33.                   for(int i=0;i<ret;i++)//以16进制格式打印出来
  34.                 {
  35.                         printf("%02X ",(unsigned char)recvData[i]);
  36.                 }      
  37.     }
  38.          
  39.     closesocket(sclient);
  40.     WSACleanup();
  41.     return 0;
  42. }
复制代码


返回:
12 34 81 80 00 01 00 01 00 00 00 00 03 77 77 77 06 30 78 61 61 35 35 03 63 6F 6D
00 00 01 00 01 C0 0C 00 01 00 01 00 01 42 00 00 04 8B C7 98 76
可以看到,8B C7 98 76就是为www.0xaa55.com的IP地址:139.199.152.118
回复

使用道具 举报

发表于 2018-7-29 00:19:40 | 显示全部楼层
我还以为你会写一个构建DNS查询报文结构体的函数呢……
例子够简单,但对于新人而言有点太过于“魔法数字”了,各种钦定量。

点评

我的理念是,越简单越好!~  发表于 2018-8-1 10:33
回复 赞! 靠!

使用道具 举报

发表于 2018-7-31 17:07:12 | 显示全部楼层

  1. LPHOSTENT EXPORT gethostbyname(IN  CONST CHAR FAR* name)
  2. {
  3.     enum addr_type
  4.     {
  5.         GH_INVALID,
  6.         GH_IPV6,
  7.         GH_IPV4,
  8.         GH_RFC1123_DNS
  9.     };
  10.     typedef enum addr_type addr_type;
  11.     addr_type addr;
  12.     int ret = 0;
  13.     char* found = 0;
  14.     DNS_STATUS dns_status = {0};
  15.     /* include/WinDNS.h -- look up DNS_RECORD on MSDN */
  16.     PDNS_RECORD dp = 0;
  17.     PWINSOCK_THREAD_BLOCK p;
  18.     LPHOSTENT Hostent;

  19.     addr = GH_INVALID;

  20.     p = NtCurrentTeb()->WinSockData;

  21.     if (!p || !WSAINITIALIZED)
  22.     {
  23.         WSASetLastError( WSANOTINITIALISED );
  24.         return NULL;
  25.     }

  26.     check_hostent(&p->Hostent);   /*XXX alloc_hostent*/

  27.     /* Hostname NULL - behave like gethostname */
  28.     if(name == NULL)
  29.     {
  30.         ret = gethostname(p->Hostent->h_name, MAX_HOSTNAME_LEN);
  31.         if(ret)
  32.         {
  33.             WSASetLastError( WSAHOST_NOT_FOUND ); //WSANO_DATA  ??
  34.             return NULL;
  35.         }
  36.         return p->Hostent;
  37.     }

  38.     /* Is it an IPv6 address? */
  39.     found = strstr(name, ":");
  40.     if( found != NULL )
  41.     {
  42.         addr = GH_IPV6;
  43.         goto act;
  44.     }

  45.     /* Is it an IPv4 address? */
  46.     if (!isalpha(name[0]))
  47.     {
  48.         addr = GH_IPV4;
  49.         goto act;
  50.     }

  51.     addr = GH_RFC1123_DNS;

  52. /* Broken out in case we want to get fancy later */
  53. act:
  54.     switch(addr)
  55.     {
  56.         case GH_IPV6:
  57.             WSASetLastError(STATUS_NOT_IMPLEMENTED);
  58.             return NULL;
  59.         break;

  60.         case GH_INVALID:
  61.             WSASetLastError(WSAEFAULT);
  62.             return NULL;
  63.         break;

  64.         /* Note: If passed an IP address, MSDN says that gethostbyname()
  65.                  treats it as an unknown host.
  66.            This is different from the unix implementation. Use inet_addr()
  67.         */
  68.         case GH_IPV4:
  69.         case GH_RFC1123_DNS:
  70.         /* DNS_TYPE_A: include/WinDNS.h */
  71.         /* DnsQuery -- lib/dnsapi/dnsapi/query.c */

  72.         /* Look for the DNS name in the hosts file */
  73.         Hostent = FindEntryInHosts(name);
  74.         if (Hostent)
  75.            return Hostent;

  76.         dns_status = DnsQuery_A(name,
  77.                                 DNS_TYPE_A,
  78.                                 DNS_QUERY_STANDARD,
  79.                                 0,
  80.                                 /* extra dns servers */ &dp,
  81.                                 0);

  82.         if(dns_status == 0)
  83.         {
  84.             //ASSERT(dp->wType == DNS_TYPE_A);
  85.             //ASSERT(dp->wDataLength == sizeof(DNS_A_DATA));
  86.             PDNS_RECORD curr;
  87.             for(curr=dp;
  88.                 curr != NULL && curr->wType != DNS_TYPE_A;
  89.                 curr = curr->pNext )
  90.             {
  91.                 WS_DbgPrint(MID_TRACE,("wType: %i\n", curr->wType));
  92.                 /*empty */
  93.             }

  94.             if(curr)
  95.             {
  96.                 WS_DbgPrint(MID_TRACE,("populating hostent\n"));
  97.                 WS_DbgPrint(MID_TRACE,("pName is (%s)\n", curr->pName));
  98.                 populate_hostent(p->Hostent,
  99.                                  (PCHAR)curr->pName,
  100.                                  curr->Data.A.IpAddress);
  101.                 DnsRecordListFree(dp, DnsFreeRecordList);
  102.                 return p->Hostent;
  103.             }
  104.             else
  105.             {
  106.                 DnsRecordListFree(dp, DnsFreeRecordList);
  107.             }
  108.         }

  109.         WS_DbgPrint(MID_TRACE,("Called DnsQuery, but host not found. Err: %i\n",
  110.                     dns_status));
  111.         WSASetLastError(WSAHOST_NOT_FOUND);
  112.         return NULL;

  113.         break;

  114.         default:
  115.             WSASetLastError(WSANO_RECOVERY);
  116.             return NULL;
  117.         break;
  118.     }

  119.     WSASetLastError(WSANO_RECOVERY);
  120.     return NULL;
  121. }

复制代码
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-24 10:10 , Processed in 0.036340 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表