来自带有 AF_PACKET / PF_PACKET 的 recvfrom() 的套接字地址类型

发布于 2024-11-09 21:39:42 字数 912 浏览 0 评论 0原文

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

sock = 套接字(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”,包括我正在寻找的接口号。

On two PC, I am opening an AF_PACKET / PF_PACKET socket, raw protocol.

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

(edit: PROTO_BULK is a dummy type, created by myself for this test. I do not expect it to be inferring with this problem, but I may be wrong.)

The first PC send a packet to the other the standard send() way, which is received on the other side with:

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

My problem is now: what is the type of the data in "from"? Here is an exemple of what I am receiving:

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

From the length and the content, it does not look like a "struct sockaddr" nor a "sockaddr_ll". Any idea?

I am actually looking for the interface the packet was received on. I could use the destination MAC from the packet and identify the interface from it, but it would not work with a broadcast packet.

I am running a recent Linux kernel (and I do not want to investigate in the kernel sources!).

Edit: My code was wrong. I did not initialized "fromlen" with "from" buffer size, so I supposed some spurious value was there and "recvfrom()" could not do its job correctly. Thanks to Ben Voigt for pointing me this bug with his comment below! Of course, I did not include this part of the faulty code in my question, as it was obvious there could be no mistake with such simple code...

With the correct paramter, I get a "struct sockaddr_ll" correctly filled, including the interface number I was looking for.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

⊕婉儿 2024-11-16 21:39:42

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

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

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

I am actually looking for the interface the packet was received on.

You should be using recvmsg, which gives access to metadata such as the packet's destination address (useful for multihomed systems) and I think also the interface.

The sender address you're looking at now isn't going to tell you the interface. It's good for sending a reply packet with sendto though.

栀子花开つ 2024-11-16 21:39:42

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

PROTO_BULK 37984 (0x9460) 是吗?

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

I took a glance at the kernel sources. I do not claim to fully understand them, but...

Is PROTO_BULK 37984 (0x9460)?

If so, this is probably a "struct sockaddr_pkt". (It has the right size, anyway.) Although I am not sure what the other bytes mean. If I am reading the code correctly, they should be the "name" of the interface on which the packet was received. So I am probably reading the code incorrectly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文