Пример #1
0
/* delete_redirect_and_filter_rules()
 */
int
delete_redirect_and_filter_rules(unsigned short eport, int proto)
{
	int r = -1, r2 = -1;
	unsigned index = 0;
	unsigned i = 0;
	IPTC_HANDLE h;
	const struct ipt_entry * e;
	const struct ipt_entry_target * target;
	const struct ip_nat_multi_range * mr;
	const struct ipt_entry_match *match;
	unsigned short iport = 0;
	uint32_t iaddr = 0;

	h = iptc_init("nat");
	if(!h)
	{
		syslog(LOG_ERR, "delete_redirect_and_filter_rules() : "
		                "iptc_init() failed : %s",
		       iptc_strerror(errno));
		return -1;
	}
	/* First step : find the right nat rule */
	if(!iptc_is_chain(miniupnpd_nat_chain, h))
	{
		syslog(LOG_ERR, "chain %s not found", miniupnpd_nat_chain);
	}
	else
	{
#ifdef IPTABLES_143
		for(e = iptc_first_rule(miniupnpd_nat_chain, h);
		    e;
			e = iptc_next_rule(e, h), i++)
#else
		for(e = iptc_first_rule(miniupnpd_nat_chain, &h);
		    e;
			e = iptc_next_rule(e, &h), i++)
#endif
		{
			if(proto==e->ip.proto)
			{
				match = (const struct ipt_entry_match *)&e->elems;
				if(0 == strncmp(match->u.user.name, "tcp", IPT_FUNCTION_MAXNAMELEN))
				{
					const struct ipt_tcp * info;
					info = (const struct ipt_tcp *)match->data;
					if(eport != info->dpts[0])
						continue;
				}
				else
				{
					const struct ipt_udp * info;
					info = (const struct ipt_udp *)match->data;
					if(eport != info->dpts[0])
						continue;
				}
				/* get the index, the internal address and the internal port
				 * of the rule */
				index = i;
				target = (void *)e + e->target_offset;
				mr = (const struct ip_nat_multi_range *)&target->data[0];
				iaddr = mr->range[0].min_ip;
				iport = ntohs(mr->range[0].min.all);
				r = 0;
				break;
			}
		}
	}
	if(h)
#ifdef IPTABLES_143
		iptc_free(h);
#else
		iptc_free(&h);
#endif
	if(r == 0)
	{
		syslog(LOG_INFO, "Trying to delete nat rule at index %u", index);
		/* Now delete both rules */
		/* first delete the nat rule */
		h = iptc_init("nat");
		if(h)
		{
			r = delete_rule_and_commit(index, h, miniupnpd_nat_chain, "delete_redirect_rule");
		}
		if((r == 0) && (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(iport != info->dpts[0])
							continue;
					}
					else
					{
						const struct ipt_udp * info;
						info = (const struct ipt_udp *)match->data;
						if(iport != info->dpts[0])
							continue;
					}
					if(iaddr != e->ip.dst.s_addr)
						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
	}

	/*delete PEER rule*/
	if((h = iptc_init("nat")))
	{
		i = 0;
		/* we must find the right index for the filter rule */
#ifdef IPTABLES_143
		for(e = iptc_first_rule(miniupnpd_peer_chain, h);
		    e;
			e = iptc_next_rule(e, h), i++)
#else
		for(e = iptc_first_rule(miniupnpd_peer_chain, &h);
		    e;
			e = iptc_next_rule(e, &h), i++)
#endif
		{
			if(proto==e->ip.proto)
			{
				target = (void *)e + e->target_offset;
				mr = (const struct ip_nat_multi_range *)&target->data[0];
				if (eport != ntohs(mr->range[0].min.all)) {
					continue;
				}
				iaddr = e->ip.src.s_addr;
				match = (const struct ipt_entry_match *)&e->elems;
				if(0 == strncmp(match->u.user.name, "tcp", IPT_FUNCTION_MAXNAMELEN))
				{
					const struct ipt_tcp * info;
					info = (const struct ipt_tcp *)match->data;
					iport = info->spts[0];
				}
				else
				{
					const struct ipt_udp * info;
					info = (const struct ipt_udp *)match->data;
					iport = info->dpts[0];
				}

				index = i;
				syslog(LOG_INFO, "Trying to delete peer rule at index %u", index);
				r2 = delete_rule_and_commit(index, h, miniupnpd_peer_chain, "delete_peer_rule");
				h = NULL;
				break;
			}
		}
	}

	if(h)
#ifdef IPTABLES_143
		iptc_free(h);
#else
		iptc_free(&h);
#endif
	/*delete DSCP rule*/
	if((r2==0)&&(h = iptc_init("mangle")))
	{
		i = 0;
		index = -1;
		/* we must find the right index for the filter rule */
#ifdef IPTABLES_143
		for(e = iptc_first_rule(miniupnpd_nat_chain, h);
		    e;
			e = iptc_next_rule(e, h), i++)
#else
		for(e = iptc_first_rule(miniupnpd_nat_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(iport != info->spts[0])
						continue;
				}
				else
				{
					const struct ipt_udp * info;
					info = (const struct ipt_udp *)match->data;
					if(iport != info->spts[0])
						continue;
				}
				if(iaddr != e->ip.src.s_addr)
					continue;
				index = i;
				syslog(LOG_INFO, "Trying to delete dscp rule at index %u", index);
				r2 = delete_rule_and_commit(index, h, miniupnpd_nat_chain, "delete_dscp_rule");
				h = NULL;
				break;
			}
		}
	if (h)
	#ifdef IPTABLES_143
		iptc_free(h);
	#else
		iptc_free(&h);
	#endif
	}

	del_redirect_desc(eport, proto);
	return r*r2;
}
Пример #2
0
/* delete_redirect_and_filter_rules()
 */
int
delete_redirect_and_filter_rules(unsigned short eport, int proto)
{
	int r = -1;
	unsigned index = 0;
	unsigned i = 0;
	iptc_handle_t h;
	const struct ipt_entry * e;
	const struct ipt_entry_match *match;

	h = iptc_init("nat");
	if(!h)
	{
		syslog(LOG_ERR, "delete_redirect_and_filter_rules() : "
		                "iptc_init() failed : %s",
		       iptc_strerror(errno));
		return -1;
	}
	if(!iptc_is_chain(miniupnpd_chain, h))
	{
		syslog(LOG_ERR, "chain %s not found", miniupnpd_chain);
	}
	else
	{
		for(e = iptc_first_rule(miniupnpd_chain, &h);
		    e;
			e = iptc_next_rule(e, &h), i++)
		{
			if(proto==e->ip.proto)
			{
				match = (const struct ipt_entry_match *)&e->elems;
				if(0 == strncmp(match->u.user.name, "tcp", IPT_FUNCTION_MAXNAMELEN))
				{
					const struct ipt_tcp * info;
					info = (const struct ipt_tcp *)match->data;
					if(eport != info->dpts[0])
						continue;
				}
				else
				{
					const struct ipt_udp * info;
					info = (const struct ipt_udp *)match->data;
					if(eport != info->dpts[0])
						continue;
				}
				index = i;
				r = 0;
				break;
			}
		}
	}
	iptc_free(&h);
	if(r == 0)
	{
		syslog(LOG_INFO, "Trying to delete rules at index %u", index);
		/* Now delete both rules */
		h = iptc_init("nat");
		if(h)
		{
			r = delete_rule_and_commit(index, &h, "delete_redirect_rule");
		}
		h = iptc_init("filter");
		if(h && (r == 0))
		{
			r = delete_rule_and_commit(index, &h, "delete_filter_rule");
		}
	}
	del_redirect_desc(eport, proto);
	return r;
}
Пример #3
0
/* delete_redirect_and_filter_rules()
 */
int
delete_redirect_and_filter_rules(unsigned short eport, int proto)
{
    int r = -1;
    struct rdr_desc * p, * last;
    char rule[256];
    int is_nat_flashed = 0;
    
    p = rdr_desc_list;
    last = 0;
    while(p)
    {
        if(p->eport == eport && p->proto == proto)
        {
            if(!last)
                rdr_desc_list = p->next;
            else
                last->next = p->next;
            snprintf(rule, sizeof(rule),"rdr %s %s port %d -> %s port %d %s",
                p->ifname, p->eaddr, p->eport, p->iaddr, p->iport, 
                (p->proto == IPPROTO_TCP)? "tcp":"udp");
            NP_UPNP_DEBUG("%s\n", rule);
            DelUPnPPortMapRule();
            is_nat_flashed = 1;
            r = 0;
        }
        last = p;
        p = p->next;
    }
    if(1 == is_nat_flashed)
    {
        p = rdr_desc_list;
        while(p)
        {
            NAT_PORTMAP_INFO_ST portmap_info;
            memset(&portmap_info, 0, sizeof(portmap_info));
            portmap_info.portmap_index = 0;
            portmap_info.portmap_enabled = ENABLE_FEATURE;
            if(NULL != p->str)
            {
                strncpy((char *)portmap_info.portmap_name, p->str, NAME_LEN_MAX);
            }
            if(NULL != p->eaddr)
            {
                strncpy((char *)portmap_info.remote_host_addr, p->eaddr, IPV4_ADDRESS_LEN);
            }
            if(NULL != p->iaddr)
            {
                strncpy((char *)portmap_info.internal_client_addr, p->iaddr, IPV4_ADDRESS_LEN);
            }
            strncpy((char *)portmap_info.protocol, ((6 == p->proto) ? "tcp" : "udp"), IP_PROTO_LEN);
            portmap_info.external_port = p->eport;
            portmap_info.external_port_end = p->eport;
            portmap_info.internal_port = p->iport;
    
            if(1 == p->enabled)
            {
                AddUPnPPortMapRule(&portmap_info);
            }

            p = p->next;
        }
    }

    del_redirect_desc(eport, proto);
    
    return r;
}