当我打开一个原始套接字是OS X,构建我自己的udp数据包(标题和数据),并调用sendto()时,我收到错误“无效参数”。以下是来自网站http://www.tenouk.com/Module43a.html的示例程序“rawudp.c”,它演示了此问题。该程序(在添加字符串和stdlib #includes之后)在Fedora 10下运行但在OS X下失败并显示“无效参数”。任何人都可以建议为什么在OS X中失败?我看了看,看了看sendto()调用,但所有参数看起来都不错。我正在以root身份运行代码,等等。是否有内核设置阻止甚至uid 0可执行文件通过OS X Snow Leopard中的原始套接字发送数据包?感谢。
答案 0 :(得分:6)
我可能已经解开了这个谜团。
我也制作了一个原始套接字示例,它在Linux上运行良好,但在OS X 10.6上出现“无效参数”错误。
在谷歌上搜索答案时,我遇到了这个页面“FreeBSD socket bugs and peculiarities”。它说:
写入RAW套接字
- ip_len和ip_off必须按主机字节顺序
所以我替换
ip.ip_len = htons(len);
与
ip.ip_len = len;
OS X上的。它有效,但不管它多么奇怪。
答案 1 :(得分:3)
user37278,我在Mac OS X(Snow Leopard)上运行了相同的程序,并收到相同的错误消息。我发现问题是自定义IP头结构与IP头格式不一致。 (可能在机器上有所作为......我不确定。)
我所做的是删除了自定义IP头结构并使用了Mac OS X附带的IP头结构。头信息在<netinet/ip.h>
中定义,结构为struct ip
。我还发现了另一个名为struct iphdr
的结构,我不确定它的区别。
我添加的标题是<netinet/ip.h> <netinet/udp.h> <netinet/in.h> <arpa/inet.h>
希望这有帮助。
答案 2 :(得分:0)
FreeBSD采用另一种方法。 永远不会将TCP或UDP数据包传递给raw 插座。这些数据包需要通过使用直接在数据链路层读取 像libpcap或bpf API这样的库。它也从不传递任何碎片 数据报。每个数据报必须在传递之前重新组装完成 到一个原始套接字。
这可能适用于OSX