0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

教你动手写UDP协议栈—DNS报文解析

电子设计 来源:电子设计 作者:电子设计 2020-12-24 16:16 次阅读

教你动手写UDP协议栈系列文章序号内容1《教你动手写UDP协议栈-UDP协议栈格式》2《教你动手写UDP协议栈-DHCP报文解析》3《教你动手写UDP协议栈-OTA上位机》4《教你动手写UDP协议栈-DNS报文解析》背景因特网上的节点通过IP地址唯一标识,并且能通过IP地址来识别参与分布式应用的主机。但对于大多数人来说,这些地址太繁琐而且难以使用和记忆(特别是IPV6地址)。因此互联网支持使用主机名称来识别包括客户机和服务器在内的主机。

为了使用如TCP和IP等协议,主机名称可以通过称为域名解析的过程转换成IP地址。在互联网中存在不同形式的名称解析,但是最普遍、最重要的一种是采用分布式数据库系统,即我们熟知的域名系统(DNS),也是这篇文章的主角。DNS - 是一个分布式的客户机-服务器网络数据库,TCP/IP应用程序使用它来完成主机名称和IP地址之间的映射,提供电子邮件路由信息、服务命名和其他服务。DNS使用TCP和UDP的端口--53。DNS - 为了可扩展性,DNS名称是分层的。每一级域名长度的限制是63个字符,域名总长度则不能超过253个字符。下面来介绍DNS报文的格式解析,以及如何将域名转为IP地址的流程。准备工具工具介绍WireShark网络封包分析软件,分析数据包CMDwindow 命令行DNS报文解析抓包分析打开CMD和WireShark工具。在WireShark中设置过滤信息,我们只抓取DNS报文。在CMD键入ping www.baidu.com,然后查看WireShark的抓包信息。

可以看到两包DNS报文,一个是DNS发送报文,一个是DNS接收报文发送报文

接收报文

发送报文和接收报文格式是不一样的,从上面截图可以看到,接收报文多一个Answers字段。

DNS可以使用UDP与TCP两种协议。这里我们主要以UDP进行分析。

DNS报文字段解析DNS报文格式:

DNS字段格式:发送报文

接收报文

DNS报文头部

字段说明字段说明Transaction ID辨别DNS应答报文是哪个请求报文的响应QRFlags字段,1为响应,0位查询OpCodeFlags字段,查询或响应类型,0为标准,1为反向,2为服务器状态请求AAFlags字段,授权回答TCFlags字段,截断,1表示超过512字节并已被截断,0表示没有发送截断RDFlags字段,是否希望得到递归回答RAFlags字段,响应报文中为1便是得到递归响应ZFlags字段,0ADFlags字段,真是数据CDFlags字段,禁止校验RCODEFlags字段,返回码:0-无差错,1-格式错误,2-服务器失效,3-不存在域名,4-查询类型不支持,5-被禁止,6-15保留QuestionsFlags字段,查询数AnswerFlags字段,资源记录数AuthorityFlags字段,授权资源记录数AdditionalFlags字段,额外资源记录数代码实现/** DNS message header */PACK_STRUCT_BEGINstruct dns_header { PACK_STRUCT_FIELD(uint16_t id); PACK_STRUCT_FIELD(uint8_t flags1); PACK_STRUCT_FIELD(uint8_t flags2); PACK_STRUCT_FIELD(uint16_t numquestions); PACK_STRUCT_FIELD(uint16_t numanswers); PACK_STRUCT_FIELD(uint16_t numauthrr); PACK_STRUCT_FIELD(uint16_t numextrarr);}PACK_STRUCT_STRUCT;PACK_STRUCT_ENDDNS报文问题字段

字段说明查询名称格式:

字段说明name查询名称,不定长type查询类型class查询类代码实现(由于名字是不定长,另作处理)PACK_STRUCT_BEGINstruct dns_query { PACK_STRUCT_FIELD(uint16_t type); PACK_STRUCT_FIELD(uint16_t class);}PACK_STRUCT_STRUCT;PACK_STRUCT_ENDDNS报文应答字段

字段说明(此字段只有应答包才有)字段说明name查询名称,不定长type查询类型class查询类TTL该资源记录的生命周期data length资源数据长度address返回的IP地址,即域名转换的IP地址代码实现struct dns_answer { PACK_STRUCT_FIELD(uint16_t name); PACK_STRUCT_FIELD(uint16_t type); PACK_STRUCT_FIELD(uint16_t class); PACK_STRUCT_FIELD(uint32_t ttl); PACK_STRUCT_FIELD(uint16_t len); PACK_STRUCT_FIELD(struct ip_addr server_ip);}PACK_STRUCT_STRUCT;PACK_STRUCT_ENDDNS报文发送实现代码实现static void dns_packet_output(uint8_t *host_name){ struct dns_header dns_hdr = {0}; struct dns_query dns_qry = {0}; struct dest_device_info dest_info = {0}; uint8_t *dns_packet = NULL; uint8_t *dns_name = NULL; uint16_t query_index = 0; uint16_t label_len = 0; uint16_t dns_name_len = strlen(host_name) + 2;
dns_packet = malloc(DNS_HDR_SIZE + dns_name_len + DNS_QUERY_SIZE); dns_name = malloc(strlen(host_name) + 2);
if(dns_packet != NULL && dns_name !=NULL) { //打包DNS header memset(&dns_hdr, 0, DNS_HDR_SIZE); dns_hdr.id = mu_htons(TRANSACTION_ID); dns_hdr.flags1 = DNS_FLAG1_RD; dns_hdr.numquestions = mu_htons(1); memcpy(dns_packet, &dns_hdr, DNS_HDR_SIZE);
//将域名转换DNS数据包格式 change_to_dns_name(dns_name, host_name);
memcpy(dns_packet + DNS_HDR_SIZE, dns_name, dns_name_len);
dns_qry.type = mu_htons(DNS_RRTYPE_A); dns_qry.class = mu_htons(DNS_RRCLASS_IN); //打包DNS query memcpy(dns_packet + DNS_HDR_SIZE + dns_name_len, &dns_qry, DNS_QUERY_SIZE);
memcpy(&dest_info.dest_mac, get_gw_mac(), MAC_ADDR_SIZE); memcpy(&dest_info.dest_ip, get_dns_server(), IP_ADDR_SIZE); dest_info.src_port = DNS_CLIENT_PORT; dest_info.dest_port = DNS_SERVER_PORT; //通过UDP报文发送 mini_udp_output(&dest_info, dns_packet, (DNS_HDR_SIZE + dns_name_len + DNS_QUERY_SIZE)); }
if(dns_packet != NULL) { free(dns_packet); } if(dns_name != NULL) { free(dns_name); }}验证代码结果,我们通过查询CSDN的IP地址,CSDN的域名:www.csdn.net

通过wireshark抓包,可以看到我们DNS报文已发送成功,并且有应答包

DNS报文接收实现代码实现static void dns_packet_input(void *dns_packet_data){ struct dns_header *dns_hdr = {0}; struct dns_answer *dns_ans = {0}; uint16_t dns_name_len = strlen("www.csdn.net") + 2; uint8_t *server_dns_name = malloc(strlen("www.csdn.net") + 2);
if(server_dns_name == NULL) { LOG_E("malloc fail!!"); return; }
dns_hdr = dns_packet_data; if(dns_hdr->id == mu_ntohs(TRANSACTION_ID) && (dns_hdr->numanswers > 1)) { change_to_dns_name(server_dns_name, "www.csdn.net");
if(strncmp(dns_packet_data + DNS_HDR_SIZE, server_dns_name, dns_name_len) == 0) { dns_ans = dns_packet_data + DNS_HDR_SIZE + dns_name_len + DNS_QUERY_SIZE;
printf("CSDN IP: %d:%d:%d:%d ", dns_ans->server_ip.addr[0], dns_ans->server_ip.addr[1], dns_ans->server_ip.addr[2], dns_ans->server_ip.addr[3]); } } free(server_dns_name);}通过wireshark抓包的IP与代码捕获的IP一致:

审核编辑:符乾江


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • DNS
    DNS
    +关注

    关注

    0

    文章

    199

    浏览量

    19604
  • UDP协议栈
    +关注

    关注

    0

    文章

    4

    浏览量

    1100
收藏 人收藏

    评论

    相关推荐

    udp是什么协议udp协议介绍

    UDP(User Datagram Protocol,用户数据报协议)是一种无连接的传输层协议,不保证数据传输的可靠性,只负责把数据包发送给目标地址。它提供了简单、高效的数据传输方式,适合对传输质量
    的头像 发表于 04-19 15:57 108次阅读

    通信必备知识!TCP与UDP协议介绍及使用

    协议,它在数据传输之前不需要建立连接。发送端可以直接将数据报文(数据段)扔到网络上,而接收端则从网络中接收数据,并从消息队列中读取数据段。UDP不提供可靠性和顺序
    的头像 发表于 03-15 08:19 1016次阅读
    通信必备知识!TCP与<b class='flag-5'>UDP</b><b class='flag-5'>协议</b>介绍及使用

    通信网络协议栈之UDP协议技术解析

    在通常的网络协议栈中,TCP/IP协议栈是一个常见的示例,其中UDP和TCP都是传输层协议。传输层负责提供端到端的数据传输服务,它在网络层(如IP
    发表于 02-01 11:00 204次阅读
    通信网络<b class='flag-5'>协议</b>栈之<b class='flag-5'>UDP</b><b class='flag-5'>协议</b>技术<b class='flag-5'>解析</b>

    接收UDP报文的过程

    最近工作中遇到某个服务器应用程序 UDP 丢包,在排查过程中查阅了很多资料,总结出来这篇文章,供更多人参考。 在开始之前,我们先用一张图解释 linux 系统接收网络报文的过程。 首先网络报文通过
    的头像 发表于 11-11 11:22 472次阅读
    接收<b class='flag-5'>UDP</b><b class='flag-5'>报文</b>的过程

    UDP协议的原理

    为啥要自己写一个mini UDP协议栈?因为我们干偷偷摸摸的事情,哈哈哈!!! 其实是为了不跑一个庞大的LWIP协议栈,通过自己写的mini udp
    的头像 发表于 11-10 10:08 293次阅读
    <b class='flag-5'>UDP</b><b class='flag-5'>协议</b>的原理

    UDP有发送缓存区吗?如何解决UDP丢包的问题呢?

    每个 UDP 报文分为 UDP 报头和 UDP 数据区两部分。报头由 4 个 16 位长(2 字节)字段组成,分别说明该报文的源端口、目的端
    的头像 发表于 08-15 09:33 5243次阅读
    <b class='flag-5'>UDP</b>有发送缓存区吗?如何解决<b class='flag-5'>UDP</b>丢包的问题呢?

    什么是UDP协议?什么场景下会去用这种协议呢?

    传输层除了TCP协议,还有个很重要的协议UDP协议。接下来看下UDP协议是个什么东西,它又是怎
    发表于 07-10 15:50 696次阅读
    什么是<b class='flag-5'>UDP</b><b class='flag-5'>协议</b>?什么场景下会去用这种<b class='flag-5'>协议</b>呢?

    udp是什么协议 TCP与UDP的区别

    TCP协议提供可靠的数据传输,UDP协议提供尽量高效的数据传输。TCP协议通过使用序列号、确认应答等机制,保证数据传输的可靠性,而UDP
    的头像 发表于 06-26 17:47 7080次阅读

    DNS报文结构与编码解析

    网上很多人都说 DNS 根服务器只有 13 台,中国一台也没有。在网络世界,中国被美国卡住了脖子。那 DNS 根服务器真的只有 13 台吗?如果是,那原因又是什么?今天就给大家说道说道。
    的头像 发表于 06-26 10:54 1007次阅读

    TCP协议UDP协议最核心的区别是什么?

    对于TCP协议UDP协议,大家应该都有所耳闻。TCP协议UDP协议都工作在传输层,他们的目标
    发表于 06-15 09:37 350次阅读
    TCP<b class='flag-5'>协议</b>和<b class='flag-5'>UDP</b><b class='flag-5'>协议</b>最核心的区别是什么?

    udp协议的特性有哪些 udp的应用原理

    UDP(User Datagram Protocol)是一个独立的传输层协议,不包含其他协议。它仅在IP协议上增加了端口号的概念,以便能够将数据报正确地传送给目标端口。
    的头像 发表于 06-14 18:21 1426次阅读

    基于Socket的UDP和TCP编程解析 2

    TCP(传输控制协议)和UDP(用户数据报协议是网络体系结TCP/IP模型中传输层一层中的两个不同的通信协议。 TCP:传输控制协议
    的头像 发表于 05-18 17:22 463次阅读
    基于Socket的<b class='flag-5'>UDP</b>和TCP编程<b class='flag-5'>解析</b> 2

    基于Socket的UDP和TCP编程解析 1

    TCP(传输控制协议)和UDP(用户数据报协议是网络体系结TCP/IP模型中传输层一层中的两个不同的通信协议。 TCP:传输控制协议
    的头像 发表于 05-18 17:22 730次阅读
    基于Socket的<b class='flag-5'>UDP</b>和TCP编程<b class='flag-5'>解析</b> 1

    UDP协议报文格式

    UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议
    发表于 05-06 15:26 2689次阅读
    <b class='flag-5'>UDP</b><b class='flag-5'>协议</b>的<b class='flag-5'>报文</b>格式

    什么是UDP协议

    UDP协议即用户数据报协议,该协议主要为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法。nternet的传输层有两个主要协议
    发表于 05-06 15:19 1720次阅读