blob: 931dcfdbece4c8fcf44224ea14166217c7fed1ca [file] [log] [blame]
/* Shared library add-on to iptables to add IP pool mangling target. */
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <ctype.h>
#include <iptables.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ip_nat_rule.h>
#include <linux/netfilter_ipv4/ip_pool.h>
#include <linux/netfilter_ipv4/ipt_pool.h>
#include <libippool/ip_pool_support.h>
/* FIXME --RR */
#define ip_pool_init ip_POOL_init
#define ip_pool_get_index ip_POOL_get_index
#define ip_pool_get_name ip_POOL_get_name
#include "../ippool/libippool.c"
/* Function which prints out usage message. */
static void
help(void)
{
printf(
"POOL v%s options:\n"
" --add-srcip <pool>\n"
" --del-srcip <pool>\n"
" --add-dstip <pool>\n"
" --del-dstip <pool>\n"
" add/del src/dst IP from pool.\n\n",
IPTABLES_VERSION);
}
static struct option opts[] = {
{ "add-srcip", 1, 0, '1' },
{ "del-srcip", 1, 0, '2' },
{ "add-dstip", 1, 0, '3' },
{ "del-dstip", 1, 0, '4' },
{ 0 }
};
/* Initialize the target. */
static void
init(struct ipt_entry_target *target, unsigned int *nfcache)
{
struct ipt_pool_info *ipi = (struct ipt_pool_info *) target->data;
ipi->src = ipi->dst = IP_POOL_NONE;
ipi->flags = 0;
/* Can't cache this */
*nfcache |= NFC_UNKNOWN;
}
/* Function which parses command options; returns true if it
ate an option */
static int
parse(int c, char **argv, int invert, unsigned int *flags,
const struct ipt_entry *entry,
struct ipt_entry_target **target)
{
struct ipt_pool_info *ipi = (struct ipt_pool_info *) (*target)->data;
switch (c) {
case '1': /* --add-srcip <pool> */
ipi->src = ip_pool_get_index(optarg);
ipi->flags &= ~IPT_POOL_DEL_SRC;
break;
case '2': /* --del-srcip <pool> */
ipi->src = ip_pool_get_index(optarg);
ipi->flags |= IPT_POOL_DEL_SRC;
break;
case '3': /* --add-dstip <pool> */
ipi->dst = ip_pool_get_index(optarg);
ipi->flags &= ~IPT_POOL_DEL_DST;
break;
case '4': /* --del-dstip <pool> */
ipi->dst = ip_pool_get_index(optarg);
ipi->flags |= IPT_POOL_DEL_DST;
break;
default:
return 0;
}
return 1;
}
/* Final check; don't care. */
static void final_check(unsigned int flags)
{
}
/* Prints out the targinfo. */
static void
print(const struct ipt_ip *ip,
const struct ipt_entry_target *target,
int numeric)
{
char buf[256];
struct ipt_pool_info *ipi = (struct ipt_pool_info *) target->data;
printf("POOL");
if (ipi->src != IP_POOL_NONE) {
printf(" --%s-srcip %s",
(ipi->flags & IPT_POOL_DEL_SRC) ? "del" : "add",
ip_pool_get_name(buf, sizeof(buf), ipi->src, numeric));
}
if (ipi->dst != IP_POOL_NONE) {
printf(" --%s-dstip %s",
(ipi->flags & IPT_POOL_DEL_DST) ? "del" : "add",
ip_pool_get_name(buf, sizeof(buf), ipi->dst, numeric));
}
}
/* Saves the union ipt_targinfo in parsable form to stdout. */
static void
save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
{
char buf[256];
struct ipt_pool_info *ipi = (struct ipt_pool_info *) target->data;
printf("-j POOL");
if (ipi->src != IP_POOL_NONE) {
printf(" --%s-srcip %s",
(ipi->flags & IPT_POOL_DEL_SRC) ? "del" : "add",
ip_pool_get_name(buf, sizeof(buf), ipi->src, 0));
}
if (ipi->dst != IP_POOL_NONE) {
printf(" --%s-dstip %s",
(ipi->flags & IPT_POOL_DEL_DST) ? "del" : "add",
ip_pool_get_name(buf, sizeof(buf), ipi->dst, 0));
}
}
static
struct iptables_target ipt_pool_target
= { NULL,
"POOL",
IPTABLES_VERSION,
IPT_ALIGN(sizeof(struct ipt_pool_info)),
IPT_ALIGN(sizeof(struct ipt_pool_info)),
&help,
&init,
&parse,
&final_check,
&print,
&save,
opts
};
void _init(void)
{
register_target(&ipt_pool_target);
}