ESXi上创建Raw Socket无法接收数据的问题咨询
问题:ESXi 6.7下Raw Socket的recvfrom()始终返回EAGAIN无数据
我正在开展一个需要在ESXi主机上创建Raw Socket的项目,该程序在Ubuntu上可正常编译运行,但移植到ESXi 6.7后,recvfrom()始终无法获取数据。
代码示例
int main() { int saddr_size , data_size; struct sockaddr saddr; unsigned char buffer[512]; int sock_raw; // 补充原代码遗漏的变量定义 //Create a raw socket sock_raw = socket(AF_PACKET, SOCK_RAW | SOCK_NONBLOCK, htons(ETH_P_ALL)); if(sock_raw < 0) { printf("Socket Error\n"); return 1; } while(1) { saddr_size = sizeof saddr; //Receive a packet data_size = recvfrom(sock_raw, buffer, 512, 0, &saddr, &saddr_size); if(data_size < 0 ) { printf("Recvfrom() error, failed to get packets\n"); return 1; } //Now process the packet } close(sock_raw); printf("Finished"); return 0; }
调试情况
添加调试信息后发现,程序循环执行recvfrom()但始终无数据,返回值为-1且errno设为EAGAIN。运行期间我通过TCP Connect扫描确保有数据包发送,也尝试将ETH_P_ALL替换为IPPROTO_TCP,结果一致。同时试过静态编译和动态编译,均未解决问题。请问ESXi是否有需要修改的相关设置?
解决方案分析
ESXi网络栈的特殊性:ESXi的VMkernel网络栈和普通Linux不同,
AF_PACKET类型的Raw Socket默认无法直接捕获物理网卡的全量流量,因为VMkernel会对网络流量做隔离、转发处理,只有特定场景下才能让用户态程序获取原始数据包。权限与VMkernel配置调整:
- 必须以root权限运行程序,ESXi下Raw Socket需要最高权限才能创建和使用。
- 开启VMkernel的Raw Socket支持:执行
esxcli network ip raw set --enabled=true(部分ESXi版本默认禁用此功能)。 - 开启物理网卡的混杂模式:执行
esxcli network nic set --nic=vmnicX --promiscuous=true,将vmnicX替换为你要捕获流量的物理网卡名称,Raw Socket捕获全量流量依赖网卡的混杂模式。
Socket参数兼容性调整:
- 尝试移除
SOCK_NONBLOCK标记,改用阻塞模式测试。ESXi的VMkernel对非阻塞Socket的处理逻辑和Ubuntu存在差异,阻塞模式下更容易验证是否能收到数据包。 - 可以尝试改用
AF_INET+SOCK_RAW的组合(协议指定IPPROTO_TCP或IPPROTO_UDP),这种方式只能捕获IP层以上的流量,但可以快速验证Raw Socket功能是否正常工作。
- 尝试移除
ESXi安全限制:ESXi 6.7默认有严格的网络安全策略,部分Raw Socket的底层捕获功能被禁用。需要确认是否有VMkernel防火墙规则阻止了数据包接收,可通过
esxcli network firewall ruleset list查看相关规则,必要时临时关闭防火墙测试。
内容的提问来源于stack exchange,提问作者nahjoh45
相关产品推荐
相关产品推荐

