parent
a5fd382e95
commit
b16787cd5f
|
@ -1,8 +1,8 @@
|
||||||
/* $Id: obsdrdr.c,v 1.101 2022/02/19 19:15:24 nanard Exp $ */
|
/* $Id: obsdrdr.c,v 1.102 2023/12/07 18:56:32 nanard Exp $ */
|
||||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||||
* MiniUPnP project
|
* MiniUPnP project
|
||||||
* http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
|
* http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
|
||||||
* (c) 2006-2022 Thomas Bernard
|
* (c) 2006-2023 Thomas Bernard
|
||||||
* This software is subject to the conditions detailed
|
* This software is subject to the conditions detailed
|
||||||
* in the LICENCE file provided within the distribution */
|
* in the LICENCE file provided within the distribution */
|
||||||
|
|
||||||
|
@ -74,6 +74,17 @@
|
||||||
#error "USE_PF macro is undefined, check consistency between config.h and Makefile"
|
#error "USE_PF macro is undefined, check consistency between config.h and Makefile"
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#if defined(PF_NEWSTYLE) && defined(DIOCXEND)
|
||||||
|
#define PF_RELEASETICKETS
|
||||||
|
#define release_ticket(device, ticket_num) {\
|
||||||
|
if (ioctl((device), DIOCXEND, &(ticket_num)) < 0) {\
|
||||||
|
syslog(LOG_ERR, "ioctl(dev, DIOCXEND, ...): %m");\
|
||||||
|
}\
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define release_ticket(device, ticket_num) (void)(ticket_num)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* list to keep timestamps for port mappings having a lease duration */
|
/* list to keep timestamps for port mappings having a lease duration */
|
||||||
struct timestamp_entry {
|
struct timestamp_entry {
|
||||||
struct timestamp_entry * next;
|
struct timestamp_entry * next;
|
||||||
|
@ -463,6 +474,7 @@ static int
|
||||||
delete_nat_rule(const char * ifname, unsigned short iport, int proto, in_addr_t iaddr)
|
delete_nat_rule(const char * ifname, unsigned short iport, int proto, in_addr_t iaddr)
|
||||||
{
|
{
|
||||||
int i, n;
|
int i, n;
|
||||||
|
unsigned int tnum;
|
||||||
struct pfioc_rule pr;
|
struct pfioc_rule pr;
|
||||||
UNUSED(ifname);
|
UNUSED(ifname);
|
||||||
if(dev<0) {
|
if(dev<0) {
|
||||||
|
@ -483,12 +495,16 @@ delete_nat_rule(const char * ifname, unsigned short iport, int proto, in_addr_t
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
n = pr.nr;
|
n = pr.nr;
|
||||||
|
#ifdef PF_RELEASETICKETS
|
||||||
|
tnum = pr.ticket;
|
||||||
|
#endif /* PF_RELEASETICKETS */
|
||||||
for(i=0; i<n; i++)
|
for(i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
pr.nr = i;
|
pr.nr = i;
|
||||||
if(ioctl(dev, DIOCGETRULE, &pr) < 0)
|
if(ioctl(dev, DIOCGETRULE, &pr) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
|
@ -504,6 +520,7 @@ delete_nat_rule(const char * ifname, unsigned short iport, int proto, in_addr_t
|
||||||
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0)
|
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_GET_TICKET: %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_GET_TICKET: %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
pr.action = PF_CHANGE_REMOVE;
|
pr.action = PF_CHANGE_REMOVE;
|
||||||
|
@ -511,11 +528,14 @@ delete_nat_rule(const char * ifname, unsigned short iport, int proto, in_addr_t
|
||||||
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0)
|
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_REMOVE: %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_REMOVE: %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
release_ticket(dev, tnum);
|
||||||
syslog(LOG_NOTICE, "could not find nat rule to delete iport=%hu addr=%8x", iport, ntohl(iaddr));
|
syslog(LOG_NOTICE, "could not find nat rule to delete iport=%hu addr=%8x", iport, ntohl(iaddr));
|
||||||
error:
|
error:
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -827,6 +847,7 @@ get_redirect_rule_count(const char * ifname)
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULES, ...): %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULES, ...): %m");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
release_ticket(dev, pr.ticket);
|
||||||
return pr.nr;
|
return pr.nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -842,6 +863,7 @@ get_redirect_rule(const char * ifname, unsigned short eport, int proto,
|
||||||
u_int64_t * packets, u_int64_t * bytes)
|
u_int64_t * packets, u_int64_t * bytes)
|
||||||
{
|
{
|
||||||
int i, n;
|
int i, n;
|
||||||
|
unsigned int tnum;
|
||||||
struct pfioc_rule pr;
|
struct pfioc_rule pr;
|
||||||
#ifndef PF_NEWSTYLE
|
#ifndef PF_NEWSTYLE
|
||||||
struct pfioc_pooladdr pp;
|
struct pfioc_pooladdr pp;
|
||||||
|
@ -863,12 +885,16 @@ get_redirect_rule(const char * ifname, unsigned short eport, int proto,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
n = pr.nr;
|
n = pr.nr;
|
||||||
|
#ifdef PF_RELEASETICKETS
|
||||||
|
tnum = pr.ticket;
|
||||||
|
#endif /* PF_RELEASETICKETS */
|
||||||
for(i=0; i<n; i++)
|
for(i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
pr.nr = i;
|
pr.nr = i;
|
||||||
if(ioctl(dev, DIOCGETRULE, &pr) < 0)
|
if(ioctl(dev, DIOCGETRULE, &pr) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
@ -954,9 +980,11 @@ get_redirect_rule(const char * ifname, unsigned short eport, int proto,
|
||||||
}
|
}
|
||||||
if(timestamp)
|
if(timestamp)
|
||||||
*timestamp = get_timestamp(eport, proto);
|
*timestamp = get_timestamp(eport, proto);
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
release_ticket(dev, tnum);
|
||||||
error:
|
error:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -977,6 +1005,7 @@ priv_delete_redirect_rule_check_desc(const char * ifname, unsigned short eport,
|
||||||
int check_desc, const char * desc)
|
int check_desc, const char * desc)
|
||||||
{
|
{
|
||||||
int i, n;
|
int i, n;
|
||||||
|
unsigned int tnum;
|
||||||
struct pfioc_rule pr;
|
struct pfioc_rule pr;
|
||||||
UNUSED(ifname);
|
UNUSED(ifname);
|
||||||
|
|
||||||
|
@ -995,12 +1024,16 @@ priv_delete_redirect_rule_check_desc(const char * ifname, unsigned short eport,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
n = pr.nr;
|
n = pr.nr;
|
||||||
|
#ifdef PF_RELEASETICKETS
|
||||||
|
tnum = pr.ticket;
|
||||||
|
#endif /* PF_RELEASETICKETS */
|
||||||
for(i=0; i<n; i++)
|
for(i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
pr.nr = i;
|
pr.nr = i;
|
||||||
if(ioctl(dev, DIOCGETRULE, &pr) < 0)
|
if(ioctl(dev, DIOCGETRULE, &pr) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
@ -1074,6 +1107,7 @@ priv_delete_redirect_rule_check_desc(const char * ifname, unsigned short eport,
|
||||||
if(check_desc) {
|
if(check_desc) {
|
||||||
if((desc == NULL && pr.rule.label[0] == '\0') ||
|
if((desc == NULL && pr.rule.label[0] == '\0') ||
|
||||||
(desc && 0 == strcmp(desc, pr.rule.label))) {
|
(desc && 0 == strcmp(desc, pr.rule.label))) {
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1081,6 +1115,7 @@ priv_delete_redirect_rule_check_desc(const char * ifname, unsigned short eport,
|
||||||
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0)
|
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_GET_TICKET: %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_GET_TICKET: %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
pr.action = PF_CHANGE_REMOVE;
|
pr.action = PF_CHANGE_REMOVE;
|
||||||
|
@ -1088,12 +1123,15 @@ priv_delete_redirect_rule_check_desc(const char * ifname, unsigned short eport,
|
||||||
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0)
|
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_REMOVE: %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_REMOVE: %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
remove_timestamp_entry(eport, proto);
|
remove_timestamp_entry(eport, proto);
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
release_ticket(dev, tnum);
|
||||||
syslog(LOG_NOTICE, "could not find redirect rule to delete eport=%hu", eport);
|
syslog(LOG_NOTICE, "could not find redirect rule to delete eport=%hu", eport);
|
||||||
error:
|
error:
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1115,6 +1153,7 @@ priv_delete_filter_rule(const char * ifname, unsigned short iport,
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
int i, n;
|
int i, n;
|
||||||
|
unsigned int tnum;
|
||||||
struct pfioc_rule pr;
|
struct pfioc_rule pr;
|
||||||
UNUSED(ifname);
|
UNUSED(ifname);
|
||||||
if(dev<0) {
|
if(dev<0) {
|
||||||
|
@ -1130,12 +1169,16 @@ priv_delete_filter_rule(const char * ifname, unsigned short iport,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
n = pr.nr;
|
n = pr.nr;
|
||||||
|
#ifdef PF_RELEASETICKETS
|
||||||
|
tnum = pr.ticket;
|
||||||
|
#endif /* PF_RELEASETICKETS */
|
||||||
for(i=0; i<n; i++)
|
for(i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
pr.nr = i;
|
pr.nr = i;
|
||||||
if(ioctl(dev, DIOCGETRULE, &pr) < 0)
|
if(ioctl(dev, DIOCGETRULE, &pr) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
|
@ -1153,6 +1196,7 @@ syslog(LOG_DEBUG, "%2d port=%hu proto=%d addr=%8x",
|
||||||
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0)
|
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_GET_TICKET: %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_GET_TICKET: %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
pr.action = PF_CHANGE_REMOVE;
|
pr.action = PF_CHANGE_REMOVE;
|
||||||
|
@ -1160,11 +1204,14 @@ syslog(LOG_DEBUG, "%2d port=%hu proto=%d addr=%8x",
|
||||||
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0)
|
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_REMOVE: %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_REMOVE: %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
release_ticket(dev, tnum);
|
||||||
syslog(LOG_NOTICE, "could not find filter rule to delete iport=%hu addr=%8x", iport, ntohl(iaddr));
|
syslog(LOG_NOTICE, "could not find filter rule to delete iport=%hu addr=%8x", iport, ntohl(iaddr));
|
||||||
error:
|
error:
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1207,6 +1254,7 @@ get_redirect_rule_by_index(int index,
|
||||||
u_int64_t * packets, u_int64_t * bytes)
|
u_int64_t * packets, u_int64_t * bytes)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
unsigned int tnum;
|
||||||
struct pfioc_rule pr;
|
struct pfioc_rule pr;
|
||||||
#ifndef PF_NEWSTYLE
|
#ifndef PF_NEWSTYLE
|
||||||
struct pfioc_pooladdr pp;
|
struct pfioc_pooladdr pp;
|
||||||
|
@ -1230,10 +1278,14 @@ get_redirect_rule_by_index(int index,
|
||||||
n = pr.nr;
|
n = pr.nr;
|
||||||
if(index >= n)
|
if(index >= n)
|
||||||
goto error;
|
goto error;
|
||||||
|
#ifdef PF_RELEASETICKETS
|
||||||
|
tnum = pr.ticket;
|
||||||
|
#endif /* PF_RELEASETICKETS */
|
||||||
pr.nr = index;
|
pr.nr = index;
|
||||||
if(ioctl(dev, DIOCGETRULE, &pr) < 0)
|
if(ioctl(dev, DIOCGETRULE, &pr) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
*proto = pr.rule.proto;
|
*proto = pr.rule.proto;
|
||||||
|
@ -1318,6 +1370,7 @@ get_redirect_rule_by_index(int index,
|
||||||
}
|
}
|
||||||
if(timestamp)
|
if(timestamp)
|
||||||
*timestamp = get_timestamp(*eport, *proto);
|
*timestamp = get_timestamp(*eport, *proto);
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
error:
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1330,7 +1383,7 @@ get_portmappings_in_range(unsigned short startport, unsigned short endport,
|
||||||
int proto, unsigned int * number)
|
int proto, unsigned int * number)
|
||||||
{
|
{
|
||||||
unsigned short * array;
|
unsigned short * array;
|
||||||
unsigned int capacity;
|
unsigned int capacity, tnum;
|
||||||
int i, n;
|
int i, n;
|
||||||
unsigned short eport;
|
unsigned short eport;
|
||||||
struct pfioc_rule pr;
|
struct pfioc_rule pr;
|
||||||
|
@ -1359,6 +1412,9 @@ get_portmappings_in_range(unsigned short startport, unsigned short endport,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
n = pr.nr;
|
n = pr.nr;
|
||||||
|
#ifdef PF_RELEASETICKETS
|
||||||
|
tnum = pr.ticket;
|
||||||
|
#endif /* PF_RELEASETICKETS */
|
||||||
for(i=0; i<n; i++)
|
for(i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
pr.nr = i;
|
pr.nr = i;
|
||||||
|
@ -1388,6 +1444,7 @@ get_portmappings_in_range(unsigned short startport, unsigned short endport,
|
||||||
syslog(LOG_ERR, "get_portmappings_in_range() : realloc(%lu) error", sizeof(unsigned short)*capacity);
|
syslog(LOG_ERR, "get_portmappings_in_range() : realloc(%lu) error", sizeof(unsigned short)*capacity);
|
||||||
*number = 0;
|
*number = 0;
|
||||||
free(array);
|
free(array);
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
array = tmp;
|
array = tmp;
|
||||||
|
@ -1396,6 +1453,7 @@ get_portmappings_in_range(unsigned short startport, unsigned short endport,
|
||||||
(*number)++;
|
(*number)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1470,6 +1528,7 @@ list_rules(void)
|
||||||
char buf[32];
|
char buf[32];
|
||||||
char buf2[32];
|
char buf2[32];
|
||||||
int i, n;
|
int i, n;
|
||||||
|
unsigned int tnum;
|
||||||
struct pfioc_rule pr;
|
struct pfioc_rule pr;
|
||||||
#ifndef PF_NEWSTYLE
|
#ifndef PF_NEWSTYLE
|
||||||
struct pfioc_pooladdr pp;
|
struct pfioc_pooladdr pp;
|
||||||
|
@ -1536,6 +1595,7 @@ list_rules(void)
|
||||||
printf(" %s\n", inet_ntop(AF_INET, &pr.rule.rdr.addr.v.a.addr.v4.s_addr, buf, 32));
|
printf(" %s\n", inet_ntop(AF_INET, &pr.rule.rdr.addr.v.a.addr.v4.s_addr, buf, 32));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
release_ticket(dev, tnum);
|
||||||
}
|
}
|
||||||
#endif /* TEST */
|
#endif /* TEST */
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/* $Id: pfpinhole.c,v 1.29 2020/05/10 22:22:50 nanard Exp $ */
|
/* $Id: pfpinhole.c,v 1.30 2023/12/07 18:56:48 nanard Exp $ */
|
||||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||||
* MiniUPnP project
|
* MiniUPnP project
|
||||||
* http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
|
* http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
|
||||||
* (c) 2012-2020 Thomas Bernard
|
* (c) 2012-2023 Thomas Bernard
|
||||||
* This software is subject to the conditions detailed
|
* This software is subject to the conditions detailed
|
||||||
* in the LICENCE file provided within the distribution */
|
* in the LICENCE file provided within the distribution */
|
||||||
|
|
||||||
|
@ -55,6 +55,17 @@ static int next_uid = 1;
|
||||||
#define PINEHOLE_LABEL_FORMAT "pinhole-%d ts-%u: %s"
|
#define PINEHOLE_LABEL_FORMAT "pinhole-%d ts-%u: %s"
|
||||||
#define PINEHOLE_LABEL_FORMAT_SKIPDESC "pinhole-%d ts-%u: %*s"
|
#define PINEHOLE_LABEL_FORMAT_SKIPDESC "pinhole-%d ts-%u: %*s"
|
||||||
|
|
||||||
|
#if defined(PF_NEWSTYLE) && defined(DIOCXEND)
|
||||||
|
#define PF_RELEASETICKETS
|
||||||
|
#define release_ticket(device, ticket_num) {\
|
||||||
|
if (ioctl((device), DIOCXEND, &(ticket_num)) < 0) {\
|
||||||
|
syslog(LOG_ERR, "ioctl(dev, DIOCXEND, ...): %m");\
|
||||||
|
}\
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define release_ticket(device, ticket_num) (void)(ticket_num)
|
||||||
|
#endif
|
||||||
|
|
||||||
int add_pinhole(const char * ifname,
|
int add_pinhole(const char * ifname,
|
||||||
const char * rem_host, unsigned short rem_port,
|
const char * rem_host, unsigned short rem_port,
|
||||||
const char * int_client, unsigned short int_port,
|
const char * int_client, unsigned short int_port,
|
||||||
|
@ -167,7 +178,7 @@ int find_pinhole(const char * ifname,
|
||||||
char *desc, int desc_len, unsigned int * timestamp)
|
char *desc, int desc_len, unsigned int * timestamp)
|
||||||
{
|
{
|
||||||
int uid;
|
int uid;
|
||||||
unsigned int ts;
|
unsigned int ts, tnum;
|
||||||
int i, n;
|
int i, n;
|
||||||
struct pfioc_rule pr;
|
struct pfioc_rule pr;
|
||||||
struct in6_addr saddr;
|
struct in6_addr saddr;
|
||||||
|
@ -194,10 +205,14 @@ int find_pinhole(const char * ifname,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
n = pr.nr;
|
n = pr.nr;
|
||||||
|
#ifdef PF_RELEASETICKETS
|
||||||
|
tnum = pr.ticket;
|
||||||
|
#endif /* PF_RELEASETICKETS */
|
||||||
for(i=0; i<n; i++) {
|
for(i=0; i<n; i++) {
|
||||||
pr.nr = i;
|
pr.nr = i;
|
||||||
if(ioctl(dev, DIOCGETRULE, &pr) < 0) {
|
if(ioctl(dev, DIOCGETRULE, &pr) < 0) {
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if((proto == pr.rule.proto) && (rem_port == ntohs(pr.rule.src.port[0]))
|
if((proto == pr.rule.proto) && (rem_port == ntohs(pr.rule.src.port[0]))
|
||||||
|
@ -216,15 +231,18 @@ int find_pinhole(const char * ifname,
|
||||||
strlcpy(desc, p, desc_len);
|
strlcpy(desc, p, desc_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return uid;
|
return uid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int delete_pinhole(unsigned short uid)
|
int delete_pinhole(unsigned short uid)
|
||||||
{
|
{
|
||||||
int i, n;
|
int i, n;
|
||||||
|
unsigned int tnum;
|
||||||
struct pfioc_rule pr;
|
struct pfioc_rule pr;
|
||||||
char label_start[PF_RULE_LABEL_SIZE];
|
char label_start[PF_RULE_LABEL_SIZE];
|
||||||
char tmp_label[PF_RULE_LABEL_SIZE];
|
char tmp_label[PF_RULE_LABEL_SIZE];
|
||||||
|
@ -245,6 +263,9 @@ int delete_pinhole(unsigned short uid)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
n = pr.nr;
|
n = pr.nr;
|
||||||
|
#ifdef PF_RELEASETICKETS
|
||||||
|
tnum = pr.ticket;
|
||||||
|
#endif
|
||||||
for(i=0; i<n; i++) {
|
for(i=0; i<n; i++) {
|
||||||
pr.nr = i;
|
pr.nr = i;
|
||||||
if(ioctl(dev, DIOCGETRULE, &pr) < 0) {
|
if(ioctl(dev, DIOCGETRULE, &pr) < 0) {
|
||||||
|
@ -257,17 +278,21 @@ int delete_pinhole(unsigned short uid)
|
||||||
pr.action = PF_CHANGE_GET_TICKET;
|
pr.action = PF_CHANGE_GET_TICKET;
|
||||||
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0) {
|
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0) {
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_GET_TICKET: %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_GET_TICKET: %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pr.action = PF_CHANGE_REMOVE;
|
pr.action = PF_CHANGE_REMOVE;
|
||||||
pr.nr = i;
|
pr.nr = i;
|
||||||
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0) {
|
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0) {
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_REMOVE: %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_REMOVE: %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
release_ticket(dev, tnum);
|
||||||
/* not found */
|
/* not found */
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
@ -281,6 +306,7 @@ get_pinhole_info(unsigned short uid,
|
||||||
u_int64_t * packets, u_int64_t * bytes)
|
u_int64_t * packets, u_int64_t * bytes)
|
||||||
{
|
{
|
||||||
int i, n;
|
int i, n;
|
||||||
|
unsigned int tnum;
|
||||||
struct pfioc_rule pr;
|
struct pfioc_rule pr;
|
||||||
char label_start[PF_RULE_LABEL_SIZE];
|
char label_start[PF_RULE_LABEL_SIZE];
|
||||||
char tmp_label[PF_RULE_LABEL_SIZE];
|
char tmp_label[PF_RULE_LABEL_SIZE];
|
||||||
|
@ -302,10 +328,14 @@ get_pinhole_info(unsigned short uid,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
n = pr.nr;
|
n = pr.nr;
|
||||||
|
#ifdef PF_RELEASETICKETS
|
||||||
|
tnum = pr.ticket;
|
||||||
|
#endif
|
||||||
for(i=0; i<n; i++) {
|
for(i=0; i<n; i++) {
|
||||||
pr.nr = i;
|
pr.nr = i;
|
||||||
if(ioctl(dev, DIOCGETRULE, &pr) < 0) {
|
if(ioctl(dev, DIOCGETRULE, &pr) < 0) {
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
strlcpy(tmp_label, pr.rule.label, sizeof(tmp_label));
|
strlcpy(tmp_label, pr.rule.label, sizeof(tmp_label));
|
||||||
|
@ -313,11 +343,13 @@ get_pinhole_info(unsigned short uid,
|
||||||
strsep(&p, " ");
|
strsep(&p, " ");
|
||||||
if(0 == strcmp(tmp_label, label_start)) {
|
if(0 == strcmp(tmp_label, label_start)) {
|
||||||
if(rem_host && (inet_ntop(AF_INET6, &pr.rule.src.addr.v.a.addr.v6, rem_host, rem_hostlen) == NULL)) {
|
if(rem_host && (inet_ntop(AF_INET6, &pr.rule.src.addr.v.a.addr.v6, rem_host, rem_hostlen) == NULL)) {
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(rem_port)
|
if(rem_port)
|
||||||
*rem_port = ntohs(pr.rule.src.port[0]);
|
*rem_port = ntohs(pr.rule.src.port[0]);
|
||||||
if(int_client && (inet_ntop(AF_INET6, &pr.rule.dst.addr.v.a.addr.v6, int_client, int_clientlen) == NULL)) {
|
if(int_client && (inet_ntop(AF_INET6, &pr.rule.dst.addr.v.a.addr.v6, int_client, int_clientlen) == NULL)) {
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(int_port)
|
if(int_port)
|
||||||
|
@ -345,9 +377,11 @@ get_pinhole_info(unsigned short uid,
|
||||||
if(bytes)
|
if(bytes)
|
||||||
*bytes = pr.rule.bytes;
|
*bytes = pr.rule.bytes;
|
||||||
#endif
|
#endif
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
release_ticket(dev, tnum);
|
||||||
/* not found */
|
/* not found */
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
@ -370,7 +404,7 @@ int clean_pinhole_list(unsigned int * next_timestamp)
|
||||||
int i;
|
int i;
|
||||||
struct pfioc_rule pr;
|
struct pfioc_rule pr;
|
||||||
time_t current_time;
|
time_t current_time;
|
||||||
unsigned int ts;
|
unsigned int ts, tnum;
|
||||||
int uid;
|
int uid;
|
||||||
unsigned int min_ts = UINT_MAX;
|
unsigned int min_ts = UINT_MAX;
|
||||||
int min_uid = INT_MAX, max_uid = -1;
|
int min_uid = INT_MAX, max_uid = -1;
|
||||||
|
@ -390,10 +424,14 @@ int clean_pinhole_list(unsigned int * next_timestamp)
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULES, ...): %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULES, ...): %m");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#ifdef PF_RELEASETICKETS
|
||||||
|
tnum = pr.ticket;
|
||||||
|
#endif
|
||||||
for(i = pr.nr - 1; i >= 0; i--) {
|
for(i = pr.nr - 1; i >= 0; i--) {
|
||||||
pr.nr = i;
|
pr.nr = i;
|
||||||
if(ioctl(dev, DIOCGETRULE, &pr) < 0) {
|
if(ioctl(dev, DIOCGETRULE, &pr) < 0) {
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(sscanf(pr.rule.label, PINEHOLE_LABEL_FORMAT_SKIPDESC, &uid, &ts) != 2) {
|
if(sscanf(pr.rule.label, PINEHOLE_LABEL_FORMAT_SKIPDESC, &uid, &ts) != 2) {
|
||||||
|
@ -405,22 +443,28 @@ int clean_pinhole_list(unsigned int * next_timestamp)
|
||||||
pr.action = PF_CHANGE_GET_TICKET;
|
pr.action = PF_CHANGE_GET_TICKET;
|
||||||
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0) {
|
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0) {
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_GET_TICKET: %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_GET_TICKET: %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pr.action = PF_CHANGE_REMOVE;
|
pr.action = PF_CHANGE_REMOVE;
|
||||||
pr.nr = i;
|
pr.nr = i;
|
||||||
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0) {
|
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0) {
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_REMOVE: %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_REMOVE: %m");
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
n++;
|
n++;
|
||||||
#ifndef PF_NEWSTYLE
|
#ifndef PF_NEWSTYLE
|
||||||
pr.rule.action = PF_PASS;
|
pr.rule.action = PF_PASS;
|
||||||
#endif
|
#endif
|
||||||
|
release_ticket(dev, tnum);
|
||||||
if(ioctl(dev, DIOCGETRULES, &pr) < 0) {
|
if(ioctl(dev, DIOCGETRULES, &pr) < 0) {
|
||||||
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULES, ...): %m");
|
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULES, ...): %m");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#ifdef PF_RELEASETICKETS
|
||||||
|
tnum = pr.ticket;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if(uid > max_uid)
|
if(uid > max_uid)
|
||||||
max_uid = uid;
|
max_uid = uid;
|
||||||
|
@ -440,6 +484,7 @@ int clean_pinhole_list(unsigned int * next_timestamp)
|
||||||
next_uid = 1;
|
next_uid = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
release_ticket(dev, tnum);
|
||||||
return n; /* number of rules removed */
|
return n; /* number of rules removed */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue