diff --git a/miniupnpd/netfilter/iptcrdr.c b/miniupnpd/netfilter/iptcrdr.c index 48c6dbb..d800f94 100644 --- a/miniupnpd/netfilter/iptcrdr.c +++ b/miniupnpd/netfilter/iptcrdr.c @@ -621,6 +621,69 @@ delete_rule_and_commit(unsigned int index, IPTC_HANDLE h, return r; } +/* delete_filter_rule() + */ +int +delete_filter_rule(const char * ifname, unsigned short port, int proto) +{ + int r = -1; + unsigned index = 0; + unsigned i = 0; + IPTC_HANDLE h; + const struct ipt_entry * e; + const struct ipt_entry_match *match; + UNUSED(ifname); + + if((h = iptc_init("filter"))) + { + i = 0; + /* we must find the right index for the filter rule */ +#ifdef IPTABLES_143 + for(e = iptc_first_rule(miniupnpd_forward_chain, h); + e; + e = iptc_next_rule(e, h), i++) +#else + for(e = iptc_first_rule(miniupnpd_forward_chain, &h); + e; + e = iptc_next_rule(e, &h), i++) +#endif + { + if(proto==e->ip.proto) + { + match = (const struct ipt_entry_match *)&e->elems; + /*syslog(LOG_DEBUG, "filter rule #%u: %s %s", + i, match->u.user.name, inet_ntoa(e->ip.dst));*/ + if(0 == strncmp(match->u.user.name, "tcp", IPT_FUNCTION_MAXNAMELEN)) + { + const struct ipt_tcp * info; + info = (const struct ipt_tcp *)match->data; + if(port != info->dpts[0]) + continue; + } + else + { + const struct ipt_udp * info; + info = (const struct ipt_udp *)match->data; + if(port != info->dpts[0]) + continue; + } + index = i; + /*syslog(LOG_INFO, "Trying to delete filter rule at index %u", index);*/ + r = delete_rule_and_commit(index, h, miniupnpd_forward_chain, "delete_filter_rule"); + h = NULL; + break; + } + } + } + if(h) +#ifdef IPTABLES_143 + iptc_free(h); +#else + iptc_free(&h); +#endif + return r; +} + /* delete_redirect_and_filter_rules() */ int diff --git a/miniupnpd/netfilter/iptcrdr.h b/miniupnpd/netfilter/iptcrdr.h index 21d5405..a7310e4 100644 --- a/miniupnpd/netfilter/iptcrdr.h +++ b/miniupnpd/netfilter/iptcrdr.h @@ -32,6 +32,9 @@ add_filter_rule2(const char * ifname, int delete_redirect_and_filter_rules(unsigned short eport, int proto); +int +delete_filter_rule(const char * ifname, unsigned short port, int proto); + int add_peer_dscp_rule2(const char * ifname, const char * rhost, unsigned short rport, diff --git a/miniupnpd/pf/obsdrdr.c b/miniupnpd/pf/obsdrdr.c index 0b00ad9..72d4070 100644 --- a/miniupnpd/pf/obsdrdr.c +++ b/miniupnpd/pf/obsdrdr.c @@ -790,7 +790,7 @@ syslog(LOG_DEBUG, "%2d port=%hu proto=%d addr=%8x", #endif if( (iport == ntohs(pr.rule.dst.port[0])) && (pr.rule.proto == proto) && - (iaddr == pr.rule.dst.addr.v.a.addr.v4.s_addr) + (iaddr == 0 || iaddr == pr.rule.dst.addr.v.a.addr.v4.s_addr) ) { pr.action = PF_CHANGE_GET_TICKET; @@ -814,6 +814,12 @@ error: #endif } +int +delete_filter_rule(const char * ifname, unsigned short port, int proto) +{ + return priv_delete_filter_rule(ifname, port, proto, 0); +} + int delete_redirect_and_filter_rules(const char * ifname, unsigned short eport, int proto) diff --git a/miniupnpd/pf/obsdrdr.h b/miniupnpd/pf/obsdrdr.h index 3defa8e..7a70263 100644 --- a/miniupnpd/pf/obsdrdr.h +++ b/miniupnpd/pf/obsdrdr.h @@ -58,6 +58,9 @@ int delete_redirect_and_filter_rules(const char * ifname, unsigned short eport, int proto); +int +delete_filter_rule(const char * ifname, unsigned short port, int proto); + #ifdef TEST int clear_redirect_rules(void);