博客
关于我
DNS传输协议解析!pcap报文中的域名获取
阅读量:96 次
发布时间:2019-02-26

本文共 3994 字,大约阅读时间需要 13 分钟。

DNS协议详解

DNS(Domain Name System,域名系统)是互联网中用于将易于记忆的域名(如www.google.com)转换为机器可理解的IP地址(如172.217.27.142)的系统。通过DNS,用户无需记住复杂的IP地址即可访问网站,这大大简化了网络通信过程。

DNS解析过程

DNS解析过程主要包括以下几个步骤:

  • 询问(Query):用户输入域名(如www.google.com),DNS客户端向DNS服务器发送查询请求。
  • 解答(Response):DNS服务器返回相应的记录,通常为A记录,包含目标IP地址。
  • 递归或迭代:如果DNS服务器无法直接回答查询,会返回另一个DNS服务器(递归)或继续查找(迭代)。
  • DNS系统的作用

    DNS系统的核心作用是将人类友好的域名映射到机器友好的IP地址。IP地址是网络中计算机识别的标识符,但其长难记。通过DNS,用户可以用更简洁的方式访问网站。

    DNS传输协议

    DNS使用UDP协议(端口53)进行通信,因为UDP速度快且开销低。然而,对于复杂的DNS查询(如区域传输),TCP协议也被用于确保数据完整性。

    DNS报文结构

    DNS报文包括以下几个部分:

  • 头部(Header):包含标识符、标志位、查询数量、响应数量等信息。
  • 标志位(Flags):1位或4位位组,表示消息类型、权威性、递归查询等。
  • 查询部分(Questions):包含要解析的域名和记录类型(如A、AAAA、MX等)。
  • 答案部分(Answers):包含查询结果,包括域名、记录类型、类别、生存时间(TTL)等。
  • DNS查询格式

    DNS查询格式如下:

    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+| || QNAME || |+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+| QTYPE |+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+| QCLASS |+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    • QNAME:域名,由标签组成,每个标签以其长度前缀。
    • QTYPE:记录类型代码,0x0001表示A记录。
    • QCLASS:记录类别代码,0x0001表示Internet地址。

    DNS回答格式

    DNS回答格式如下:

    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+| || || NAME || |+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+| TYPE |+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+| CLASS |+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+| TTL || |+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+| RDLENGTH |+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|| RDATA || |+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
    • NAME:查询的域名。
    • TYPE:记录类型代码,0x0001表示A记录。
    • CLASS:记录类别代码,0x0001表示Internet地址。
    • TTL:记录可缓存的秒数。
    • RDATA:记录数据,根据类型不同而不同。

    DNS协议实现

    以下是DNS协议的代码实现示例:

    struct dnshdr {    uint16_t id;    uint16_t flags;    uint16_t quest;    uint16_t ans;    uint16_t auth;    uint16_t add;};struct dnshdr_name {    const char *ns_name;    int ns_name_len;    unsigned int labels;};static unsigned int qname_labels_count(const char *name, int name_len) {    unsigned int labels = 0;    if (name_len > 1) {        for (int i = 0; i < name_len; ++i) {            if (name[i] == '.') {                labels++;            }        }        labels++;    }    return labels;}int get_dns_name(u_char *dns_data, int offset, int max_len, int dns_data_offset, const char **name, int *name_len) {    int len;    len = expand_dns_name(dns_data, offset, max_len, dns_data_offset, name, name_len);    if (name[0] == '\0' && len <= MIN_DNAME_LEN) {        *name = "
    "; *name_len = (int)strlen(*name); return len; } if ((len < MIN_DNAME_LEN) || (len > MIN_DNAME_LEN && name_len == 0)) { printf("ReportedBoundsError\n"); } return len;}static void dissect_dns(u_char *data_info, int payload_len) { int used_bytes = 0; dnshdr_name dns_domain; used_bytes = get_dns_name(data_info, DNS_HDRLEN, 0, 0, &dns_domain.ns_name, &dns_domain.ns_name_len); dns_domain.labels = qname_labels_count(dns_domain.ns_name, dns_domain.ns_name_len); printf("ns_name: %s\n", dns_domain.ns_name); printf("ns_name_len: %d\n", dns_domain.ns_name_len); printf("labels: %d\n", dns_domain.labels);}static void confirm_dns_packet(struct ip *pIp) { int iIpTotalLen = ntohs(pIp->ip_len); int offset = 0; int nFragSeq = 0; struct udphdr *pUdpHdr = (struct udphdr *)(char *)pIp + (pIp->ip_hl < 2); if (pIp->ip_p == IPPROTO_UDP && (ntohs(pUdpHdr->dest) == DEFAULT_DNS_PORT_RANGE || ntohs(pUdpHdr->source) == DEFAULT_DNS_PORT_RANGE)) { printf("\n"); printf("info udp\n"); int iPayloadLen = iIpTotalLen - (pIp->ip_hl < 2) - 8; printf("UDP Payload Len %d\n", iPayloadLen); u_char *pDnsHdr = (u_char *)(pUdpHdr + 1); dissect_dns(pDnsHdr, iPayloadLen); }}

    DNS抓包示例

    以下是DNS协议的实际抓包示例:

    DNS Query:- Domain Name: www.google.com- Query Type: A- Class: 1DNS Response:- Name: www.google.com- Type: 1 (A Record)- Class: 1- TTL: 60- RDATA: 172.217.27.142

    总结

    DNS协议通过将易于记忆的域名映射到机器友好的IP地址,为互联网用户和设备提供了便利。深入理解DNS协议,建议参考RFC官方文档。

    欢迎关注微信公众号【程序猿编码】,加入技术交流群,共同探讨技术奥秘!

    转载地址:http://yuiy.baihongyu.com/

    你可能感兴趣的文章
    Openlayers实战:输入WKT数据,输出GML、Polyline、GeoJSON格式数据
    查看>>
    Openlayers实战:选择feature,列表滑动,定位到相应的列表位置
    查看>>
    Openlayers实战:非4326,3857的投影
    查看>>
    Openlayers高级交互(1/20): 控制功能综合展示(版权、坐标显示、放缩、比例尺、测量等)
    查看>>
    Openlayers高级交互(10/20):绘制矩形,截取对应部分的地图并保存
    查看>>
    Openlayers高级交互(11/20):显示带箭头的线段轨迹,箭头居中
    查看>>
    Openlayers高级交互(12/20):利用高德逆地理编码,点击位置,显示坐标和地址
    查看>>
    Openlayers高级交互(13/20):选择左右两部分的地图内容,横向卷帘
    查看>>
    Openlayers高级交互(14/20):汽车移动轨迹动画(开始、暂停、结束)
    查看>>
    Openlayers高级交互(15/20):显示海量多边形,10ms加载完成
    查看>>
    Openlayers高级交互(16/20):两个多边形的交集、差集、并集处理
    查看>>
    Openlayers高级交互(17/20):通过坐标显示多边形,计算出最大幅宽
    查看>>
    Openlayers高级交互(18/20):根据feature,将图形适配到最可视化窗口
    查看>>
    Openlayers高级交互(19/20): 地图上点击某处,列表中显示对应位置
    查看>>
    Openlayers高级交互(2/20):清除所有图层的有效方法
    查看>>
    Openlayers高级交互(20/20):超级数据聚合,页面不再混乱
    查看>>
    Openlayers高级交互(3/20):动态添加 layer 到 layerGroup,并动态删除
    查看>>
    Openlayers高级交互(4/20):手绘多边形,导出KML文件,可以自定义name和style
    查看>>
    Openlayers高级交互(5/20):右键点击,获取该点下多个图层的feature信息
    查看>>
    Openlayers高级交互(6/20):绘制某点,判断它是否在一个电子围栏内
    查看>>