2021-02-28

Bonjour协议分析

 

介绍

Bonjour这个词来源于法语,是“你好”的意思,应该是指遵从这个协议的设备可以通过主动打招呼的形式发现彼此。

 

Bonjour是Apple推出的零配置网络协议,主要的目的是在缺少中心服务器的情况下解决网络设备的IP获取,名称解析和服务发现等关键问题。

 

Bonjour主要基于两个协议:mDns协议 和 DNS-SD协议。

 

mDns协议是一个用于零配置网络发现协议,本身借鉴DNS协议,只不过作了些修改,DNS是点播基于53端口,mDns是组播基于5353端口。

 

DNS-SD协议是mDns协议的补充协议,因为mDns协议仅仅是约定了消息的基本格式和消息的收发顺序,具体的内容就由DNS-SD协议来补充。

 

mDns协议和Upnp协议发现部分功能类似,都是用于局域网设备服务发现,只不过Upnp是包含发现设备后,控制,通知等一套完整的协议,而mDns仅仅用于网络发现,至于发现之后怎么使用全凭用户自己架构。

 

在介绍mDns协议之前,我们有必要说明下Dns协议。

 

Dns协议

Dns报文结构:

 

mdns.png

 

Dns协议包含报头和正文两部分,其中报头固定12个字节,正文长度可变,而且分四种。

 

报头

mdns_head.png

 

以上就是12字节的报头格式,具体说下每个字段的意思吧:

 

ID:16位的标识符,主要用来配对请求和应答。

 

QR:占用1位,用以区分报文是请求还是应答。

 

OPCODE:占用4位,用于指定查询类型。

 

0:标准查询

1:逆向查询

2:查询服务状态

3:保留

4:通知

5:更新

6-15:保留

 

AR:占用1位,仅当应答才设置为1。

 

TC:占用1位,截断标志,如果被截断为1.

 

RD:占用1位,可选项,表示要求递归与否,为1要求递归。

 

RA:占用1位,代表应答服务器可以执行递归查询。

 

Z:占用3位,保留,必须为0.

 

RCODE:占用4位,仅在DNS应答时才设置,意义如下:

 

0:无错误

1:格式错误

2:严重失败

3:名字错误

4:没有实现

5:拒绝

6-15:保留

 

QDCOUNT:占用16位,指明DNS查询段中查询问题的数量。

 

ANCOUNT:占用16位,指明DNS应答中返回的资源记录的数量,在查询段中为0。

 

NSCOUNT:占用16位,指明DNS应答段中所包括的授权域名服务器的资源记录的数量,在查询段中该值为0。

 

ARCOUNT:占用16位,指明DNS附加段里所含资源记录的数量,在查询段中该值为0。

 

正文段

 

包含4种:查询段,应答段,授权段,附加段,其中应答段,授权段,附加段的格式一样。

 

查询段格式

mdns_query.png

 

QNAME:该字段是可变长字段,其中包含一个被请求的域名,用一系列标签表示,每一个标签由一个表示长度的十六进制数和相应长度的值组成。

 

QTYPE:该字段占用16位,指定查询的资源类型。

 

QCLASS:该字段占用16位,制定查询的类别。

 

其余三个格式

mdns_response.png

 

查询段是主机向域名服务器发出的报文,域名服务器按照主机查询类型,返回应答段,授权段或附加段。

 

NAME:可变字长,同查询段。

 

TYPE:占用16位,同查询段。

 

CLASS:占用16位,同查询段。

 

TTL:占用32位,代表资源记录的生命周期,以秒为单位。

 

RDLENGTH:占用16位,表示资源数据的长度,以字节为单位。

 

RDATA:可变字长,按不同的查询类型返回不同的数据。

 

抓包分析

使用wireshark抓包软件,使用window的命令行工具,ping www.sina.com 抓包如下:

 

查询报文:

 

mdns2.png

 

应答报文:

 

mdns3.png

 

注意在查询报文中,可以包含若干查询段,若干授权段,若干附加段的,同样在响应报文中,也可以包含若干应答段,若干授权段,若干附加段的,只是得按顺序排列下来,如上图的 Answers 里面就有7条响应段。

 

另外为了解释可变字长,打开二进制查看器如下:

 

mdns4.png

 

03代表3个字节,后面跟了77 77 77,表示 w w w

 

04代表4个字节,后面跟了73 69 6e 61,表示s i n a

 

03代表3个字节,后面跟了63 6f 6d,表示c o m

 

00代表0个字节,表示可变数据完结

 

以上就是Dns协议的大概,结构上看还是很简单的。

 

mDns协议

mDns协议基于UDP/IP,使用多播地址224.0.0.251/5353来通信,除了借用Dns的所有概念之外,mDns还特别对其中的部分概念作了扩展,这里归纳下几个基本的概念。

 

资源记录:局域网中各个主机之间交换的消息内容。

 

资源记录包含几个关键字段:

 

记录名称:表示消息内容(对应上面的NAME)。

记录类型:表示消息内容的类型(对应上面的TYPE)。

记录类别:在mDns中取值固定为1(对应上面的CLASS)。

其中的记录类型又分为以下几种:

 

A 类型:主机名称和IPV4之间的对应关系。

AAAA 类型:主机名称和IPV6之间的对应关系。

SRV 类型:标识服务实例名称对应哪一个主机名和端口号。

PTR 类型:标识服务实例名称和服务类型之间的对应关系,一般在查询具有相同服务类型的实例时使用。

TXT 类型:对某个服务实例提供的附加信息按照key/value形式给出。

ANY 类型:任意类型,一般用于查询中。

 

mDns协议的基本工作过程为:寻址,探测,宣告,查询/监听并响应。其中探测和宣告需要保证主机名和服务名在局域网中具有唯一性。

 

至于mDns格式方面也不用作多余的解释,基本和Dns一致,只是在报头中的FLAG标志里只有QR,AR,TC有意义,其它都是固定为0。

 

DNS-SD 协议

mDns协议规定了消息的基本格式和消息的收发的基本顺序,DNS-SD 协议在这基础上,首先对实例名,服务名称,域名长度/顺序等作出了具体的定义,然后规定了如何方便地进行服务发现和描述。

 

服务实例名称 = <服务实例>.<服务类型>.<域名>

服务实例一般由一个或多个标签组成,标签之间用 . 隔开。

 

服务类型表明该服务是使用什么协议实现的,由 _ 下划线和服务使用的协议名称组成,如大部分使用的 _tcp 协议,另外,可以同时使用多个协议标签,如: “_http._tcp” 就表明该服务类型使用了基于tcp的http协议。

 

域名一般都固定为 “local”

 

DNS-SD 协议使用了PTR、SRV、TXT 3种类型的资源记录来完整地描述了一个服务。当主机通过查询得到了一个PTR响应记录后,就获得了一个它所关心服务的实例名称,它可以同通过继续获取 SRV 和 TXT 记录来拿到进一步的信息。其中的 SRV 记录中有该服务对应的主机名和端口号。TXT 记录中有该服务的其他附加信息。

 

协议总结

以上只是总结了mDns协议和mDns-SD协议的大概,具体应用中还有许多需要看协议文档,比如:规定了设备入网第一次查询要求单播,之后使用多播,规定了一个消息包中尽可能地包含所有记录,规定了收到查询请求之后,主机在回应之前需要随机等待一段时间,以减少响应消息的数量等等。

 

协议实践

从mDNSResponder获取源代码,里面有各个平台的client,可以在window及linux系统中编译使用。

 

在我的ubuntu系统中,使用mDNSPosix版的client,使用 make os=”linux” 和 make os=”linux” install 命令即可编译安装,window版本的直接使用virsual studio导入编译运行即可。

 

抓包如下:

actor.png

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值