简体   繁体   English

OS X中的原始套接字sendto()失败

[英]Raw socket sendto() failure in OS X

When I open a raw socket is OS X, construct my own udp packet (headers and data), and call sendto(), I get the error "Invalid Argument". 当我打开一个原始套接字是OS X,构建我自己的udp数据包(标头和数据),并调用sendto(),我得到错误“无效的参数”。 Here is a sample program "rawudp.c" from the web site http://www.tenouk.com/Module43a.html that demonstrates this problem. 以下是来自网站http://www.tenouk.com/Module43a.html的示例程序“rawudp.c”,它演示了此问题。 The program (after adding string and stdlib #includes) runs under Fedora 10 but fails with "Invalid Argument" under OS X. Can anyone suggest why this fails in OS X? 该程序(在添加字符串和stdlib #includes之后)在Fedora 10下运行但在OS X下失败并显示“无效参数”。任何人都可以建议为什么在OS X中失败? I have looked and looked and looked at the sendto() call, but all the parameters look good. 我看了看,看了看sendto()调用,但所有参数看起来都不错。 I'm running the code as root, etc. Is there perhaps a kernel setting that prevents even uid 0 executables from sending packets through raw sockets in OS X Snow Leopard? 我正在以root身份运行代码,等等。是否有内核设置阻止甚至uid 0可执行文件通过OS X Snow Leopard中的原始套接字发送数据包? Thanks. 谢谢。

I may have solved the mystery. 我可能已经解开了这个谜团。 I too crafted a raw socket example, which runs fine on Linux, but got "Invalid Argument" error on OS X 10.6. 我也制作了一个原始套接字示例,它在Linux上运行良好,但在OS X 10.6上出现“无效参数”错误。
I encountered this page " FreeBSD socket bugs and peculiarities " while googling for an answer. 在谷歌上搜索答案时,我遇到了这个页面“ FreeBSD socket bug and specialclicarities ”。 And it says: 它说:

Writing to RAW sockets 写入RAW套接字


- ip_len and ip_off must be in host byte order - ip_len和ip_off必须按主机字节顺序排列

So I replace 所以我更换

ip.ip_len = htons(len);

with

ip.ip_len = len;

on OS X. And it works, however strange it is. 在OS X上。它的工作原理有点奇怪。

user37278, I ran the same program on my Mac OS X (Snow Leopard) and get the same error message. user37278,我在Mac OS X(Snow Leopard)上运行了相同的程序,并得到相同的错误消息。 I found the problem is that the custom IP header structure is incoherent with the IP header format. 我发现问题是自定义IP头结构与IP头格式不一致。 (Might have something to do difference in machines.. I'm not sure). (可能在机器上有所作为......我不确定)。

What I did was I removed his custom IP header structure and used the IP header struct included with Mac OS X. The header information is defined in <netinet/ip.h> and the struct is struct ip . 我做的是删除了他的自定义IP头结构,并使用了Mac OS X附带的IP头结构。头信息在<netinet/ip.h>定义,结构是struct ip I also found another struct called struct iphdr and I'm not sure the difference. 我还发现了另一个名为struct iphdr ,我不确定它的区别。

The headers I included are <netinet/ip.h> <netinet/udp.h> <netinet/in.h> <arpa/inet.h> 我包含的标题是<netinet/ip.h> <netinet/udp.h> <netinet/in.h> <arpa/inet.h>

Hope this helps. 希望这可以帮助。

FreeBSD takes another approach. FreeBSD采取了另一种方法。 It never passes TCP or UDP packets to raw sockets. 永远不会将TCP或UDP数据包传递给原始套接字。 Such packets need to be read directly at the datalink layer by using libraries like libpcap or the bpf API. 需要使用libpcap或bpf API等库直接在数据链路层读取此类数据包。 It also never passes any fragmented datagram. 它也从不传递任何碎片数据报。 Each datagram has to be completeley reassembled before it is passed to a raw socket. 每个数据报在传递给原始套接字之前必须重新组装。

this might go for OSX as well 这也可能适用于OSX

Source: http://sock-raw.org/papers/sock_raw 资料来源: http//sock-raw.org/papers/sock_raw

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM