为什么你的广播包收不到
‘为什么收不到广播包’,听到的答案都是被路由丢弃了,其实这只是一种情况,而这种情况是比较好理解,一般都会规避,往往实际情况不是这样,比如:
- 同一个路由器下,两台设备的广播包到不了
- 两台设备网线直连,广播包到不了
本文将为大家一一介绍其中的缘由.
1. 概念
广播包,即发给所有本地主机的包,分为:
- 受限广播包(255.255.255.255)- 不被转发
- 子网广播包(netid.1)- 往所有子网广播
- 主机广播包(netid.subnetid.1)- 往指定子网广播
这里有一点需要强调:广播包是基于 UDP ,TCP 是没有广播包的说法
2. 用途
广播包的用途自然就不用说,ARP、DHCP等一些非常重要的协议都是基于广播包。当然也不能滥用,否则会影响网络及主机性能,就好比你天天都在小区大喊,谁也受不了。
3. 阻碍因子
广播包既然可以发给所有主机,按理说所有主机都需要处理它,那有哪些因素会阻碍『收广播包』?
3.1. 路由器
为了保证网络的干净,路由器一般不转发广播包,于是这里大家常常误解,以为只要广播包一接入路由器,都有可能被路由器丢弃;于是往往有个答案『你的广播包被路由器丢弃』,其实只有经过 WAN口的广播包才会丢弃。因此如果是2个 LAN 口间的广播包是不会丢弃的,即使两个主机 IP 不一样。
比如:192.168.1.88与192.168.2.88两台主机连到192.168.2.1路由上照样可以正常收发广播包。
3.2. 多网卡(发送方)
默认是不会往所有网卡发送广播包,广播包跟其他数据包一样,也是通过本地路由表来决策该往哪个网卡发送,比如有一台双网卡,分别是61和161网段,有如下路由表:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
...
0.0.0.0 192.168.161.1 0.0.0.0 UG 0 0 0 em1
0.0.0.0 192.168.61.1 0.0.0.0 UG 0 0 0 em2
广播包是往 em1发送,而不会往 em0发送(优先匹配前面规则),当然你也可以指定往哪个网卡发送
srcaddr.sin_addr.s_addr=inet_addr("192.168.61.223");
实测 window 系统,也是如此.
因此,如果是双网卡,请确保是否发对网卡。
3.3. 系统内核过滤(接收方)
还有一种情况,比如 linux 系统增加了一种 Reverse Path Filter,即会对来源 IP 合法性进行判断,即是否本该从该网卡发过来,若不符合,则丢弃。简单地判断就是验证是否可以往相应网口向该 IP 发送数据。
比如你的路由表如下:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.161.0 192.168.161.1 255.255.255.0 UG 0 0 0 em1
192.168.161.0 0.0.0.0 255.255.255.0 U 0 0 0 em1
192.168.61.0 0.0.0.0 255.255.255.0 U 0 0 0 em2
则以下情况都是不合法来源
- 在网口 em1,收到了192.168.61.xx的数据包(应该在 em2上收到)
- 网卡 em1或 em2收到10.10.xx.xx的数据包
该机制是为防止恶意攻击,具体各位可以去了解下。那么是否可以关闭该特性,肯定是可以.
vim /etc/sysctl.conf
net.ipv4.conf.default.rp_filter = 0
即可,当然也可以增加路由表来解决。
该特性只在 linux 上,window系统就不得而知了。
3.4 VLAN
为了防止大量广播消耗网络资源,有些大型局域网会使用VLAN技术,将交换机下的某些口组成一个单独的 LAN,这样广播包只会在该 LAN,而不会发到其他端口上.
4. 总结
当你遇到广播包收不到问题,可以基于如下思路排查:
- 确认物理连接是否属于统一网段(注意是物理连接,而不是说IP)
- 确认发送发是否发对网卡
- 如果是接收方是 linux,确认系统是否开启 rpfilter