manpages: do not include v4-only modules in ip6tables manpage
[jleu-iptables.git] / extensions / libipt_addrtype.c
blobecd51b510c2e72b71f9a31a524fedd00e94669c4
1 /* Shared library add-on to iptables to add addrtype matching support
2 *
3 * This program is released under the terms of GNU GPL */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <getopt.h>
9 #include <xtables.h>
11 #include <linux/netfilter_ipv4/ipt_addrtype.h>
13 /* from linux/rtnetlink.h, must match order of enumeration */
14 static const char *const rtn_names[] = {
15 "UNSPEC",
16 "UNICAST",
17 "LOCAL",
18 "BROADCAST",
19 "ANYCAST",
20 "MULTICAST",
21 "BLACKHOLE",
22 "UNREACHABLE",
23 "PROHIBIT",
24 "THROW",
25 "NAT",
26 "XRESOLVE",
27 NULL
30 static void addrtype_help_types(void)
32 int i;
34 for (i = 0; rtn_names[i]; i++)
35 printf(" %s\n", rtn_names[i]);
38 static void addrtype_help_v0(void)
40 printf(
41 "Address type match options:\n"
42 " [!] --src-type type[,...] Match source address type\n"
43 " [!] --dst-type type[,...] Match destination address type\n"
44 "\n"
45 "Valid types: \n");
46 addrtype_help_types();
49 static void addrtype_help_v1(void)
51 printf(
52 "Address type match options:\n"
53 " [!] --src-type type[,...] Match source address type\n"
54 " [!] --dst-type type[,...] Match destination address type\n"
55 " --limit-iface-in Match only on the packet's incoming device\n"
56 " --limit-iface-out Match only on the packet's incoming device\n"
57 "\n"
58 "Valid types: \n");
59 addrtype_help_types();
62 static int
63 parse_type(const char *name, size_t len, u_int16_t *mask)
65 int i;
67 for (i = 0; rtn_names[i]; i++)
68 if (strncasecmp(name, rtn_names[i], len) == 0) {
69 /* build up bitmask for kernel module */
70 *mask |= (1 << i);
71 return 1;
74 return 0;
77 static void parse_types(const char *arg, u_int16_t *mask)
79 const char *comma;
81 while ((comma = strchr(arg, ',')) != NULL) {
82 if (comma == arg || !parse_type(arg, comma-arg, mask))
83 xtables_error(PARAMETER_PROBLEM,
84 "addrtype: bad type `%s'", arg);
85 arg = comma + 1;
88 if (strlen(arg) == 0 || !parse_type(arg, strlen(arg), mask))
89 xtables_error(PARAMETER_PROBLEM, "addrtype: bad type \"%s\"", arg);
92 #define IPT_ADDRTYPE_OPT_SRCTYPE 0x1
93 #define IPT_ADDRTYPE_OPT_DSTTYPE 0x2
94 #define IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN 0x4
95 #define IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT 0x8
97 static int
98 addrtype_parse_v0(int c, char **argv, int invert, unsigned int *flags,
99 const void *entry, struct xt_entry_match **match)
101 struct ipt_addrtype_info *info =
102 (struct ipt_addrtype_info *) (*match)->data;
104 switch (c) {
105 case '1':
106 if (*flags&IPT_ADDRTYPE_OPT_SRCTYPE)
107 xtables_error(PARAMETER_PROBLEM,
108 "addrtype: can't specify src-type twice");
109 xtables_check_inverse(optarg, &invert, &optind, 0);
110 parse_types(argv[optind-1], &info->source);
111 if (invert)
112 info->invert_source = 1;
113 *flags |= IPT_ADDRTYPE_OPT_SRCTYPE;
114 break;
115 case '2':
116 if (*flags&IPT_ADDRTYPE_OPT_DSTTYPE)
117 xtables_error(PARAMETER_PROBLEM,
118 "addrtype: can't specify dst-type twice");
119 xtables_check_inverse(optarg, &invert, &optind, 0);
120 parse_types(argv[optind-1], &info->dest);
121 if (invert)
122 info->invert_dest = 1;
123 *flags |= IPT_ADDRTYPE_OPT_DSTTYPE;
124 break;
125 default:
126 return 0;
129 return 1;
132 static int
133 addrtype_parse_v1(int c, char **argv, int invert, unsigned int *flags,
134 const void *entry, struct xt_entry_match **match)
136 struct ipt_addrtype_info_v1 *info =
137 (struct ipt_addrtype_info_v1 *) (*match)->data;
139 switch (c) {
140 case '1':
141 if (*flags & IPT_ADDRTYPE_OPT_SRCTYPE)
142 xtables_error(PARAMETER_PROBLEM,
143 "addrtype: can't specify src-type twice");
144 xtables_check_inverse(optarg, &invert, &optind, 0);
145 parse_types(argv[optind-1], &info->source);
146 if (invert)
147 info->flags |= IPT_ADDRTYPE_INVERT_SOURCE;
148 *flags |= IPT_ADDRTYPE_OPT_SRCTYPE;
149 break;
150 case '2':
151 if (*flags & IPT_ADDRTYPE_OPT_DSTTYPE)
152 xtables_error(PARAMETER_PROBLEM,
153 "addrtype: can't specify dst-type twice");
154 xtables_check_inverse(optarg, &invert, &optind, 0);
155 parse_types(argv[optind-1], &info->dest);
156 if (invert)
157 info->flags |= IPT_ADDRTYPE_INVERT_DEST;
158 *flags |= IPT_ADDRTYPE_OPT_DSTTYPE;
159 break;
160 case '3':
161 if (*flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN)
162 xtables_error(PARAMETER_PROBLEM,
163 "addrtype: can't specify limit-iface-in twice");
164 info->flags |= IPT_ADDRTYPE_LIMIT_IFACE_IN;
165 *flags |= IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN;
166 break;
167 case '4':
168 if (*flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT)
169 xtables_error(PARAMETER_PROBLEM,
170 "addrtype: can't specify limit-iface-out twice");
171 info->flags |= IPT_ADDRTYPE_LIMIT_IFACE_OUT;
172 *flags |= IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT;
173 break;
174 default:
175 return 0;
178 return 1;
181 static void addrtype_check_v0(unsigned int flags)
183 if (!(flags & (IPT_ADDRTYPE_OPT_SRCTYPE|IPT_ADDRTYPE_OPT_DSTTYPE)))
184 xtables_error(PARAMETER_PROBLEM,
185 "addrtype: you must specify --src-type or --dst-type");
188 static void addrtype_check_v1(unsigned int flags)
190 if (!(flags & (IPT_ADDRTYPE_OPT_SRCTYPE|IPT_ADDRTYPE_OPT_DSTTYPE)))
191 xtables_error(PARAMETER_PROBLEM,
192 "addrtype: you must specify --src-type or --dst-type");
193 if (flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN &&
194 flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT)
195 xtables_error(PARAMETER_PROBLEM,
196 "addrtype: you can't specify both --limit-iface-in "
197 "and --limit-iface-out");
200 static void print_types(u_int16_t mask)
202 const char *sep = "";
203 int i;
205 for (i = 0; rtn_names[i]; i++)
206 if (mask & (1 << i)) {
207 printf("%s%s", sep, rtn_names[i]);
208 sep = ",";
211 printf(" ");
214 static void addrtype_print_v0(const void *ip, const struct xt_entry_match *match,
215 int numeric)
217 const struct ipt_addrtype_info *info =
218 (struct ipt_addrtype_info *) match->data;
220 printf("ADDRTYPE match ");
221 if (info->source) {
222 printf("src-type ");
223 if (info->invert_source)
224 printf("!");
225 print_types(info->source);
227 if (info->dest) {
228 printf("dst-type ");
229 if (info->invert_dest)
230 printf("!");
231 print_types(info->dest);
235 static void addrtype_print_v1(const void *ip, const struct xt_entry_match *match,
236 int numeric)
238 const struct ipt_addrtype_info_v1 *info =
239 (struct ipt_addrtype_info_v1 *) match->data;
241 printf("ADDRTYPE match ");
242 if (info->source) {
243 printf("src-type ");
244 if (info->flags & IPT_ADDRTYPE_INVERT_SOURCE)
245 printf("!");
246 print_types(info->source);
248 if (info->dest) {
249 printf("dst-type ");
250 if (info->flags & IPT_ADDRTYPE_INVERT_DEST)
251 printf("!");
252 print_types(info->dest);
254 if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
255 printf("limit-in ");
257 if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
258 printf("limit-out ");
262 static void addrtype_save_v0(const void *ip, const struct xt_entry_match *match)
264 const struct ipt_addrtype_info *info =
265 (struct ipt_addrtype_info *) match->data;
267 if (info->source) {
268 if (info->invert_source)
269 printf("! ");
270 printf("--src-type ");
271 print_types(info->source);
273 if (info->dest) {
274 if (info->invert_dest)
275 printf("! ");
276 printf("--dst-type ");
277 print_types(info->dest);
281 static void addrtype_save_v1(const void *ip, const struct xt_entry_match *match)
283 const struct ipt_addrtype_info_v1 *info =
284 (struct ipt_addrtype_info_v1 *) match->data;
286 if (info->source) {
287 if (info->flags & IPT_ADDRTYPE_INVERT_SOURCE)
288 printf("! ");
289 printf("--src-type ");
290 print_types(info->source);
292 if (info->dest) {
293 if (info->flags & IPT_ADDRTYPE_INVERT_DEST)
294 printf("! ");
295 printf("--dst-type ");
296 print_types(info->dest);
298 if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
299 printf("--limit-iface-in ");
301 if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
302 printf("--limit-iface-out ");
306 static const struct option addrtype_opts[] = {
307 { "src-type", 1, NULL, '1' },
308 { "dst-type", 1, NULL, '2' },
309 { .name = NULL }
312 static const struct option addrtype_opts_v0[] = {
313 { "src-type", 1, NULL, '1' },
314 { "dst-type", 1, NULL, '2' },
315 { .name = NULL }
318 static const struct option addrtype_opts_v1[] = {
319 { "src-type", 1, NULL, '1' },
320 { "dst-type", 1, NULL, '2' },
321 { "limit-iface-in", 0, NULL, '3' },
322 { "limit-iface-out", 0, NULL, '4' },
323 { .name = NULL }
326 static struct xtables_match addrtype_mt_reg_v0 = {
327 .name = "addrtype",
328 .version = XTABLES_VERSION,
329 .family = NFPROTO_IPV4,
330 .size = XT_ALIGN(sizeof(struct ipt_addrtype_info)),
331 .userspacesize = XT_ALIGN(sizeof(struct ipt_addrtype_info)),
332 .help = addrtype_help_v0,
333 .parse = addrtype_parse_v0,
334 .final_check = addrtype_check_v0,
335 .print = addrtype_print_v0,
336 .save = addrtype_save_v0,
337 .extra_opts = addrtype_opts_v0,
340 static struct xtables_match addrtype_mt_reg_v1 = {
341 .name = "addrtype",
342 .version = XTABLES_VERSION,
343 .family = NFPROTO_IPV4,
344 .size = XT_ALIGN(sizeof(struct ipt_addrtype_info_v1)),
345 .userspacesize = XT_ALIGN(sizeof(struct ipt_addrtype_info_v1)),
346 .help = addrtype_help_v1,
347 .parse = addrtype_parse_v1,
348 .final_check = addrtype_check_v1,
349 .print = addrtype_print_v1,
350 .save = addrtype_save_v1,
351 .extra_opts = addrtype_opts_v1,
352 .revision = 1,
356 void _init(void)
358 xtables_register_match(&addrtype_mt_reg_v0);
359 xtables_register_match(&addrtype_mt_reg_v1);