Example #1
0
/* Kernel module to match an IP set. */

#include <linux/module.h>
#include <linux/ip.h>
#include <linux/skbuff.h>
#include <linux/version.h>

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
#include <linux/netfilter_ipv4/ip_tables.h>
#define xt_register_match	ipt_register_match
#define xt_unregister_match	ipt_unregister_match
#define xt_match		ipt_match
#else
#include <linux/netfilter/x_tables.h>
#endif
#include <linux/netfilter_ipv4/ip_set.h>
#include <linux/netfilter_ipv4/ipt_set.h>


#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
#ifndef IPT_ALIGN
#define IPT_ALIGN XT_ALIGN
#endif
#endif

static inline int
match_set(const struct ipt_set_info *info,
          const struct sk_buff *skb,
          int inv)
{
    if (ip_set_testip_kernel(info->index, skb, info->flags))
        inv = !inv;
    return inv;
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
static int
match(const struct sk_buff *skb,
      const struct net_device *in,
      const struct net_device *out,
      const void *matchinfo,
      int offset,
      const void *hdr,
      u_int16_t datalen,
      int *hotdrop)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
static int
match(const struct sk_buff *skb,
      const struct net_device *in,
      const struct net_device *out,
      const void *matchinfo,
      int offset,
      int *hotdrop)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
static int
match(const struct sk_buff *skb,
      const struct net_device *in,
      const struct net_device *out,
      const void *matchinfo,
      int offset,
      unsigned int protoff,
      int *hotdrop)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
static int
match(const struct sk_buff *skb,
      const struct net_device *in,
      const struct net_device *out,
      const struct xt_match *match,
      const void *matchinfo,
      int offset,
      unsigned int protoff,
      int *hotdrop)
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) */
static bool
match(const struct sk_buff *skb,
      const struct net_device *in,
      const struct net_device *out,
      const struct xt_match *match,
      const void *matchinfo,
      int offset,
      unsigned int protoff,
      bool *hotdrop)
#endif
{
    const struct ipt_set_info_match *info = matchinfo;

    return match_set(&info->match_set,
                     skb,
                     info->match_set.flags[0] & IPSET_MATCH_INV);
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
static int
checkentry(const char *tablename,
           const struct ipt_ip *ip,
           void *matchinfo,
           unsigned int matchsize,
           unsigned int hook_mask)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
static int
checkentry(const char *tablename,
           const void *inf,
           void *matchinfo,
           unsigned int matchsize,
           unsigned int hook_mask)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
static int
checkentry(const char *tablename,
           const void *inf,
           const struct xt_match *match,
           void *matchinfo,
           unsigned int matchsize,
           unsigned int hook_mask)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
static int
checkentry(const char *tablename,
           const void *inf,
           const struct xt_match *match,
           void *matchinfo,
           unsigned int hook_mask)
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) */
static bool
checkentry(const char *tablename,
           const void *inf,
           const struct xt_match *match,
           void *matchinfo,
           unsigned int hook_mask)
#endif
{
    struct ipt_set_info_match *info = matchinfo;
    ip_set_id_t index;

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
    if (matchsize != IPT_ALIGN(sizeof(struct ipt_set_info_match))) {
        ip_set_printk("invalid matchsize %d", matchsize);
        return 0;
    }
#endif

    index = ip_set_get_byindex(info->match_set.index);

    if (index == IP_SET_INVALID_ID) {
        ip_set_printk("Cannot find set indentified by id %u to match",
                      info->match_set.index);
        return 0;	/* error */
    }
    if (info->match_set.flags[IP_SET_MAX_BINDINGS] != 0) {
        ip_set_printk("That's nasty!");
        return 0;	/* error */
    }

    return 1;
}
Example #2
0
static int
ipt_limit_checkentry(const char *tablename,
		     const struct ipt_ip *ip,
		     void *matchinfo,
		     unsigned int matchsize,
		     unsigned int hook_mask)
{
	struct ipt_rateinfo *r = matchinfo;

	if (matchsize != IPT_ALIGN(sizeof(struct ipt_rateinfo)))
		return 0;

	/* Check for overflow. */
	if (r->burst == 0
	    || user2credits(r->avg * r->burst) < user2credits(r->avg)) {
		printk("Overflow in ipt_limit, try lower: %u/%u\n",
		       r->avg, r->burst);
		return 0;
	}

	/* User avg in seconds * IPT_LIMIT_SCALE: convert to jiffies *
	   128. */
	r->prev = jiffies;
	r->credit = user2credits(r->avg * r->burst);	 /* Credits full. */
	r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */
	r->cost = user2credits(r->avg);

	/* For SMP, we only want to use one set of counters. */
	r->master = r;

	return 1;
}
Example #3
0
static struct ipt_entry_target *
get_dscp_target(unsigned char dscp)
{
	struct ipt_entry_target * target;
	struct xt_DSCP_info * di;
	size_t size;

	size =   IPT_ALIGN(sizeof(struct ipt_entry_target))
	       + IPT_ALIGN(sizeof(struct xt_DSCP_info));
	target = calloc(1, size);
	target->u.target_size = size;
	strncpy(target->u.user.name, "DSCP", sizeof(target->u.user.name));
	/* one ip_nat_range already included in ip_nat_multi_range */
	di = (struct xt_DSCP_info *)&target->data[0];
	di->dscp=dscp;
	return target;
}
static struct ipt_entry_match *
get_udp_match(unsigned short dport)
{
	struct ipt_entry_match *match;
	struct ipt_udp * udpinfo;
	size_t size;
	size =   IPT_ALIGN(sizeof(struct ipt_entry_match))
	       + IPT_ALIGN(sizeof(struct ipt_udp));
	match = calloc(1, size);
	match->u.match_size = size;
	strncpy(match->u.user.name, "udp", IPT_FUNCTION_MAXNAMELEN);
	udpinfo = (struct ipt_udp *)match->data;
	udpinfo->spts[0] = 0;		/* all source ports */
	udpinfo->spts[1] = 0xFFFF;
	udpinfo->dpts[0] = dport;	/* specified destination port */
	udpinfo->dpts[1] = dport;
	return match;
}
Example #5
0
/* TODO : add the -m state --state NEW,ESTABLISHED,RELATED
 * only for the filter rule */
static struct ipt_entry_match *
get_tcp_match(unsigned short dport)
{
    struct ipt_entry_match *match;
    struct ipt_tcp * tcpinfo;
    size_t size;
    size =   IPT_ALIGN(sizeof(struct ipt_entry_match))
             + IPT_ALIGN(sizeof(struct ipt_tcp));
    match = calloc(1, size);
    match->u.match_size = size;
    strncpy(match->u.user.name, "tcp", sizeof(match->u.user.name));
    tcpinfo = (struct ipt_tcp *)match->data;
    tcpinfo->spts[0] = 0;		/* all source ports */
    tcpinfo->spts[1] = 0xFFFF;
    tcpinfo->dpts[0] = dport;	/* specified destination port */
    tcpinfo->dpts[1] = dport;
    return match;
}
Example #6
0
static int check(const char *tablename,
		 const struct ipt_ip *ip,
		 void *matchinfo,
		 unsigned int matchsize,
		 unsigned int hook_mask)
{
	if (matchsize != IPT_ALIGN(sizeof(struct ipt_state_info)))
		return 0;

	return 1;
}
Example #7
0
static int
checkentry(const char *tablename,
	   const struct ipt_entry *e,
           void *targinfo,
           unsigned int targinfosize,
           unsigned int hook_mask)
{
	const struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)targinfo;

	if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ECN_info))) {
		printk(KERN_WARNING "ECN: targinfosize %u != %Zu\n",
		       targinfosize,
		       IPT_ALIGN(sizeof(struct ipt_ECN_info)));
		return 0;
	}

	if (strcmp(tablename, "mangle") != 0) {
		printk(KERN_WARNING "ECN: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
		return 0;
	}

	if (einfo->operation & IPT_ECN_OP_MASK) {
		printk(KERN_WARNING "ECN: unsupported ECN operation %x\n",
			einfo->operation);
		return 0;
	}
	if (einfo->ip_ect & ~IPT_ECN_IP_MASK) {
		printk(KERN_WARNING "ECN: new ECT codepoint %x out of mask\n",
			einfo->ip_ect);
		return 0;
	}

	if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR))
	    && e->ip.proto != IPPROTO_TCP) {
		printk(KERN_WARNING "ECN: cannot use TCP operations on a "
		       "non-tcp rule\n");
		return 0;
	}

	return 1;
}
Example #8
0
static int
checkentry(const char *tablename,
	   const struct ipt_entry *e,
           void *targinfo,
           unsigned int targinfosize,
           unsigned int hook_mask)
{
	if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info))) {
		printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n",
		       targinfosize,
		       IPT_ALIGN(sizeof(struct ipt_mark_target_info)));
		return 0;
	}

	if (strcmp(tablename, "mangle") != 0) {
		printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
		return 0;
	}

	return 1;
}
Example #9
0
static int
checkentry(const char *tablename,
           const struct ipt_ip *ip,
           void *matchinfo,
           unsigned int matchsize,
           unsigned int hook_mask)
{
        if (hook_mask
            & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING))) {
                printk("ipt_owner: only valid for LOCAL_OUT or POST_ROUTING.\n");
                return 0;
        }

	if (matchsize != IPT_ALIGN(sizeof(struct ipt_owner_info))) {
		printk("Matchsize %u != %Zu\n", matchsize,
		       IPT_ALIGN(sizeof(struct ipt_owner_info)));
		return 0;
	}

	return 1;
}
static int
checkentry(const char *tablename,
	   const struct ipt_entry *e,
           void *targinfo,
           unsigned int targinfosize,
           unsigned int hook_mask)
{
	if (targinfosize != IPT_ALIGN(0))
		return 0;

	return 1;
}
Example #11
0
static int ipt_led_checkentry(const char *tablename,
			      const struct ipt_entry *e,
			      void *targinfo,
			      unsigned int targinfosize,
			      unsigned int hook_mask)
{
	const struct ipt_led_info *ledinfo = targinfo;

	if (targinfosize != IPT_ALIGN(sizeof(struct ipt_led_info))) {
		DEBUGP("LED: targinfosize %u != %u\n",
		       targinfosize, IPT_ALIGN(sizeof(struct ipt_led_info)));
		return 0;
	}

	if (ledinfo->led >= LEDMAN_MAX) {
		DEBUGP("LED: led %u >= %u\n", ledinfo->led, LEDMAN_MAX);
		return 0;
	}

	return 1;
}
Example #12
0
/* Kernel module to match an IP set. */

#include <linux/module.h>
#include <linux/ip.h>
#include <linux/skbuff.h>
#include <linux/version.h>

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
#include <linux/netfilter_ipv4/ip_tables.h>
#define xt_register_match	ipt_register_match
#define xt_unregister_match	ipt_unregister_match
#define xt_match		ipt_match
#else
#include <linux/netfilter/x_tables.h>
#endif
#include <linux/netfilter_ipv4/ip_set.h>
#include <linux/netfilter_ipv4/ipt_set.h>


#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
#ifndef IPT_ALIGN
#define IPT_ALIGN XT_ALIGN
#endif
#endif

static inline int
match_set(const struct ipt_set_info *info,
          const struct sk_buff *skb,
          int inv)
{
    if (ip_set_testip_kernel(info->index, skb, info->flags))
        inv = !inv;
    return inv;
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
static int
match(const struct sk_buff *skb,
      const struct net_device *in,
      const struct net_device *out,
      const void *matchinfo,
      int offset,
      const void *hdr,
      u_int16_t datalen,
      int *hotdrop)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
static int
match(const struct sk_buff *skb,
      const struct net_device *in,
      const struct net_device *out,
      const void *matchinfo,
      int offset,
      int *hotdrop)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
static int
match(const struct sk_buff *skb,
      const struct net_device *in,
      const struct net_device *out,
      const void *matchinfo,
      int offset,
      unsigned int protoff,
      int *hotdrop)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
static int
match(const struct sk_buff *skb,
      const struct net_device *in,
      const struct net_device *out,
      const struct xt_match *match,
      const void *matchinfo,
      int offset,
      unsigned int protoff,
      int *hotdrop)
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) */
static bool
match(const struct sk_buff *skb,
      const struct net_device *in,
      const struct net_device *out,
      const struct xt_match *match,
      const void *matchinfo,
      int offset,
      unsigned int protoff,
      bool *hotdrop)
#endif
{
    const struct ipt_set_info_match *info = matchinfo;

    return match_set(&info->match_set,
                     skb,
                     info->match_set.flags[0] & IPSET_MATCH_INV);
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
static int
checkentry(const char *tablename,
           const struct ipt_ip *ip,
           void *matchinfo,
           unsigned int matchsize,
           unsigned int hook_mask)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
static int
checkentry(const char *tablename,
           const void *inf,
           void *matchinfo,
           unsigned int matchsize,
           unsigned int hook_mask)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
static int
checkentry(const char *tablename,
           const void *inf,
           const struct xt_match *match,
           void *matchinfo,
           unsigned int matchsize,
           unsigned int hook_mask)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
static int
checkentry(const char *tablename,
           const void *inf,
           const struct xt_match *match,
           void *matchinfo,
           unsigned int hook_mask)
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) */
static bool
checkentry(const char *tablename,
           const void *inf,
           const struct xt_match *match,
           void *matchinfo,
           unsigned int hook_mask)
#endif
{
    struct ipt_set_info_match *info = matchinfo;
    ip_set_id_t index;

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
    if (matchsize != IPT_ALIGN(sizeof(struct ipt_set_info_match))) {
        ip_set_printk("invalid matchsize %d", matchsize);
        return 0;
    }
#endif

    index = ip_set_get_byindex(info->match_set.index);

    if (index == IP_SET_INVALID_ID) {
        ip_set_printk("Cannot find set indentified by id %u to match",
                      info->match_set.index);
        return 0;	/* error */
    }
    if (info->match_set.flags[IP_SET_MAX_BINDINGS] != 0) {
        ip_set_printk("That's nasty!");
        return 0;	/* error */
    }

    return 1;
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
static void destroy(void *matchinfo,
                    unsigned int matchsize)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
static void destroy(const struct xt_match *match,
                    void *matchinfo,
                    unsigned int matchsize)
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19) */
static void destroy(const struct xt_match *match,
                    void *matchinfo)
#endif
{
    struct ipt_set_info_match *info = matchinfo;

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
    if (matchsize != IPT_ALIGN(sizeof(struct ipt_set_info_match))) {
        ip_set_printk("invalid matchsize %d", matchsize);
        return;
    }
#endif
    ip_set_put(info->match_set.index);
}
Example #13
0
static struct ipt_entry_target *
get_dnat_target(const char * daddr, unsigned short dport)
{
	struct ipt_entry_target * target;
	struct ip_nat_multi_range * mr;
	struct ip_nat_range * range;
	size_t size;

	size =   IPT_ALIGN(sizeof(struct ipt_entry_target))
	       + IPT_ALIGN(sizeof(struct ip_nat_multi_range));
	target = calloc(1, size);
	target->u.target_size = size;
	strncpy(target->u.user.name, "DNAT", IPT_FUNCTION_MAXNAMELEN);
	/* one ip_nat_range already included in ip_nat_multi_range */
	mr = (struct ip_nat_multi_range *)&target->data[0];
	mr->rangesize = 1;
	range = &mr->range[0];
	range->min_ip = range->max_ip = inet_addr(daddr);
	range->flags |= IP_NAT_RANGE_MAP_IPS;
	range->min.all = range->max.all = htons(dport);
	range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
	return target;
}
Example #14
0
static struct ipt_natinfo *
append_range(struct ipt_natinfo *info, const struct ip_nat_range *range) {
	unsigned int size;

	/* One ip_nat_range already included in ip_nat_multi_range */
	size = IPT_ALIGN(sizeof(*info) + info->mr.rangesize * sizeof(*range));

	info = realloc(info, size);

	info->t.u.target_size = size;
	info->mr.range[info->mr.rangesize] = *range;
	info->mr.rangesize++;

	return info;
}
Example #15
0
static int
checkentry(const char *tablename,
	   const struct ipt_entry *e,
	   void *targinfo,
	   unsigned int targinfosize,
	   unsigned int hook_mask)
{
	struct ipt_connmark_target_info *matchinfo = targinfo;
	if (targinfosize != IPT_ALIGN(sizeof(struct ipt_connmark_target_info))) {
		printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n",
		       targinfosize,
		       IPT_ALIGN(sizeof(struct ipt_connmark_target_info)));
		return 0;
	}

	if (matchinfo->mode == IPT_CONNMARK_RESTORE) {
	    if (strcmp(tablename, "mangle") != 0) {
		    printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename);
		    return 0;
	    }
	}

	return 1;
}
Example #16
0
static int
checkentry(const char *tablename,
		       const struct ipt_ip *ip,
		       void *matchinfo,
		       unsigned int matchsize,
		       unsigned int hook_mask)
{
	const struct ipt_physdev_info *info = matchinfo;

	if (matchsize != IPT_ALIGN(sizeof(struct ipt_physdev_info)))
		return 0;
	if (!(info->bitmask & IPT_PHYSDEV_OP_MASK) ||
	    info->bitmask & ~IPT_PHYSDEV_OP_MASK)
		return 0;
	return 1;
}
static int check(const char *tablename,
		 const struct ipt_ip *ip,
		 void *matchinfo,
		 unsigned int matchsize,
		 unsigned int hook_mask)
{
	struct ipt_helper_info *info = matchinfo;

	info->name[29] = '\0';

	/* verify size */
	if (matchsize != IPT_ALIGN(sizeof(struct ipt_helper_info)))
		return 0;

	return 1;
}
Example #18
0
static struct ipt_natinfo *
append_range(struct ipt_natinfo *info, const struct ip_nat_range *range)
{
	unsigned int size;

	/* One rangesize already in struct ipt_natinfo */
	size = IPT_ALIGN(sizeof(*info) + info->mr.rangesize * sizeof(*range));

	info = realloc(info, size);
	if (!info)
		exit_error(OTHER_PROBLEM, "Out of memory\n");

	info->t.u.target_size = size;
	info->mr.range[info->mr.rangesize] = *range;
	info->mr.rangesize++;

	return info;
}
static int
checkentry(const char *tablename,
           const struct ipt_ip *ip,
           void *matchinfo,
           unsigned int matchsize,
           unsigned int hook_mask)
{
	struct ipt_mark_info *minfo = (struct ipt_mark_info *) matchinfo;

	if (matchsize != IPT_ALIGN(sizeof(struct ipt_mark_info)))
		return 0;

	if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) {
		printk(KERN_WARNING "mark: only supports 32bit mark\n");
		return 0;
	}

	return 1;
}
Example #20
0
static int
checkentry_v1(const char *tablename,
	      const struct ipt_ip *ip,
	      void *matchinfo,
	      unsigned int matchsize,
	      unsigned int hook_mask)
{
	const struct ipt_multiport_v1 *multiinfo = matchinfo;

	/* Must specify supported protocol, no unknown flags or bad count */
	return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP
		|| ip->proto == IPPROTO_SCTP)
		&& !(ip->invflags & IPT_INV_PROTO)
		&& matchsize == IPT_ALIGN(sizeof(struct ipt_multiport_v1))
		&& (multiinfo->flags == IPT_MULTIPORT_SOURCE
		    || multiinfo->flags == IPT_MULTIPORT_DESTINATION
		    || multiinfo->flags == IPT_MULTIPORT_EITHER)
		&& multiinfo->count <= IPT_MULTI_PORTS;
}
Example #21
0
/* ipt_SET.c - netfilter target to manipulate IP sets */

#include <linux/module.h>
#include <linux/ip.h>
#include <linux/skbuff.h>
#include <linux/version.h>

#include <linux/netfilter_ipv4.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
#include <linux/netfilter_ipv4/ip_tables.h>
#define xt_register_target	ipt_register_target
#define xt_unregister_target	ipt_unregister_target
#define xt_target		ipt_target
#define XT_CONTINUE		IPT_CONTINUE
#else
#include <linux/netfilter/x_tables.h>
#endif
#include <linux/netfilter_ipv4/ipt_set.h>

static unsigned int
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
target(struct sk_buff **pskb,
       unsigned int hooknum,
       const struct net_device *in,
       const struct net_device *out,
       const void *targinfo,
       void *userinfo)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
target(struct sk_buff **pskb,
       const struct net_device *in,
       const struct net_device *out,
       unsigned int hooknum,
       const void *targinfo,
       void *userinfo)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
target(struct sk_buff **pskb,
       const struct net_device *in,
       const struct net_device *out,
       unsigned int hooknum,
       const struct xt_target *target,
       const void *targinfo,
       void *userinfo)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
target(struct sk_buff **pskb,
       const struct net_device *in,
       const struct net_device *out,
       unsigned int hooknum,
       const struct xt_target *target,
       const void *targinfo)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
target(struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       unsigned int hooknum,
       const struct xt_target *target,
       const void *targinfo)
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) */
target(struct sk_buff *skb,
       const struct xt_target_param *par)
#endif
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
	const struct ipt_set_info_target *info = targinfo;
#else
	const struct ipt_set_info_target *info = par->targinfo;
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
	struct sk_buff *skb = *pskb;
#endif

	
	if (info->add_set.index != IP_SET_INVALID_ID)
		ip_set_addip_kernel(info->add_set.index,
				    skb,
				    info->add_set.flags);
	if (info->del_set.index != IP_SET_INVALID_ID)
		ip_set_delip_kernel(info->del_set.index,
				    skb,
				    info->del_set.flags);

	return XT_CONTINUE;
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
static int
checkentry(const char *tablename,
	   const struct ipt_entry *e,
	   void *targinfo,
	   unsigned int targinfosize,
	   unsigned int hook_mask)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
static int
checkentry(const char *tablename,
	   const void *e,
	   void *targinfo,
	   unsigned int targinfosize,
	   unsigned int hook_mask)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
static int
checkentry(const char *tablename,
	   const void *e,
	   const struct xt_target *target,
	   void *targinfo,
	   unsigned int targinfosize,
	   unsigned int hook_mask)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
static int
checkentry(const char *tablename,
	   const void *e,
	   const struct xt_target *target,
	   void *targinfo,
	   unsigned int hook_mask)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
static bool
checkentry(const char *tablename,
	   const void *e,
	   const struct xt_target *target,
	   void *targinfo,
	   unsigned int hook_mask)
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) */
static bool
checkentry(const struct xt_tgchk_param *par)
#endif
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
	const struct ipt_set_info_target *info = targinfo;
#else
	const struct ipt_set_info_target *info = par->targinfo;
#endif
	ip_set_id_t index;

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
	if (targinfosize != IPT_ALIGN(sizeof(*info))) {
		DP("bad target info size %u", targinfosize);
		return 0;
	}
#endif

	if (info->add_set.index != IP_SET_INVALID_ID) {
		index = ip_set_get_byindex(info->add_set.index);
		if (index == IP_SET_INVALID_ID) {
			ip_set_printk("cannot find add_set index %u as target",
				      info->add_set.index);
			return 0;	/* error */
		}
	}

	if (info->del_set.index != IP_SET_INVALID_ID) {
		index = ip_set_get_byindex(info->del_set.index);
		if (index == IP_SET_INVALID_ID) {
			ip_set_printk("cannot find del_set index %u as target",
				      info->del_set.index);
			return 0;	/* error */
		}
	}
	if (info->add_set.flags[IP_SET_MAX_BINDINGS] != 0
	    || info->del_set.flags[IP_SET_MAX_BINDINGS] != 0) {
		ip_set_printk("That's nasty!");
		return 0;	/* error */
	}

	return 1;
}
Example #22
0
static int check(const char *tablename,
                 const struct ipt_ip *ip,
                 void *matchinfo,
                 unsigned int matchsize,
                 unsigned int hook_mask)
{
	if (hook_mask
	    & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) |
	        (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN))) {
		printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, "
		       "LOCAL_IN or FORWARD.\n");
		return 0;
	}
	if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info))) {
		printk("ipt_realm: invalid matchsize.\n");
		return 0;
	}
	return 1;
}
Example #23
0
static int
ipt_mac_checkentry(const char *tablename,
		   const struct ipt_ip *ip,
		   void *matchinfo,
		   unsigned int matchsize,
		   unsigned int hook_mask)
{
	/* FORWARD isn't always valid, but it's nice to be able to do --RR */
	if (hook_mask
	    & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN)
		| (1 << NF_IP_FORWARD))) {
		printk("ipt_mac: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n");
		return 0;
	}

	if (matchsize != IPT_ALIGN(sizeof(struct ipt_mac_info)))
		return 0;

	return 1;
}
Example #24
0
/* ipt_SET.c - netfilter target to manipulate IP sets */

#include <linux/module.h>
#include <linux/ip.h>
#include <linux/skbuff.h>
#include <linux/version.h>

#include <linux/netfilter_ipv4.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
#include <linux/netfilter_ipv4/ip_tables.h>
#define xt_register_target	ipt_register_target
#define xt_unregister_target	ipt_unregister_target
#define xt_target		ipt_target
#define XT_CONTINUE		IPT_CONTINUE
#else
#include <linux/netfilter/x_tables.h>
#endif
#include <linux/netfilter_ipv4/ipt_set.h>

static unsigned int
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
target(struct sk_buff **pskb,
       unsigned int hooknum,
       const struct net_device *in,
       const struct net_device *out,
       const void *targinfo,
       void *userinfo)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
target(struct sk_buff **pskb,
       const struct net_device *in,
       const struct net_device *out,
       unsigned int hooknum,
       const void *targinfo,
       void *userinfo)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
target(struct sk_buff **pskb,
       const struct net_device *in,
       const struct net_device *out,
       unsigned int hooknum,
       const struct xt_target *target,
       const void *targinfo,
       void *userinfo)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
target(struct sk_buff **pskb,
       const struct net_device *in,
       const struct net_device *out,
       unsigned int hooknum,
       const struct xt_target *target,
       const void *targinfo)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
target(struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       unsigned int hooknum,
       const struct xt_target *target,
       const void *targinfo)
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) */
target(struct sk_buff *skb,
       const struct xt_target_param *par)
#endif
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
	const struct ipt_set_info_target *info = targinfo;
#else
	const struct ipt_set_info_target *info = par->targinfo;
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
	struct sk_buff *skb = *pskb;
#endif

	
	if (info->add_set.index != IP_SET_INVALID_ID)
		ip_set_addip_kernel(info->add_set.index,
				    skb,
				    info->add_set.flags);
	if (info->del_set.index != IP_SET_INVALID_ID)
		ip_set_delip_kernel(info->del_set.index,
				    skb,
				    info->del_set.flags);

	return XT_CONTINUE;
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
static int
checkentry(const char *tablename,
	   const struct ipt_entry *e,
	   void *targinfo,
	   unsigned int targinfosize,
	   unsigned int hook_mask)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
static int
checkentry(const char *tablename,
	   const void *e,
	   void *targinfo,
	   unsigned int targinfosize,
	   unsigned int hook_mask)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
static int
checkentry(const char *tablename,
	   const void *e,
	   const struct xt_target *target,
	   void *targinfo,
	   unsigned int targinfosize,
	   unsigned int hook_mask)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
static int
checkentry(const char *tablename,
	   const void *e,
	   const struct xt_target *target,
	   void *targinfo,
	   unsigned int hook_mask)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
static bool
checkentry(const char *tablename,
	   const void *e,
	   const struct xt_target *target,
	   void *targinfo,
	   unsigned int hook_mask)
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) */
static bool
checkentry(const struct xt_tgchk_param *par)
#endif
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
	const struct ipt_set_info_target *info = targinfo;
#else
	const struct ipt_set_info_target *info = par->targinfo;
#endif
	ip_set_id_t index;

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
	if (targinfosize != IPT_ALIGN(sizeof(*info))) {
		DP("bad target info size %u", targinfosize);
		return 0;
	}
#endif

	if (info->add_set.index != IP_SET_INVALID_ID) {
		index = ip_set_get_byindex(info->add_set.index);
		if (index == IP_SET_INVALID_ID) {
			ip_set_printk("cannot find add_set index %u as target",
				      info->add_set.index);
			return 0;	/* error */
		}
	}

	if (info->del_set.index != IP_SET_INVALID_ID) {
		index = ip_set_get_byindex(info->del_set.index);
		if (index == IP_SET_INVALID_ID) {
			ip_set_printk("cannot find del_set index %u as target",
				      info->del_set.index);
			return 0;	/* error */
		}
	}
	if (info->add_set.flags[IP_SET_MAX_BINDINGS] != 0
	    || info->del_set.flags[IP_SET_MAX_BINDINGS] != 0) {
		ip_set_printk("That's nasty!");
		return 0;	/* error */
	}

	return 1;
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
static void destroy(void *targetinfo,
		    unsigned int targetsize)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
static void destroy(const struct xt_target *target,
		    void *targetinfo,
		    unsigned int targetsize)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
static void destroy(const struct xt_target *target,
		    void *targetinfo)
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) */
static void destroy(const struct xt_tgdtor_param *par)
#endif
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
	const struct ipt_set_info_target *info = targetinfo;
#else
	const struct ipt_set_info_target *info = par->targinfo;
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
	if (targetsize != IPT_ALIGN(sizeof(struct ipt_set_info_target))) {
		ip_set_printk("invalid targetsize %d", targetsize);
		return;
	}
#endif
	if (info->add_set.index != IP_SET_INVALID_ID)
		ip_set_put_byindex(info->add_set.index);
	if (info->del_set.index != IP_SET_INVALID_ID)
		ip_set_put_byindex(info->del_set.index);
}
Example #25
0
static unsigned char *
is_same(const STRUCT_ENTRY *a, const STRUCT_ENTRY *b, unsigned char *matchmask)
{
	unsigned int i;
	unsigned char *mptr;

	/* Always compare head structures: ignore mask here. */
	if (a->ip.src.s_addr != b->ip.src.s_addr
	    || a->ip.dst.s_addr != b->ip.dst.s_addr
	    || a->ip.smsk.s_addr != b->ip.smsk.s_addr
	    || a->ip.dmsk.s_addr != b->ip.dmsk.s_addr
	    || a->ip.proto != b->ip.proto
	    || a->ip.flags != b->ip.flags
	    || a->ip.invflags != b->ip.invflags)
		return NULL;

	for (i = 0; i < IFNAMSIZ; i++) {
		if (a->ip.iniface_mask[i] != b->ip.iniface_mask[i])
			return NULL;
		if ((a->ip.iniface[i] & a->ip.iniface_mask[i])
		    != (b->ip.iniface[i] & b->ip.iniface_mask[i]))
			return NULL;
		if (a->ip.outiface_mask[i] != b->ip.outiface_mask[i])
			return NULL;
		if ((a->ip.outiface[i] & a->ip.outiface_mask[i])
		    != (b->ip.outiface[i] & b->ip.outiface_mask[i]))
			return NULL;
	}

	if (a->nfcache != b->nfcache
	    || a->target_offset != b->target_offset
	    || a->next_offset != b->next_offset)
		return NULL;

	mptr = matchmask + sizeof(STRUCT_ENTRY);
	if (IPT_MATCH_ITERATE(a, match_different, a->elems, b->elems, &mptr))
		return NULL;
	mptr += IPT_ALIGN(sizeof(struct ipt_entry_target));

	return mptr;
}
Example #26
0
static int ipt_mirror_checkentry(const char *tablename,
				 const struct ipt_entry *e,
				 void *targinfo,
				 unsigned int targinfosize,
				 unsigned int hook_mask)
{
	/* Only on INPUT, FORWARD or PRE_ROUTING, otherwise loop danger. */
	if (hook_mask & ~((1 << NF_IP_PRE_ROUTING)
			  | (1 << NF_IP_FORWARD)
			  | (1 << NF_IP_LOCAL_IN))) {
		DEBUGP("MIRROR: bad hook\n");
		return 0;
	}

	if (targinfosize != IPT_ALIGN(0)) {
		DEBUGP("MIRROR: targinfosize %u != 0\n", targinfosize);
		return 0;
	}

	return 1;
}
static int check(const char *tablename,
		 const void *e_void,
		 void *targinfo,
		 unsigned int targinfosize,
		 unsigned int hook_mask)
{
 	const struct ipt_reject_info *rejinfo = targinfo;
	const struct ipt_entry *e = e_void;

 	if (targinfosize != IPT_ALIGN(sizeof(struct ipt_reject_info))) {
  		DEBUGP("REJECT: targinfosize %u != 0\n", targinfosize);
  		return 0;
  	}

	/* Only allow these for packet filtering. */
	if (strcmp(tablename, "filter") != 0) {
		DEBUGP("REJECT: bad table `%s'.\n", tablename);
		return 0;
	}
	if ((hook_mask & ~((1 << NF_IP_LOCAL_IN)
			   | (1 << NF_IP_FORWARD)
			   | (1 << NF_IP_LOCAL_OUT))) != 0) {
		DEBUGP("REJECT: bad hook mask %X\n", hook_mask);
		return 0;
	}

	if (rejinfo->with == IPT_ICMP_ECHOREPLY) {
		printk("REJECT: ECHOREPLY no longer supported.\n");
		return 0;
	} else if (rejinfo->with == IPT_TCP_RESET) {
		/* Must specify that it's a TCP packet */
		if (e->ip.proto != IPPROTO_TCP
		    || (e->ip.invflags & IPT_INV_PROTO)) {
			DEBUGP("REJECT: TCP_RESET invalid for non-tcp\n");
			return 0;
		}
	}

	return 1;
}
static int ipt_trigger_checkentry(const char *tablename,
			      const struct ipt_entry *e,
			      void *targinfo,
			      unsigned int targinfosize,
			      unsigned int hook_mask)
{
	const struct ipt_trigger_info *triggerinfo = targinfo;

	if (targinfosize != IPT_ALIGN(sizeof(struct ipt_trigger_info))) {
		return 0;
	}

	if (triggerinfo->timer <= 0 || triggerinfo->timer > 9999 ) {
		return 0;
	}

	if (triggerinfo->process_name[sizeof(triggerinfo->process_name)-1] != '\0') {
		return 0;
	}
	
	return 1;
}
Example #29
0
ipt_acct_check_entry (const char *table_name, const struct ipt_entry *entry,
                      void *target_info, unsigned int target_info_size,
                      unsigned int hook_mask)
#endif
{
  struct ipt_acct_info *info = (struct ipt_acct_info *) target_info;

#if LINUX_VERSION_CODE < KERNEL_VERSION (2, 6, 19)
  if (target_info_size != IPT_ALIGN (sizeof (struct ipt_acct_info)))
    {
      printk ("ipt_ACCT: wrong target_info_size = %u\n", target_info_size);
      return 0;
    } 
#endif
  
  if (info->retcode != IPT_CONTINUE && info->retcode != NF_ACCEPT
      && info->retcode != NF_DROP)
    {
      printk ("ipt_ACCT: wrong retcode = %u\n", info->retcode);
      return 0;
    }

  return 1;
}
Example #30
0
save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
{
    const struct ipt_rand_info *randinfo
        = (const struct ipt_rand_info *)match->data;
    div_t result = div((randinfo->average *100), 255);
    if (result.rem > 127)  /* round up... */
        ++result.quot;

    printf("--average %u ", result.quot);
}

struct iptables_match rand_match = {
    .next		= NULL,
    .name		= "random",
    .version	= IPTABLES_VERSION,
    .size		= IPT_ALIGN(sizeof(struct ipt_rand_info)),
    .userspacesize	= IPT_ALIGN(sizeof(struct ipt_rand_info)),
//	.help		= &help,
    .init		= &init,
    .parse		= &parse,
    .final_check	= &final_check,
    .print		= &print,
    .save		= &save,
    .extra_opts	= opts
};

void _init(void)
{
    register_match(&rand_match);
}