On 2011/05/03 19:51, Mike Belopuhov wrote:
> On Tue, May 3, 2011 at 9:56 AM, Stuart Henderson <[email protected]> wrote:
> > On 2011/05/02 22:28, Lawrence Teo wrote:
> >> The DIOCNATLOOK example program at the end of the pf(4) man page
> >> uses memset(3), but string.h is not included. The following diff
> >> fixes this. Any thoughts?
> >
> > That change is correct but I'm not sure about keeping this example
> > code at all. We've had divert-to since OpenBSD 4.4 - when this is used
> > instead of rdr-to the destination address is preserved, so it can be
> > fetched with getsockname() without the DIOCNATLOOK dance.
> >
> > As a result the code becomes much less complicated, so we don't
> > really need an example any more, also another big advantage is that
> > there's no need for access to the privileged /dev/pf device.
> >
> > How about this?
> >
>
> i'm in favor of this change, so ok mikeb
>
slightly tweaked after knowledge gained from converting tftp-proxy;
specifically, mention the socket options that will be needed for udp
as they're not easy to track down.
This was primarily used to support transparent proxies with rdr-
to rules. New proxies should use divert-to rules instead. These
do not require access to the privileged /dev/pf device and
preserve the original destination address for getsockname(2).
For SOCK_DGRAM sockets, the ip(4) socket options IP_RECVDSTADDR
and IP_RECVDSTPORT can be used to retrieve destination address
and port.
jmc asked about changing the example; if we replace it with a
code fragment using getsockname it's no longer specific to pf(4),
and the code is so much simpler than DIOCNATLOOK that IMO a
sample isn't really needed for this.
however we could probably usefully add a line or two to
getsockname(4) explaining its use with divert-to.
looking through the ports tree, there are two occasions where
DIOCNATLOOK is used that can't be replaced with divert-to/getsockname:
ftpsesame, which needs to lookup addresses gleaned from BPF captured
connections, and oidentd which needs to lookup in response to ident
requests. does anyone think it's worth keeping the example for cases
like these? (personally I don't, but could be persuaded otherwise
if people feel strongly about it).
(the other ports using DIOCNATLOOK can probably be converted
fairly easily - transproxy, tor, commoncpp, tircproxy).
Index: pf.4
===================================================================
RCS file: /cvs/src/share/man/man4/pf.4,v
retrieving revision 1.72
diff -u -p -r1.72 pf.4
--- pf.4 28 Dec 2010 13:56:11 -0000 1.72
+++ pf.4 5 May 2011 22:41:15 -0000
@@ -314,6 +314,16 @@ struct pfioc_natlook {
u_int8_t direction;
};
.Ed
+This was primarily used to support transparent proxies with rdr-to rules.
+New proxies should use divert-to rules instead.
+These do not require access to the privileged
+.Pa /dev/pf
+device and preserve the original destination address for
+.Xr getsockname 2 .
+For SOCK_DGRAM sockets, the
+.Xr ip 4
+socket options IP_RECVDSTADDR and IP_RECVDSTPORT can be used to retrieve
+destination address and port.
.It Dv DIOCSETDEBUG Fa "u_int32_t *level"
Set the debug level.
See the
@@ -988,73 +998,6 @@ Explicitly remove source tracking nodes.
.It Pa /dev/pf
packet filtering device.
.El
-.Sh EXAMPLES
-The following example demonstrates how to use the
-.Dv DIOCNATLOOK
-command to find the internal host/port of a NATed connection:
-.Bd -literal
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/fcntl.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <net/pfvar.h>
-#include <err.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-u_int32_t
-read_address(const char *s)
-{
- int a, b, c, d;
-
- sscanf(s, "%i.%i.%i.%i", &a, &b, &c, &d);
- return htonl(a << 24 | b << 16 | c << 8 | d);
-}
-
-void
-print_address(u_int32_t a)
-{
- a = ntohl(a);
- printf("%d.%d.%d.%d", a >> 24 & 255, a >> 16 & 255,
- a >> 8 & 255, a & 255);
-}
-
-int
-main(int argc, char *argv[])
-{
- struct pfioc_natlook nl;
- int dev;
-
- if (argc != 5) {
- printf("%s <gwy addr> <gwy port> <ext addr> <ext port>\en",
- argv[0]);
- return 1;
- }
-
- dev = open("/dev/pf", O_RDWR);
- if (dev == -1)
- err(1, "open(\e"/dev/pf\e") failed");
-
- memset(&nl, 0, sizeof(struct pfioc_natlook));
- nl.saddr.v4.s_addr = read_address(argv[1]);
- nl.sport = htons(atoi(argv[2]));
- nl.daddr.v4.s_addr = read_address(argv[3]);
- nl.dport = htons(atoi(argv[4]));
- nl.af = AF_INET;
- nl.proto = IPPROTO_TCP;
- nl.direction = PF_IN;
-
- if (ioctl(dev, DIOCNATLOOK, &nl))
- err(1, "DIOCNATLOOK");
-
- printf("internal host ");
- print_address(nl.rsaddr.v4.s_addr);
- printf(":%u\en", ntohs(nl.rsport));
- return 0;
-}
-.Ed
.Sh SEE ALSO
.Xr ioctl 2 ,
.Xr bridge 4 ,