On Wed, Feb 23, 2022 at 10:34 AM David Gwynne <[email protected]> wrote:

>
>
> > On 23 Feb 2022, at 02:12, K R <[email protected]> wrote:
> >
> > Hi David,
> >
> > On Tue, Feb 22, 2022 at 5:27 AM David Gwynne <[email protected]> wrote:
> >
> >
> > > On 22 Feb 2022, at 06:31, K R <[email protected]> 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.
>

Fantastic, I just saw your commit.  Thanks, again!

--Kor


>
> >
> >
> > 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