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
