我正在编写代码以在两个Linux盒之间发送原始以太网帧。为了测试这一点,我只想获得一个简单的客户端发送和服务器接收。
我让客户端正确地制作了数据包(我可以使用数据包嗅探器看到它们)。
在服务器端,我像这样初始化套接字:
fd = socket(PF_PACKET, SOCK_RAW, htons(MY_ETH_PROTOCOL));
MY_ETH_PROTOCOL我用作ethertype的2字节常量在哪里,所以我听不到多余的网络流量。
MY_ETH_PROTOCOL
当我将此套接字绑定到接口时,必须在socket_addr结构中再次将其传递给协议: socket_address.sll_protocol = htons(MY_ETH_PROTOCOL); 如果我像这样编译并运行代码,则它将失败。我的服务器看不到该数据包。但是,如果我这样更改代码: socket_address.sll_protocol = htons(ETH_P_ALL); 服务器随后可以看到从客户端发送的数据包(以及许多其他数据包),因此我必须对数据包进行一些检查以确保其匹配MY_ETH_PROTOCOL。
socket_address.sll_protocol = htons(MY_ETH_PROTOCOL);
socket_address.sll_protocol = htons(ETH_P_ALL);
但是我不希望我的服务器听到未按指定协议发送的流量,因此这不是解决方案。我该怎么做呢?
我已经解决了这个问题。
根据http://linuxreviews.org/dictionary/Ethernet/,引用了MAC地址后面的2个字节字段:
“该字段的值介于64和1522之间,表示使用的是带有长度字段的新802.3以太网格式,而十进制的1536(十六进制的0600)或更大的值表示使用带有EtherType子帧的原始DIX或以太网II帧格式- 协议标识符。”
所以我必须确保我的以太类型> = 0x0600。
根据http://standards.ieee.org/regauth/ethertype/eth.txt,使用0x88b5和0x88b6是“可用于原型和特定于供应商的协议开发的公共用途”。这就是我将要用作ethertype的内容。我不需要任何进一步的过滤,因为内核应确保仅选择具有正确目标MAC地址并使用该协议的以太网帧。