1

I receive a UDP packet using recvmsg(2). I would like to know if it is from the local machine or not.

I can use IP_PKTINFO with recvmsg to get the interface the packet was received on. When the packet was sent to a loopback address this is the loopback interface, which is great. When the packet was sent to an address of some other network interface, it comes back as that interface whether the packet was locally generated or not, which is not so great.

I can check if the source address of the packet is an address of the local machine, but if reverse path filtering is disabled then it could have that address and still be from another machine, and I can't assume that it isn't. Also, this would be a race between when I receive the packet and when I check what the local addresses are.

The system is Linux. C or C++. The process doing this has CAP_NET_ADMIN. How do I determine if the received packet is from the local machine or not?

zrm
  • 111
  • 2
  • 1
    Does this https://stackoverflow.com/questions/13105713/finding-the-source-ip-process-of-a-udp-packet help? Not that you mention your programming language of choice ... – tink Apr 30 '20 at 04:11
  • That gives the source address of the packet, but how do you know it was sent from the local machine? Even if that address is on the local machine now, it might not have been 5ms ago when the packet was received; it's a race condition. Even if it was, an external (malicious) machine could have the same IP address and send a packet from it. – zrm Apr 30 '20 at 04:24
  • 2
    The solution here is to not do this in your program, but let a firewall that filters packets at the kernel level decide for you. You cannot correctly make this decision in userspace, when the data has already arrived and (as you say) there is a race condition. – Marco Bonelli Apr 30 '20 at 09:15
  • You can't use the source address because of the race condition. What I want is something else that implies local source. Is there a way to get the sender's UID when the sender is local? Can I bind two sockets to the wildcard addr and have one receive only the local packets somehow? Is there any cmsg ancillary data with any flag set only for local packets? (Is there a list of those anywhere?) Anything that would be different in the netfilter conntrack state? The program may run on third party systems whose admins have rpfilter disabled. – zrm Apr 30 '20 at 15:03

0 Answers0