![为什么 ifconfig 显示不同的 IP 地址](https://linux22.com/image/196634/%E4%B8%BA%E4%BB%80%E4%B9%88%20ifconfig%20%E6%98%BE%E7%A4%BA%E4%B8%8D%E5%90%8C%E7%9A%84%20IP%20%E5%9C%B0%E5%9D%80.png)
我有通过以太网电缆连接到本地网络的嵌入式 Linux 设备。我通过子网上的本地 IP 地址访问每台设备,192.168.34.0/24.
例如,一台设备具有192.168.34.240
.
ifconfig
当我在设备内部的终端上运行时,我得到以 169 开头的不同 IP 地址,如下所示。我很困惑。为什么是这样?
eth0 Link encap:Ethernet HWaddr 00:D0:91:4B:45:C9
inet addr:169.254.253.217 Bcast:169.254.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:634513 errors:0 dropped:3 overruns:0 frame:0
TX packets:1318475 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:78343668 (74.7 MiB) TX bytes:399586128 (381.0 MiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:24085508 errors:0 dropped:0 overruns:0 frame:0
TX packets:24085508 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:11614050334 (10.8 GiB) TX bytes:11614050334 (10.8 GiB)
答案1
因为在 Linux 上ifconfig
使用过时的内核 API(基于 ioctl),该 API 已在 20 多年前被基于netlink 套接字消息。旧 API 的其他限制包括:
- 只能处理一IPv4 地址(尽管它可以处理多个 IPv6 地址)。即使删除这个地址也是通过拼凑完成的:将地址设置为 0.0.0.0
- 设置时不会同时提供地址的网络掩码。因此,分配地址通常需要两个系统调用:一个用于地址(的主机部分),一个用于修复其网络掩码
- 处理多个 IPv4 地址也是通过一种拼凑完成的:所谓的别名接口(实际上是通过地址上的标签实现的,而不是作为单独的接口),只有
ifconfig
,而不是其他部分(路由、防火墙...)。 - 正如OP所示,没有标签的其他IP地址(因此使用较新的API配置)根本不会被
ifconfig
.
显然,如果没有地址标签(如果命名正确,则将显示为别名接口ifconfig
),则您的网络是使用较新的基于 netlink 的 API 进行配置的。因此,您甚至可以通过坚持使用更新的工具并ifconfig
完全删除来节省嵌入式空间。
ip address
将显示所有接口上分配的所有地址,包括多个 IPv4 地址(如果有多个)。
可以ifconfig
使用较新的 API 重新实现(这里至少有 UL SE 的常规用户这样做了),但看起来需要升级此命令(例如:为了与其他 *NIX 兼容),而不是(慢慢地)将其替换为大多数 Linux 开发人员或发行版维护人员对更新的工具并不感兴趣。
所以在 Linux 上你应该考虑使用ip link
和ip address
代替ifconfig
。同样,ip route
要替换route
,bridge
(除了ip link
)替换brctl
然后是其他子命令ip
替换各种其他命令(用于 VLAN、隧道、绑定接口...)。
现在谈谈为什么有多个地址。可能的原因是该设备利用阿瓦希/零配置(相当于 Apple 的 Bonjour 实现)在 LAN 中进行通信并宣布功能。同时,它可能配置了 DHCP 以进行标准通信(包括互联网)。 Zeroconf 使用(不可路由)IPv4LL地址与使用 DHCP 带来的常用地址分开。