【问题标题】:Type of socket address from recvfrom() with AF_PACKET / PF_PACKET带有 AF_PACKET / PF_PACKET 的 recvfrom() 的套接字地址类型
【发布时间】:2011-09-02 17:00:30
【问题描述】:

在两台 PC 上,我打开一个 AF_PACKET / PF_PACKET 套接字,原始协议。

sock = socket(AF_PACKET, SOCK_RAW, htons(PROTO_BULK))

(编辑:PROTO_BULK 是一个虚拟类型,由我自己为此测试创建。我不认为它会推断出这个问题,但我可能错了。)

第一台PC以标准的send()方式向另一台发送一个数据包,另一端接收到:

recvfrom(sock, buffer, 1600, 0, (struct sockaddr*) &from, &fromlen);

我现在的问题是:“from”中的数据类型是什么?这是我收到的一个示例:

00 00 00 00 00 00 00 00 f8 cd a1 00 58 1d a1 00 94 60

从长度和内容来看,它不像是“struct sockaddr”,也不是“sockaddr_ll”。任何想法?

我实际上是在寻找接收数据包的接口。我可以使用数据包中的目标 MAC 并从中识别接口,但它不适用于广播数据包。

我正在运行一个最新的 Linux 内核(我不想研究内核源代码!)。

编辑:我的代码有误。我没有用“from”缓冲区大小初始化“fromlen”,所以我认为存在一些虚假值,并且“recvfrom()”无法正确完成其工作。感谢 Ben Voigt 在下面的评论中指出了这个错误!当然,我的问题中没有包含这部分错误代码,因为很明显,这么简单的代码不会出错......

使用正确的参数,我得到一个正确填充的“struct sockaddr_ll”,包括我正在寻找的接口号。

【问题讨论】:

  • 1. fromlen 的值是多少。 2、你有没有试过投到sockaddr_ll,发现里面有无效数据?
  • 致 cnicutar: 1. fromlen 为 18,如转储所示。 2.是的,没有意义。
  • struct sockaddr 不保证具有可移植布局,因此还请包括当缓冲区被解释(通过强制转换)为struct sockaddrstruct sockaddr_pktstruct sockaddr_ll 时的不同字段等。
  • 在打电话给recvfrom 之前,fromlen 是什么?内核无法使您的地址缓冲区比开始时更大。

标签: c linux sockets


【解决方案1】:

我实际上是在寻找接收数据包的接口。

您应该使用recvmsg,它可以访问元数据,例如数据包的目标地址(对多宿主系统很有用),我认为也是接口。

您现在查看的发件人地址不会告诉您接口。不过,用sendto 发送回复数据包很有用。

【讨论】:

    【解决方案2】:

    我浏览了内核源代码。我并没有声称完全理解它们,但是......

    PROTO_BULK 是 37984 (0x9460) 吗?

    如果是这样,这可能是一个“struct sockaddr_pkt”。 (无论如何,它的大小是正确的。)虽然我不确定其他字节是什么意思。如果我正确阅读代码,它们应该是接收数据包的接口的“名称”。所以我可能读错了代码。

    【讨论】:

    • 关于 PROTO_BULK,我将编辑原始问题。 “sockaddr_pkt”的大小正确,但数据不匹配。从“man 7 packet”文档中,它还说它是 Linux 2.0 的遗物。
    猜你喜欢
    • 2015-05-23
    • 1970-01-01
    • 2013-08-20
    • 2019-03-24
    • 2015-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多