【问题标题】:Raw socket sendto() failure in OS XOS X 中的原始套接字 sendto() 失败
【发布时间】:2011-10-27 16:06:49
【问题描述】:

当我打开一个原始套接字是 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 中的原始套接字发送数据包?谢谢。

【问题讨论】:

  • 这是一个很好的问题,但它确实会从程序员那里得到更好的答案。出于这个原因,我投票将其迁移到stackoverflow.com。一旦有更多人投票,它将自动发生,因此您无需在此处重新创建。

标签: sockets macos


【解决方案1】:

我可能已经解开了这个谜。 我也制作了一个原始套接字示例,它在 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 上。不管它多么奇怪,它都能正常工作。

【讨论】:

  • 这种行为实际上记录在 Steven 的“Unix 网络编程”第一卷第 25 章“原始套接字”第 2 版中。
【解决方案2】:

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>

希望这会有所帮助。

【讨论】:

    【解决方案3】:

    FreeBSD 采用了另一种方法。它从不将 TCP 或 UDP 数据包传递给 raw 插座。此类数据包需要直接在数据链路层通过使用 libpcap 或 bpf API 等库。它也从不传递任何碎片 数据报。每个数据报在传递之前必须完全重新组装 到原始套接字。

    这也可能适用于 OSX

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-15
      • 2011-04-25
      • 1970-01-01
      • 1970-01-01
      • 2017-02-02
      • 1970-01-01
      • 1970-01-01
      • 2016-01-07
      相关资源
      最近更新 更多