私有网络(Private

在之前的Mac在局域网中突然很慢(包括SMB、NFS、SCP、SSH、Ping等场景均很慢)这篇文章中,我提到在使用netstat -rn检查服务器的时候发现,169.254/16居然对应两个接口:

为什么这个 IP 块会对应两个接口?

首先,这个是系统内核自动生成的,也就是说,你就算删了重启之后还会再次出现,所以我并不建议你去改路由表的条目,而是修改掩码部分(或者新增条目,例如169.254.0.0,掩码为255.255.255.0)。

那么问题就变成了:为什么系统会生成这样的条目呢?

在寻找这个问题的答案的过程中,我对私有网络和本地连接的区别有了一些认识,而且了解了点对点 Wi-Fi 连接技术与 Wi-Fi Direct 的关系。

虽然我们常说 IP 地址是“门牌号”,我们可以通过 IP 地址与某一设备通信,但是,由于一些技术和历史遗留问题,IP 地址的设计远比所谓的“门牌号”复杂的多。

在设计 IP 地址的时候,有一些特殊的地址块,在 RFC5735 中,给出了一些特殊的 IPv4 地址:

可以看到,10.0.0.0/8、172.16.0.0/12和192.168.0.0/16是三个留下来的私用网络 IP 地址块,而169.254.0.0/16则是“Link Local(本地连接)”。

私有网络(Private-Use Networks)

私有网络是为了延长 IPv4 的寿命。你肯定听说过这样一个描述:最好是给每个设备一个 IP 地址,但是由于现在设备过多,IPv4 已经不够用了,所以可以给一个网络一个公共 IP,内部使用私有网络,这样可以大大减少 IP 地址的使用数量。

比如你家的路由器拥有一个公共 IP,也就是全球唯一的 IP。这个路由器连接着你家的手机、电视等设备,那么路由器会给你家的手机、电视、洗衣机、电脑、iPad 分配一个私有网络的 IP 地址(一般是通过 DHCP 自动分配),也就是192.168.x.x(不过由于掩码设置,也有可能是192.168.1.x或者其他的)。当你需要访问其他网络,那么可以通过路由器/网关的建立与其他网络上设备的通信。将私有 IP 转换成 公共 IP 就是 NAT(网络地址转换)。而你在使用这些私有网络 IP 的时候,设备/路由器按照协议自然知道这是私有网络内的设备,就不会发向公共网络。当然这里只是简单地描述,详细技术实现要复杂的多。

这里多说一句,5GHz 的 Wi-Fi 能比 2.4GHz 的Wi-Fi 处理更多的设备,所以如果你家设备很多,发现连接不了 Wi-Fi,那么请连接 5GHz 的 Wi-Fi(我朋友他家的洗衣机就无法连接 2.4 GHz 的,似乎有些设备为了保证上网质量,对数量有限制)。

RFC1918 中有这样一段话,简短清晰的解释了什么叫私有网络:

The cost of using private internet address space is the potentially costly effort to renumber hosts and networks between public and private… 本文档描述了私有互联网的地址分配。该分配允许企业内部所有主机以及不同企业所有公共主机之间实现完整的网络层连接。

本地连接(Link Local)

前文提到,一个网络的 IP 地址一般是通过 DHCP 或者其他来源自动/手动分配的。但是如果没有相关配置,那么主机会给接口配置一个 IPv4 地址,该地址位于169.254/16前缀内,可用于与连接到同一物理(背靠背直连)或逻辑(交换机)链路的其他设备进行通信。换句话说,本地连接是指“位于同一链路上的”。

例如在之前那篇文章中 PC 与 Mac 通过交换机连接,并没有路由器或者其他设备建立一个网络给每个设备分配 IP 地址。那么就表示使用本地连接其他设备,并不会有路由等行为。所以 RFC3927 中也使用“不可路由地址”来指代169.254/16。

我之前在《树莓派在Raspbian系统(Bookworm)中无法获取RJ45网口eth0或end0的IP地址(没有IPv4的地址无法操作)》 这篇文章中提到过相关现象:RJ45 接口没有 IP 地址,调整成“Link_Local Only”就有了。现在看来就是接口或许在等路由器 DHCP 自动分配一个 IP 地址。

RFC3927 中有这样一段对于本地连接的描述:

如果满足以下所有条件,则这些主机被视为“位于同一链路上”:

当该组中的任意主机 A 使用单播、多播或广播向该组中的任意其他主机 B 发送数据包时,整个链路层数据包有效载荷均未经过修改地到达;该组主机中的任意主机通过该链路发送的广播,可以被该组中的所有其他主机接收。

其实到这里你应该也可以理解为什么一般路由器 DHCP 分配的地址是 192.168/16开头,而没有接网线的 RJ45 接口的 IP 地址是169.254/16开头。

为什么169.254/16会对应两个接口

按照前面对于本地网络链路的定义,Wi-Fi 接口其实也可以满足这个定义:可以直接建立点对点的 Wi-Fi 连接,无需路由器。那么自然一些系统会给 Wi-Fi 接口也给个本地连接 IP 前缀。

现在经常使用的点对点 Wi-Fi 连接技术叫做“Wi-Fi Direct”。

需要注意这个技术名字就叫做“Wi-Fi Direct”,而这类技术叫做点对点 Wi-Fi (peer-to-peer Wi-Fi)。“Wi-Fi Direct”是点对点 Wi-Fi 的一种,注意区分。

当然这个使用似乎并不常见,大部分用 Wi-Fi 都是上网或者通过路由器操作连接的洗衣机等设备。但其实它的应用场景和支持现在也非常多了。

如果你在 Ubuntu 22.04 上使用 nmcli dev status 查看各个接口设备的情况,会发现有个wifi-p2p类型的 Wi-Fi 接口:

这验证了我之前的猜想,终于找到为什么系统会自动给两个接口都分配169.254/16的原因了。

希望能帮到有需要的人~

各类平台与厂商中的 Wi-Fi Direct

下面是一些使用 Wi-Fi Direct 技术的相关介绍,主要是为了展示这一技术并不冷门。

现在你就可以退出本文了,因为后面基本上是介绍和扩展,感兴趣可以看看。

安卓

安卓开发关于通过 Wi-Fi Direct 创建点对点连接:

安卓手机设置

在很多安卓手机中,都有相关设置,例如一加/OPPO 的设置中,就叫做“WLAN 直连”:

此外,OPPO 关于 Wi-Fi Direct 和 Wi-Fi 网络共享有什么区别的介绍如下:

三星

三星关于 Wi-Fi Direct 技术介绍:

惠普

惠普使用 Wi-Fi Direct 的打印机使用介绍:

苹果(有点特殊)

苹果的“隔空投送”混用多种网络,包括蓝牙、无线网络甚至是互联网:

例如当我断开了所有的 Wi-Fi 连接并关闭了蓝牙,但 Airdrop 依旧可用:

而且速度要比开蓝牙(48MB/s)略快:

不过苹果的 Wi-Fi 直连技术有点特殊:它不是一对一的,而是 m 对 n 的。

State of Apple’s “Wifi-Direct”, UDP connections, etc. - Apple Developer Forums 这个帖子中给了一个不错的描述:

Apple 的点对点 Wi-Fi 允许 N 个客户端与 M 个服务器通信,就像平时使用的 Wi-Fi 一样。例如,如果两个服务器 A 和 B 注册了一个服务,两个客户端 C 和 D 浏览服务,则 C 和 D 可以看到 A 和 B 并与之通信。

关于点对点网络,苹果官方在 TN3151: Choosing the right networking API - Peer-to-peer networking 中的介绍如下:

“点对点替代方案”是使用 Multipeer Connectivity 框架:

扩展阅读

文章中已经贴出了很多相关资料,这里所以这里都是一些和本文关系不大,但是我在研究过程中发现的文章。

P2P networking between Apple devices - Apple Developer Forums:这篇帖子中,DTS Engineer 给出的一些资料和解释不错,例如:

Wi-Fi Fundamentals - Apple Developer Forums:这是上一篇帖子中,DTS Engineer 给的一篇资料,也是他写的,里面对于一些 Wi-Fi 相关技术有所介绍。

iOS and Wi-Fi Direct - Apple Developer Forums:这篇帖子虽然是 2015 年的,但是 DTS Engineer 的一些回复还是很有帮助。比如里面居然给出了和我之前演示类似的方案:

Copyright © 2088 秘境大冒险活动站 - 探索专属福利指南 All Rights Reserved.
友情链接