1/* Shared library add-on to iptables to add IP pool mangling target. */ 2#include <stdio.h> 3#include <netdb.h> 4#include <string.h> 5#include <stdlib.h> 6#include <getopt.h> 7#include <ctype.h> 8 9#include <iptables.h> 10#include <linux/netfilter_ipv4/ip_tables.h> 11#include <linux/netfilter_ipv4/ip_nat_rule.h> 12#include <linux/netfilter_ipv4/ip_pool.h> 13#include <linux/netfilter_ipv4/ipt_pool.h> 14 15#include <libippool/ip_pool_support.h> 16 17#define ip_pool_init ip_POOL_init 18#define ip_pool_get_index ip_POOL_get_index 19#define ip_pool_get_name ip_POOL_get_name 20#include "../ippool/libippool.c" 21 22/* Function which prints out usage message. */ 23static void 24help(void) 25{ 26 printf( 27"POOL v%s options:\n" 28" --add-srcip <pool>\n" 29" --del-srcip <pool>\n" 30" --add-dstip <pool>\n" 31" --del-dstip <pool>\n" 32" add/del src/dst IP from pool.\n\n", 33IPTABLES_VERSION); 34} 35 36static struct option opts[] = { 37 { "add-srcip", 1, 0, '1' }, 38 { "del-srcip", 1, 0, '2' }, 39 { "add-dstip", 1, 0, '3' }, 40 { "del-dstip", 1, 0, '4' }, 41 { 0 } 42}; 43 44/* Initialize the target. */ 45static void 46init(struct ipt_entry_target *target, unsigned int *nfcache) 47{ 48 struct ipt_pool_info *ipi = (struct ipt_pool_info *) target->data; 49 50 ipi->src = ipi->dst = IP_POOL_NONE; 51 ipi->flags = 0; 52 53 /* Can't cache this */ 54 *nfcache |= NFC_UNKNOWN; 55} 56 57/* Function which parses command options; returns true if it 58 ate an option */ 59static int 60parse(int c, char **argv, int invert, unsigned int *flags, 61 const struct ipt_entry *entry, 62 struct ipt_entry_target **target) 63{ 64 struct ipt_pool_info *ipi = (struct ipt_pool_info *) (*target)->data; 65 switch (c) { 66 case '1': /* --add-srcip <pool> */ 67 ipi->src = ip_pool_get_index(optarg); 68 ipi->flags &= ~IPT_POOL_DEL_SRC; 69 break; 70 case '2': /* --del-srcip <pool> */ 71 ipi->src = ip_pool_get_index(optarg); 72 ipi->flags |= IPT_POOL_DEL_SRC; 73 break; 74 case '3': /* --add-dstip <pool> */ 75 ipi->dst = ip_pool_get_index(optarg); 76 ipi->flags &= ~IPT_POOL_DEL_DST; 77 break; 78 case '4': /* --del-dstip <pool> */ 79 ipi->dst = ip_pool_get_index(optarg); 80 ipi->flags |= IPT_POOL_DEL_DST; 81 break; 82 default: 83 return 0; 84 } 85 return 1; 86} 87 88/* Final check; don't care. */ 89static void final_check(unsigned int flags) 90{ 91} 92 93/* Prints out the targinfo. */ 94static void 95print(const struct ipt_ip *ip, 96 const struct ipt_entry_target *target, 97 int numeric) 98{ 99 char buf[256]; 100 struct ipt_pool_info *ipi = (struct ipt_pool_info *) target->data; 101 102 printf("POOL"); 103 if (ipi->src != IP_POOL_NONE) { 104 printf(" --%s-srcip %s", 105 (ipi->flags & IPT_POOL_DEL_SRC) ? "del" : "add", 106 ip_pool_get_name(buf, sizeof(buf), ipi->src, numeric)); 107 } 108 if (ipi->dst != IP_POOL_NONE) { 109 printf(" --%s-dstip %s", 110 (ipi->flags & IPT_POOL_DEL_DST) ? "del" : "add", 111 ip_pool_get_name(buf, sizeof(buf), ipi->dst, numeric)); 112 } 113} 114 115/* Saves the union ipt_targinfo in parsable form to stdout. */ 116static void 117save(const struct ipt_ip *ip, const struct ipt_entry_target *target) 118{ 119 char buf[256]; 120 struct ipt_pool_info *ipi = (struct ipt_pool_info *) target->data; 121 122 printf("-j POOL"); 123 if (ipi->src != IP_POOL_NONE) { 124 printf(" --%s-srcip %s", 125 (ipi->flags & IPT_POOL_DEL_SRC) ? "del" : "add", 126 ip_pool_get_name(buf, sizeof(buf), ipi->src, 0)); 127 } 128 if (ipi->dst != IP_POOL_NONE) { 129 printf(" --%s-dstip %s", 130 (ipi->flags & IPT_POOL_DEL_DST) ? "del" : "add", 131 ip_pool_get_name(buf, sizeof(buf), ipi->dst, 0)); 132 } 133} 134 135static 136struct iptables_target ipt_pool_target 137= { NULL, 138 "POOL", 139 IPTABLES_VERSION, 140 IPT_ALIGN(sizeof(struct ipt_pool_info)), 141 IPT_ALIGN(sizeof(struct ipt_pool_info)), 142 &help, 143 &init, 144 &parse, 145 &final_check, 146 &print, 147 &save, 148 opts 149}; 150 151void _init(void) 152{ 153 register_target(&ipt_pool_target); 154} 155