> 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