linux原始套接字能不能不收自己发出去的数据

henryying 2016-03-03 02:05:00
背景:用原始套接字直接操作数据链路层,走自定义协议,数据开头不是dstmac srcmac 协议号
即除了底层物理链路用的网口,其他一点关系都没了

这种需求可能写一个内核模块更合适,但能力有限,skb啥的都只是了解一些概念而已,因此选择用原始套接字实现


socket(PF_PACKET, SOCKET_RAW, htons(ETH_P_ALL));
其他一些绑定eth的代码不贴出来了,都是标准的
发送试过sendto, write接收试过read, recv , recvfrom,都能收发

问题来了:
我想达到的效果: 发送一个报文,然后接收一个ack报文
而实际情况是: 我发送一个报文,首先收到的是自己发出去的报文,然后才是ack
就有点像tcpdump,在链路上收发的数据全被读出来了

由于典型应用是发1518,收12字节应答
结果变成了发1518,收1518,应用层判断丢弃,再收12字节应答
因为处理器频率很低,这种无意义的数据拷贝很影响性能


我尝试了一种方法,就是按照以太网帧的方式
dstmac srcmac protocol中的protocol字段要求对方应答时必须设置为一个特殊值,和发送区分开,这样原始套接字不用ETH_P_ALL,而用自定义值就能只收应答数据了


求教各位大神,如何配置原始套接字能让只接收真正收到的数据,而不是把自己发出去的也收回来,cpu资源真的不够把数据收到应用层判断
...全文
229 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
henryying 2016-03-05
  • 打赏
  • 举报
回复
这个问题我找到其他规避了 建立原始套接字, 协议号为0,只能发不能收 协议号为ETH_P_ALL,特性就是把发出去的数据再抓回来 协议号为其他专用协议号,就可以做到发出去的数据不会抓回来 而我实际的需求是发送的数据根本就不是以太网帧,也就是 6字节dstmac 6字节srcmac 2字节协议号 要规避这个问题,内核编写驱动,直接操作驱动的读写借口无疑是最高效的办法 但一定要使用原始套接字操作数据链路层,对应的,收发的数据就必须是一个完整的以太网帧 即自定义协议头至少包含14字节,其中的13~14两个字节协议号填写固定字,前面的12字节mac就无所谓了 反正设为混杂模式之后,系统也不会管这12字节的mac 相当于我最后对自己的协议进行了改造,头长度从12字节强行扩展到14字节,以实现对原始套接字妥协

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧