Commited, thanks :).

On 8 February 2012 01:19, Lawrence Teo <l...@lteo.net> wrote:
> On Mon, Feb 06, 2012 at 09:12:35PM -0500, Lawrence Teo wrote:
>> This is a revised version of a diff that sthen@ and I worked on back in
>> May 2011. The original thread and history is at
>> http://marc.info/?t=130438996800003&r=1&w=2 if anyone is interested.
>>
>> To summarize, the current pf(4) man page's example program uses
>> DIOCNATLOOK. But Stuart pointed out in the above thread that divert-to
>> has existed since OpenBSD 4.4, so the better approach is to fetch the
>> destination address using getsockname() instead of DIOCNATLOOK. This
>> also does not require access to /dev/pf.
>>
>> In this diff, Stuart added a paragraph to the DIOCNATLOOK description in
>> the pf(4) man page to mention divert-to, while I replaced the example
>> program with one that demonstrates DIOCGETLIMIT instead. I picked
>> DIOCGETLIMIT because it will work as-is on any OpenBSD system
>> regardless of their PF rules.
>
> Here's another revision that addresses jmc@'s comments (thank you
> Jason!). It uses .Dv where appropriate and adds a missing "the" in the
> DIOCNATLOOK paragraph. The example program remains unchanged.
>
> Any further comments would be appreciated.
>
> Thank you,
> Lawrence
>
>
> Index: pf.4
> ===================================================================
> RCS file: /cvs/src/share/man/man4/pf.4,v
> retrieving revision 1.73
> diff -u -p -r1.73 pf.4
> --- pf.4        23 Dec 2011 17:00:47 -0000      1.73
> +++ pf.4        8 Feb 2012 03:11:39 -0000
> @@ -314,6 +314,22 @@ struct pfioc_natlook {
>        u_int8_t         direction;
>  };
>  .Ed
> +.Pp
> +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
> +.Dv SOCK_DGRAM
> +sockets, the
> +.Xr ip 4
> +socket options
> +.Dv IP_RECVDSTADDR
> +and
> +.Dv IP_RECVDSTPORT
> +can be used to retrieve the destination address and port.
>  .It Dv DIOCSETDEBUG Fa "u_int32_t *level"
>  Set the debug level.
>  See the
> @@ -990,68 +1006,81 @@ 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:
> +.Dv DIOCGETLIMIT
> +command to show the hard limit of a memory pool used by the packet filter:
>  .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>
> +#include <string.h>
> +#include <err.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);
> -}
> +static const struct {
> +       const char      *name;
> +       int             index;
> +} pf_limits[] = {
> +       { "states",             PF_LIMIT_STATES },
> +       { "src-nodes",          PF_LIMIT_SRC_NODES },
> +       { "frags",              PF_LIMIT_FRAGS },
> +       { "tables",             PF_LIMIT_TABLES },
> +       { "table-entries",      PF_LIMIT_TABLE_ENTRIES },
> +       { NULL,                 0 }
> +};
>
>  void
> -print_address(u_int32_t a)
> +usage(void)
>  {
> -       a = ntohl(a);
> -       printf("%d.%d.%d.%d", a >> 24 & 255, a >> 16 & 255,
> -           a >> 8 & 255, a & 255);
> +       extern char *__progname;
> +       int i;
> +
> +       fprintf(stderr, "usage: %s [", __progname);
> +       for (i = 0; pf_limits[i].name; i++)
> +               fprintf(stderr, "%s%s", (i > 0 ? "|" : ""),
pf_limits[i].name);
> +       fprintf(stderr, "]\en");
> +       exit(1);
>  }
>
>  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;
> +       struct pfioc_limit pl;
> +       int i, dev;
> +       int pool_index = -1;
> +
> +       if (argc != 2)
> +               usage();
> +
> +       for (i = 0; pf_limits[i].name; i++)
> +               if (!strcmp(argv[1], pf_limits[i].name)) {
> +                       pool_index = pf_limits[i].index;
> +                       break;
> +               }
> +
> +       if (pool_index == -1) {
> +               warnx("no such memory pool: %s", argv[1]);
> +               usage();
>        }
>
>        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));
> +       bzero(&pl, sizeof(struct pfioc_limit));
> +       pl.index = pool_index;
> +
> +       if (ioctl(dev, DIOCGETLIMIT, &pl))
> +               err(1, "DIOCGETLIMIT");
> +
> +       printf("The %s memory pool has ", pf_limits[i].name);
> +       if (pl.limit == UINT_MAX)
> +               printf("unlimited entries.\en");
> +       else
> +               printf("a hard limit of %u entries.\en", pl.limit);
>        return 0;
>  }
>  .Ed

Reply via email to