Is there a way to get struct msghdr or ancillary data of it for the last received packet, i.e. after the recv() call? My guess is that recvmsg() is the only way to populate msghdr, but probably there is a hack on how to get ancillary data independently of recv.
1 Answer
the point at which the syscall gets the data from kernel space into user space is the point at which the kernel knows it can reclaim the kernel memory used for storing the packet and its metadata.
So, no, not from the kernel; the data is gone. You might "hack" your libc implementation of recv() to retain some of the data that recvmsg gives you (that is indeed a hack, because usually, on Linux, a recv() libc call leads to a recvfrom syscall, with the the addresses where the kernel would put the data you want set to NULL, i.e., you need to monkeypatch your libc).
But then you need to implement some method to free that data, as well, and at that point you're just implementing a new API; you'd simply patch your software to use recvmsg at that point.
I think you're asking the wrong question, and probably want something like a capture interface instead. You can do things like combining libpcap and inspection of your process of interest to build something useful.
- 1Thanks for the detailed answer, now it's clear that ancillary data is strictly relevant to a packet, the socket stores no part of it.
libpcapis what I am planning to look at next.Alex– Alex2025-06-27 11:10:12 +00:00Commented Jun 27 at 11:10
tcp_infostores some data independently of receive calls. Butmsghdrseems to be bound more to the packet and less to the socket thus probably there is no way to get it similarly to getsockopt with TCP_INFO.