> On 23 Feb 2022, at 02:12, K R <daharmaster...@gmail.com> wrote:
> 
> Hi David,
> 
> On Tue, Feb 22, 2022 at 5:27 AM David Gwynne <da...@gwynne.id.au> wrote:
> 
> 
> > 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.
> 
> Thanks, of course, you are right.  Now that you mentioned it, I could find 
> this information on the ip(4)
> 
>      If the IP_RECVDSTADDR option is enabled on a SOCK_DGRAM socket, the
>      recvmsg(2) call will return the destination IP address for a UDP
>      datagram.  The msg_control field in the msghdr structure points to a
>      buffer that contains a cmsghdr structure followed by the IP address.
>      [...]
> 
> and pf(4) manpages:
>  
>              getsockname(2).  For SOCK_DGRAM sockets, the ip(4) socket
>              options IP_RECVDSTADDR and IP_RECVDSTPORT can be used to
>              retrieve the destination address and port.
> 
> What would be nice, IMHO, is to make this clear on the pf.conf(5) 
> manpage when diverto-to is mentioned:
> 
>      divert-to host port port
>              Used to redirect packets to a local socket bound to host and
>              port.  The packets will not be modified, so getsockname(2) on
>              the socket will return the original destination address of the
>              packet.

agreed. i put something in.

> 
> 
> src/usr.bin/tftpd/tftpd.c does this if you want some code to refer to.
> 
> I believe it is src/usr.sbin/tftp-proxy/tftp-proxy.c, correct?

even though tftpd isn't used with diver-to, it still uses the sockopts and 
control messages to get destination addresses for tftp requests. tftp-proxy 
might be better, but i was in tftpd more recently so it was what i remembered 
first.

dlg

Reply via email to