miniupnpd/pf: delete_redirect_and_filter_rules() now take internal address into account

This commit is contained in:
Thomas Bernard 2014-03-06 14:24:10 +01:00
parent acc149ee99
commit 60e129d131
1 changed files with 48 additions and 6 deletions

View File

@ -602,7 +602,8 @@ error:
static int static int
priv_delete_redirect_rule(const char * ifname, unsigned short eport, priv_delete_redirect_rule(const char * ifname, unsigned short eport,
int proto, unsigned short * iport) int proto, unsigned short * iport,
in_addr_t * iaddr)
{ {
int i, n; int i, n;
struct pfioc_rule pr; struct pfioc_rule pr;
@ -643,8 +644,40 @@ priv_delete_redirect_rule(const char * ifname, unsigned short eport,
/* retrieve iport in order to remove filter rule */ /* retrieve iport in order to remove filter rule */
#ifndef PF_NEWSTYLE #ifndef PF_NEWSTYLE
if(iport) *iport = pr.rule.rpool.proxy_port[0]; if(iport) *iport = pr.rule.rpool.proxy_port[0];
if(iaddr)
{
/* retrieve internal address */
struct pfioc_pooladdr pp;
memset(&pp, 0, sizeof(pp));
strlcpy(pp.anchor, anchor_name, MAXPATHLEN);
pp.r_action = PF_RDR;
pp.r_num = i;
pp.ticket = pr.ticket;
if(ioctl(dev, DIOCGETADDRS, &pp) < 0)
{
syslog(LOG_ERR, "ioctl(dev, DIOCGETADDRS, ...): %m");
goto error;
}
if(pp.nr != 1)
{
syslog(LOG_NOTICE, "No address associated with pf rule");
goto error;
}
pp.nr = 0; /* first */
if(ioctl(dev, DIOCGETADDR, &pp) < 0)
{
syslog(LOG_ERR, "ioctl(dev, DIOCGETADDR, ...): %m");
goto error;
}
*iaddr = pp.addr.addr.v.a.addr.v4.s_addr;
}
#else #else
if(iport) *iport = pr.rule.rdr.proxy_port[0]; if(iport) *iport = pr.rule.rdr.proxy_port[0];
if(iaddr)
{
/* retrieve internal address */
*iaddr = pr.rule.rdr.addr.v.a.addr.v4.s_addr;
}
#endif #endif
pr.action = PF_CHANGE_GET_TICKET; pr.action = PF_CHANGE_GET_TICKET;
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0) if(ioctl(dev, DIOCCHANGERULE, &pr) < 0)
@ -671,12 +704,12 @@ int
delete_redirect_rule(const char * ifname, unsigned short eport, delete_redirect_rule(const char * ifname, unsigned short eport,
int proto) int proto)
{ {
return priv_delete_redirect_rule(ifname, eport, proto, NULL); return priv_delete_redirect_rule(ifname, eport, proto, NULL, NULL);
} }
static int static int
priv_delete_filter_rule(const char * ifname, unsigned short iport, priv_delete_filter_rule(const char * ifname, unsigned short iport,
int proto) int proto, in_addr_t iaddr)
{ {
#ifndef PF_ENABLE_FILTER_RULES #ifndef PF_ENABLE_FILTER_RULES
UNUSED(ifname); UNUSED(iport); UNUSED(proto); UNUSED(ifname); UNUSED(iport); UNUSED(proto);
@ -706,8 +739,16 @@ priv_delete_filter_rule(const char * ifname, unsigned short iport,
syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m"); syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
goto error; goto error;
} }
#ifdef TEST
syslog(LOG_DEBUG, "%2d port=%hu proto=%d addr=%8x",
i, ntohs(pr.rule.dst.port[0]), pr.rule.proto,
pr.rule.dst.addr.v.a.addr.v4.s_addr);
/*pr.rule.dst.addr.v.a.mask.v4.s_addr*/
#endif
if( (iport == ntohs(pr.rule.dst.port[0])) if( (iport == ntohs(pr.rule.dst.port[0]))
&& (pr.rule.proto == proto) ) && (pr.rule.proto == proto) &&
(iaddr == pr.rule.dst.addr.v.a.addr.v4.s_addr)
)
{ {
pr.action = PF_CHANGE_GET_TICKET; pr.action = PF_CHANGE_GET_TICKET;
if(ioctl(dev, DIOCCHANGERULE, &pr) < 0) if(ioctl(dev, DIOCCHANGERULE, &pr) < 0)
@ -736,10 +777,11 @@ delete_redirect_and_filter_rules(const char * ifname, unsigned short eport,
{ {
int r; int r;
unsigned short iport; unsigned short iport;
r = priv_delete_redirect_rule(ifname, eport, proto, &iport); in_addr_t iaddr;
r = priv_delete_redirect_rule(ifname, eport, proto, &iport, &iaddr);
if(r == 0) if(r == 0)
{ {
priv_delete_filter_rule(ifname, iport, proto); r = priv_delete_filter_rule(ifname, iport, proto, iaddr);
} }
return r; return r;
} }