技术宅的结界

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

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 213|回复: 3
收起左侧

DNS域名解析C代码

[复制链接]

11

主题

44

帖子

340

积分

用户组: 中·技术宅

UID
2285
精华
0
威望
28 点
宅币
240 个
贡献
0 次
宅之契约
0 份
在线时间
26 小时
注册时间
2017-2-25
发表于 2018-7-27 13:00:04 | 显示全部楼层 |阅读模式

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

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

x
[C] 纯文本查看 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winsock.h>
 
#pragma comment(lib,"ws2_32.lib")
 
//定义DNS数据       ID       tag       numq      numa       numa1    numa2
char DNS_DATA[]={0x12,0x34,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
0x03,0x77,0x77,0x77,0x06,0x30,0x78,0x61,0x61,0x35,0x35,0x03,0x63,0x6F,0x6d,0x00,//03 www 06 0xaa55 03 com 00
0x00,0x01,0x00,0x01};//前两字节为1表示A记录; 后两字节为1表示DNS_HDR+域名+DNS_QER
 
 
int main(int argc,char* argv[])
{
	WORD socketVersion = MAKEWORD(2,2);
    WSADATA wsaData; 
    if(WSAStartup(socketVersion, &wsaData) != 0)
    {
  		printf("error");      
		return 0;
    }
	//创建UDP通信套接字
    SOCKET sclient = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    
    SOCKADDR_IN sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(53);//DNS远程端口固定为53
    sin.sin_addr.S_un.S_addr = inet_addr("114.114.114.114");//DNS服务器IP地址,可以填网关地址如(192.168.0.1)
    
	//发送域名数据
    sendto(sclient, DNS_DATA, sizeof(DNS_DATA), 0, (SOCKADDR *)&sin, sizeof(sin));
 
    char recvData[255];     
    int ret = recv(sclient, recvData, 255, 0);//等待接收数据
    if(ret > 0)//收到大于0的数据
    {
  		for(int i=0;i<ret;i++)//以16进制格式打印出来
		{
			printf("%02X ",(unsigned char)recvData[i]);
		}      
    }
	 
    closesocket(sclient);
    WSACleanup();
    return 0;
}


返回:
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

996

主题

2213

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
197
威望
261 点
宅币
16510 个
贡献
32858 次
宅之契约
0 份
在线时间
1574 小时
注册时间
2014-1-26
发表于 2018-7-29 00:19:40 | 显示全部楼层
我还以为你会写一个构建DNS查询报文结构体的函数呢……
例子够简单,但对于新人而言有点太过于“魔法数字”了,各种钦定量。

点评

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

266

主题

438

帖子

4597

积分

用户组: 真·技术宅

UID
2
精华
61
威望
147 点
宅币
3435 个
贡献
125 次
宅之契约
0 份
在线时间
593 小时
注册时间
2014-1-25
发表于 2018-7-31 17:07:12 | 显示全部楼层
[C] 纯文本查看 复制代码
LPHOSTENT EXPORT gethostbyname(IN  CONST CHAR FAR* name)
{
    enum addr_type
    {
        GH_INVALID,
        GH_IPV6,
        GH_IPV4,
        GH_RFC1123_DNS
    };
    typedef enum addr_type addr_type;
    addr_type addr;
    int ret = 0;
    char* found = 0;
    DNS_STATUS dns_status = {0};
    /* include/WinDNS.h -- look up DNS_RECORD on MSDN */
    PDNS_RECORD dp = 0;
    PWINSOCK_THREAD_BLOCK p;
    LPHOSTENT Hostent;

    addr = GH_INVALID;

    p = NtCurrentTeb()->WinSockData;

    if (!p || !WSAINITIALIZED)
    {
        WSASetLastError( WSANOTINITIALISED );
        return NULL;
    }

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

    /* Hostname NULL - behave like gethostname */
    if(name == NULL)
    {
        ret = gethostname(p->Hostent->h_name, MAX_HOSTNAME_LEN);
        if(ret)
        {
            WSASetLastError( WSAHOST_NOT_FOUND ); //WSANO_DATA  ??
            return NULL;
        }
        return p->Hostent;
    }

    /* Is it an IPv6 address? */
    found = strstr(name, ":");
    if( found != NULL )
    {
        addr = GH_IPV6;
        goto act;
    }

    /* Is it an IPv4 address? */
    if (!isalpha(name[0]))
    {
        addr = GH_IPV4;
        goto act;
    }

    addr = GH_RFC1123_DNS;

 /* Broken out in case we want to get fancy later */
 act:
    switch(addr)
    {
        case GH_IPV6:
            WSASetLastError(STATUS_NOT_IMPLEMENTED);
            return NULL;
        break;

        case GH_INVALID:
            WSASetLastError(WSAEFAULT);
            return NULL;
        break;

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

        /* Look for the DNS name in the hosts file */
        Hostent = FindEntryInHosts(name);
        if (Hostent)
           return Hostent;

        dns_status = DnsQuery_A(name,
                                DNS_TYPE_A,
                                DNS_QUERY_STANDARD,
                                0,
                                /* extra dns servers */ &dp,
                                0);

        if(dns_status == 0)
        {
            //ASSERT(dp->wType == DNS_TYPE_A);
            //ASSERT(dp->wDataLength == sizeof(DNS_A_DATA));
            PDNS_RECORD curr;
            for(curr=dp;
                curr != NULL && curr->wType != DNS_TYPE_A;
                curr = curr->pNext )
            {
                WS_DbgPrint(MID_TRACE,("wType: %i\n", curr->wType));
                /*empty */
            }

            if(curr)
            {
                WS_DbgPrint(MID_TRACE,("populating hostent\n"));
                WS_DbgPrint(MID_TRACE,("pName is (%s)\n", curr->pName));
                populate_hostent(p->Hostent,
                                 (PCHAR)curr->pName,
                                 curr->Data.A.IpAddress);
                DnsRecordListFree(dp, DnsFreeRecordList);
                return p->Hostent;
            }
            else
            {
                DnsRecordListFree(dp, DnsFreeRecordList);
            }
        }

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

        break;

        default:
            WSASetLastError(WSANO_RECOVERY);
            return NULL;
        break;
    }

    WSASetLastError(WSANO_RECOVERY);
    return NULL;
}
 

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号|网站地图

GMT+8, 2018-10-19 10:34 , Processed in 0.110989 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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