IPTables-libiptc

 view release on metacpan or  search on metacpan

libiptc.xs  view on Meta::CPAN

	    RETVAL  = -1;
	    SET_ERRNUM(errno);
	    SET_ERRSTR("%s", iptc_strerror(errno));
	    SvIOK_on(ERROR_SV);
	}
    }
  OUTPUT:
    RETVAL


##########################################
# Rules/Entries affecting a full chain
##########################################

int
flush_entries(self, chain)
    IPTables::libiptc self
    ipt_chainlabel    chain
  CODE:
    if (self == NULL) croak(ERRSTR_NULL_HANDLE);
    else {
	RETVAL = iptc_flush_entries(chain, self);
	if (!RETVAL) {
	    SET_ERRNUM(errno);
	    SET_ERRSTR("%s", iptc_strerror(errno));
	    SvIOK_on(ERROR_SV);
	}
    }
  OUTPUT:
    RETVAL


int
zero_entries(self, chain)
    IPTables::libiptc self
    ipt_chainlabel    chain
  CODE:
    if (self == NULL) croak(ERRSTR_NULL_HANDLE);
    else {
	RETVAL = iptc_zero_entries(chain, self);
	if (!RETVAL) {
	    SET_ERRNUM(errno);
	    SET_ERRSTR("%s", iptc_strerror(errno));
	    SvIOK_on(ERROR_SV);
	}
    }
  OUTPUT:
    RETVAL

##########################################
# Listing related
##########################################

void
list_chains(self)
    IPTables::libiptc self
  PREINIT:
    char * chain;
    SV *   sv;
    int    count = 0;
  PPCODE:
    sv = ST(0);
    if (self == NULL) croak(ERRSTR_NULL_HANDLE);
    else {
	chain = (char *)iptc_first_chain(self);
	while(chain) {
	    count++;
	    if (GIMME_V == G_ARRAY)
		XPUSHs(sv_2mortal(newSVpv(chain, 0)));
	    chain = (char *)iptc_next_chain(self);
	}
	if (GIMME_V == G_SCALAR)
	    XPUSHs(sv_2mortal(newSViv(count)));
    }


void
list_rules_IPs(self, type, chain)
    IPTables::libiptc self
    ipt_chainlabel    chain
    char *            type
  PREINIT:
    SV *   sv;
    int    count = 0;
    struct ipt_entry *entry;
    int    the_type;
    char   buf[100]; /* I should be enough with only 32 chars */
    static char * errmsg = "Wrong listing type requested.";
  PPCODE:
    sv = ST(0);
    if (self == NULL) croak(ERRSTR_NULL_HANDLE);
    else {
	if(iptc_is_chain(chain, self)) {
	    entry = (struct ipt_entry *)iptc_first_rule(chain, self);

	    /* Parse what type was requested */
	    if      (strcasecmp(type, "dst") == 0) the_type = 'd';
	    else if (strcasecmp(type, "src") == 0) the_type = 's';
	    else croak(errmsg);

	    while(entry) {
		count++;
 		if (GIMME_V == G_ARRAY) {

		    switch (the_type) {
		    case 'd':
			sprintf(buf,"%s",xtables_ipaddr_to_numeric(&(entry->ip.dst)));
			strcat(buf, xtables_ipmask_to_numeric(&(entry->ip.dmsk)));
			sv = newSVpv(buf, 0);
		        break;
		    case 's':
			sprintf(buf,"%s",xtables_ipaddr_to_numeric(&(entry->ip.src)));
			strcat(buf, xtables_ipmask_to_numeric(&(entry->ip.smsk)));
			sv = newSVpv(buf, 0);
		        break;
		    default:
		        croak(errmsg);
		    }
		    XPUSHs(sv_2mortal(sv));
		}
		entry = (struct ipt_entry *)iptc_next_rule(entry, self);
	    }
	    if (GIMME_V == G_SCALAR)
		XPUSHs(sv_2mortal(newSViv(count)));
	} else {
	    XSRETURN_UNDEF;
	}
    }


##########################################
# Policy related
##########################################

void
get_policy(self, chain)
    IPTables::libiptc self
    ipt_chainlabel    chain
  PREINIT:
    struct ipt_counters  counters;
    SV *                 sv;
    char *               policy;
    char *               temp;
  PPCODE:
    sv = ST(0);
    if (self == NULL) croak(ERRSTR_NULL_HANDLE);
    else {
	if((policy = (char *)iptc_get_policy(chain, &counters, self))) {
	    XPUSHs(sv_2mortal(newSVpv(policy, 0)));
	    asprintf(&temp, "%llu", counters.pcnt);
	    XPUSHs(sv_2mortal(newSVpv(temp, 0)));
	    free(temp);
	    asprintf(&temp, "%llu", counters.bcnt);
	    XPUSHs(sv_2mortal(newSVpv(temp, 0)));
	    free(temp);
	} else {
	    SET_ERRNUM(errno);
	    SET_ERRSTR("%s", iptc_strerror(errno));
	    SvIOK_on(ERROR_SV);
	}
    }


void
set_policy(self, chain, policy, pkt_cnt=0, byte_cnt=0)
    IPTables::libiptc self
    ipt_chainlabel    chain
    ipt_chainlabel    policy
    unsigned int      pkt_cnt
    unsigned int      byte_cnt
  PREINIT:
    struct ipt_counters *  counters = NULL;
    struct ipt_counters    old_counters;
    char *                 old_policy;
    char *                 temp;
    int retval;
  PPCODE:
    if (self == NULL) croak(ERRSTR_NULL_HANDLE);
    else {
	if(pkt_cnt && byte_cnt) {
	    counters = malloc(sizeof(struct ipt_counters));
	    counters->pcnt = pkt_cnt;
	    counters->bcnt = byte_cnt;
	}
	/* Read the old policy and counters */
	old_policy = (char *)iptc_get_policy(chain, &old_counters, self);

	retval = iptc_set_policy(chain, policy, counters, self);
	/* Return retval to perl */
	XPUSHs(sv_2mortal(newSViv(retval)));
	if (!retval) {
	    SET_ERRNUM(errno);
	    SET_ERRSTR("%s", iptc_strerror(errno));
	    SvIOK_on(ERROR_SV);
	} else {
	    /* return old policy and counters to perl */
      	    if (old_policy) {
		XPUSHs(sv_2mortal(newSVpv(old_policy, 0)));
		asprintf(&temp, "%llu", old_counters.pcnt);
		XPUSHs(sv_2mortal(newSVpv(temp, 0)));
		free(temp);
		asprintf(&temp, "%llu", old_counters.bcnt);
		XPUSHs(sv_2mortal(newSVpv(temp, 0)));
		free(temp);
	    }
	}
    }
    if(counters) free(counters);


##########################################
# iptables.{h,c,o} related
##########################################

# !!!FUNCTION NOT TESTED!!!
int
iptables_delete_chain(self, chain)
    IPTables::libiptc self
    ipt_chainlabel    chain
  CODE:
    if (self == NULL) croak(ERRSTR_NULL_HANDLE);
    else {
	RETVAL = delete_chain(chain, 0, self);
	if (!RETVAL) {
	    SET_ERRNUM(errno);
	    SET_ERRSTR("%s", iptc_strerror(errno));
	    SvIOK_on(ERROR_SV);
	}
    }
  OUTPUT:
    RETVAL


# int do_command(int argc, char *argv[], char **table,
#                iptc_handle_t *handle);
#
int



( run in 1.440 second using v1.01-cache-2.11-cpan-5511b514fd6 )