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

    文章

    230

    浏览量

    21236
  • UDP协议栈
    +关注

    关注

    0

    文章

    4

    浏览量

    1264
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    基于Xilinx K7 325t的千兆网UDP协议实现小记

    基于xilinx k7 325t实现的千兆网udp协议,只需要设置好IP,端口,就可以直接给数据,基本等同于透传,可以不用管底层协议
    的头像 发表于 04-27 15:04 89次阅读
    基于Xilinx K7 325t的千兆网<b class='flag-5'>UDP</b><b class='flag-5'>协议</b>实现小记

    一文读懂 NMEA 报文:GNSS 定位日志解析与实战

    因子、时间速度等字段解析方法,帮助嵌入式与物联网开发者快速理解定位报文、判断信号质量与定位有效性,为设备调试提供实用参考。
    的头像 发表于 04-21 15:46 186次阅读
    一文读懂 NMEA <b class='flag-5'>报文</b>:GNSS 定位日志<b class='flag-5'>解析</b>与实战

    WiMi-net五层协议深度拆解:有中心自组网的落地实践

    从OSI七层到WiMi-net五层,经典理论如何落地?本文深度拆解WiMi-net有中心自组网协议的五层架构:物理层(Sub-GHz射频)、链路层(TDMA时隙)、网络层(动态路由)、传输层
    的头像 发表于 04-02 17:40 1806次阅读
    WiMi-net五层<b class='flag-5'>协议</b><b class='flag-5'>栈</b>深度拆解:有中心自组网的落地实践

    DNS 解析故障:安全风险、诊断排查与防护指南

    前言DNS作为互联网的“地址导航系统”,其稳定运行直接关系到网络访问的安全性与可用性。一旦出现解析故障,不仅会导致网站无法访问,更可能引发一系列严重的安全风险,给个人用户和企业带来数据泄露、业务中断
    的头像 发表于 01-28 10:28 1560次阅读
    <b class='flag-5'>DNS</b> <b class='flag-5'>解析</b>故障:安全风险、诊断排查与防护指南

    RDMA设计12:融合以太网协议设计1

    本文主要交流设计思路,在本博客已给出相关博文90多篇,希望对初学者有用。注意这里只是抛砖引玉,切莫认为参考这就可以完成商用IP设计。 融合以太网协议负责用户请求与 RDMA 数据包的转换、管理
    发表于 12-25 11:39

    工业智能网关支持IEC104协议

    。工业智能网关通过内置协议或模块化设计,能够直接解析IEC104协议报文,支持以下核心功能: 数据采集 :实时采集电力设备(如变电站、发电
    的头像 发表于 12-18 14:42 702次阅读
    工业智能网关支持IEC104<b class='flag-5'>协议</b>吗

    以太网通讯在FPGA上的实现

    模块用来将需要发送的数据添加报文头封装为UDP报文,然后发送给MAC层,也负责将接收到的UDP报文提取出数据供FPGA其他模块使用,TCP
    发表于 10-30 07:45

    移植网络PHY芯片驱动,如何融入 rt-thread 的网络体系,并添加新的以太网类型的报文

    的 TCP 和 UDP 报文不冲突(对于同一个网络接口,可能会同时收发 TCP、UDP 和 HPGP报文)。
    发表于 09-22 06:11

    mqtt dns解析失败是为什么?

    解析域名的ip地址就能正常连上,而直接解析域名就不行,为什么呢
    发表于 09-16 06:38

    用于各种设备协议间做报文转换的网关是什么

    功能是实现不同协议格式的报文(数据)在传输过程中的解析、转换和转发。 一、协议转换网关的核心作用 1.协议
    的头像 发表于 08-11 14:08 1229次阅读
    用于各种设备<b class='flag-5'>协议</b>间做<b class='flag-5'>报文</b>转换的网关是什么

    第五章 W55MH32 UDP示例

    本文介绍了在 W55MH32 芯片上实现 UDP 通信及数据回环测试的方法。阐述了 UDP 协议的概念、特点、应用场景、报文传输流程和报文
    的头像 发表于 07-24 09:13 1393次阅读
    第五章 W55MH32 <b class='flag-5'>UDP</b>示例

    协议分析仪能监测哪些异常行为?

    协议分析仪通过深度解析网络通信中的协议字段、时序和状态,能够精准识别多种异常行为,涵盖从配置错误到恶意攻击的广泛场景。以下是其可监测的核心异常行为类型及具体实例:一、协议实现违规:违反
    发表于 07-22 14:20

    RDMA简介3之四种子协议对比

    ,通过ETH Type标识RoCE报文。而RoCE v2基于UDP/IP协议承载RDMA,可部署在三层网络环境下,在原有IB协议报文基础上增
    发表于 06-04 16:05

    ModbusRTU转profibusDP网关与RAC400通讯报文解析

    高性能的现场总线标准,适用于高速、实时性要求较高的场景。为了实现这两种协议之间的互联互通,我们需要一个专门的转换网关。本文将以RAC400为例,介绍如何通过ModbusRTU转ProfibusDP网关与RAC400进行通信报文解析
    的头像 发表于 05-25 20:01 674次阅读
    ModbusRTU转profibusDP网关与RAC400通讯<b class='flag-5'>报文</b><b class='flag-5'>解析</b>

    如何在Linux中配置DNS服务器

    本文详细介绍了如何在Linux中配置DNS服务器,包括DNS工作原理、本地缓存、DNS查询过程,以及正向和反向查询的配置。步骤包括服务器配置、编辑BIND配置文件、添加解析信息和客户端
    的头像 发表于 05-09 13:38 2797次阅读
    如何在Linux中配置<b class='flag-5'>DNS</b>服务器