套接字 – 为什么在执行read()时ETH_P_IP和ETH_P_ALL之间存在差异

我有以下设置:

client(eth0) --- (eth2) linux bridge (eth1) --- (eth1) server

当我在linux桥上打开RAW套接字时使用

fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

我有套接字绑定到eth2.当客户端向服务器发送数据包时,在网桥上运行的wireshark报告数据包的源mac地址为client(eth0),目标mac地址为server(eth1).

当我执行read()时,读取的数据的前6个字节是目标mac地址,它被正确读取为服务器(eth1).

但是,当我将语句更改为

fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));

当我执行read()时,读取的数据的前6个字节显示目标mac地址是linux bridge(eth2).

为什么会这样?内核或以太网卡驱动程序是否将自己的mac地址放在缓冲区中,而不是使用ETH_P_IP读取线路?

最佳答案 对于ETH_P_IP情况,您所描述的内容听起来像普通的“路由”方案.

(即路由mac是目标mac.)

如果您的客户端和服务器位于不同的子网/ VLAN上,并且介于两者之间,那么这将是有意义的.

但是,该图表示linux“桥”.
它只做桥接而根本没有路由吗?

编辑

ETH_P_IP仅根据以下答案捕获传入的IP数据包:
Packet Sniffing using Raw Sockets in Linux in C

点赞