blob: 23e2922da3d80a08fd05fce05377144d81b98b46 [file] [log] [blame]
Rusty Russell52451822000-08-27 07:47:46 +00001/* 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. */
19static void
20help(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", NETFILTER_VERSION, IPPOOL_CONF);
28}
29
30static struct option opts[] = {
31 { "srcpool", 1, 0, '1' },
32 { "dstpool", 1, 0, '2' },
33 {0}
34};
35
36/* Initialize the match. */
37static void
38init(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 /* Can't cache this - XXX */
47 *nfcache |= NFC_UNKNOWN;
48}
49
50/* Function which parses command options; returns true if it ate an option */
51static int
52parse(int c, char **argv, int invert, unsigned int *flags,
53 const struct ipt_entry *entry,
54 unsigned int *nfcache,
55 struct ipt_entry_match **match)
56{
57 struct ipt_pool_info *info =
58 (struct ipt_pool_info *)(*match)->data;
59
60 switch (c) {
61 case '1':
62 if (check_inverse(optarg, &invert)) optind++;
63 info->src = ip_pool_get_index(argv[optind-1]);
64 if (invert) info->flags |= IPT_POOL_INV_SRC;
65 *flags = 1;
66 break;
67 case '2':
68 if (check_inverse(optarg, &invert)) optind++;
69 info->dst = ip_pool_get_index(argv[optind-1]);
70 if (invert) info->flags |= IPT_POOL_INV_DST;
71 *flags = 1;
72 break;
73
74 default:
75 return 0;
76 }
77
78 return 1;
79}
80
81/* Final check; must have specified --srcpool or --dstpool. */
82static void final_check(unsigned int flags)
83{
84 if (!flags)
85 exit_error(PARAMETER_PROBLEM, "You must specify either `--srcpool or --dstpool'");
86}
87
88/* Prints out the matchinfo. */
89static void
90print(const struct ipt_ip *ip,
91 const struct ipt_entry_match *match,
92 int numeric)
93{
94 char buf[256];
95 struct ipt_pool_info *info =
96 (struct ipt_pool_info *)match->data;
97
98 if (info->src != IP_POOL_NONE)
99 printf("%ssrcpool %s ",
100 (info->flags & IPT_POOL_INV_SRC) ? "!" : "",
101 ip_pool_get_name(buf, sizeof(buf), info->src, 0));
102 if (info->dst != IP_POOL_NONE)
103 printf("%sdstpool %s ",
104 (info->flags & IPT_POOL_INV_DST) ? "!" : "",
105 ip_pool_get_name(buf, sizeof(buf), info->dst, 0));
106}
107
108/* Saves the matchinfo in parsable form to stdout. */
109static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
110{
111 char buf[256];
112 struct ipt_pool_info *info =
113 (struct ipt_pool_info *)match->data;
114
115 if (info->src != IP_POOL_NONE)
116 printf("%s--srcpool %s",
117 (info->flags & IPT_POOL_INV_SRC) ? "! " : "",
118 ip_pool_get_name(buf, sizeof(buf), info->src, 0));
119 if (info->dst != IP_POOL_NONE)
120 printf("%s--dstpool %s",
121 (info->flags & IPT_POOL_INV_DST) ? "! " : "",
122 ip_pool_get_name(buf, sizeof(buf), info->dst, 0));
123}
124
125struct iptables_match pool
126= { NULL,
127 "pool",
128 NETFILTER_VERSION,
129 IPT_ALIGN(sizeof(struct ipt_pool_info)),
130 IPT_ALIGN(sizeof(struct ipt_pool_info)),
131 &help,
132 &init,
133 &parse,
134 &final_check,
135 &print,
136 &save,
137 opts
138};
139
140void _init(void)
141{
142 register_match(&pool);
143}