First working experiment of IPv6 "pinhole" with pf

This commit is contained in:
Thomas Bernard 2012-04-19 01:43:50 +02:00
parent f934bf5d17
commit b165afbba7
3 changed files with 37 additions and 8 deletions

View File

@ -1,4 +1,7 @@
$Id: Changelog.txt,v 1.270 2012/04/14 22:26:09 nanard Exp $ $Id: Changelog.txt,v 1.271 2012/04/18 23:44:35 nanard Exp $
2012/04/19:
First working experiment of IPv6 "pinhole" with pf
2012/04/15: 2012/04/15:
More C++ => ANSI C comments to compile with -ansi option More C++ => ANSI C comments to compile with -ansi option

View File

@ -1,4 +1,4 @@
/* $Id: pfpinhole.c,v 1.2 2012/04/18 20:45:33 nanard Exp $ */ /* $Id: pfpinhole.c,v 1.4 2012/04/18 23:44:51 nanard Exp $ */
/* MiniUPnP project /* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2012 Thomas Bernard * (c) 2006-2012 Thomas Bernard
@ -26,6 +26,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "../config.h" #include "../config.h"
#include "pfpinhole.h"
#include "../upnpglobalvars.h" #include "../upnpglobalvars.h"
/* /dev/pf when opened */ /* /dev/pf when opened */
@ -38,6 +39,9 @@ int add_pinhole (const char * ifname,
{ {
int r; int r;
struct pfioc_rule pcr; struct pfioc_rule pcr;
#ifndef PF_NEWSTYLE
struct pfioc_pooladdr pp;
#endif
if(dev<0) { if(dev<0) {
syslog(LOG_ERR, "pf device is not open"); syslog(LOG_ERR, "pf device is not open");
@ -45,10 +49,26 @@ int add_pinhole (const char * ifname,
} }
r = 0; r = 0;
memset(&pcr, 0, sizeof(pcr)); memset(&pcr, 0, sizeof(pcr));
strlcpy(pcr.anchor, anchor_name, MAXPATHLEN);
#ifndef PF_NEWSTYLE
memset(&pp, 0, sizeof(pp));
strlcpy(pp.anchor, anchor_name, MAXPATHLEN);
if(ioctl(dev, DIOCBEGINADDRS, &pp) < 0) {
syslog(LOG_ERR, "ioctl(dev, DIOCBEGINADDRS, ...): %m");
return -1;
} else {
pcr.pool_ticket = pp.ticket;
#else
{ {
#endif
pcr.rule.direction = PF_IN; pcr.rule.direction = PF_IN;
pcr.rule.action = PF_PASS; pcr.rule.action = PF_PASS;
pcr.rule.af = AF_INET6; pcr.rule.af = AF_INET6;
#ifdef PF_NEWSTYLE
pcr.rule.nat.addr.type = PF_ADDR_NONE;
pcr.rule.rdr.addr.type = PF_ADDR_NONE;
#endif
#ifdef USE_IFNAME_IN_RULES #ifdef USE_IFNAME_IN_RULES
if(ifname) if(ifname)
strlcpy(pcr.rule.ifname, ifname, IFNAMSIZ); strlcpy(pcr.rule.ifname, ifname, IFNAMSIZ);
@ -74,16 +94,21 @@ int add_pinhole (const char * ifname,
if(tag) if(tag)
strlcpy(pcr.rule.tagname, tag, PF_TAG_NAME_SIZE); strlcpy(pcr.rule.tagname, tag, PF_TAG_NAME_SIZE);
pcr.rule.src.port_op = PF_OP_EQ; if(rem_port) {
pcr.rule.src.port[0] = htons(rem_port); pcr.rule.src.port_op = PF_OP_EQ;
if(rem_host && rem_host[0] != '\0' && rem_host[0] != '*') pcr.rule.src.port[0] = htons(rem_port);
{ }
inet_pton(AF_INET6, rem_host, &pcr.rule.src.addr.v.a.addr.v6); if(rem_host && rem_host[0] != '\0' && rem_host[0] != '*') {
pcr.rule.src.addr.type = PF_ADDR_ADDRMASK;
if(inet_pton(AF_INET6, rem_host, &pcr.rule.src.addr.v.a.addr.v6) != 1) {
syslog(LOG_ERR, "inet_pton(%s) failed", rem_host);
}
memset(&pcr.rule.src.addr.v.a.mask.addr8, 255, 16); memset(&pcr.rule.src.addr.v.a.mask.addr8, 255, 16);
} }
pcr.rule.dst.port_op = PF_OP_EQ; pcr.rule.dst.port_op = PF_OP_EQ;
pcr.rule.dst.port[0] = htons(int_port); pcr.rule.dst.port[0] = htons(int_port);
pcr.rule.dst.addr.type = PF_ADDR_ADDRMASK;
if(inet_pton(AF_INET6, int_client, &pcr.rule.dst.addr.v.a.addr.v6) != 1) { if(inet_pton(AF_INET6, int_client, &pcr.rule.dst.addr.v.a.addr.v6) != 1) {
syslog(LOG_ERR, "inet_pton(%s) failed", int_client); syslog(LOG_ERR, "inet_pton(%s) failed", int_client);
} }

View File

@ -1,4 +1,4 @@
/* $Id: testpfpinhole.c,v 1.1 2012/04/18 20:45:33 nanard Exp $ */ /* $Id: testpfpinhole.c,v 1.2 2012/04/18 23:44:51 nanard Exp $ */
/* MiniUPnP project /* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2012 Thomas Bernard * (c) 2006-2012 Thomas Bernard
@ -31,6 +31,7 @@ int main(int argc, char * *argv)
} }
ret = add_pinhole("ep0", "2001::1:2:3", 12345, "123::ff", 54321, IPPROTO_UDP); ret = add_pinhole("ep0", "2001::1:2:3", 12345, "123::ff", 54321, IPPROTO_UDP);
ret = add_pinhole("ep0", NULL, 0, "dead:beef::42:42", 8080, IPPROTO_UDP);
return 0; return 0;
} }