Beispiel #1
0
/* add_filter_rule()
 * */
static int
add_filter_rule(int proto, const char * rhost,
                const char * iaddr, unsigned short iport)
{
	int r = 0;
	struct ipt_entry * e;
	struct ipt_entry * tmp;
	struct ipt_entry_match *match = NULL;
	struct ipt_entry_target *target = NULL;

	e = calloc(1, sizeof(struct ipt_entry));
	if(!e) {
		syslog(LOG_ERR, "%s: calloc(%d) error", "add_filter_rule",
		       (int)sizeof(struct ipt_entry));
		return -1;
	}
	e->ip.proto = proto;
	if(proto == IPPROTO_TCP) {
		match = get_tcp_match(iport,0);
	} else {
		match = get_udp_match(iport,0);
	}
	e->nfcache = NFC_IP_DST_PT;
	e->ip.dst.s_addr = inet_addr(iaddr);
	e->ip.dmsk.s_addr = INADDR_NONE;
	target = get_accept_target();
	e->nfcache |= NFC_UNKNOWN;
	tmp = realloc(e, sizeof(struct ipt_entry)
	               + match->u.match_size
				   + target->u.target_size);
	if(!tmp) {
		syslog(LOG_ERR, "%s: realloc(%d) error", "add_filter_rule",
		       (int)(sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size));
		free(e);
		free(match);
		free(target);
		return -1;
	}
	e = tmp;
	memcpy(e->elems, match, match->u.match_size);
	memcpy(e->elems + match->u.match_size, target, target->u.target_size);
	e->target_offset = sizeof(struct ipt_entry)
	                   + match->u.match_size;
	e->next_offset = sizeof(struct ipt_entry)
	                 + match->u.match_size
					 + target->u.target_size;
	/* remote host */
	if(rhost && (rhost[0] != '\0') && (0 != strcmp(rhost, "*")))
	{
		e->ip.src.s_addr = inet_addr(rhost);
		e->ip.smsk.s_addr = INADDR_NONE;
	}

	r = iptc_init_verify_and_append("filter", miniupnpd_forward_chain, e, "add_filter_rule()");
	free(target);
	free(match);
	free(e);
	return r;
}
Beispiel #2
0
/* iptables -t mangle -A MINIUPNPD -s iaddr -d rhost
 *    -p proto --sport iport --dport rport -j DSCP
 *    --set-dscp 0xXXXX                   */
static int
addpeerdscprule(int proto, unsigned char dscp,
           const char * iaddr, unsigned short iport,
           const char * rhost, unsigned short rport)
{
	int r = 0;
	struct ipt_entry * e;
	struct ipt_entry_match *match = NULL;
	struct ipt_entry_target *target = NULL;

	e = calloc(1, sizeof(struct ipt_entry));
	e->ip.proto = proto;
	/* TODO: Fill port matches and SNAT */
	if(proto == IPPROTO_TCP)
	{
		match = get_tcp_match(rport, iport);
	}
	else
	{
		match = get_udp_match(rport, iport);
	}
	e->nfcache = NFC_IP_DST_PT | NFC_IP_SRC_PT;
	target = get_dscp_target(dscp);
	e->nfcache |= NFC_UNKNOWN;
	e = realloc(e, sizeof(struct ipt_entry)
	               + match->u.match_size
				   + target->u.target_size);
	memcpy(e->elems, match, match->u.match_size);
	memcpy(e->elems + match->u.match_size, target, target->u.target_size);
	e->target_offset = sizeof(struct ipt_entry)
	                   + match->u.match_size;
	e->next_offset = sizeof(struct ipt_entry)
	                 + match->u.match_size
					 + target->u.target_size;

	/* internal host */
	if(iaddr && (iaddr[0] != '\0') && (0 != strcmp(iaddr, "*")))
	{
		e->ip.src.s_addr = inet_addr(iaddr);
		e->ip.smsk.s_addr = INADDR_NONE;
	}
	/* remote host */
	if(rhost && (rhost[0] != '\0') && (0 != strcmp(rhost, "*")))
	{
		e->ip.dst.s_addr = inet_addr(rhost);
		e->ip.dmsk.s_addr = INADDR_NONE;
	}

	r = iptc_init_verify_and_append("mangle", miniupnpd_nat_chain, e,
	                                "addpeerDSCPrule()");
	free(target);
	free(match);
	free(e);
	return r;
}
/* add nat rule 
 * iptables -t nat -A MINIUPNPD -p proto --dport eport -j DNAT --to iaddr:iport
 * */
int
addnatrule(int proto, unsigned short eport,
           const char * iaddr, unsigned short iport,
           const char * eaddr) /* Chun add: for CD_ROUTER */
{
	int r = 0;
	struct ipt_entry * e;
	struct ipt_entry_match *match = NULL;
	struct ipt_entry_target *target = NULL;

	e = calloc(1, sizeof(struct ipt_entry));
	e->ip.proto = proto;
	if(proto == IPPROTO_TCP)
	{
		match = get_tcp_match(eport);
	}
	else
	{
		match = get_udp_match(eport);
	}
	e->nfcache = NFC_IP_DST_PT;
	/* Chun add: for CD_ROUTER */
	if(eaddr)
	{
		e->ip.src.s_addr = inet_addr(eaddr);
		e->ip.smsk.s_addr = INADDR_NONE;
	}
	target = get_dnat_target(iaddr, iport);
	e->nfcache |= NFC_UNKNOWN;
	e = realloc(e, sizeof(struct ipt_entry)
	               + match->u.match_size
				   + target->u.target_size);
	memcpy(e->elems, match, match->u.match_size);
	memcpy(e->elems + match->u.match_size, target, target->u.target_size);
	e->target_offset = sizeof(struct ipt_entry)
	                   + match->u.match_size;
	e->next_offset = sizeof(struct ipt_entry)
	                 + match->u.match_size
					 + target->u.target_size;
	
	r = iptc_init_verify_and_append("nat", e, "addnatrule()");
	free(target);
	free(match);
	free(e);
	return r;
}
Beispiel #4
0
/* add nat rule
 * iptables -t nat -A MINIUPNPD -p proto --dport eport -j DNAT --to iaddr:iport
 * */
static int
addnatrule(int proto, unsigned short eport,
           const char * iaddr, unsigned short iport,
           const char * rhost)
{
    int r = 0;
    struct ipt_entry * e;
    struct ipt_entry_match *match = NULL;
    struct ipt_entry_target *target = NULL;

    e = calloc(1, sizeof(struct ipt_entry));
    e->ip.proto = proto;
    if(proto == IPPROTO_TCP)
    {
        match = get_tcp_match(eport);
    }
    else
    {
        match = get_udp_match(eport);
    }
    e->nfcache = NFC_IP_DST_PT;
    target = get_dnat_target(iaddr, iport);
    e->nfcache |= NFC_UNKNOWN;
    e = realloc(e, sizeof(struct ipt_entry)
                + match->u.match_size
                + target->u.target_size);
    memcpy(e->elems, match, match->u.match_size);
    memcpy(e->elems + match->u.match_size, target, target->u.target_size);
    e->target_offset = sizeof(struct ipt_entry)
                       + match->u.match_size;
    e->next_offset = sizeof(struct ipt_entry)
                     + match->u.match_size
                     + target->u.target_size;
    /* remote host */
    if(rhost && (rhost[0] != '\0') && (0 != strcmp(rhost, "*")))
    {
        e->ip.src.s_addr = inet_addr(rhost);
        e->ip.smsk.s_addr = INADDR_NONE;
    }

    r = iptc_init_verify_and_append("nat", miniupnpd_nat_chain, e, "addnatrule()");
    free(target);
    free(match);
    free(e);
    return r;
}
/* add_filter_rule()
 * */
int
add_filter_rule(int proto, const char * iaddr, unsigned short iport)
{
	int r = 0;
	struct ipt_entry * e;
	struct ipt_entry_match *match = NULL;
	struct ipt_entry_target *target = NULL;

	e = calloc(1, sizeof(struct ipt_entry));
	e->ip.proto = proto;
	if(proto == IPPROTO_TCP)
	{
		match = get_tcp_match(iport);
	}
	else
	{
		match = get_udp_match(iport);
	}
	e->nfcache = NFC_IP_DST_PT;
	e->ip.dst.s_addr = inet_addr(iaddr);
	e->ip.dmsk.s_addr = INADDR_NONE;
	target = get_accept_target();
	e->nfcache |= NFC_UNKNOWN;
	e = realloc(e, sizeof(struct ipt_entry)
	               + match->u.match_size
				   + target->u.target_size);
	memcpy(e->elems, match, match->u.match_size);
	memcpy(e->elems + match->u.match_size, target, target->u.target_size);
	e->target_offset = sizeof(struct ipt_entry)
	                   + match->u.match_size;
	e->next_offset = sizeof(struct ipt_entry)
	                 + match->u.match_size
					 + target->u.target_size;
	
	r = iptc_init_verify_and_append("filter", e, "add_filter_rule()");
	free(target);
	free(match);
	free(e);
	return r;
}
Beispiel #6
0
void iptc_add_rule(const char *table,
                   const char *chain,
                   const char *protocol,
                   const char *iniface,
                   const char *outiface,
                   const char *src,
                   const char *dest,
                   const char *srcports,
                   const char *destports,
                   const char *target,
                   const char *dnat_to,
                   const int append)
{
	iptc_handle_t handle;
	struct ipt_entry *chain_entry;
	struct ipt_entry_match *entry_match = NULL;
	struct ipt_entry_target *entry_target = NULL;
	ipt_chainlabel labelit;
	long match_size;
	int result = 0;

	chain_entry = calloc(1, sizeof(*chain_entry));

	if (src) {
		chain_entry->ip.src.s_addr = inet_addr(src);
		chain_entry->ip.smsk.s_addr = inet_addr("255.255.255.255");
	}
	if (dest) {
		chain_entry->ip.dst.s_addr = inet_addr(dest);
		chain_entry->ip.dmsk.s_addr = inet_addr("255.255.255.255");
	}

	if (iniface) strncpy(chain_entry->ip.iniface, iniface, IFNAMSIZ);
	if (outiface) strncpy(chain_entry->ip.outiface, outiface, IFNAMSIZ);

	if (strcmp(protocol, "TCP") == 0) {
		chain_entry->ip.proto = IPPROTO_TCP;
		entry_match = get_tcp_match(srcports, destports, &chain_entry->nfcache);
	}
	else if (strcmp(protocol, "UDP") == 0) {
		chain_entry->ip.proto = IPPROTO_UDP;
		entry_match = get_udp_match(srcports, destports, &chain_entry->nfcache);
	}
	else {
		trace(1, "Unsupported protocol: %s", protocol);
		return;
	}

	if (strcmp(target, "") == 0
	    || strcmp(target, IPTC_LABEL_ACCEPT) == 0
	    || strcmp(target, IPTC_LABEL_DROP) == 0
	    || strcmp(target, IPTC_LABEL_QUEUE) == 0
	    || strcmp(target, IPTC_LABEL_RETURN) == 0) {
		size_t size;

		size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + IPT_ALIGN(sizeof(int));
		entry_target = calloc(1, size);
		entry_target->u.user.target_size = size;
		strncpy(entry_target->u.user.name, target, IPT_FUNCTION_MAXNAMELEN);
	}
	else if (strcmp(target, "DNAT") == 0) {
		entry_target = get_dnat_target(dnat_to, &chain_entry->nfcache);
	}

	if (entry_match)
		match_size = entry_match->u.match_size;
	else
		match_size = 0;

	chain_entry = realloc(chain_entry, sizeof(*chain_entry) + match_size + entry_target->u.target_size);
	memcpy(chain_entry->elems + match_size, entry_target, entry_target->u.target_size);
	chain_entry->target_offset = sizeof(*chain_entry) + match_size;
	chain_entry->next_offset = sizeof(*chain_entry) + match_size + entry_target->u.target_size;

	if (entry_match)
		memcpy(chain_entry->elems, entry_match, match_size);

	handle = iptc_init(table);
	if (!handle) {
		trace(1, "libiptc error: Can't initialize table %s, %s", table, iptc_strerror(errno));
		return;
	}

	strncpy(labelit, chain, sizeof(ipt_chainlabel));
	result = iptc_is_chain(chain, handle);
	if (!result) {
		trace(1, "libiptc error: Chain %s does not exist!", chain);
		return;
	}
	if (append)
		result = iptc_append_entry(labelit, chain_entry, &handle);
	else
		result = iptc_insert_entry(labelit, chain_entry, 0, &handle);

	if (!result) {
		trace(1, "libiptc error: Can't add, %s", iptc_strerror(errno));
		return;
	}
	result = iptc_commit(&handle);
	if (!result) {
	  trace(1, "libiptc error: Commit error, %s", iptc_strerror(errno));
		return;
	}
	else 
	  trace(3, "added new rule to block successfully");

	if (entry_match) free(entry_match);
	free(entry_target);
	free(chain_entry);
}