利用 mDNS 协议来定位局域网主机

再也不用费劲去找树莓派的 IP 地址了!你的操作系统自带了“网络发现”功能。

在一个平常的局域网(开启了 DHCP)下面,获得一台主机的 IP 地址常常有这么几种方法:

  1. arp -a 命令查询 arp 缓存;
  2. 在目标主机上查找本机的 IP 地址,使用例如 ipconfig 命令;
  3. 浏览器登录路由器的后台,从连接的主机列表中查找;
  4. 给目标主机设置静态IP。

曾几何时,我一直用上面的方法来连接我的树莓派。树莓派没接显示器,没办法在主机上操作,每次要么使用手机热点(设备管理里面能显示 IP),要么直接改配置分配静态IP。这些方法都有局限性,网络环境一变化,又得配置半天。

现在,一个新的方法出现了!(其实一直就有)只要知道你的设备的主机名,你就可以得到你的设备的 IP 地址。例如,我的树莓派是 Raspbian 系统,它的默认主机名是 raspberrypi,就可以通过域名 raspberrypi.local 来连接,像这样:

这就是 mDNS (Multicast DNS)协议给我们提供的便利。

偶然的发现

在研究 IGMP 协议的时候,我用 Wireshark 对无线网卡抓取 IGMP 数据包,想看看有没有什么服务是在使用组播(Multicast)地址的。

Wireshark软件截图

之后我看到了局域网内的电脑基本上都会加入这几个组播地址:224.0.0.251224.0.0.252239.255.255.250

经过查找,这三个组播地址分别是协议 mDNS,LLMNR 和 SSDP 协议的。mDNS实现了类似 DNS 的功能,使得主机在局域网内能够加入和通信;LLMNR 的功能和 mDNS 类似;SSDP 是 UPnP 协议的一部分,也是用来实现设备和服务的发现的。

在一段 mDNS 报文中,我看到了这样的内容:

来源是 192.168.10.108,目的是 224.0.0.251。 返回的记录中有我的树莓派的 IPv4 和 IPv6 地址,以及一个相同的字段 raspberrypi.local

难道说 raspberrypi.local 就是我树莓派的域名?我立马 ping 了一下:

确实可以。我流下了激动的泪水:这么好的东西怎么没早发现呢!

mDNS 查询过程

通过分析抓包数据,mDNS 协议在局域网内的 IP 地址查询过程大致是这样的:

A:发起查询的主机

B:被查询的主机

  1. A,B 在加入网络时都会发 IGMP 报文加入组 224.0.0.251
  2. A 向组 224.0.0.251 发送 mDNS 组播报文查询 B 的主机名,所有在组内的主机都会收到这个查询请求;
  3. B 向组 224.0.0.251 发送回应 mDNS 报文,内容包括自己的主机名和 IP 地址;
  4. A 得到 B 的 IP 地址。

其中,mDNS 报文是包装在 UDP 组播报文中的,使用 5353 端口。

主机名的查询和修改

Windows 系统的主机名在环境变量 COMPUTERNAME 查看,可以在系统设置中修改。

Windows更改主机名

Linux 系统主机名存在 /etc/hostname 中。使用 hostnamectl 可以查询和修改。/etc/hosts 里也有主机名的记录,也要一并修改。

我的系统支持吗

Windows 10 以后,系统就能够支持 mDNS 协议了。Windows 10 以下的系统怎么办?你可以:

  1. 给 Windows 安装苹果公司的 Bonjour,只有 5 Mb 大小,推荐。
  2. 使用 NetBIOS 协议,这是微软的网络发现服务。Linux 系统上安装 samba,它的 nmbd 服务使得能被 Windows 主机发现。使用方法:
    • Windows上:主机名即为域名。主机名是 raspberrypi,直接 ping raspberrypi
    • Linux上:默认不解析 NetBIOS 主机名,使用 nmblookup 主机名 来得到 Windows 主机 IP。如果要实现解析 NetBIOS 主机名,需要修改配置文件,没折腾了,看这篇文章 -> 在 Linux 解析 Netbios 名稱

Linux 一般是安装了 avahi-daemon 服务。使用指令 systemctl status avahi-daemon.service 来查看服务运行状态。

avahi-daemon

安卓系统似乎不支持,我的华为手机没有。

还可以查询 UDP 5353 端口。

Windows:

Linux:

其实最简单的就是 ping 一下 主机名.local 看看有没有就知道了。

参见:

 

添加一条评论

电子邮件地址不会被公开。 必填项已用*标注