> On 22 Feb 2022, at 06:31, K R <daharmaster...@gmail.com> wrote:
> 
>> Synopsis:      UDP divert-to rule: getsockname(2) won't show original
> destination
>> Category:      kernel amd64
>> Environment:
>        System      : OpenBSD 7.1-beta
>        Details     : OpenBSD 7.1-beta (GENERIC) #353: Sun Feb 20 17:14:05
> MST 2022
> 
>        Architecture: OpenBSD.amd64
>        Machine     : amd64
>> Description:
> 
> getsockname(2) won't show the original destination address/port for a
> UDP inet packet redirected using a PF divert-to rule to a local
> socket.
> 
> This works as expected for TCP.
> 
>> How-To-Repeat:
> 
> server:
> 
> (pf.conf)
> pass in on vio0 inet proto udp from any to 100.64.0.100 divert-to 127.0.0.1
> port 9000
> 
>>>> import socket
>>>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>>> s.bind(("127.0.0.1", 9000))
>>>> s.recvfrom(1024)
> (b'data\n', ('100.64.0.1', 16079))
>>>> s.getsockname()
> ('127.0.0.1', 9000)
> 
> client:
> 
> $ echo data | nc -u 100.64.0.100 12345
> 
>> Fix:
>        Unknown.

This is working as expected for UDP, which is a datagram socket, not a 
connected TCP stream socket like what you're trying to compare it to. A locally 
bound but not connected UDP socket will not keep information about received 
packets on it, you have to get all that from the messages as they're being 
received.

If you want the original destination address for that message, you have to ask 
for it as part of receiving the message. For IPv4 you do that by setting the 
IP_RECVDSTADDR sockopt on the UDP socket, and then using recvmsg() instead of 
recvfrom() with space for a control message set up for it to use.

src/usr.bin/tftpd/tftpd.c does this if you want some code to refer to.

dlg

Reply via email to