1 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
2 * Patrick Schaaf <bof@bof.de>
3 * Martin Josefsson <gandalf@wlug.westbo.se>
4 * Copyright (C) 2003-2004 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 /* Shared library add-on to iptables to add IP set matching. */
21 #include <linux/netfilter_ipv4/ipt_set.h>
22 #include "libipt_set.h"
24 /* Function which prints out usage message. */
25 static void help(void)
27 printf("set v%s options:\n"
28 " [!] --set name flags\n"
29 " 'name' is the set name from to match,\n"
30 " 'flags' are the comma separated list of\n"
32 "\n", IPTABLES_VERSION
);
35 static struct option opts
[] = {
40 /* Initialize the match. */
41 static void init(struct ipt_entry_match
*match
, unsigned int *nfcache
)
43 struct ipt_set_info_match
*info
=
44 (struct ipt_set_info_match
*) match
->data
;
47 memset(info
, 0, sizeof(struct ipt_set_info_match
));
51 /* Function which parses command options; returns true if it ate an option */
53 parse(int c
, char **argv
, int invert
, unsigned int *flags
,
54 const struct ipt_entry
*entry
,
55 unsigned int *nfcache
, struct ipt_entry_match
**match
)
57 struct ipt_set_info_match
*myinfo
=
58 (struct ipt_set_info_match
*) (*match
)->data
;
59 struct ipt_set_info
*info
= &myinfo
->match_set
;
62 case '1': /* --set <set> <flag>[,<flag> */
64 exit_error(PARAMETER_PROBLEM
,
65 "--set can be specified only once");
67 check_inverse(optarg
, &invert
, &optind
, 0);
69 info
->flags
[0] |= IPSET_MATCH_INV
;
72 || argv
[optind
][0] == '-'
73 || argv
[optind
][0] == '!')
74 exit_error(PARAMETER_PROBLEM
,
75 "--set requires two args.");
77 if (strlen(argv
[optind
-1]) > IP_SET_MAXNAMELEN
- 1)
78 exit_error(PARAMETER_PROBLEM
,
79 "setname `%s' too long, max %d characters.",
80 argv
[optind
-1], IP_SET_MAXNAMELEN
- 1);
82 get_set_byname(argv
[optind
- 1], info
);
83 parse_bindings(argv
[optind
], info
);
84 DEBUGP("parse: set index %u\n", info
->index
);
97 /* Final check; must have specified --set. */
98 static void final_check(unsigned int flags
)
101 exit_error(PARAMETER_PROBLEM
,
102 "You must specify `--set' with proper arguments");
103 DEBUGP("final check OK\n");
107 print_match(const char *prefix
, const struct ipt_set_info
*info
)
110 char setname
[IP_SET_MAXNAMELEN
];
112 get_set_byid(setname
, info
->index
);
114 (info
->flags
[0] & IPSET_MATCH_INV
) ? "! " : "",
117 for (i
= 0; i
< IP_SET_MAX_BINDINGS
; i
++) {
122 info
->flags
[i
] & IPSET_SRC
? "src" : "dst");
127 /* Prints out the matchinfo. */
129 print(const struct ipt_ip
*ip
,
130 const struct ipt_entry_match
*match
, int numeric
)
132 struct ipt_set_info_match
*info
=
133 (struct ipt_set_info_match
*) match
->data
;
135 print_match("set", &info
->match_set
);
138 /* Saves the matchinfo in parsable form to stdout. */
139 static void save(const struct ipt_ip
*ip
,
140 const struct ipt_entry_match
*match
)
142 struct ipt_set_info_match
*info
=
143 (struct ipt_set_info_match
*) match
->data
;
145 print_match("--set", &info
->match_set
);
149 struct iptables_match set
= {
151 .version
= IPTABLES_VERSION
,
152 .size
= IPT_ALIGN(sizeof(struct ipt_set_info_match
)),
153 .userspacesize
= IPT_ALIGN(sizeof(struct ipt_set_info_match
)),
157 .final_check
= &final_check
,
165 register_match(&set
);