This commit was manufactured by cvs2svn to create branch
[iptables.git] / extensions / libipt_pool.c
1 /* Shared library add-on to iptables to add IP address pool matching. */
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_conntrack.h>
11 #include <linux/netfilter_ipv4/ipt_pool.h>
12
13 #include <libippool/ip_pool_support.h>
14
15 /* FIXME --RR */
16 #include "../ippool/libippool.c"
17
18 /* Function which prints out usage message. */
19 static void
20 help(void)
21 {
22         printf(
23 "pool v%s options:\n"
24 " [!] --srcpool NAME|INDEX\n"
25 " [!] --dstpool NAME|INDEX\n"
26 "                       Pool index (or name from %s) to match\n"
27 "\n", IPTABLES_VERSION, IPPOOL_CONF);
28 }
29
30 static struct option opts[] = {
31         { "srcpool", 1, 0, '1' },
32         { "dstpool", 1, 0, '2' },
33         {0}
34 };
35
36 /* Initialize the match. */
37 static void
38 init(struct ipt_entry_match *match, unsigned int *nfcache)
39 {
40         struct ipt_pool_info *info =
41                 (struct ipt_pool_info *)match->data;
42
43         info->src = IP_POOL_NONE;
44         info->dst = IP_POOL_NONE;
45         info->flags = 0;
46 }
47
48 /* Function which parses command options; returns true if it ate an option */
49 static int
50 parse(int c, char **argv, int invert, unsigned int *flags,
51       const struct ipt_entry *entry,
52       unsigned int *nfcache,
53       struct ipt_entry_match **match)
54 {
55         struct ipt_pool_info *info =
56                 (struct ipt_pool_info *)(*match)->data;
57
58         switch (c) {
59         case '1':
60                 check_inverse(optarg, &invert, &optind, 0);
61                 info->src = ip_pool_get_index(argv[optind-1]);
62                 if (invert) info->flags |= IPT_POOL_INV_SRC;
63                 *flags = 1;
64                 break;
65         case '2':
66                 check_inverse(optarg, &invert, &optind, 0);
67                 info->dst = ip_pool_get_index(argv[optind-1]);
68                 if (invert) info->flags |= IPT_POOL_INV_DST;
69                 *flags = 1;
70                 break;
71
72         default:
73                 return 0;
74         }
75
76         return 1;
77 }
78
79 /* Final check; must have specified --srcpool or --dstpool. */
80 static void final_check(unsigned int flags)
81 {
82         if (!flags)
83                 exit_error(PARAMETER_PROBLEM, "You must specify either `--srcpool or --dstpool'");
84 }
85
86 /* Prints out the matchinfo. */
87 static void
88 print(const struct ipt_ip *ip,
89       const struct ipt_entry_match *match,
90       int numeric)
91 {
92         char buf[256];
93         struct ipt_pool_info *info =
94                 (struct ipt_pool_info *)match->data;
95
96         if (info->src != IP_POOL_NONE)
97                 printf("%ssrcpool %s ",
98                         (info->flags & IPT_POOL_INV_SRC) ? "!" : "",
99                         ip_pool_get_name(buf, sizeof(buf), info->src, 0));
100         if (info->dst != IP_POOL_NONE)
101                 printf("%sdstpool %s ",
102                         (info->flags & IPT_POOL_INV_DST) ? "!" : "",
103                         ip_pool_get_name(buf, sizeof(buf), info->dst, 0));
104 }
105
106 /* Saves the matchinfo in parsable form to stdout. */
107 static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
108 {
109         char buf[256];
110         struct ipt_pool_info *info =
111                 (struct ipt_pool_info *)match->data;
112
113         if (info->src != IP_POOL_NONE)
114                 printf("%s--srcpool %s ",
115                         (info->flags & IPT_POOL_INV_SRC) ? "! " : "",
116                         ip_pool_get_name(buf, sizeof(buf), info->src, 0));
117         if (info->dst != IP_POOL_NONE)
118                 printf("%s--dstpool %s ",
119                         (info->flags & IPT_POOL_INV_DST) ? "! " : "",
120                         ip_pool_get_name(buf, sizeof(buf), info->dst, 0));
121 }
122
123 static struct iptables_match pool = { 
124         .next           = NULL,
125         .name           = "pool",
126         .version        = IPTABLES_VERSION,
127         .size           = IPT_ALIGN(sizeof(struct ipt_pool_info)),
128         .userspacesize  = IPT_ALIGN(sizeof(struct ipt_pool_info)),
129         .help           = &help,
130         .init           = &init,
131         .parse          = &parse,
132         .final_check    = &final_check,
133         .print          = &print,
134         .save           = &save,
135         .extra_opts     = opts
136 };
137
138 void _init(void)
139 {
140         register_match(&pool);
141 }