* [PATCH 01/11] src: collect do_command variables in a struct
2011-02-09 1:48 iptables: clean up main command loop Jan Engelhardt
@ 2011-02-09 1:48 ` Jan Engelhardt
2011-02-09 1:48 ` [PATCH 02/11] src: move large default: block from do_command6 into its own function Jan Engelhardt
` (10 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Jan Engelhardt @ 2011-02-09 1:48 UTC (permalink / raw)
To: kaber; +Cc: netfilter-devel
This will make it easier to put the code for the cases into separate
functions.
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
ip6tables.c | 323 ++++++++++++++++++++++++++++++-----------------------------
iptables.c | 323 ++++++++++++++++++++++++++++++-----------------------------
2 files changed, 330 insertions(+), 316 deletions(-)
diff --git a/ip6tables.c b/ip6tables.c
index 8c1b504..cb9e1f5 100644
--- a/ip6tables.c
+++ b/ip6tables.c
@@ -1288,32 +1288,39 @@ static void clear_rule_matches(struct xtables_rule_match **matches)
*matches = NULL;
}
+struct iptables_command_state {
+ struct ip6t_entry fw;
+ int invert;
+ int c;
+ unsigned int options;
+ struct xtables_rule_match *matches;
+ struct xtables_target *target;
+ char *protocol;
+ int proto_used;
+};
+
int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **handle)
{
- struct ip6t_entry fw, *e = NULL;
- int invert = 0;
+ struct iptables_command_state cs;
+ struct ip6t_entry *e = NULL;
unsigned int nsaddrs = 0, ndaddrs = 0;
struct in6_addr *saddrs = NULL, *daddrs = NULL;
struct in6_addr *smasks = NULL, *dmasks = NULL;
- int c, verbose = 0;
+ int verbose = 0;
const char *chain = NULL;
const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL;
const char *policy = NULL, *newname = NULL;
- unsigned int rulenum = 0, options = 0, command = 0;
+ unsigned int rulenum = 0, command = 0;
const char *pcnt = NULL, *bcnt = NULL;
int ret = 1;
struct xtables_match *m;
- struct xtables_rule_match *matches = NULL;
struct xtables_rule_match *matchp;
- struct xtables_target *target = NULL;
struct xtables_target *t;
const char *jumpto = "";
- char *protocol = NULL;
- int proto_used = 0;
unsigned long long cnt;
- memset(&fw, 0, sizeof(fw));
+ memset(&cs, 0, sizeof(cs));
/* re-set optind to 0 in case do_command gets called
* a second time */
@@ -1334,22 +1341,22 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
opterr = 0;
opts = xt_params->orig_opts;
- while ((c = getopt_long(argc, argv,
+ while ((cs.c = getopt_long(argc, argv,
"-A:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:bvnt:m:xc:g:",
opts, NULL)) != -1) {
- switch (c) {
+ switch (cs.c) {
/*
* Command selection
*/
case 'A':
add_command(&command, CMD_APPEND, CMD_NONE,
- invert);
+ cs.invert);
chain = optarg;
break;
case 'D':
add_command(&command, CMD_DELETE, CMD_NONE,
- invert);
+ cs.invert);
chain = optarg;
if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!') {
@@ -1360,7 +1367,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
case 'R':
add_command(&command, CMD_REPLACE, CMD_NONE,
- invert);
+ cs.invert);
chain = optarg;
if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1373,7 +1380,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
case 'I':
add_command(&command, CMD_INSERT, CMD_NONE,
- invert);
+ cs.invert);
chain = optarg;
if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1383,7 +1390,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
case 'L':
add_command(&command, CMD_LIST,
- CMD_ZERO | CMD_ZERO_NUM, invert);
+ CMD_ZERO | CMD_ZERO_NUM, cs.invert);
if (optarg) chain = optarg;
else if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1395,7 +1402,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
case 'S':
add_command(&command, CMD_LIST_RULES,
- CMD_ZERO | CMD_ZERO_NUM, invert);
+ CMD_ZERO | CMD_ZERO_NUM, cs.invert);
if (optarg) chain = optarg;
else if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1407,7 +1414,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
case 'F':
add_command(&command, CMD_FLUSH, CMD_NONE,
- invert);
+ cs.invert);
if (optarg) chain = optarg;
else if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1416,7 +1423,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
case 'Z':
add_command(&command, CMD_ZERO, CMD_LIST|CMD_LIST_RULES,
- invert);
+ cs.invert);
if (optarg) chain = optarg;
else if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1438,13 +1445,13 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
"chain name may not clash "
"with target name\n");
add_command(&command, CMD_NEW_CHAIN, CMD_NONE,
- invert);
+ cs.invert);
chain = optarg;
break;
case 'X':
add_command(&command, CMD_DELETE_CHAIN, CMD_NONE,
- invert);
+ cs.invert);
if (optarg) chain = optarg;
else if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1453,7 +1460,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
case 'E':
add_command(&command, CMD_RENAME_CHAIN, CMD_NONE,
- invert);
+ cs.invert);
chain = optarg;
if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1467,7 +1474,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
case 'P':
add_command(&command, CMD_SET_POLICY, CMD_NONE,
- invert);
+ cs.invert);
chain = optarg;
if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1483,86 +1490,86 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
optarg = argv[optind];
/* ip6tables -p icmp -h */
- if (!matches && protocol)
- xtables_find_match(protocol, XTF_TRY_LOAD,
- &matches);
+ if (!cs.matches && cs.protocol)
+ xtables_find_match(cs.protocol, XTF_TRY_LOAD,
+ &cs.matches);
- exit_printhelp(matches);
+ exit_printhelp(cs.matches);
/*
* Option selection
*/
case 'p':
- xtables_check_inverse(optarg, &invert, &optind, argc, argv);
- set_option(&options, OPT_PROTOCOL, &fw.ipv6.invflags,
- invert);
+ xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
+ set_option(&cs.options, OPT_PROTOCOL, &cs.fw.ipv6.invflags,
+ cs.invert);
/* Canonicalize into lower case */
- for (protocol = optarg; *protocol; protocol++)
- *protocol = tolower(*protocol);
+ for (cs.protocol = optarg; *cs.protocol; cs.protocol++)
+ *cs.protocol = tolower(*cs.protocol);
- protocol = optarg;
- fw.ipv6.proto = xtables_parse_protocol(protocol);
- fw.ipv6.flags |= IP6T_F_PROTO;
+ cs.protocol = optarg;
+ cs.fw.ipv6.proto = xtables_parse_protocol(cs.protocol);
+ cs.fw.ipv6.flags |= IP6T_F_PROTO;
- if (fw.ipv6.proto == 0
- && (fw.ipv6.invflags & IP6T_INV_PROTO))
+ if (cs.fw.ipv6.proto == 0
+ && (cs.fw.ipv6.invflags & IP6T_INV_PROTO))
xtables_error(PARAMETER_PROBLEM,
"rule would never match protocol");
- if (is_exthdr(fw.ipv6.proto)
- && (fw.ipv6.invflags & IP6T_INV_PROTO) == 0)
+ if (is_exthdr(cs.fw.ipv6.proto)
+ && (cs.fw.ipv6.invflags & IP6T_INV_PROTO) == 0)
fprintf(stderr,
"Warning: never matched protocol: %s. "
"use extension match instead.\n",
- protocol);
+ cs.protocol);
break;
case 's':
- xtables_check_inverse(optarg, &invert, &optind, argc, argv);
- set_option(&options, OPT_SOURCE, &fw.ipv6.invflags,
- invert);
+ xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
+ set_option(&cs.options, OPT_SOURCE, &cs.fw.ipv6.invflags,
+ cs.invert);
shostnetworkmask = optarg;
break;
case 'd':
- xtables_check_inverse(optarg, &invert, &optind, argc, argv);
- set_option(&options, OPT_DESTINATION, &fw.ipv6.invflags,
- invert);
+ xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
+ set_option(&cs.options, OPT_DESTINATION, &cs.fw.ipv6.invflags,
+ cs.invert);
dhostnetworkmask = optarg;
break;
#ifdef IP6T_F_GOTO
case 'g':
- set_option(&options, OPT_JUMP, &fw.ipv6.invflags,
- invert);
- fw.ipv6.flags |= IP6T_F_GOTO;
+ set_option(&cs.options, OPT_JUMP, &cs.fw.ipv6.invflags,
+ cs.invert);
+ cs.fw.ipv6.flags |= IP6T_F_GOTO;
jumpto = parse_target(optarg);
break;
#endif
case 'j':
- set_option(&options, OPT_JUMP, &fw.ipv6.invflags,
- invert);
+ set_option(&cs.options, OPT_JUMP, &cs.fw.ipv6.invflags,
+ cs.invert);
jumpto = parse_target(optarg);
/* TRY_LOAD (may be chain name) */
- target = xtables_find_target(jumpto, XTF_TRY_LOAD);
+ cs.target = xtables_find_target(jumpto, XTF_TRY_LOAD);
- if (target) {
+ if (cs.target) {
size_t size;
size = IP6T_ALIGN(sizeof(struct ip6t_entry_target))
- + target->size;
-
- target->t = xtables_calloc(1, size);
- target->t->u.target_size = size;
- strcpy(target->t->u.user.name, jumpto);
- target->t->u.user.revision = target->revision;
- if (target->init != NULL)
- target->init(target->t);
+ + cs.target->size;
+
+ cs.target->t = xtables_calloc(1, size);
+ cs.target->t->u.target_size = size;
+ strcpy(cs.target->t->u.user.name, jumpto);
+ cs.target->t->u.user.revision = cs.target->revision;
+ if (cs.target->init != NULL)
+ cs.target->init(cs.target->t);
opts = xtables_merge_options(ip6tables_globals.orig_opts, opts,
- target->extra_opts,
- &target->option_offset);
+ cs.target->extra_opts,
+ &cs.target->option_offset);
if (opts == NULL)
xtables_error(OTHER_PROBLEM,
"can't alloc memory!");
@@ -1575,12 +1582,12 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
xtables_error(PARAMETER_PROBLEM,
"Empty interface is likely to be "
"undesired");
- xtables_check_inverse(optarg, &invert, &optind, argc, argv);
- set_option(&options, OPT_VIANAMEIN, &fw.ipv6.invflags,
- invert);
+ xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
+ set_option(&cs.options, OPT_VIANAMEIN, &cs.fw.ipv6.invflags,
+ cs.invert);
xtables_parse_interface(optarg,
- fw.ipv6.iniface,
- fw.ipv6.iniface_mask);
+ cs.fw.ipv6.iniface,
+ cs.fw.ipv6.iniface_mask);
break;
case 'o':
@@ -1588,30 +1595,30 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
xtables_error(PARAMETER_PROBLEM,
"Empty interface is likely to be "
"undesired");
- xtables_check_inverse(optarg, &invert, &optind, argc, argv);
- set_option(&options, OPT_VIANAMEOUT, &fw.ipv6.invflags,
- invert);
+ xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
+ set_option(&cs.options, OPT_VIANAMEOUT, &cs.fw.ipv6.invflags,
+ cs.invert);
xtables_parse_interface(optarg,
- fw.ipv6.outiface,
- fw.ipv6.outiface_mask);
+ cs.fw.ipv6.outiface,
+ cs.fw.ipv6.outiface_mask);
break;
case 'v':
if (!verbose)
- set_option(&options, OPT_VERBOSE,
- &fw.ipv6.invflags, invert);
+ set_option(&cs.options, OPT_VERBOSE,
+ &cs.fw.ipv6.invflags, cs.invert);
verbose++;
break;
case 'm': {
size_t size;
- if (invert)
+ if (cs.invert)
xtables_error(PARAMETER_PROBLEM,
"unexpected ! flag before --match");
m = xtables_find_match(optarg, XTF_LOAD_MUST_SUCCEED,
- &matches);
+ &cs.matches);
size = IP6T_ALIGN(sizeof(struct ip6t_entry_match))
+ m->size;
m->m = xtables_calloc(1, size);
@@ -1627,24 +1634,24 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
break;
case 'n':
- set_option(&options, OPT_NUMERIC, &fw.ipv6.invflags,
- invert);
+ set_option(&cs.options, OPT_NUMERIC, &cs.fw.ipv6.invflags,
+ cs.invert);
break;
case 't':
- if (invert)
+ if (cs.invert)
xtables_error(PARAMETER_PROBLEM,
"unexpected ! flag before --table");
*table = optarg;
break;
case 'x':
- set_option(&options, OPT_EXPANDED, &fw.ipv6.invflags,
- invert);
+ set_option(&cs.options, OPT_EXPANDED, &cs.fw.ipv6.invflags,
+ cs.invert);
break;
case 'V':
- if (invert)
+ if (cs.invert)
printf("Not %s ;-)\n", prog_vers);
else
printf("%s v%s\n",
@@ -1652,8 +1659,8 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
exit(0);
case '0':
- set_option(&options, OPT_LINENUMBERS, &fw.ipv6.invflags,
- invert);
+ set_option(&cs.options, OPT_LINENUMBERS, &cs.fw.ipv6.invflags,
+ cs.invert);
break;
case 'M':
@@ -1662,8 +1669,8 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
case 'c':
- set_option(&options, OPT_COUNTERS, &fw.ipv6.invflags,
- invert);
+ set_option(&cs.options, OPT_COUNTERS, &cs.fw.ipv6.invflags,
+ cs.invert);
pcnt = optarg;
bcnt = strchr(pcnt + 1, ',');
if (bcnt)
@@ -1680,22 +1687,22 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
xtables_error(PARAMETER_PROBLEM,
"-%c packet counter not numeric",
opt2char(OPT_COUNTERS));
- fw.counters.pcnt = cnt;
+ cs.fw.counters.pcnt = cnt;
if (sscanf(bcnt, "%llu", &cnt) != 1)
xtables_error(PARAMETER_PROBLEM,
"-%c byte counter not numeric",
opt2char(OPT_COUNTERS));
- fw.counters.bcnt = cnt;
+ cs.fw.counters.bcnt = cnt;
break;
case 1: /* non option */
if (optarg[0] == '!' && optarg[1] == '\0') {
- if (invert)
+ if (cs.invert)
xtables_error(PARAMETER_PROBLEM,
"multiple consecutive ! not"
" allowed");
- invert = TRUE;
+ cs.invert = TRUE;
optarg[0] = '\0';
continue;
}
@@ -1703,24 +1710,24 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
exit_tryhelp(2);
default:
- if (target == NULL || target->parse == NULL ||
- c < target->option_offset ||
- c >= target->option_offset + XT_OPTION_OFFSET_SCALE ||
- !target->parse(c - target->option_offset,
- argv, invert,
- &target->tflags,
- &fw, &target->t)) {
- for (matchp = matches; matchp; matchp = matchp->next) {
+ if (cs.target == NULL || cs.target->parse == NULL ||
+ cs.c < cs.target->option_offset ||
+ cs.c >= cs.target->option_offset + XT_OPTION_OFFSET_SCALE ||
+ !cs.target->parse(cs.c - cs.target->option_offset,
+ argv, cs.invert,
+ &cs.target->tflags,
+ &cs.fw, &cs.target->t)) {
+ for (matchp = cs.matches; matchp; matchp = matchp->next) {
if (matchp->completed ||
matchp->match->parse == NULL)
continue;
- if (c < matchp->match->option_offset ||
- c >= matchp->match->option_offset + XT_OPTION_OFFSET_SCALE)
+ if (cs.c < matchp->match->option_offset ||
+ cs.c >= matchp->match->option_offset + XT_OPTION_OFFSET_SCALE)
continue;
- if (matchp->match->parse(c - matchp->match->option_offset,
- argv, invert,
+ if (matchp->match->parse(cs.c - matchp->match->option_offset,
+ argv, cs.invert,
&matchp->match->mflags,
- &fw,
+ &cs.fw,
&matchp->match->m))
break;
}
@@ -1750,19 +1757,19 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
* loaded
*/
if (m == NULL
- && protocol
- && (!find_proto(protocol, XTF_DONT_LOAD,
- options&OPT_NUMERIC, NULL)
- || (find_proto(protocol, XTF_DONT_LOAD,
- options&OPT_NUMERIC, NULL)
- && (proto_used == 0))
+ && cs.protocol
+ && (!find_proto(cs.protocol, XTF_DONT_LOAD,
+ cs.options&OPT_NUMERIC, NULL)
+ || (find_proto(cs.protocol, XTF_DONT_LOAD,
+ cs.options&OPT_NUMERIC, NULL)
+ && (cs.proto_used == 0))
)
- && (m = find_proto(protocol, XTF_TRY_LOAD,
- options&OPT_NUMERIC, &matches))) {
+ && (m = find_proto(cs.protocol, XTF_TRY_LOAD,
+ cs.options&OPT_NUMERIC, &cs.matches))) {
/* Try loading protocol */
size_t size;
- proto_used = 1;
+ cs.proto_used = 1;
size = IP6T_ALIGN(sizeof(struct ip6t_entry_match))
+ m->size;
@@ -1782,7 +1789,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
}
if (!m) {
- if (c == '?') {
+ if (cs.c == '?') {
if (optopt) {
xtables_error(
PARAMETER_PROBLEM,
@@ -1803,15 +1810,15 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
}
}
}
- invert = FALSE;
+ cs.invert = FALSE;
}
- for (matchp = matches; matchp; matchp = matchp->next)
+ for (matchp = cs.matches; matchp; matchp = matchp->next)
if (matchp->match->final_check != NULL)
matchp->match->final_check(matchp->match->mflags);
- if (target != NULL && target->final_check != NULL)
- target->final_check(target->tflags);
+ if (cs.target != NULL && cs.target->final_check != NULL)
+ cs.target->final_check(cs.target->tflags);
/* Fix me: must put inverse options checking here --MN */
@@ -1820,14 +1827,14 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
"unknown arguments found on commandline");
if (!command)
xtables_error(PARAMETER_PROBLEM, "no command specified");
- if (invert)
+ if (cs.invert)
xtables_error(PARAMETER_PROBLEM,
"nothing appropriate following !");
if (command & (CMD_REPLACE | CMD_INSERT | CMD_DELETE | CMD_APPEND)) {
- if (!(options & OPT_DESTINATION))
+ if (!(cs.options & OPT_DESTINATION))
dhostnetworkmask = "::0/0";
- if (!(options & OPT_SOURCE))
+ if (!(cs.options & OPT_SOURCE))
shostnetworkmask = "::0/0";
}
@@ -1840,7 +1847,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
&dmasks, &ndaddrs);
if ((nsaddrs > 1 || ndaddrs > 1) &&
- (fw.ipv6.invflags & (IP6T_INV_SRCIP | IP6T_INV_DSTIP)))
+ (cs.fw.ipv6.invflags & (IP6T_INV_SRCIP | IP6T_INV_DSTIP)))
xtables_error(PARAMETER_PROBLEM, "! not allowed with multiple"
" source or destination IP addresses");
@@ -1848,7 +1855,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
xtables_error(PARAMETER_PROBLEM, "Replacement rule does not "
"specify a unique address");
- generic_opt_check(command, options);
+ generic_opt_check(command, cs.options);
if (chain != NULL && strlen(chain) >= XT_EXTENSION_MAXNAMELEN)
xtables_error(PARAMETER_PROBLEM,
@@ -1875,7 +1882,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
if (strcmp(chain, "PREROUTING") == 0
|| strcmp(chain, "INPUT") == 0) {
/* -o not valid with incoming packets. */
- if (options & OPT_VIANAMEOUT)
+ if (cs.options & OPT_VIANAMEOUT)
xtables_error(PARAMETER_PROBLEM,
"Can't use -%c with %s\n",
opt2char(OPT_VIANAMEOUT),
@@ -1885,57 +1892,57 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
if (strcmp(chain, "POSTROUTING") == 0
|| strcmp(chain, "OUTPUT") == 0) {
/* -i not valid with outgoing packets */
- if (options & OPT_VIANAMEIN)
+ if (cs.options & OPT_VIANAMEIN)
xtables_error(PARAMETER_PROBLEM,
"Can't use -%c with %s\n",
opt2char(OPT_VIANAMEIN),
chain);
}
- if (target && ip6tc_is_chain(jumpto, *handle)) {
+ if (cs.target && ip6tc_is_chain(jumpto, *handle)) {
fprintf(stderr,
"Warning: using chain %s, not extension\n",
jumpto);
- if (target->t)
- free(target->t);
+ if (cs.target->t)
+ free(cs.target->t);
- target = NULL;
+ cs.target = NULL;
}
/* If they didn't specify a target, or it's a chain
name, use standard. */
- if (!target
+ if (!cs.target
&& (strlen(jumpto) == 0
|| ip6tc_is_chain(jumpto, *handle))) {
size_t size;
- target = xtables_find_target(IP6T_STANDARD_TARGET,
+ cs.target = xtables_find_target(IP6T_STANDARD_TARGET,
XTF_LOAD_MUST_SUCCEED);
size = sizeof(struct ip6t_entry_target)
- + target->size;
- target->t = xtables_calloc(1, size);
- target->t->u.target_size = size;
- strcpy(target->t->u.user.name, jumpto);
- if (target->init != NULL)
- target->init(target->t);
+ + cs.target->size;
+ cs.target->t = xtables_calloc(1, size);
+ cs.target->t->u.target_size = size;
+ strcpy(cs.target->t->u.user.name, jumpto);
+ if (cs.target->init != NULL)
+ cs.target->init(cs.target->t);
}
- if (!target) {
+ if (!cs.target) {
/* it is no chain, and we can't load a plugin.
* We cannot know if the plugin is corrupt, non
* existant OR if the user just misspelled a
* chain. */
#ifdef IP6T_F_GOTO
- if (fw.ipv6.flags & IP6T_F_GOTO)
+ if (cs.fw.ipv6.flags & IP6T_F_GOTO)
xtables_error(PARAMETER_PROBLEM,
"goto '%s' is not a chain\n", jumpto);
#endif
xtables_find_target(jumpto, XTF_LOAD_MUST_SUCCEED);
} else {
- e = generate_entry(&fw, matches, target->t);
- free(target->t);
+ e = generate_entry(&cs.fw, cs.matches, cs.target->t);
+ free(cs.target->t);
}
}
@@ -1944,15 +1951,15 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
ret = append_entry(chain, e,
nsaddrs, saddrs, smasks,
ndaddrs, daddrs, dmasks,
- options&OPT_VERBOSE,
+ cs.options&OPT_VERBOSE,
*handle);
break;
case CMD_DELETE:
ret = delete_entry(chain, e,
nsaddrs, saddrs, smasks,
ndaddrs, daddrs, dmasks,
- options&OPT_VERBOSE,
- *handle, matches, target);
+ cs.options&OPT_VERBOSE,
+ *handle, cs.matches, cs.target);
break;
case CMD_DELETE_NUM:
ret = ip6tc_delete_num_entry(chain, rulenum - 1, *handle);
@@ -1960,20 +1967,20 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
case CMD_REPLACE:
ret = replace_entry(chain, e, rulenum - 1,
saddrs, smasks, daddrs, dmasks,
- options&OPT_VERBOSE, *handle);
+ cs.options&OPT_VERBOSE, *handle);
break;
case CMD_INSERT:
ret = insert_entry(chain, e, rulenum - 1,
nsaddrs, saddrs, smasks,
ndaddrs, daddrs, dmasks,
- options&OPT_VERBOSE,
+ cs.options&OPT_VERBOSE,
*handle);
break;
case CMD_FLUSH:
- ret = flush_entries(chain, options&OPT_VERBOSE, *handle);
+ ret = flush_entries(chain, cs.options&OPT_VERBOSE, *handle);
break;
case CMD_ZERO:
- ret = zero_entries(chain, options&OPT_VERBOSE, *handle);
+ ret = zero_entries(chain, cs.options&OPT_VERBOSE, *handle);
break;
case CMD_ZERO_NUM:
ret = ip6tc_zero_counter(chain, rulenum, *handle);
@@ -1983,14 +1990,14 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
case CMD_LIST|CMD_ZERO_NUM:
ret = list_entries(chain,
rulenum,
- options&OPT_VERBOSE,
- options&OPT_NUMERIC,
- options&OPT_EXPANDED,
- options&OPT_LINENUMBERS,
+ cs.options&OPT_VERBOSE,
+ cs.options&OPT_NUMERIC,
+ cs.options&OPT_EXPANDED,
+ cs.options&OPT_LINENUMBERS,
*handle);
if (ret && (command & CMD_ZERO))
ret = zero_entries(chain,
- options&OPT_VERBOSE, *handle);
+ cs.options&OPT_VERBOSE, *handle);
if (ret && (command & CMD_ZERO_NUM))
ret = ip6tc_zero_counter(chain, rulenum, *handle);
break;
@@ -1999,11 +2006,11 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
case CMD_LIST_RULES|CMD_ZERO_NUM:
ret = list_rules(chain,
rulenum,
- options&OPT_VERBOSE,
+ cs.options&OPT_VERBOSE,
*handle);
if (ret && (command & CMD_ZERO))
ret = zero_entries(chain,
- options&OPT_VERBOSE, *handle);
+ cs.options&OPT_VERBOSE, *handle);
if (ret && (command & CMD_ZERO_NUM))
ret = ip6tc_zero_counter(chain, rulenum, *handle);
break;
@@ -2011,13 +2018,13 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
ret = ip6tc_create_chain(chain, *handle);
break;
case CMD_DELETE_CHAIN:
- ret = delete_chain(chain, options&OPT_VERBOSE, *handle);
+ ret = delete_chain(chain, cs.options&OPT_VERBOSE, *handle);
break;
case CMD_RENAME_CHAIN:
ret = ip6tc_rename_chain(chain, newname, *handle);
break;
case CMD_SET_POLICY:
- ret = ip6tc_set_policy(chain, policy, options&OPT_COUNTERS ? &fw.counters : NULL, *handle);
+ ret = ip6tc_set_policy(chain, policy, cs.options&OPT_COUNTERS ? &cs.fw.counters : NULL, *handle);
break;
default:
/* We should never reach this... */
@@ -2027,7 +2034,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
if (verbose > 1)
dump_entries6(*handle);
- clear_rule_matches(&matches);
+ clear_rule_matches(&cs.matches);
if (e != NULL) {
free(e);
diff --git a/iptables.c b/iptables.c
index 2459b64..5f62ae5 100644
--- a/iptables.c
+++ b/iptables.c
@@ -1311,32 +1311,39 @@ get_kernel_version(void) {
kernel_version = LINUX_VERSION(x, y, z);
}
+struct iptables_command_state {
+ struct ipt_entry fw;
+ int invert;
+ int c;
+ unsigned int options;
+ struct xtables_rule_match *matches;
+ struct xtables_target *target;
+ char *protocol;
+ int proto_used;
+};
+
int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle)
{
- struct ipt_entry fw, *e = NULL;
- int invert = 0;
+ struct iptables_command_state cs;
+ struct ipt_entry *e = NULL;
unsigned int nsaddrs = 0, ndaddrs = 0;
struct in_addr *saddrs = NULL, *smasks = NULL;
struct in_addr *daddrs = NULL, *dmasks = NULL;
- int c, verbose = 0;
+ int verbose = 0;
const char *chain = NULL;
const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL;
const char *policy = NULL, *newname = NULL;
- unsigned int rulenum = 0, options = 0, command = 0;
+ unsigned int rulenum = 0, command = 0;
const char *pcnt = NULL, *bcnt = NULL;
int ret = 1;
struct xtables_match *m;
- struct xtables_rule_match *matches = NULL;
struct xtables_rule_match *matchp;
- struct xtables_target *target = NULL;
struct xtables_target *t;
const char *jumpto = "";
- char *protocol = NULL;
- int proto_used = 0;
unsigned long long cnt;
- memset(&fw, 0, sizeof(fw));
+ memset(&cs, 0, sizeof(cs));
/* re-set optind to 0 in case do_command gets called
* a second time */
@@ -1357,22 +1364,22 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
opterr = 0;
opts = xt_params->orig_opts;
- while ((c = getopt_long(argc, argv,
+ while ((cs.c = getopt_long(argc, argv,
"-A:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvnt:m:xc:g:",
opts, NULL)) != -1) {
- switch (c) {
+ switch (cs.c) {
/*
* Command selection
*/
case 'A':
add_command(&command, CMD_APPEND, CMD_NONE,
- invert);
+ cs.invert);
chain = optarg;
break;
case 'D':
add_command(&command, CMD_DELETE, CMD_NONE,
- invert);
+ cs.invert);
chain = optarg;
if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!') {
@@ -1383,7 +1390,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
case 'R':
add_command(&command, CMD_REPLACE, CMD_NONE,
- invert);
+ cs.invert);
chain = optarg;
if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1396,7 +1403,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
case 'I':
add_command(&command, CMD_INSERT, CMD_NONE,
- invert);
+ cs.invert);
chain = optarg;
if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1406,7 +1413,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
case 'L':
add_command(&command, CMD_LIST,
- CMD_ZERO | CMD_ZERO_NUM, invert);
+ CMD_ZERO | CMD_ZERO_NUM, cs.invert);
if (optarg) chain = optarg;
else if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1418,7 +1425,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
case 'S':
add_command(&command, CMD_LIST_RULES,
- CMD_ZERO|CMD_ZERO_NUM, invert);
+ CMD_ZERO|CMD_ZERO_NUM, cs.invert);
if (optarg) chain = optarg;
else if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1430,7 +1437,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
case 'F':
add_command(&command, CMD_FLUSH, CMD_NONE,
- invert);
+ cs.invert);
if (optarg) chain = optarg;
else if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1439,7 +1446,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
case 'Z':
add_command(&command, CMD_ZERO, CMD_LIST|CMD_LIST_RULES,
- invert);
+ cs.invert);
if (optarg) chain = optarg;
else if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1461,13 +1468,13 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
"chain name may not clash "
"with target name\n");
add_command(&command, CMD_NEW_CHAIN, CMD_NONE,
- invert);
+ cs.invert);
chain = optarg;
break;
case 'X':
add_command(&command, CMD_DELETE_CHAIN, CMD_NONE,
- invert);
+ cs.invert);
if (optarg) chain = optarg;
else if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1476,7 +1483,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
case 'E':
add_command(&command, CMD_RENAME_CHAIN, CMD_NONE,
- invert);
+ cs.invert);
chain = optarg;
if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1490,7 +1497,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
case 'P':
add_command(&command, CMD_SET_POLICY, CMD_NONE,
- invert);
+ cs.invert);
chain = optarg;
if (optind < argc && argv[optind][0] != '-'
&& argv[optind][0] != '!')
@@ -1506,80 +1513,80 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
optarg = argv[optind];
/* iptables -p icmp -h */
- if (!matches && protocol)
- xtables_find_match(protocol,
- XTF_TRY_LOAD, &matches);
+ if (!cs.matches && cs.protocol)
+ xtables_find_match(cs.protocol,
+ XTF_TRY_LOAD, &cs.matches);
- exit_printhelp(matches);
+ exit_printhelp(cs.matches);
/*
* Option selection
*/
case 'p':
- xtables_check_inverse(optarg, &invert, &optind, argc, argv);
- set_option(&options, OPT_PROTOCOL, &fw.ip.invflags,
- invert);
+ xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
+ set_option(&cs.options, OPT_PROTOCOL, &cs.fw.ip.invflags,
+ cs.invert);
/* Canonicalize into lower case */
- for (protocol = optarg; *protocol; protocol++)
- *protocol = tolower(*protocol);
+ for (cs.protocol = optarg; *cs.protocol; cs.protocol++)
+ *cs.protocol = tolower(*cs.protocol);
- protocol = optarg;
- fw.ip.proto = xtables_parse_protocol(protocol);
+ cs.protocol = optarg;
+ cs.fw.ip.proto = xtables_parse_protocol(cs.protocol);
- if (fw.ip.proto == 0
- && (fw.ip.invflags & IPT_INV_PROTO))
+ if (cs.fw.ip.proto == 0
+ && (cs.fw.ip.invflags & IPT_INV_PROTO))
xtables_error(PARAMETER_PROBLEM,
"rule would never match protocol");
break;
case 's':
- xtables_check_inverse(optarg, &invert, &optind, argc, argv);
- set_option(&options, OPT_SOURCE, &fw.ip.invflags,
- invert);
+ xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
+ set_option(&cs.options, OPT_SOURCE, &cs.fw.ip.invflags,
+ cs.invert);
shostnetworkmask = optarg;
break;
case 'd':
- xtables_check_inverse(optarg, &invert, &optind, argc, argv);
- set_option(&options, OPT_DESTINATION, &fw.ip.invflags,
- invert);
+ xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
+ set_option(&cs.options, OPT_DESTINATION, &cs.fw.ip.invflags,
+ cs.invert);
dhostnetworkmask = optarg;
break;
#ifdef IPT_F_GOTO
case 'g':
- set_option(&options, OPT_JUMP, &fw.ip.invflags,
- invert);
- fw.ip.flags |= IPT_F_GOTO;
+ set_option(&cs.options, OPT_JUMP, &cs.fw.ip.invflags,
+ cs.invert);
+ cs.fw.ip.flags |= IPT_F_GOTO;
jumpto = parse_target(optarg);
break;
#endif
case 'j':
- set_option(&options, OPT_JUMP, &fw.ip.invflags,
- invert);
+ set_option(&cs.options, OPT_JUMP, &cs.fw.ip.invflags,
+ cs.invert);
jumpto = parse_target(optarg);
/* TRY_LOAD (may be chain name) */
- target = xtables_find_target(jumpto, XTF_TRY_LOAD);
+ cs.target = xtables_find_target(jumpto, XTF_TRY_LOAD);
- if (target) {
+ if (cs.target) {
size_t size;
size = IPT_ALIGN(sizeof(struct ipt_entry_target))
- + target->size;
-
- target->t = xtables_calloc(1, size);
- target->t->u.target_size = size;
- strcpy(target->t->u.user.name, jumpto);
- target->t->u.user.revision = target->revision;
- if (target->init != NULL)
- target->init(target->t);
+ + cs.target->size;
+
+ cs.target->t = xtables_calloc(1, size);
+ cs.target->t->u.target_size = size;
+ strcpy(cs.target->t->u.user.name, jumpto);
+ cs.target->t->u.user.revision = cs.target->revision;
+ if (cs.target->init != NULL)
+ cs.target->init(cs.target->t);
opts = xtables_merge_options(
iptables_globals.orig_opts,
opts,
- target->extra_opts,
- &target->option_offset);
+ cs.target->extra_opts,
+ &cs.target->option_offset);
if (opts == NULL)
xtables_error(OTHER_PROBLEM,
"can't alloc memory!");
@@ -1592,12 +1599,12 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
xtables_error(PARAMETER_PROBLEM,
"Empty interface is likely to be "
"undesired");
- xtables_check_inverse(optarg, &invert, &optind, argc, argv);
- set_option(&options, OPT_VIANAMEIN, &fw.ip.invflags,
- invert);
+ xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
+ set_option(&cs.options, OPT_VIANAMEIN, &cs.fw.ip.invflags,
+ cs.invert);
xtables_parse_interface(optarg,
- fw.ip.iniface,
- fw.ip.iniface_mask);
+ cs.fw.ip.iniface,
+ cs.fw.ip.iniface_mask);
break;
case 'o':
@@ -1605,36 +1612,36 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
xtables_error(PARAMETER_PROBLEM,
"Empty interface is likely to be "
"undesired");
- xtables_check_inverse(optarg, &invert, &optind, argc, argv);
- set_option(&options, OPT_VIANAMEOUT, &fw.ip.invflags,
- invert);
+ xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
+ set_option(&cs.options, OPT_VIANAMEOUT, &cs.fw.ip.invflags,
+ cs.invert);
xtables_parse_interface(optarg,
- fw.ip.outiface,
- fw.ip.outiface_mask);
+ cs.fw.ip.outiface,
+ cs.fw.ip.outiface_mask);
break;
case 'f':
- set_option(&options, OPT_FRAGMENT, &fw.ip.invflags,
- invert);
- fw.ip.flags |= IPT_F_FRAG;
+ set_option(&cs.options, OPT_FRAGMENT, &cs.fw.ip.invflags,
+ cs.invert);
+ cs.fw.ip.flags |= IPT_F_FRAG;
break;
case 'v':
if (!verbose)
- set_option(&options, OPT_VERBOSE,
- &fw.ip.invflags, invert);
+ set_option(&cs.options, OPT_VERBOSE,
+ &cs.fw.ip.invflags, cs.invert);
verbose++;
break;
case 'm': {
size_t size;
- if (invert)
+ if (cs.invert)
xtables_error(PARAMETER_PROBLEM,
"unexpected ! flag before --match");
m = xtables_find_match(optarg, XTF_LOAD_MUST_SUCCEED,
- &matches);
+ &cs.matches);
size = IPT_ALIGN(sizeof(struct ipt_entry_match))
+ m->size;
m->m = xtables_calloc(1, size);
@@ -1658,24 +1665,24 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
break;
case 'n':
- set_option(&options, OPT_NUMERIC, &fw.ip.invflags,
- invert);
+ set_option(&cs.options, OPT_NUMERIC, &cs.fw.ip.invflags,
+ cs.invert);
break;
case 't':
- if (invert)
+ if (cs.invert)
xtables_error(PARAMETER_PROBLEM,
"unexpected ! flag before --table");
*table = optarg;
break;
case 'x':
- set_option(&options, OPT_EXPANDED, &fw.ip.invflags,
- invert);
+ set_option(&cs.options, OPT_EXPANDED, &cs.fw.ip.invflags,
+ cs.invert);
break;
case 'V':
- if (invert)
+ if (cs.invert)
printf("Not %s ;-)\n", prog_vers);
else
printf("%s v%s\n",
@@ -1683,8 +1690,8 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
exit(0);
case '0':
- set_option(&options, OPT_LINENUMBERS, &fw.ip.invflags,
- invert);
+ set_option(&cs.options, OPT_LINENUMBERS, &cs.fw.ip.invflags,
+ cs.invert);
break;
case 'M':
@@ -1693,8 +1700,8 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
case 'c':
- set_option(&options, OPT_COUNTERS, &fw.ip.invflags,
- invert);
+ set_option(&cs.options, OPT_COUNTERS, &cs.fw.ip.invflags,
+ cs.invert);
pcnt = optarg;
bcnt = strchr(pcnt + 1, ',');
if (bcnt)
@@ -1711,23 +1718,23 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
xtables_error(PARAMETER_PROBLEM,
"-%c packet counter not numeric",
opt2char(OPT_COUNTERS));
- fw.counters.pcnt = cnt;
+ cs.fw.counters.pcnt = cnt;
if (sscanf(bcnt, "%llu", &cnt) != 1)
xtables_error(PARAMETER_PROBLEM,
"-%c byte counter not numeric",
opt2char(OPT_COUNTERS));
- fw.counters.bcnt = cnt;
+ cs.fw.counters.bcnt = cnt;
break;
case 1: /* non option */
if (optarg[0] == '!' && optarg[1] == '\0') {
- if (invert)
+ if (cs.invert)
xtables_error(PARAMETER_PROBLEM,
"multiple consecutive ! not"
" allowed");
- invert = TRUE;
+ cs.invert = TRUE;
optarg[0] = '\0';
continue;
}
@@ -1735,24 +1742,24 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
exit_tryhelp(2);
default:
- if (target == NULL || target->parse == NULL ||
- c < target->option_offset ||
- c >= target->option_offset + XT_OPTION_OFFSET_SCALE ||
- !target->parse(c - target->option_offset,
- argv, invert,
- &target->tflags,
- &fw, &target->t)) {
- for (matchp = matches; matchp; matchp = matchp->next) {
+ if (cs.target == NULL || cs.target->parse == NULL ||
+ cs.c < cs.target->option_offset ||
+ cs.c >= cs.target->option_offset + XT_OPTION_OFFSET_SCALE ||
+ !cs.target->parse(cs.c - cs.target->option_offset,
+ argv, cs.invert,
+ &cs.target->tflags,
+ &cs.fw, &cs.target->t)) {
+ for (matchp = cs.matches; matchp; matchp = matchp->next) {
if (matchp->completed ||
matchp->match->parse == NULL)
continue;
- if (c < matchp->match->option_offset ||
- c >= matchp->match->option_offset + XT_OPTION_OFFSET_SCALE)
+ if (cs.c < matchp->match->option_offset ||
+ cs.c >= matchp->match->option_offset + XT_OPTION_OFFSET_SCALE)
continue;
- if (matchp->match->parse(c - matchp->match->option_offset,
- argv, invert,
+ if (matchp->match->parse(cs.c - matchp->match->option_offset,
+ argv, cs.invert,
&matchp->match->mflags,
- &fw,
+ &cs.fw,
&matchp->match->m))
break;
}
@@ -1782,19 +1789,19 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
* loaded
*/
if (m == NULL
- && protocol
- && (!find_proto(protocol, XTF_DONT_LOAD,
- options&OPT_NUMERIC, NULL)
- || (find_proto(protocol, XTF_DONT_LOAD,
- options&OPT_NUMERIC, NULL)
- && (proto_used == 0))
+ && cs.protocol
+ && (!find_proto(cs.protocol, XTF_DONT_LOAD,
+ cs.options&OPT_NUMERIC, NULL)
+ || (find_proto(cs.protocol, XTF_DONT_LOAD,
+ cs.options&OPT_NUMERIC, NULL)
+ && (cs.proto_used == 0))
)
- && (m = find_proto(protocol, XTF_TRY_LOAD,
- options&OPT_NUMERIC, &matches))) {
+ && (m = find_proto(cs.protocol, XTF_TRY_LOAD,
+ cs.options&OPT_NUMERIC, &cs.matches))) {
/* Try loading protocol */
size_t size;
- proto_used = 1;
+ cs.proto_used = 1;
size = IPT_ALIGN(sizeof(struct ipt_entry_match))
+ m->size;
@@ -1819,7 +1826,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
continue;
}
if (!m) {
- if (c == '?') {
+ if (cs.c == '?') {
if (optopt) {
xtables_error(
PARAMETER_PROBLEM,
@@ -1840,7 +1847,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
}
}
}
- invert = FALSE;
+ cs.invert = FALSE;
}
if (strcmp(*table, "nat") == 0 &&
@@ -1850,12 +1857,12 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
"\nThe \"nat\" table is not intended for filtering, "
"the use of DROP is therefore inhibited.\n\n");
- for (matchp = matches; matchp; matchp = matchp->next)
+ for (matchp = cs.matches; matchp; matchp = matchp->next)
if (matchp->match->final_check != NULL)
matchp->match->final_check(matchp->match->mflags);
- if (target != NULL && target->final_check != NULL)
- target->final_check(target->tflags);
+ if (cs.target != NULL && cs.target->final_check != NULL)
+ cs.target->final_check(cs.target->tflags);
/* Fix me: must put inverse options checking here --MN */
@@ -1864,14 +1871,14 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
"unknown arguments found on commandline");
if (!command)
xtables_error(PARAMETER_PROBLEM, "no command specified");
- if (invert)
+ if (cs.invert)
xtables_error(PARAMETER_PROBLEM,
"nothing appropriate following !");
if (command & (CMD_REPLACE | CMD_INSERT | CMD_DELETE | CMD_APPEND)) {
- if (!(options & OPT_DESTINATION))
+ if (!(cs.options & OPT_DESTINATION))
dhostnetworkmask = "0.0.0.0/0";
- if (!(options & OPT_SOURCE))
+ if (!(cs.options & OPT_SOURCE))
shostnetworkmask = "0.0.0.0/0";
}
@@ -1884,7 +1891,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
&dmasks, &ndaddrs);
if ((nsaddrs > 1 || ndaddrs > 1) &&
- (fw.ip.invflags & (IPT_INV_SRCIP | IPT_INV_DSTIP)))
+ (cs.fw.ip.invflags & (IPT_INV_SRCIP | IPT_INV_DSTIP)))
xtables_error(PARAMETER_PROBLEM, "! not allowed with multiple"
" source or destination IP addresses");
@@ -1892,7 +1899,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
xtables_error(PARAMETER_PROBLEM, "Replacement rule does not "
"specify a unique address");
- generic_opt_check(command, options);
+ generic_opt_check(command, cs.options);
if (chain != NULL && strlen(chain) >= XT_EXTENSION_MAXNAMELEN)
xtables_error(PARAMETER_PROBLEM,
@@ -1919,7 +1926,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
if (strcmp(chain, "PREROUTING") == 0
|| strcmp(chain, "INPUT") == 0) {
/* -o not valid with incoming packets. */
- if (options & OPT_VIANAMEOUT)
+ if (cs.options & OPT_VIANAMEOUT)
xtables_error(PARAMETER_PROBLEM,
"Can't use -%c with %s\n",
opt2char(OPT_VIANAMEOUT),
@@ -1929,59 +1936,59 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
if (strcmp(chain, "POSTROUTING") == 0
|| strcmp(chain, "OUTPUT") == 0) {
/* -i not valid with outgoing packets */
- if (options & OPT_VIANAMEIN)
+ if (cs.options & OPT_VIANAMEIN)
xtables_error(PARAMETER_PROBLEM,
"Can't use -%c with %s\n",
opt2char(OPT_VIANAMEIN),
chain);
}
- if (target && iptc_is_chain(jumpto, *handle)) {
+ if (cs.target && iptc_is_chain(jumpto, *handle)) {
fprintf(stderr,
"Warning: using chain %s, not extension\n",
jumpto);
- if (target->t)
- free(target->t);
+ if (cs.target->t)
+ free(cs.target->t);
- target = NULL;
+ cs.target = NULL;
}
/* If they didn't specify a target, or it's a chain
name, use standard. */
- if (!target
+ if (!cs.target
&& (strlen(jumpto) == 0
|| iptc_is_chain(jumpto, *handle))) {
size_t size;
- target = xtables_find_target(IPT_STANDARD_TARGET,
+ cs.target = xtables_find_target(IPT_STANDARD_TARGET,
XTF_LOAD_MUST_SUCCEED);
size = sizeof(struct ipt_entry_target)
- + target->size;
- target->t = xtables_calloc(1, size);
- target->t->u.target_size = size;
- strcpy(target->t->u.user.name, jumpto);
+ + cs.target->size;
+ cs.target->t = xtables_calloc(1, size);
+ cs.target->t->u.target_size = size;
+ strcpy(cs.target->t->u.user.name, jumpto);
if (!iptc_is_chain(jumpto, *handle))
- target->t->u.user.revision = target->revision;
- if (target->init != NULL)
- target->init(target->t);
+ cs.target->t->u.user.revision = cs.target->revision;
+ if (cs.target->init != NULL)
+ cs.target->init(cs.target->t);
}
- if (!target) {
+ if (!cs.target) {
/* it is no chain, and we can't load a plugin.
* We cannot know if the plugin is corrupt, non
* existant OR if the user just misspelled a
* chain. */
#ifdef IPT_F_GOTO
- if (fw.ip.flags & IPT_F_GOTO)
+ if (cs.fw.ip.flags & IPT_F_GOTO)
xtables_error(PARAMETER_PROBLEM,
"goto '%s' is not a chain\n", jumpto);
#endif
xtables_find_target(jumpto, XTF_LOAD_MUST_SUCCEED);
} else {
- e = generate_entry(&fw, matches, target->t);
- free(target->t);
+ e = generate_entry(&cs.fw, cs.matches, cs.target->t);
+ free(cs.target->t);
}
}
@@ -1990,15 +1997,15 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
ret = append_entry(chain, e,
nsaddrs, saddrs, smasks,
ndaddrs, daddrs, dmasks,
- options&OPT_VERBOSE,
+ cs.options&OPT_VERBOSE,
*handle);
break;
case CMD_DELETE:
ret = delete_entry(chain, e,
nsaddrs, saddrs, smasks,
ndaddrs, daddrs, dmasks,
- options&OPT_VERBOSE,
- *handle, matches, target);
+ cs.options&OPT_VERBOSE,
+ *handle, cs.matches, cs.target);
break;
case CMD_DELETE_NUM:
ret = iptc_delete_num_entry(chain, rulenum - 1, *handle);
@@ -2006,20 +2013,20 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
case CMD_REPLACE:
ret = replace_entry(chain, e, rulenum - 1,
saddrs, smasks, daddrs, dmasks,
- options&OPT_VERBOSE, *handle);
+ cs.options&OPT_VERBOSE, *handle);
break;
case CMD_INSERT:
ret = insert_entry(chain, e, rulenum - 1,
nsaddrs, saddrs, smasks,
ndaddrs, daddrs, dmasks,
- options&OPT_VERBOSE,
+ cs.options&OPT_VERBOSE,
*handle);
break;
case CMD_FLUSH:
- ret = flush_entries(chain, options&OPT_VERBOSE, *handle);
+ ret = flush_entries(chain, cs.options&OPT_VERBOSE, *handle);
break;
case CMD_ZERO:
- ret = zero_entries(chain, options&OPT_VERBOSE, *handle);
+ ret = zero_entries(chain, cs.options&OPT_VERBOSE, *handle);
break;
case CMD_ZERO_NUM:
ret = iptc_zero_counter(chain, rulenum, *handle);
@@ -2029,14 +2036,14 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
case CMD_LIST|CMD_ZERO_NUM:
ret = list_entries(chain,
rulenum,
- options&OPT_VERBOSE,
- options&OPT_NUMERIC,
- options&OPT_EXPANDED,
- options&OPT_LINENUMBERS,
+ cs.options&OPT_VERBOSE,
+ cs.options&OPT_NUMERIC,
+ cs.options&OPT_EXPANDED,
+ cs.options&OPT_LINENUMBERS,
*handle);
if (ret && (command & CMD_ZERO))
ret = zero_entries(chain,
- options&OPT_VERBOSE, *handle);
+ cs.options&OPT_VERBOSE, *handle);
if (ret && (command & CMD_ZERO_NUM))
ret = iptc_zero_counter(chain, rulenum, *handle);
break;
@@ -2045,11 +2052,11 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
case CMD_LIST_RULES|CMD_ZERO_NUM:
ret = list_rules(chain,
rulenum,
- options&OPT_VERBOSE,
+ cs.options&OPT_VERBOSE,
*handle);
if (ret && (command & CMD_ZERO))
ret = zero_entries(chain,
- options&OPT_VERBOSE, *handle);
+ cs.options&OPT_VERBOSE, *handle);
if (ret && (command & CMD_ZERO_NUM))
ret = iptc_zero_counter(chain, rulenum, *handle);
break;
@@ -2057,13 +2064,13 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
ret = iptc_create_chain(chain, *handle);
break;
case CMD_DELETE_CHAIN:
- ret = delete_chain(chain, options&OPT_VERBOSE, *handle);
+ ret = delete_chain(chain, cs.options&OPT_VERBOSE, *handle);
break;
case CMD_RENAME_CHAIN:
ret = iptc_rename_chain(chain, newname, *handle);
break;
case CMD_SET_POLICY:
- ret = iptc_set_policy(chain, policy, options&OPT_COUNTERS ? &fw.counters : NULL, *handle);
+ ret = iptc_set_policy(chain, policy, cs.options&OPT_COUNTERS ? &cs.fw.counters : NULL, *handle);
break;
default:
/* We should never reach this... */
@@ -2073,7 +2080,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
if (verbose > 1)
dump_entries(*handle);
- clear_rule_matches(&matches);
+ clear_rule_matches(&cs.matches);
if (e != NULL) {
free(e);
--
1.7.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 02/11] src: move large default: block from do_command6 into its own function
2011-02-09 1:48 iptables: clean up main command loop Jan Engelhardt
2011-02-09 1:48 ` [PATCH 01/11] src: collect do_command variables in a struct Jan Engelhardt
@ 2011-02-09 1:48 ` Jan Engelhardt
2011-02-09 1:48 ` [PATCH 03/11] src: share iptables_command_state across the two programs Jan Engelhardt
` (9 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Jan Engelhardt @ 2011-02-09 1:48 UTC (permalink / raw)
To: kaber; +Cc: netfilter-devel
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
ip6tables.c | 209 ++++++++++++++++++++++++++++++---------------------------
iptables.c | 219 +++++++++++++++++++++++++++++++----------------------------
2 files changed, 225 insertions(+), 203 deletions(-)
diff --git a/ip6tables.c b/ip6tables.c
index cb9e1f5..947f3c9 100644
--- a/ip6tables.c
+++ b/ip6tables.c
@@ -1297,8 +1297,115 @@ struct iptables_command_state {
struct xtables_target *target;
char *protocol;
int proto_used;
+ char **argv;
};
+static void command_default(struct iptables_command_state *cs)
+{
+ struct xtables_rule_match *matchp;
+ struct xtables_match *m;
+
+ if (cs->target == NULL || cs->target->parse == NULL ||
+ cs->c < cs->target->option_offset ||
+ cs->c >= cs->target->option_offset + XT_OPTION_OFFSET_SCALE ||
+ !cs->target->parse(cs->c - cs->target->option_offset,
+ cs->argv, cs->invert,
+ &cs->target->tflags,
+ &cs->fw, &cs->target->t)) {
+ for (matchp = cs->matches; matchp; matchp = matchp->next) {
+ if (matchp->completed ||
+ matchp->match->parse == NULL)
+ continue;
+ if (cs->c < matchp->match->option_offset ||
+ cs->c >= matchp->match->option_offset + XT_OPTION_OFFSET_SCALE)
+ continue;
+ if (matchp->match->parse(cs->c - matchp->match->option_offset,
+ cs->argv, cs->invert,
+ &matchp->match->mflags,
+ &cs->fw,
+ &matchp->match->m))
+ break;
+ }
+ m = matchp ? matchp->match : NULL;
+
+ /* If you listen carefully, you can
+ actually hear this code suck. */
+
+ /* some explanations (after four different bugs
+ * in 3 different releases): If we encounter a
+ * parameter, that has not been parsed yet,
+ * it's not an option of an explicitly loaded
+ * match or a target. However, we support
+ * implicit loading of the protocol match
+ * extension. '-p tcp' means 'l4 proto 6' and
+ * at the same time 'load tcp protocol match on
+ * demand if we specify --dport'.
+ *
+ * To make this work, we need to make sure:
+ * - the parameter has not been parsed by
+ * a match (m above)
+ * - a protocol has been specified
+ * - the protocol extension has not been
+ * loaded yet, or is loaded and unused
+ * [think of ip6tables-restore!]
+ * - the protocol extension can be successively
+ * loaded
+ */
+ if (m == NULL
+ && cs->protocol
+ && (!find_proto(cs->protocol, XTF_DONT_LOAD,
+ cs->options&OPT_NUMERIC, NULL)
+ || (find_proto(cs->protocol, XTF_DONT_LOAD,
+ cs->options&OPT_NUMERIC, NULL)
+ && (cs->proto_used == 0))
+ )
+ && (m = find_proto(cs->protocol, XTF_TRY_LOAD,
+ cs->options&OPT_NUMERIC, &cs->matches))) {
+ /* Try loading protocol */
+ size_t size;
+
+ cs->proto_used = 1;
+
+ size = IP6T_ALIGN(sizeof(struct ip6t_entry_match))
+ + m->size;
+
+ m->m = xtables_calloc(1, size);
+ m->m->u.match_size = size;
+ strcpy(m->m->u.user.name, m->name);
+ m->m->u.user.revision = m->revision;
+ if (m->init != NULL)
+ m->init(m->m);
+
+ opts = xtables_merge_options(ip6tables_globals.orig_opts, opts,
+ m->extra_opts, &m->option_offset);
+
+ optind--;
+ return;
+ }
+
+ if (!m) {
+ if (cs->c == '?') {
+ if (optopt) {
+ xtables_error(
+ PARAMETER_PROBLEM,
+ "option `%s' "
+ "requires an "
+ "argument",
+ cs->argv[optind-1]);
+ } else {
+ xtables_error(
+ PARAMETER_PROBLEM,
+ "unknown option "
+ "`%s'",
+ cs->argv[optind-1]);
+ }
+ }
+ xtables_error(PARAMETER_PROBLEM,
+ "Unknown arg `%s'", optarg);
+ }
+ }
+}
+
int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **handle)
{
struct iptables_command_state cs;
@@ -1321,6 +1428,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
unsigned long long cnt;
memset(&cs, 0, sizeof(cs));
+ cs.argv = argv;
/* re-set optind to 0 in case do_command gets called
* a second time */
@@ -1710,105 +1818,8 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
exit_tryhelp(2);
default:
- if (cs.target == NULL || cs.target->parse == NULL ||
- cs.c < cs.target->option_offset ||
- cs.c >= cs.target->option_offset + XT_OPTION_OFFSET_SCALE ||
- !cs.target->parse(cs.c - cs.target->option_offset,
- argv, cs.invert,
- &cs.target->tflags,
- &cs.fw, &cs.target->t)) {
- for (matchp = cs.matches; matchp; matchp = matchp->next) {
- if (matchp->completed ||
- matchp->match->parse == NULL)
- continue;
- if (cs.c < matchp->match->option_offset ||
- cs.c >= matchp->match->option_offset + XT_OPTION_OFFSET_SCALE)
- continue;
- if (matchp->match->parse(cs.c - matchp->match->option_offset,
- argv, cs.invert,
- &matchp->match->mflags,
- &cs.fw,
- &matchp->match->m))
- break;
- }
- m = matchp ? matchp->match : NULL;
-
- /* If you listen carefully, you can
- actually hear this code suck. */
-
- /* some explanations (after four different bugs
- * in 3 different releases): If we encounter a
- * parameter, that has not been parsed yet,
- * it's not an option of an explicitly loaded
- * match or a target. However, we support
- * implicit loading of the protocol match
- * extension. '-p tcp' means 'l4 proto 6' and
- * at the same time 'load tcp protocol match on
- * demand if we specify --dport'.
- *
- * To make this work, we need to make sure:
- * - the parameter has not been parsed by
- * a match (m above)
- * - a protocol has been specified
- * - the protocol extension has not been
- * loaded yet, or is loaded and unused
- * [think of ip6tables-restore!]
- * - the protocol extension can be successively
- * loaded
- */
- if (m == NULL
- && cs.protocol
- && (!find_proto(cs.protocol, XTF_DONT_LOAD,
- cs.options&OPT_NUMERIC, NULL)
- || (find_proto(cs.protocol, XTF_DONT_LOAD,
- cs.options&OPT_NUMERIC, NULL)
- && (cs.proto_used == 0))
- )
- && (m = find_proto(cs.protocol, XTF_TRY_LOAD,
- cs.options&OPT_NUMERIC, &cs.matches))) {
- /* Try loading protocol */
- size_t size;
-
- cs.proto_used = 1;
-
- size = IP6T_ALIGN(sizeof(struct ip6t_entry_match))
- + m->size;
-
- m->m = xtables_calloc(1, size);
- m->m->u.match_size = size;
- strcpy(m->m->u.user.name, m->name);
- m->m->u.user.revision = m->revision;
- if (m->init != NULL)
- m->init(m->m);
-
- opts = xtables_merge_options(ip6tables_globals.orig_opts, opts,
- m->extra_opts, &m->option_offset);
-
- optind--;
- continue;
- }
-
- if (!m) {
- if (cs.c == '?') {
- if (optopt) {
- xtables_error(
- PARAMETER_PROBLEM,
- "option `%s' "
- "requires an "
- "argument",
- argv[optind-1]);
- } else {
- xtables_error(
- PARAMETER_PROBLEM,
- "unknown option "
- "`%s'",
- argv[optind-1]);
- }
- }
- xtables_error(PARAMETER_PROBLEM,
- "Unknown arg `%s'", optarg);
- }
- }
+ command_default(&cs);
+ break;
}
cs.invert = FALSE;
}
diff --git a/iptables.c b/iptables.c
index 5f62ae5..4303cdf 100644
--- a/iptables.c
+++ b/iptables.c
@@ -1320,8 +1320,120 @@ struct iptables_command_state {
struct xtables_target *target;
char *protocol;
int proto_used;
+ char **argv;
};
+static void command_default(struct iptables_command_state *cs)
+{
+ struct xtables_rule_match *matchp;
+ struct xtables_match *m;
+
+ if (cs->target == NULL || cs->target->parse == NULL ||
+ cs->c < cs->target->option_offset ||
+ cs->c >= cs->target->option_offset + XT_OPTION_OFFSET_SCALE ||
+ !cs->target->parse(cs->c - cs->target->option_offset,
+ cs->argv, cs->invert,
+ &cs->target->tflags,
+ &cs->fw, &cs->target->t)) {
+ for (matchp = cs->matches; matchp; matchp = matchp->next) {
+ if (matchp->completed ||
+ matchp->match->parse == NULL)
+ continue;
+ if (cs->c < matchp->match->option_offset ||
+ cs->c >= matchp->match->option_offset + XT_OPTION_OFFSET_SCALE)
+ continue;
+ if (matchp->match->parse(cs->c - matchp->match->option_offset,
+ cs->argv, cs->invert,
+ &matchp->match->mflags,
+ &cs->fw,
+ &matchp->match->m))
+ break;
+ }
+ m = matchp ? matchp->match : NULL;
+
+ /* If you listen carefully, you can
+ actually hear this code suck. */
+
+ /* some explanations (after four different bugs
+ * in 3 different releases): If we encounter a
+ * parameter, that has not been parsed yet,
+ * it's not an option of an explicitly loaded
+ * match or a target. However, we support
+ * implicit loading of the protocol match
+ * extension. '-p tcp' means 'l4 proto 6' and
+ * at the same time 'load tcp protocol match on
+ * demand if we specify --dport'.
+ *
+ * To make this work, we need to make sure:
+ * - the parameter has not been parsed by
+ * a match (m above)
+ * - a protocol has been specified
+ * - the protocol extension has not been
+ * loaded yet, or is loaded and unused
+ * [think of iptables-restore!]
+ * - the protocol extension can be successively
+ * loaded
+ */
+ if (m == NULL
+ && cs->protocol
+ && (!find_proto(cs->protocol, XTF_DONT_LOAD,
+ cs->options&OPT_NUMERIC, NULL)
+ || (find_proto(cs->protocol, XTF_DONT_LOAD,
+ cs->options&OPT_NUMERIC, NULL)
+ && (cs->proto_used == 0))
+ )
+ && (m = find_proto(cs->protocol, XTF_TRY_LOAD,
+ cs->options&OPT_NUMERIC, &cs->matches))) {
+ /* Try loading protocol */
+ size_t size;
+
+ cs->proto_used = 1;
+
+ size = IPT_ALIGN(sizeof(struct ipt_entry_match))
+ + m->size;
+
+ m->m = xtables_calloc(1, size);
+ m->m->u.match_size = size;
+ strcpy(m->m->u.user.name, m->name);
+ m->m->u.user.revision = m->revision;
+ if (m->init != NULL)
+ m->init(m->m);
+
+ opts = xtables_merge_options(
+ iptables_globals.orig_opts,
+ opts,
+ m->extra_opts,
+ &m->option_offset);
+ if (opts == NULL)
+ xtables_error(OTHER_PROBLEM,
+ "can't alloc memory!");
+
+ optind--;
+ return;
+ }
+ if (!m) {
+ if (cs->c == '?') {
+ if (optopt) {
+ xtables_error(
+ PARAMETER_PROBLEM,
+ "option `%s' "
+ "requires an "
+ "argument",
+ cs->argv[optind-1]);
+ } else {
+ xtables_error(
+ PARAMETER_PROBLEM,
+ "unknown option "
+ "`%s'",
+ cs->argv[optind-1]);
+ }
+ }
+ xtables_error(PARAMETER_PROBLEM,
+ "Unknown arg `%s'", optarg);
+ }
+ }
+}
+
int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle)
{
struct iptables_command_state cs;
@@ -1344,6 +1456,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
unsigned long long cnt;
memset(&cs, 0, sizeof(cs));
+ cs.argv = argv;
/* re-set optind to 0 in case do_command gets called
* a second time */
@@ -1742,110 +1855,8 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
exit_tryhelp(2);
default:
- if (cs.target == NULL || cs.target->parse == NULL ||
- cs.c < cs.target->option_offset ||
- cs.c >= cs.target->option_offset + XT_OPTION_OFFSET_SCALE ||
- !cs.target->parse(cs.c - cs.target->option_offset,
- argv, cs.invert,
- &cs.target->tflags,
- &cs.fw, &cs.target->t)) {
- for (matchp = cs.matches; matchp; matchp = matchp->next) {
- if (matchp->completed ||
- matchp->match->parse == NULL)
- continue;
- if (cs.c < matchp->match->option_offset ||
- cs.c >= matchp->match->option_offset + XT_OPTION_OFFSET_SCALE)
- continue;
- if (matchp->match->parse(cs.c - matchp->match->option_offset,
- argv, cs.invert,
- &matchp->match->mflags,
- &cs.fw,
- &matchp->match->m))
- break;
- }
- m = matchp ? matchp->match : NULL;
-
- /* If you listen carefully, you can
- actually hear this code suck. */
-
- /* some explanations (after four different bugs
- * in 3 different releases): If we encounter a
- * parameter, that has not been parsed yet,
- * it's not an option of an explicitly loaded
- * match or a target. However, we support
- * implicit loading of the protocol match
- * extension. '-p tcp' means 'l4 proto 6' and
- * at the same time 'load tcp protocol match on
- * demand if we specify --dport'.
- *
- * To make this work, we need to make sure:
- * - the parameter has not been parsed by
- * a match (m above)
- * - a protocol has been specified
- * - the protocol extension has not been
- * loaded yet, or is loaded and unused
- * [think of iptables-restore!]
- * - the protocol extension can be successively
- * loaded
- */
- if (m == NULL
- && cs.protocol
- && (!find_proto(cs.protocol, XTF_DONT_LOAD,
- cs.options&OPT_NUMERIC, NULL)
- || (find_proto(cs.protocol, XTF_DONT_LOAD,
- cs.options&OPT_NUMERIC, NULL)
- && (cs.proto_used == 0))
- )
- && (m = find_proto(cs.protocol, XTF_TRY_LOAD,
- cs.options&OPT_NUMERIC, &cs.matches))) {
- /* Try loading protocol */
- size_t size;
-
- cs.proto_used = 1;
-
- size = IPT_ALIGN(sizeof(struct ipt_entry_match))
- + m->size;
-
- m->m = xtables_calloc(1, size);
- m->m->u.match_size = size;
- strcpy(m->m->u.user.name, m->name);
- m->m->u.user.revision = m->revision;
- if (m->init != NULL)
- m->init(m->m);
-
- opts = xtables_merge_options(
- iptables_globals.orig_opts,
- opts,
- m->extra_opts,
- &m->option_offset);
- if (opts == NULL)
- xtables_error(OTHER_PROBLEM,
- "can't alloc memory!");
-
- optind--;
- continue;
- }
- if (!m) {
- if (cs.c == '?') {
- if (optopt) {
- xtables_error(
- PARAMETER_PROBLEM,
- "option `%s' "
- "requires an "
- "argument",
- argv[optind-1]);
- } else {
- xtables_error(
- PARAMETER_PROBLEM,
- "unknown option "
- "`%s'",
- argv[optind-1]);
- }
- }
- xtables_error(PARAMETER_PROBLEM,
- "Unknown arg `%s'", optarg);
- }
- }
+ command_default(&cs);
+ break;
}
cs.invert = FALSE;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 03/11] src: share iptables_command_state across the two programs
2011-02-09 1:48 iptables: clean up main command loop Jan Engelhardt
2011-02-09 1:48 ` [PATCH 01/11] src: collect do_command variables in a struct Jan Engelhardt
2011-02-09 1:48 ` [PATCH 02/11] src: move large default: block from do_command6 into its own function Jan Engelhardt
@ 2011-02-09 1:48 ` Jan Engelhardt
2011-02-09 1:48 ` [PATCH 04/11] src: deduplicate find_proto function Jan Engelhardt
` (8 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Jan Engelhardt @ 2011-02-09 1:48 UTC (permalink / raw)
To: kaber; +Cc: netfilter-devel
struct iptables_command_state and quite a bit of the code looks worthy
of deduplication.
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
ip6tables.c | 74 ++++++++++++++++++++++++----------------------------------
iptables.c | 12 ---------
xshared.h | 18 ++++++++++++++
3 files changed, 49 insertions(+), 55 deletions(-)
diff --git a/ip6tables.c b/ip6tables.c
index 947f3c9..dac0c52 100644
--- a/ip6tables.c
+++ b/ip6tables.c
@@ -1288,18 +1288,6 @@ static void clear_rule_matches(struct xtables_rule_match **matches)
*matches = NULL;
}
-struct iptables_command_state {
- struct ip6t_entry fw;
- int invert;
- int c;
- unsigned int options;
- struct xtables_rule_match *matches;
- struct xtables_target *target;
- char *protocol;
- int proto_used;
- char **argv;
-};
-
static void command_default(struct iptables_command_state *cs)
{
struct xtables_rule_match *matchp;
@@ -1311,7 +1299,7 @@ static void command_default(struct iptables_command_state *cs)
!cs->target->parse(cs->c - cs->target->option_offset,
cs->argv, cs->invert,
&cs->target->tflags,
- &cs->fw, &cs->target->t)) {
+ &cs->fw6, &cs->target->t)) {
for (matchp = cs->matches; matchp; matchp = matchp->next) {
if (matchp->completed ||
matchp->match->parse == NULL)
@@ -1322,7 +1310,7 @@ static void command_default(struct iptables_command_state *cs)
if (matchp->match->parse(cs->c - matchp->match->option_offset,
cs->argv, cs->invert,
&matchp->match->mflags,
- &cs->fw,
+ &cs->fw6,
&matchp->match->m))
break;
}
@@ -1609,7 +1597,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
*/
case 'p':
xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
- set_option(&cs.options, OPT_PROTOCOL, &cs.fw.ipv6.invflags,
+ set_option(&cs.options, OPT_PROTOCOL, &cs.fw6.ipv6.invflags,
cs.invert);
/* Canonicalize into lower case */
@@ -1617,16 +1605,16 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
*cs.protocol = tolower(*cs.protocol);
cs.protocol = optarg;
- cs.fw.ipv6.proto = xtables_parse_protocol(cs.protocol);
- cs.fw.ipv6.flags |= IP6T_F_PROTO;
+ cs.fw6.ipv6.proto = xtables_parse_protocol(cs.protocol);
+ cs.fw6.ipv6.flags |= IP6T_F_PROTO;
- if (cs.fw.ipv6.proto == 0
- && (cs.fw.ipv6.invflags & IP6T_INV_PROTO))
+ if (cs.fw6.ipv6.proto == 0
+ && (cs.fw6.ipv6.invflags & IP6T_INV_PROTO))
xtables_error(PARAMETER_PROBLEM,
"rule would never match protocol");
- if (is_exthdr(cs.fw.ipv6.proto)
- && (cs.fw.ipv6.invflags & IP6T_INV_PROTO) == 0)
+ if (is_exthdr(cs.fw6.ipv6.proto)
+ && (cs.fw6.ipv6.invflags & IP6T_INV_PROTO) == 0)
fprintf(stderr,
"Warning: never matched protocol: %s. "
"use extension match instead.\n",
@@ -1635,29 +1623,29 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
case 's':
xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
- set_option(&cs.options, OPT_SOURCE, &cs.fw.ipv6.invflags,
+ set_option(&cs.options, OPT_SOURCE, &cs.fw6.ipv6.invflags,
cs.invert);
shostnetworkmask = optarg;
break;
case 'd':
xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
- set_option(&cs.options, OPT_DESTINATION, &cs.fw.ipv6.invflags,
+ set_option(&cs.options, OPT_DESTINATION, &cs.fw6.ipv6.invflags,
cs.invert);
dhostnetworkmask = optarg;
break;
#ifdef IP6T_F_GOTO
case 'g':
- set_option(&cs.options, OPT_JUMP, &cs.fw.ipv6.invflags,
+ set_option(&cs.options, OPT_JUMP, &cs.fw6.ipv6.invflags,
cs.invert);
- cs.fw.ipv6.flags |= IP6T_F_GOTO;
+ cs.fw6.ipv6.flags |= IP6T_F_GOTO;
jumpto = parse_target(optarg);
break;
#endif
case 'j':
- set_option(&cs.options, OPT_JUMP, &cs.fw.ipv6.invflags,
+ set_option(&cs.options, OPT_JUMP, &cs.fw6.ipv6.invflags,
cs.invert);
jumpto = parse_target(optarg);
/* TRY_LOAD (may be chain name) */
@@ -1691,11 +1679,11 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
"Empty interface is likely to be "
"undesired");
xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
- set_option(&cs.options, OPT_VIANAMEIN, &cs.fw.ipv6.invflags,
+ set_option(&cs.options, OPT_VIANAMEIN, &cs.fw6.ipv6.invflags,
cs.invert);
xtables_parse_interface(optarg,
- cs.fw.ipv6.iniface,
- cs.fw.ipv6.iniface_mask);
+ cs.fw6.ipv6.iniface,
+ cs.fw6.ipv6.iniface_mask);
break;
case 'o':
@@ -1704,17 +1692,17 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
"Empty interface is likely to be "
"undesired");
xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
- set_option(&cs.options, OPT_VIANAMEOUT, &cs.fw.ipv6.invflags,
+ set_option(&cs.options, OPT_VIANAMEOUT, &cs.fw6.ipv6.invflags,
cs.invert);
xtables_parse_interface(optarg,
- cs.fw.ipv6.outiface,
- cs.fw.ipv6.outiface_mask);
+ cs.fw6.ipv6.outiface,
+ cs.fw6.ipv6.outiface_mask);
break;
case 'v':
if (!verbose)
set_option(&cs.options, OPT_VERBOSE,
- &cs.fw.ipv6.invflags, cs.invert);
+ &cs.fw6.ipv6.invflags, cs.invert);
verbose++;
break;
@@ -1742,7 +1730,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
break;
case 'n':
- set_option(&cs.options, OPT_NUMERIC, &cs.fw.ipv6.invflags,
+ set_option(&cs.options, OPT_NUMERIC, &cs.fw6.ipv6.invflags,
cs.invert);
break;
@@ -1754,7 +1742,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
break;
case 'x':
- set_option(&cs.options, OPT_EXPANDED, &cs.fw.ipv6.invflags,
+ set_option(&cs.options, OPT_EXPANDED, &cs.fw6.ipv6.invflags,
cs.invert);
break;
@@ -1767,7 +1755,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
exit(0);
case '0':
- set_option(&cs.options, OPT_LINENUMBERS, &cs.fw.ipv6.invflags,
+ set_option(&cs.options, OPT_LINENUMBERS, &cs.fw6.ipv6.invflags,
cs.invert);
break;
@@ -1777,7 +1765,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
case 'c':
- set_option(&cs.options, OPT_COUNTERS, &cs.fw.ipv6.invflags,
+ set_option(&cs.options, OPT_COUNTERS, &cs.fw6.ipv6.invflags,
cs.invert);
pcnt = optarg;
bcnt = strchr(pcnt + 1, ',');
@@ -1795,13 +1783,13 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
xtables_error(PARAMETER_PROBLEM,
"-%c packet counter not numeric",
opt2char(OPT_COUNTERS));
- cs.fw.counters.pcnt = cnt;
+ cs.fw6.counters.pcnt = cnt;
if (sscanf(bcnt, "%llu", &cnt) != 1)
xtables_error(PARAMETER_PROBLEM,
"-%c byte counter not numeric",
opt2char(OPT_COUNTERS));
- cs.fw.counters.bcnt = cnt;
+ cs.fw6.counters.bcnt = cnt;
break;
case 1: /* non option */
@@ -1858,7 +1846,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
&dmasks, &ndaddrs);
if ((nsaddrs > 1 || ndaddrs > 1) &&
- (cs.fw.ipv6.invflags & (IP6T_INV_SRCIP | IP6T_INV_DSTIP)))
+ (cs.fw6.ipv6.invflags & (IP6T_INV_SRCIP | IP6T_INV_DSTIP)))
xtables_error(PARAMETER_PROBLEM, "! not allowed with multiple"
" source or destination IP addresses");
@@ -1946,13 +1934,13 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
* existant OR if the user just misspelled a
* chain. */
#ifdef IP6T_F_GOTO
- if (cs.fw.ipv6.flags & IP6T_F_GOTO)
+ if (cs.fw6.ipv6.flags & IP6T_F_GOTO)
xtables_error(PARAMETER_PROBLEM,
"goto '%s' is not a chain\n", jumpto);
#endif
xtables_find_target(jumpto, XTF_LOAD_MUST_SUCCEED);
} else {
- e = generate_entry(&cs.fw, cs.matches, cs.target->t);
+ e = generate_entry(&cs.fw6, cs.matches, cs.target->t);
free(cs.target->t);
}
}
@@ -2035,7 +2023,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
ret = ip6tc_rename_chain(chain, newname, *handle);
break;
case CMD_SET_POLICY:
- ret = ip6tc_set_policy(chain, policy, cs.options&OPT_COUNTERS ? &cs.fw.counters : NULL, *handle);
+ ret = ip6tc_set_policy(chain, policy, cs.options&OPT_COUNTERS ? &cs.fw6.counters : NULL, *handle);
break;
default:
/* We should never reach this... */
diff --git a/iptables.c b/iptables.c
index 4303cdf..6881981 100644
--- a/iptables.c
+++ b/iptables.c
@@ -1311,18 +1311,6 @@ get_kernel_version(void) {
kernel_version = LINUX_VERSION(x, y, z);
}
-struct iptables_command_state {
- struct ipt_entry fw;
- int invert;
- int c;
- unsigned int options;
- struct xtables_rule_match *matches;
- struct xtables_target *target;
- char *protocol;
- int proto_used;
- char **argv;
-};
-
static void command_default(struct iptables_command_state *cs)
{
struct xtables_rule_match *matchp;
diff --git a/xshared.h b/xshared.h
index e5b2a02..4a7f96f 100644
--- a/xshared.h
+++ b/xshared.h
@@ -1,9 +1,27 @@
#ifndef IPTABLES_XSHARED_H
#define IPTABLES_XSHARED_H 1
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+
struct xtables_rule_match;
struct xtables_target;
+struct iptables_command_state {
+ union {
+ struct ipt_entry fw;
+ struct ip6t_entry fw6;
+ };
+ int invert;
+ int c;
+ unsigned int options;
+ struct xtables_rule_match *matches;
+ struct xtables_target *target;
+ char *protocol;
+ int proto_used;
+ char **argv;
+};
+
enum {
XT_OPTION_OFFSET_SCALE = 256,
};
--
1.7.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 04/11] src: deduplicate find_proto function
2011-02-09 1:48 iptables: clean up main command loop Jan Engelhardt
` (2 preceding siblings ...)
2011-02-09 1:48 ` [PATCH 03/11] src: share iptables_command_state across the two programs Jan Engelhardt
@ 2011-02-09 1:48 ` Jan Engelhardt
2011-02-09 1:48 ` [PATCH 05/11] src: move OPT_FRAGMENT to the end so the list can be shared Jan Engelhardt
` (7 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Jan Engelhardt @ 2011-02-09 1:48 UTC (permalink / raw)
To: kaber; +Cc: netfilter-devel
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
ip6tables.c | 36 ------------------------------------
iptables.c | 35 -----------------------------------
xshared.c | 37 +++++++++++++++++++++++++++++++++++++
xshared.h | 4 ++++
4 files changed, 41 insertions(+), 71 deletions(-)
diff --git a/ip6tables.c b/ip6tables.c
index dac0c52..ac376e2 100644
--- a/ip6tables.c
+++ b/ip6tables.c
@@ -205,24 +205,6 @@ struct pprot {
uint8_t num;
};
-static const char *
-proto_to_name(uint8_t proto, int nolookup)
-{
- unsigned int i;
-
- if (proto && !nolookup) {
- const struct protoent *pent = getprotobynumber(proto);
- if (pent)
- return pent->p_name;
- }
-
- for (i = 0; xtables_chain_protos[i].name != NULL; ++i)
- if (xtables_chain_protos[i].num == proto)
- return xtables_chain_protos[i].name;
-
- return NULL;
-}
-
static void __attribute__((noreturn))
exit_tryhelp(int status)
{
@@ -406,24 +388,6 @@ add_command(unsigned int *cmd, const int newcmd, const int othercmds,
* return global static data.
*/
-/* Christophe Burki wants `-p 6' to imply `-m tcp'. */
-static struct xtables_match *
-find_proto(const char *pname, enum xtables_tryload tryload,
- int nolookup, struct xtables_rule_match **matches)
-{
- unsigned int proto;
-
- if (xtables_strtoui(pname, NULL, &proto, 0, UINT8_MAX)) {
- const char *protoname = proto_to_name(proto, nolookup);
-
- if (protoname)
- return xtables_find_match(protoname, tryload, matches);
- } else
- return xtables_find_match(pname, tryload, matches);
-
- return NULL;
-}
-
/* These are invalid numbers as upper layer protocol */
static int is_exthdr(uint16_t proto)
{
diff --git a/iptables.c b/iptables.c
index 6881981..9d4f10c 100644
--- a/iptables.c
+++ b/iptables.c
@@ -213,24 +213,6 @@ int kernel_version;
#endif
#endif
-static const char *
-proto_to_name(uint8_t proto, int nolookup)
-{
- unsigned int i;
-
- if (proto && !nolookup) {
- struct protoent *pent = getprotobynumber(proto);
- if (pent)
- return pent->p_name;
- }
-
- for (i = 0; xtables_chain_protos[i].name != NULL; ++i)
- if (xtables_chain_protos[i].num == proto)
- return xtables_chain_protos[i].name;
-
- return NULL;
-}
-
enum {
IPT_DOTTED_ADDR = 0,
IPT_DOTTED_MASK
@@ -420,23 +402,6 @@ add_command(unsigned int *cmd, const int newcmd, const int othercmds,
*/
/* Christophe Burki wants `-p 6' to imply `-m tcp'. */
-static struct xtables_match *
-find_proto(const char *pname, enum xtables_tryload tryload,
- int nolookup, struct xtables_rule_match **matches)
-{
- unsigned int proto;
-
- if (xtables_strtoui(pname, NULL, &proto, 0, UINT8_MAX)) {
- const char *protoname = proto_to_name(proto, nolookup);
-
- if (protoname)
- return xtables_find_match(protoname, tryload, matches);
- } else
- return xtables_find_match(pname, tryload, matches);
-
- return NULL;
-}
-
/* Can't be zero. */
static int
parse_rulenumber(const char *rule)
diff --git a/xshared.c b/xshared.c
index 21b5b2c..40b6b56 100644
--- a/xshared.c
+++ b/xshared.c
@@ -1,3 +1,5 @@
+#include <netdb.h>
+#include <stdint.h>
#include <stdio.h>
#include <xtables.h>
#include "xshared.h"
@@ -29,3 +31,38 @@ void print_extension_helps(const struct xtables_target *t,
m->match->help();
}
}
+
+const char *
+proto_to_name(uint8_t proto, int nolookup)
+{
+ unsigned int i;
+
+ if (proto && !nolookup) {
+ struct protoent *pent = getprotobynumber(proto);
+ if (pent)
+ return pent->p_name;
+ }
+
+ for (i = 0; xtables_chain_protos[i].name != NULL; ++i)
+ if (xtables_chain_protos[i].num == proto)
+ return xtables_chain_protos[i].name;
+
+ return NULL;
+}
+
+struct xtables_match *
+find_proto(const char *pname, enum xtables_tryload tryload,
+ int nolookup, struct xtables_rule_match **matches)
+{
+ unsigned int proto;
+
+ if (xtables_strtoui(pname, NULL, &proto, 0, UINT8_MAX)) {
+ const char *protoname = proto_to_name(proto, nolookup);
+
+ if (protoname)
+ return xtables_find_match(protoname, tryload, matches);
+ } else
+ return xtables_find_match(pname, tryload, matches);
+
+ return NULL;
+}
diff --git a/xshared.h b/xshared.h
index 4a7f96f..11d95fe 100644
--- a/xshared.h
+++ b/xshared.h
@@ -1,6 +1,7 @@
#ifndef IPTABLES_XSHARED_H
#define IPTABLES_XSHARED_H 1
+#include <stdint.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
@@ -28,5 +29,8 @@ enum {
extern void print_extension_helps(const struct xtables_target *,
const struct xtables_rule_match *);
+extern const char *proto_to_name(uint8_t, int);
+extern struct xtables_match *find_proto(const char *, enum xtables_tryload,
+ int, struct xtables_rule_match **);
#endif /* IPTABLES_XSHARED_H */
--
1.7.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 05/11] src: move OPT_FRAGMENT to the end so the list can be shared
2011-02-09 1:48 iptables: clean up main command loop Jan Engelhardt
` (3 preceding siblings ...)
2011-02-09 1:48 ` [PATCH 04/11] src: deduplicate find_proto function Jan Engelhardt
@ 2011-02-09 1:48 ` Jan Engelhardt
2011-02-09 1:48 ` [PATCH 06/11] src: put shared option flags into xshared Jan Engelhardt
` (6 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Jan Engelhardt @ 2011-02-09 1:48 UTC (permalink / raw)
To: kaber; +Cc: netfilter-devel
---
iptables.c | 22 +++++++++++-----------
1 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/iptables.c b/iptables.c
index 9d4f10c..4a3860a 100644
--- a/iptables.c
+++ b/iptables.c
@@ -93,12 +93,12 @@ static const char cmdflags[] = { 'I', 'D', 'D', 'R', 'A', 'L', 'F', 'Z',
#define OPT_EXPANDED 0x00040U
#define OPT_VIANAMEIN 0x00080U
#define OPT_VIANAMEOUT 0x00100U
-#define OPT_FRAGMENT 0x00200U
-#define OPT_LINENUMBERS 0x00400U
-#define OPT_COUNTERS 0x00800U
+#define OPT_LINENUMBERS 0x00200U
+#define OPT_COUNTERS 0x00400U
+#define OPT_FRAGMENT 0x00800U
#define NUMBER_OF_OPT 12
static const char optflags[NUMBER_OF_OPT]
-= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', 'f', '0', 'c'};
+= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c', 'f'};
static struct option original_opts[] = {
{.name = "append", .has_arg = 1, .val = 'A'},
@@ -163,19 +163,19 @@ struct xtables_globals iptables_globals = {
static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
/* Well, it's better than "Re: Linux vs FreeBSD" */
{
- /* -n -s -d -p -j -v -x -i -o -f --line -c */
-/*INSERT*/ {'x',' ',' ',' ',' ',' ','x',' ',' ',' ','x',' '},
-/*DELETE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ',' ','x','x'},
+ /* -n -s -d -p -j -v -x -i -o --line -c -f */
+/*INSERT*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '},
+/*DELETE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' '},
/*DELETE_NUM*/{'x','x','x','x','x',' ','x','x','x','x','x','x'},
-/*REPLACE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ',' ','x',' '},
-/*APPEND*/ {'x',' ',' ',' ',' ',' ','x',' ',' ',' ','x',' '},
-/*LIST*/ {' ','x','x','x','x',' ',' ','x','x','x',' ','x'},
+/*REPLACE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '},
+/*APPEND*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '},
+/*LIST*/ {' ','x','x','x','x',' ',' ','x','x',' ','x','x'},
/*FLUSH*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
/*ZERO*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
/*ZERO_NUM*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
/*NEW_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
/*DEL_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
-/*SET_POLICY*/{'x','x','x','x','x',' ','x','x','x','x','x',' '},
+/*SET_POLICY*/{'x','x','x','x','x',' ','x','x','x','x',' ','x'},
/*RENAME*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
/*LIST_RULES*/{'x','x','x','x','x',' ','x','x','x','x','x','x'}
};
--
1.7.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 06/11] src: put shared option flags into xshared
2011-02-09 1:48 iptables: clean up main command loop Jan Engelhardt
` (4 preceding siblings ...)
2011-02-09 1:48 ` [PATCH 05/11] src: move OPT_FRAGMENT to the end so the list can be shared Jan Engelhardt
@ 2011-02-09 1:48 ` Jan Engelhardt
2011-02-09 1:48 ` [PATCH 07/11] src: deduplicate and simplify implicit protocol extension loading Jan Engelhardt
` (5 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Jan Engelhardt @ 2011-02-09 1:48 UTC (permalink / raw)
To: kaber; +Cc: netfilter-devel
This will be needed for the find_proto function.
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
ip6tables.c | 16 ++--------------
iptables.c | 16 ++--------------
xshared.h | 15 +++++++++++++++
3 files changed, 19 insertions(+), 28 deletions(-)
diff --git a/ip6tables.c b/ip6tables.c
index ac376e2..7f8a8df 100644
--- a/ip6tables.c
+++ b/ip6tables.c
@@ -86,20 +86,8 @@
static const char cmdflags[] = { 'I', 'D', 'D', 'R', 'A', 'L', 'F', 'Z',
'Z', 'N', 'X', 'P', 'E', 'S' };
-#define OPT_NONE 0x00000U
-#define OPT_NUMERIC 0x00001U
-#define OPT_SOURCE 0x00002U
-#define OPT_DESTINATION 0x00004U
-#define OPT_PROTOCOL 0x00008U
-#define OPT_JUMP 0x00010U
-#define OPT_VERBOSE 0x00020U
-#define OPT_EXPANDED 0x00040U
-#define OPT_VIANAMEIN 0x00080U
-#define OPT_VIANAMEOUT 0x00100U
-#define OPT_LINENUMBERS 0x00200U
-#define OPT_COUNTERS 0x00400U
-#define NUMBER_OF_OPT 11
-static const char optflags[NUMBER_OF_OPT]
+#define NUMBER_OF_OPT ARRAY_SIZE(optflags)
+static const char optflags[]
= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c'};
static struct option original_opts[] = {
diff --git a/iptables.c b/iptables.c
index 4a3860a..0de656e 100644
--- a/iptables.c
+++ b/iptables.c
@@ -83,21 +83,9 @@
static const char cmdflags[] = { 'I', 'D', 'D', 'R', 'A', 'L', 'F', 'Z',
'Z', 'N', 'X', 'P', 'E', 'S' };
-#define OPT_NONE 0x00000U
-#define OPT_NUMERIC 0x00001U
-#define OPT_SOURCE 0x00002U
-#define OPT_DESTINATION 0x00004U
-#define OPT_PROTOCOL 0x00008U
-#define OPT_JUMP 0x00010U
-#define OPT_VERBOSE 0x00020U
-#define OPT_EXPANDED 0x00040U
-#define OPT_VIANAMEIN 0x00080U
-#define OPT_VIANAMEOUT 0x00100U
-#define OPT_LINENUMBERS 0x00200U
-#define OPT_COUNTERS 0x00400U
#define OPT_FRAGMENT 0x00800U
-#define NUMBER_OF_OPT 12
-static const char optflags[NUMBER_OF_OPT]
+#define NUMBER_OF_OPT ARRAY_SIZE(optflags)
+static const char optflags[]
= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c', 'f'};
static struct option original_opts[] = {
diff --git a/xshared.h b/xshared.h
index 11d95fe..06d73ab 100644
--- a/xshared.h
+++ b/xshared.h
@@ -5,6 +5,21 @@
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
+enum {
+ OPT_NONE = 0,
+ OPT_NUMERIC = 1 << 0,
+ OPT_SOURCE = 1 << 1,
+ OPT_DESTINATION = 1 << 2,
+ OPT_PROTOCOL = 1 << 3,
+ OPT_JUMP = 1 << 4,
+ OPT_VERBOSE = 1 << 5,
+ OPT_EXPANDED = 1 << 6,
+ OPT_VIANAMEIN = 1 << 7,
+ OPT_VIANAMEOUT = 1 << 8,
+ OPT_LINENUMBERS = 1 << 9,
+ OPT_COUNTERS = 1 << 10,
+};
+
struct xtables_rule_match;
struct xtables_target;
--
1.7.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 07/11] src: deduplicate and simplify implicit protocol extension loading
2011-02-09 1:48 iptables: clean up main command loop Jan Engelhardt
` (5 preceding siblings ...)
2011-02-09 1:48 ` [PATCH 06/11] src: put shared option flags into xshared Jan Engelhardt
@ 2011-02-09 1:48 ` Jan Engelhardt
2011-02-09 1:48 ` [PATCH 08/11] src: unclutter command_default function Jan Engelhardt
` (4 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Jan Engelhardt @ 2011-02-09 1:48 UTC (permalink / raw)
To: kaber; +Cc: netfilter-devel
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
ip6tables.c | 34 +---------------------------------
iptables.c | 34 +---------------------------------
xshared.c | 35 ++++++++++++++++++++++++++++++++++-
xshared.h | 3 +--
4 files changed, 37 insertions(+), 69 deletions(-)
diff --git a/ip6tables.c b/ip6tables.c
index 7f8a8df..3330420 100644
--- a/ip6tables.c
+++ b/ip6tables.c
@@ -1268,39 +1268,7 @@ static void command_default(struct iptables_command_state *cs)
}
m = matchp ? matchp->match : NULL;
- /* If you listen carefully, you can
- actually hear this code suck. */
-
- /* some explanations (after four different bugs
- * in 3 different releases): If we encounter a
- * parameter, that has not been parsed yet,
- * it's not an option of an explicitly loaded
- * match or a target. However, we support
- * implicit loading of the protocol match
- * extension. '-p tcp' means 'l4 proto 6' and
- * at the same time 'load tcp protocol match on
- * demand if we specify --dport'.
- *
- * To make this work, we need to make sure:
- * - the parameter has not been parsed by
- * a match (m above)
- * - a protocol has been specified
- * - the protocol extension has not been
- * loaded yet, or is loaded and unused
- * [think of ip6tables-restore!]
- * - the protocol extension can be successively
- * loaded
- */
- if (m == NULL
- && cs->protocol
- && (!find_proto(cs->protocol, XTF_DONT_LOAD,
- cs->options&OPT_NUMERIC, NULL)
- || (find_proto(cs->protocol, XTF_DONT_LOAD,
- cs->options&OPT_NUMERIC, NULL)
- && (cs->proto_used == 0))
- )
- && (m = find_proto(cs->protocol, XTF_TRY_LOAD,
- cs->options&OPT_NUMERIC, &cs->matches))) {
+ if (m == NULL && (m = load_proto(cs)) != NULL) {
/* Try loading protocol */
size_t size;
diff --git a/iptables.c b/iptables.c
index 0de656e..bae14af 100644
--- a/iptables.c
+++ b/iptables.c
@@ -1292,39 +1292,7 @@ static void command_default(struct iptables_command_state *cs)
}
m = matchp ? matchp->match : NULL;
- /* If you listen carefully, you can
- actually hear this code suck. */
-
- /* some explanations (after four different bugs
- * in 3 different releases): If we encounter a
- * parameter, that has not been parsed yet,
- * it's not an option of an explicitly loaded
- * match or a target. However, we support
- * implicit loading of the protocol match
- * extension. '-p tcp' means 'l4 proto 6' and
- * at the same time 'load tcp protocol match on
- * demand if we specify --dport'.
- *
- * To make this work, we need to make sure:
- * - the parameter has not been parsed by
- * a match (m above)
- * - a protocol has been specified
- * - the protocol extension has not been
- * loaded yet, or is loaded and unused
- * [think of iptables-restore!]
- * - the protocol extension can be successively
- * loaded
- */
- if (m == NULL
- && cs->protocol
- && (!find_proto(cs->protocol, XTF_DONT_LOAD,
- cs->options&OPT_NUMERIC, NULL)
- || (find_proto(cs->protocol, XTF_DONT_LOAD,
- cs->options&OPT_NUMERIC, NULL)
- && (cs->proto_used == 0))
- )
- && (m = find_proto(cs->protocol, XTF_TRY_LOAD,
- cs->options&OPT_NUMERIC, &cs->matches))) {
+ if (m == NULL && (m = load_proto(cs)) != NULL) {
/* Try loading protocol */
size_t size;
diff --git a/xshared.c b/xshared.c
index 40b6b56..b47beb1 100644
--- a/xshared.c
+++ b/xshared.c
@@ -1,4 +1,5 @@
#include <netdb.h>
+#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <xtables.h>
@@ -50,7 +51,7 @@ proto_to_name(uint8_t proto, int nolookup)
return NULL;
}
-struct xtables_match *
+static struct xtables_match *
find_proto(const char *pname, enum xtables_tryload tryload,
int nolookup, struct xtables_rule_match **matches)
{
@@ -66,3 +67,35 @@ find_proto(const char *pname, enum xtables_tryload tryload,
return NULL;
}
+
+/*
+ * Some explanations (after four different bugs in 3 different releases): If
+ * we encounter a parameter, that has not been parsed yet, it's not an option
+ * of an explicitly loaded match or a target. However, we support implicit
+ * loading of the protocol match extension. '-p tcp' means 'l4 proto 6' and at
+ * the same time 'load tcp protocol match on demand if we specify --dport'.
+ *
+ * To make this work, we need to make sure:
+ * - the parameter has not been parsed by a match (m above)
+ * - a protocol has been specified
+ * - the protocol extension has not been loaded yet, or is loaded and unused
+ * [think of ip6tables-restore!]
+ * - the protocol extension can be successively loaded
+ */
+static bool should_load_proto(struct iptables_command_state *cs)
+{
+ if (cs->protocol == NULL)
+ return false;
+ if (find_proto(cs->protocol, XTF_DONT_LOAD,
+ cs->options & OPT_NUMERIC, NULL) != NULL)
+ return true;
+ return cs->proto_used;
+}
+
+struct xtables_match *load_proto(struct iptables_command_state *cs)
+{
+ if (!should_load_proto(cs))
+ return NULL;
+ return find_proto(cs->protocol, XTF_TRY_LOAD,
+ cs->options & OPT_NUMERIC, &cs->matches);
+}
diff --git a/xshared.h b/xshared.h
index 06d73ab..d0cb516 100644
--- a/xshared.h
+++ b/xshared.h
@@ -45,7 +45,6 @@ enum {
extern void print_extension_helps(const struct xtables_target *,
const struct xtables_rule_match *);
extern const char *proto_to_name(uint8_t, int);
-extern struct xtables_match *find_proto(const char *, enum xtables_tryload,
- int, struct xtables_rule_match **);
+extern struct xtables_match *load_proto(struct iptables_command_state *);
#endif /* IPTABLES_XSHARED_H */
--
1.7.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 08/11] src: unclutter command_default function
2011-02-09 1:48 iptables: clean up main command loop Jan Engelhardt
` (6 preceding siblings ...)
2011-02-09 1:48 ` [PATCH 07/11] src: deduplicate and simplify implicit protocol extension loading Jan Engelhardt
@ 2011-02-09 1:48 ` Jan Engelhardt
2011-02-09 1:48 ` [PATCH 09/11] src: move jump option handling from do_command6 into its own function Jan Engelhardt
` (3 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Jan Engelhardt @ 2011-02-09 1:48 UTC (permalink / raw)
To: kaber; +Cc: netfilter-devel
(Essentially, 5 levels of indentation have been stripped compared to the
original layout, and this is surely a result that looks a lot better
than it did before.)
Things to note:
1. If the m->parse call succeeded, we can return from the function and
do not need to go through the other code. As such, "m" is guaranteed to
be useless at the end of the match loop, and so, conditions can be
removed.
2. Since the per-extension parse function only ever get their own option
codes (since v1.4.10-26-gd09b6d5), their return value no longer has a
meaning and can be ignored.
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
ip6tables.c | 100 +++++++++++++++++++++---------------------------
iptables.c | 121 ++++++++++++++++++++++++++---------------------------------
2 files changed, 97 insertions(+), 124 deletions(-)
diff --git a/ip6tables.c b/ip6tables.c
index 3330420..c475bf2 100644
--- a/ip6tables.c
+++ b/ip6tables.c
@@ -1247,71 +1247,59 @@ static void command_default(struct iptables_command_state *cs)
if (cs->target == NULL || cs->target->parse == NULL ||
cs->c < cs->target->option_offset ||
- cs->c >= cs->target->option_offset + XT_OPTION_OFFSET_SCALE ||
- !cs->target->parse(cs->c - cs->target->option_offset,
- cs->argv, cs->invert,
- &cs->target->tflags,
- &cs->fw6, &cs->target->t)) {
- for (matchp = cs->matches; matchp; matchp = matchp->next) {
- if (matchp->completed ||
- matchp->match->parse == NULL)
- continue;
- if (cs->c < matchp->match->option_offset ||
- cs->c >= matchp->match->option_offset + XT_OPTION_OFFSET_SCALE)
- continue;
- if (matchp->match->parse(cs->c - matchp->match->option_offset,
- cs->argv, cs->invert,
- &matchp->match->mflags,
- &cs->fw6,
- &matchp->match->m))
- break;
- }
- m = matchp ? matchp->match : NULL;
+ cs->c >= cs->target->option_offset + XT_OPTION_OFFSET_SCALE) {
+ cs->target->parse(cs->c - cs->target->option_offset, cs->argv,
+ cs->invert, &cs->target->tflags, &cs->fw6,
+ &cs->target->t);
+ return;
+ }
- if (m == NULL && (m = load_proto(cs)) != NULL) {
- /* Try loading protocol */
- size_t size;
+ for (matchp = cs->matches; matchp; matchp = matchp->next) {
+ m = matchp->match;
- cs->proto_used = 1;
+ if (matchp->completed || m->parse == NULL)
+ continue;
+ if (cs->c < matchp->match->option_offset ||
+ cs->c >= matchp->match->option_offset + XT_OPTION_OFFSET_SCALE)
+ continue;
+ m->parse(cs->c - m->option_offset, cs->argv, cs->invert,
+ &m->mflags, &cs->fw6, &m->m);
+ return;
+ }
- size = IP6T_ALIGN(sizeof(struct ip6t_entry_match))
- + m->size;
+ /* Try loading protocol */
+ m = load_proto(cs);
+ if (m != NULL) {
+ size_t size;
- m->m = xtables_calloc(1, size);
- m->m->u.match_size = size;
- strcpy(m->m->u.user.name, m->name);
- m->m->u.user.revision = m->revision;
- if (m->init != NULL)
- m->init(m->m);
+ cs->proto_used = 1;
- opts = xtables_merge_options(ip6tables_globals.orig_opts, opts,
- m->extra_opts, &m->option_offset);
+ size = IP6T_ALIGN(sizeof(struct ip6t_entry_match)) + m->size;
- optind--;
- return;
- }
+ m->m = xtables_calloc(1, size);
+ m->m->u.match_size = size;
+ strcpy(m->m->u.user.name, m->name);
+ m->m->u.user.revision = m->revision;
+ if (m->init != NULL)
+ m->init(m->m);
- if (!m) {
- if (cs->c == '?') {
- if (optopt) {
- xtables_error(
- PARAMETER_PROBLEM,
- "option `%s' "
- "requires an "
- "argument",
- cs->argv[optind-1]);
- } else {
- xtables_error(
- PARAMETER_PROBLEM,
- "unknown option "
- "`%s'",
- cs->argv[optind-1]);
- }
- }
+ opts = xtables_merge_options(ip6tables_globals.orig_opts, opts,
+ m->extra_opts, &m->option_offset);
+
+ optind--;
+ return;
+ }
+
+ if (cs->c == '?') {
+ if (optopt)
xtables_error(PARAMETER_PROBLEM,
- "Unknown arg `%s'", optarg);
- }
+ "option \"%s\" requires an argument",
+ cs->argv[optind-1]);
+ else
+ xtables_error(PARAMETER_PROBLEM,
+ "unknown option \"%s\"", cs->argv[optind-1]);
}
+ xtables_error(PARAMETER_PROBLEM, "Unknown arg \"%s\"", optarg);
}
int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **handle)
diff --git a/iptables.c b/iptables.c
index bae14af..96732b4 100644
--- a/iptables.c
+++ b/iptables.c
@@ -1271,76 +1271,61 @@ static void command_default(struct iptables_command_state *cs)
if (cs->target == NULL || cs->target->parse == NULL ||
cs->c < cs->target->option_offset ||
- cs->c >= cs->target->option_offset + XT_OPTION_OFFSET_SCALE ||
- !cs->target->parse(cs->c - cs->target->option_offset,
- cs->argv, cs->invert,
- &cs->target->tflags,
- &cs->fw, &cs->target->t)) {
- for (matchp = cs->matches; matchp; matchp = matchp->next) {
- if (matchp->completed ||
- matchp->match->parse == NULL)
- continue;
- if (cs->c < matchp->match->option_offset ||
- cs->c >= matchp->match->option_offset + XT_OPTION_OFFSET_SCALE)
- continue;
- if (matchp->match->parse(cs->c - matchp->match->option_offset,
- cs->argv, cs->invert,
- &matchp->match->mflags,
- &cs->fw,
- &matchp->match->m))
- break;
- }
- m = matchp ? matchp->match : NULL;
+ cs->c >= cs->target->option_offset + XT_OPTION_OFFSET_SCALE) {
+ cs->target->parse(cs->c - cs->target->option_offset, cs->argv,
+ cs->invert, &cs->target->tflags, &cs->fw,
+ &cs->target->t);
+ return;
+ }
- if (m == NULL && (m = load_proto(cs)) != NULL) {
- /* Try loading protocol */
- size_t size;
+ for (matchp = cs->matches; matchp; matchp = matchp->next) {
+ m = matchp->match;
- cs->proto_used = 1;
+ if (matchp->completed || m->parse == NULL)
+ continue;
+ if (cs->c < m->option_offset ||
+ cs->c >= m->option_offset + XT_OPTION_OFFSET_SCALE)
+ continue;
+ m->parse(cs->c - m->option_offset, cs->argv, cs->invert,
+ &m->mflags, &cs->fw, &m->m);
+ return;
+ }
- size = IPT_ALIGN(sizeof(struct ipt_entry_match))
- + m->size;
+ /* Try loading protocol */
+ m = load_proto(cs);
+ if (m != NULL) {
+ size_t size;
- m->m = xtables_calloc(1, size);
- m->m->u.match_size = size;
- strcpy(m->m->u.user.name, m->name);
- m->m->u.user.revision = m->revision;
- if (m->init != NULL)
- m->init(m->m);
+ cs->proto_used = 1;
- opts = xtables_merge_options(
- iptables_globals.orig_opts,
- opts,
- m->extra_opts,
- &m->option_offset);
- if (opts == NULL)
- xtables_error(OTHER_PROBLEM,
- "can't alloc memory!");
+ size = IPT_ALIGN(sizeof(struct ipt_entry_match)) + m->size;
- optind--;
- return;
- }
- if (!m) {
- if (cs->c == '?') {
- if (optopt) {
- xtables_error(
- PARAMETER_PROBLEM,
- "option `%s' "
- "requires an "
- "argument",
- cs->argv[optind-1]);
- } else {
- xtables_error(
- PARAMETER_PROBLEM,
- "unknown option "
- "`%s'",
- cs->argv[optind-1]);
- }
- }
+ m->m = xtables_calloc(1, size);
+ m->m->u.match_size = size;
+ strcpy(m->m->u.user.name, m->name);
+ m->m->u.user.revision = m->revision;
+ if (m->init != NULL)
+ m->init(m->m);
+
+ opts = xtables_merge_options(iptables_globals.orig_opts, opts,
+ m->extra_opts, &m->option_offset);
+ if (opts == NULL)
+ xtables_error(OTHER_PROBLEM, "can't alloc memory!");
+
+ optind--;
+ return;
+ }
+
+ if (cs->c == '?') {
+ if (optopt)
xtables_error(PARAMETER_PROBLEM,
- "Unknown arg `%s'", optarg);
- }
+ "option \"%s\" requires an argument",
+ cs->argv[optind-1]);
+ else
+ xtables_error(PARAMETER_PROBLEM,
+ "unknown option \"%s\"", cs->argv[optind-1]);
}
+ xtables_error(PARAMETER_PROBLEM, "Unknown arg \"%s\"", optarg);
}
int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle)
--
1.7.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 09/11] src: move jump option handling from do_command6 into its own function
2011-02-09 1:48 iptables: clean up main command loop Jan Engelhardt
` (7 preceding siblings ...)
2011-02-09 1:48 ` [PATCH 08/11] src: unclutter command_default function Jan Engelhardt
@ 2011-02-09 1:48 ` Jan Engelhardt
2011-02-09 1:48 ` [PATCH 10/11] src: move match option handling from do_command6 into its own functions Jan Engelhardt
` (2 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Jan Engelhardt @ 2011-02-09 1:48 UTC (permalink / raw)
To: kaber; +Cc: netfilter-devel
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
ip6tables.c | 72 ++++++++++++++++++++++++++++-------------------------
iptables.c | 79 ++++++++++++++++++++++++++++++----------------------------
xshared.h | 1 +
3 files changed, 80 insertions(+), 72 deletions(-)
diff --git a/ip6tables.c b/ip6tables.c
index c475bf2..eb28dc0 100644
--- a/ip6tables.c
+++ b/ip6tables.c
@@ -1302,6 +1302,33 @@ static void command_default(struct iptables_command_state *cs)
xtables_error(PARAMETER_PROBLEM, "Unknown arg \"%s\"", optarg);
}
+static void command_jump(struct iptables_command_state *cs)
+{
+ size_t size;
+
+ set_option(&cs->options, OPT_JUMP, &cs->fw6.ipv6.invflags, cs->invert);
+ cs->jumpto = parse_target(optarg);
+ /* TRY_LOAD (may be chain name) */
+ cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
+
+ if (cs->target == NULL)
+ return;
+
+ size = IP6T_ALIGN(sizeof(struct ip6t_entry_target)) + cs->target->size;
+
+ cs->target->t = xtables_calloc(1, size);
+ cs->target->t->u.target_size = size;
+ strcpy(cs->target->t->u.user.name, cs->jumpto);
+ cs->target->t->u.user.revision = cs->target->revision;
+ if (cs->target->init != NULL)
+ cs->target->init(cs->target->t);
+ opts = xtables_merge_options(ip6tables_globals.orig_opts, opts,
+ cs->target->extra_opts,
+ &cs->target->option_offset);
+ if (opts == NULL)
+ xtables_error(OTHER_PROBLEM, "can't alloc memory!");
+}
+
int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **handle)
{
struct iptables_command_state cs;
@@ -1320,10 +1347,10 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
struct xtables_match *m;
struct xtables_rule_match *matchp;
struct xtables_target *t;
- const char *jumpto = "";
unsigned long long cnt;
memset(&cs, 0, sizeof(cs));
+ cs.jumpto = "";
cs.argv = argv;
/* re-set optind to 0 in case do_command gets called
@@ -1548,36 +1575,12 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
set_option(&cs.options, OPT_JUMP, &cs.fw6.ipv6.invflags,
cs.invert);
cs.fw6.ipv6.flags |= IP6T_F_GOTO;
- jumpto = parse_target(optarg);
+ cs.jumpto = parse_target(optarg);
break;
#endif
case 'j':
- set_option(&cs.options, OPT_JUMP, &cs.fw6.ipv6.invflags,
- cs.invert);
- jumpto = parse_target(optarg);
- /* TRY_LOAD (may be chain name) */
- cs.target = xtables_find_target(jumpto, XTF_TRY_LOAD);
-
- if (cs.target) {
- size_t size;
-
- size = IP6T_ALIGN(sizeof(struct ip6t_entry_target))
- + cs.target->size;
-
- cs.target->t = xtables_calloc(1, size);
- cs.target->t->u.target_size = size;
- strcpy(cs.target->t->u.user.name, jumpto);
- cs.target->t->u.user.revision = cs.target->revision;
- if (cs.target->init != NULL)
- cs.target->init(cs.target->t);
- opts = xtables_merge_options(ip6tables_globals.orig_opts, opts,
- cs.target->extra_opts,
- &cs.target->option_offset);
- if (opts == NULL)
- xtables_error(OTHER_PROBLEM,
- "can't alloc memory!");
- }
+ command_jump(&cs);
break;
@@ -1806,10 +1809,10 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
chain);
}
- if (cs.target && ip6tc_is_chain(jumpto, *handle)) {
+ if (cs.target && ip6tc_is_chain(cs.jumpto, *handle)) {
fprintf(stderr,
"Warning: using chain %s, not extension\n",
- jumpto);
+ cs.jumpto);
if (cs.target->t)
free(cs.target->t);
@@ -1820,8 +1823,8 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
/* If they didn't specify a target, or it's a chain
name, use standard. */
if (!cs.target
- && (strlen(jumpto) == 0
- || ip6tc_is_chain(jumpto, *handle))) {
+ && (strlen(cs.jumpto) == 0
+ || ip6tc_is_chain(cs.jumpto, *handle))) {
size_t size;
cs.target = xtables_find_target(IP6T_STANDARD_TARGET,
@@ -1831,7 +1834,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
+ cs.target->size;
cs.target->t = xtables_calloc(1, size);
cs.target->t->u.target_size = size;
- strcpy(cs.target->t->u.user.name, jumpto);
+ strcpy(cs.target->t->u.user.name, cs.jumpto);
if (cs.target->init != NULL)
cs.target->init(cs.target->t);
}
@@ -1844,9 +1847,10 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
#ifdef IP6T_F_GOTO
if (cs.fw6.ipv6.flags & IP6T_F_GOTO)
xtables_error(PARAMETER_PROBLEM,
- "goto '%s' is not a chain\n", jumpto);
+ "goto '%s' is not a chain\n",
+ cs.jumpto);
#endif
- xtables_find_target(jumpto, XTF_LOAD_MUST_SUCCEED);
+ xtables_find_target(cs.jumpto, XTF_LOAD_MUST_SUCCEED);
} else {
e = generate_entry(&cs.fw6, cs.matches, cs.target->t);
free(cs.target->t);
diff --git a/iptables.c b/iptables.c
index 96732b4..354bc9c 100644
--- a/iptables.c
+++ b/iptables.c
@@ -1328,6 +1328,34 @@ static void command_default(struct iptables_command_state *cs)
xtables_error(PARAMETER_PROBLEM, "Unknown arg \"%s\"", optarg);
}
+static void command_jump(struct iptables_command_state *cs)
+{
+ size_t size;
+
+ set_option(&cs->options, OPT_JUMP, &cs->fw.ip.invflags, cs->invert);
+ cs->jumpto = parse_target(optarg);
+ /* TRY_LOAD (may be chain name) */
+ cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
+
+ if (cs->target == NULL)
+ return;
+
+ size = IPT_ALIGN(sizeof(struct ipt_entry_target))
+ + cs->target->size;
+
+ cs->target->t = xtables_calloc(1, size);
+ cs->target->t->u.target_size = size;
+ strcpy(cs->target->t->u.user.name, cs->jumpto);
+ cs->target->t->u.user.revision = cs->target->revision;
+ if (cs->target->init != NULL)
+ cs->target->init(cs->target->t);
+ opts = xtables_merge_options(iptables_globals.orig_opts, opts,
+ cs->target->extra_opts,
+ &cs->target->option_offset);
+ if (opts == NULL)
+ xtables_error(OTHER_PROBLEM, "can't alloc memory!");
+}
+
int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle)
{
struct iptables_command_state cs;
@@ -1346,10 +1374,10 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
struct xtables_match *m;
struct xtables_rule_match *matchp;
struct xtables_target *t;
- const char *jumpto = "";
unsigned long long cnt;
memset(&cs, 0, sizeof(cs));
+ cs.jumpto = "";
cs.argv = argv;
/* re-set optind to 0 in case do_command gets called
@@ -1566,38 +1594,12 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
set_option(&cs.options, OPT_JUMP, &cs.fw.ip.invflags,
cs.invert);
cs.fw.ip.flags |= IPT_F_GOTO;
- jumpto = parse_target(optarg);
+ cs.jumpto = parse_target(optarg);
break;
#endif
case 'j':
- set_option(&cs.options, OPT_JUMP, &cs.fw.ip.invflags,
- cs.invert);
- jumpto = parse_target(optarg);
- /* TRY_LOAD (may be chain name) */
- cs.target = xtables_find_target(jumpto, XTF_TRY_LOAD);
-
- if (cs.target) {
- size_t size;
-
- size = IPT_ALIGN(sizeof(struct ipt_entry_target))
- + cs.target->size;
-
- cs.target->t = xtables_calloc(1, size);
- cs.target->t->u.target_size = size;
- strcpy(cs.target->t->u.user.name, jumpto);
- cs.target->t->u.user.revision = cs.target->revision;
- if (cs.target->init != NULL)
- cs.target->init(cs.target->t);
- opts = xtables_merge_options(
- iptables_globals.orig_opts,
- opts,
- cs.target->extra_opts,
- &cs.target->option_offset);
- if (opts == NULL)
- xtables_error(OTHER_PROBLEM,
- "can't alloc memory!");
- }
+ command_jump(&cs);
break;
@@ -1757,7 +1759,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
if (strcmp(*table, "nat") == 0 &&
((policy != NULL && strcmp(policy, "DROP") == 0) ||
- (jumpto != NULL && strcmp(jumpto, "DROP") == 0)))
+ (cs.jumpto != NULL && strcmp(cs.jumpto, "DROP") == 0)))
xtables_error(PARAMETER_PROBLEM,
"\nThe \"nat\" table is not intended for filtering, "
"the use of DROP is therefore inhibited.\n\n");
@@ -1848,10 +1850,10 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
chain);
}
- if (cs.target && iptc_is_chain(jumpto, *handle)) {
+ if (cs.target && iptc_is_chain(cs.jumpto, *handle)) {
fprintf(stderr,
"Warning: using chain %s, not extension\n",
- jumpto);
+ cs.jumpto);
if (cs.target->t)
free(cs.target->t);
@@ -1862,8 +1864,8 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
/* If they didn't specify a target, or it's a chain
name, use standard. */
if (!cs.target
- && (strlen(jumpto) == 0
- || iptc_is_chain(jumpto, *handle))) {
+ && (strlen(cs.jumpto) == 0
+ || iptc_is_chain(cs.jumpto, *handle))) {
size_t size;
cs.target = xtables_find_target(IPT_STANDARD_TARGET,
@@ -1873,8 +1875,8 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
+ cs.target->size;
cs.target->t = xtables_calloc(1, size);
cs.target->t->u.target_size = size;
- strcpy(cs.target->t->u.user.name, jumpto);
- if (!iptc_is_chain(jumpto, *handle))
+ strcpy(cs.target->t->u.user.name, cs.jumpto);
+ if (!iptc_is_chain(cs.jumpto, *handle))
cs.target->t->u.user.revision = cs.target->revision;
if (cs.target->init != NULL)
cs.target->init(cs.target->t);
@@ -1888,9 +1890,10 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
#ifdef IPT_F_GOTO
if (cs.fw.ip.flags & IPT_F_GOTO)
xtables_error(PARAMETER_PROBLEM,
- "goto '%s' is not a chain\n", jumpto);
+ "goto '%s' is not a chain\n",
+ cs.jumpto);
#endif
- xtables_find_target(jumpto, XTF_LOAD_MUST_SUCCEED);
+ xtables_find_target(cs.jumpto, XTF_LOAD_MUST_SUCCEED);
} else {
e = generate_entry(&cs.fw, cs.matches, cs.target->t);
free(cs.target->t);
diff --git a/xshared.h b/xshared.h
index d0cb516..a08e6d9 100644
--- a/xshared.h
+++ b/xshared.h
@@ -35,6 +35,7 @@ struct iptables_command_state {
struct xtables_target *target;
char *protocol;
int proto_used;
+ const char *jumpto;
char **argv;
};
--
1.7.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 10/11] src: move match option handling from do_command6 into its own functions
2011-02-09 1:48 iptables: clean up main command loop Jan Engelhardt
` (8 preceding siblings ...)
2011-02-09 1:48 ` [PATCH 09/11] src: move jump option handling from do_command6 into its own function Jan Engelhardt
@ 2011-02-09 1:48 ` Jan Engelhardt
2011-02-09 1:48 ` [PATCH 11/11] iptables: fix error message for unknown options Jan Engelhardt
2011-02-09 7:13 ` iptables: clean up main command loop Patrick McHardy
11 siblings, 0 replies; 13+ messages in thread
From: Jan Engelhardt @ 2011-02-09 1:48 UTC (permalink / raw)
To: kaber; +Cc: netfilter-devel
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
ip6tables.c | 48 ++++++++++++++++++++++++++----------------------
iptables.c | 59 +++++++++++++++++++++++++++++------------------------------
2 files changed, 55 insertions(+), 52 deletions(-)
diff --git a/ip6tables.c b/ip6tables.c
index eb28dc0..5a550bf 100644
--- a/ip6tables.c
+++ b/ip6tables.c
@@ -1329,6 +1329,29 @@ static void command_jump(struct iptables_command_state *cs)
xtables_error(OTHER_PROBLEM, "can't alloc memory!");
}
+static void command_match(struct iptables_command_state *cs)
+{
+ struct xtables_match *m;
+ size_t size;
+
+ if (cs->invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "unexpected ! flag before --match");
+
+ m = xtables_find_match(optarg, XTF_LOAD_MUST_SUCCEED, &cs->matches);
+ size = IP6T_ALIGN(sizeof(struct ip6t_entry_match)) + m->size;
+ m->m = xtables_calloc(1, size);
+ m->m->u.match_size = size;
+ strcpy(m->m->u.user.name, m->name);
+ m->m->u.user.revision = m->revision;
+ if (m->init != NULL)
+ m->init(m->m);
+ if (m != m->next)
+ /* Merge options for non-cloned matches */
+ opts = xtables_merge_options(ip6tables_globals.orig_opts, opts,
+ m->extra_opts, &m->option_offset);
+}
+
int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **handle)
{
struct iptables_command_state cs;
@@ -1617,28 +1640,9 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
verbose++;
break;
- case 'm': {
- size_t size;
-
- if (cs.invert)
- xtables_error(PARAMETER_PROBLEM,
- "unexpected ! flag before --match");
-
- m = xtables_find_match(optarg, XTF_LOAD_MUST_SUCCEED,
- &cs.matches);
- size = IP6T_ALIGN(sizeof(struct ip6t_entry_match))
- + m->size;
- m->m = xtables_calloc(1, size);
- m->m->u.match_size = size;
- strcpy(m->m->u.user.name, m->name);
- m->m->u.user.revision = m->revision;
- if (m->init != NULL)
- m->init(m->m);
- if (m != m->next)
- /* Merge options for non-cloned matches */
- opts = xtables_merge_options(ip6tables_globals.orig_opts, opts, m->extra_opts, &m->option_offset);
- }
- break;
+ case 'm':
+ command_match(&cs);
+ break;
case 'n':
set_option(&cs.options, OPT_NUMERIC, &cs.fw6.ipv6.invflags,
diff --git a/iptables.c b/iptables.c
index 354bc9c..6f5616b 100644
--- a/iptables.c
+++ b/iptables.c
@@ -1356,6 +1356,32 @@ static void command_jump(struct iptables_command_state *cs)
xtables_error(OTHER_PROBLEM, "can't alloc memory!");
}
+static void command_match(struct iptables_command_state *cs)
+{
+ struct xtables_match *m;
+ size_t size;
+
+ if (cs->invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "unexpected ! flag before --match");
+
+ m = xtables_find_match(optarg, XTF_LOAD_MUST_SUCCEED, &cs->matches);
+ size = IPT_ALIGN(sizeof(struct ipt_entry_match)) + m->size;
+ m->m = xtables_calloc(1, size);
+ m->m->u.match_size = size;
+ strcpy(m->m->u.user.name, m->name);
+ m->m->u.user.revision = m->revision;
+ if (m->init != NULL)
+ m->init(m->m);
+ if (m != m->next) {
+ /* Merge options for non-cloned matches */
+ opts = xtables_merge_options(iptables_globals.orig_opts, opts,
+ m->extra_opts, &m->option_offset);
+ if (opts == NULL)
+ xtables_error(OTHER_PROBLEM, "can't alloc memory!");
+ }
+}
+
int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle)
{
struct iptables_command_state cs;
@@ -1642,36 +1668,9 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
verbose++;
break;
- case 'm': {
- size_t size;
-
- if (cs.invert)
- xtables_error(PARAMETER_PROBLEM,
- "unexpected ! flag before --match");
-
- m = xtables_find_match(optarg, XTF_LOAD_MUST_SUCCEED,
- &cs.matches);
- size = IPT_ALIGN(sizeof(struct ipt_entry_match))
- + m->size;
- m->m = xtables_calloc(1, size);
- m->m->u.match_size = size;
- strcpy(m->m->u.user.name, m->name);
- m->m->u.user.revision = m->revision;
- if (m->init != NULL)
- m->init(m->m);
- if (m != m->next) {
- /* Merge options for non-cloned matches */
- opts = xtables_merge_options(
- iptables_globals.orig_opts,
- opts,
- m->extra_opts,
- &m->option_offset);
- if (opts == NULL)
- xtables_error(OTHER_PROBLEM,
- "can't alloc memory!");
- }
- }
- break;
+ case 'm':
+ command_match(&cs);
+ break;
case 'n':
set_option(&cs.options, OPT_NUMERIC, &cs.fw.ip.invflags,
--
1.7.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 11/11] iptables: fix error message for unknown options
2011-02-09 1:48 iptables: clean up main command loop Jan Engelhardt
` (9 preceding siblings ...)
2011-02-09 1:48 ` [PATCH 10/11] src: move match option handling from do_command6 into its own functions Jan Engelhardt
@ 2011-02-09 1:48 ` Jan Engelhardt
2011-02-09 7:13 ` iptables: clean up main command loop Patrick McHardy
11 siblings, 0 replies; 13+ messages in thread
From: Jan Engelhardt @ 2011-02-09 1:48 UTC (permalink / raw)
To: kaber; +Cc: netfilter-devel
-From: iptables v1.4.10: option "-q" requires an argument
+To: iptables v1.4.10: unknown option "-q"
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
ip6tables.c | 17 +++++++----------
iptables.c | 17 +++++++----------
2 files changed, 14 insertions(+), 20 deletions(-)
diff --git a/ip6tables.c b/ip6tables.c
index 5a550bf..5561a7d 100644
--- a/ip6tables.c
+++ b/ip6tables.c
@@ -1290,15 +1290,12 @@ static void command_default(struct iptables_command_state *cs)
return;
}
- if (cs->c == '?') {
- if (optopt)
- xtables_error(PARAMETER_PROBLEM,
- "option \"%s\" requires an argument",
- cs->argv[optind-1]);
- else
- xtables_error(PARAMETER_PROBLEM,
- "unknown option \"%s\"", cs->argv[optind-1]);
- }
+ if (cs->c == ':')
+ xtables_error(PARAMETER_PROBLEM, "option \"%s\" "
+ "requires an argument", cs->argv[optind-1]);
+ if (cs->c == '?')
+ xtables_error(PARAMETER_PROBLEM, "unknown option "
+ "\"%s\"", cs->argv[optind-1]);
xtables_error(PARAMETER_PROBLEM, "Unknown arg \"%s\"", optarg);
}
@@ -1396,7 +1393,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
opts = xt_params->orig_opts;
while ((cs.c = getopt_long(argc, argv,
- "-A:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:bvnt:m:xc:g:",
+ "-:A:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:bvnt:m:xc:g:",
opts, NULL)) != -1) {
switch (cs.c) {
/*
diff --git a/iptables.c b/iptables.c
index 6f5616b..33fd882 100644
--- a/iptables.c
+++ b/iptables.c
@@ -1316,15 +1316,12 @@ static void command_default(struct iptables_command_state *cs)
return;
}
- if (cs->c == '?') {
- if (optopt)
- xtables_error(PARAMETER_PROBLEM,
- "option \"%s\" requires an argument",
- cs->argv[optind-1]);
- else
- xtables_error(PARAMETER_PROBLEM,
- "unknown option \"%s\"", cs->argv[optind-1]);
- }
+ if (cs->c == ':')
+ xtables_error(PARAMETER_PROBLEM, "option \"%s\" "
+ "requires an argument", cs->argv[optind-1]);
+ if (cs->c == '?')
+ xtables_error(PARAMETER_PROBLEM, "unknown option "
+ "\"%s\"", cs->argv[optind-1]);
xtables_error(PARAMETER_PROBLEM, "Unknown arg \"%s\"", optarg);
}
@@ -1426,7 +1423,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
opts = xt_params->orig_opts;
while ((cs.c = getopt_long(argc, argv,
- "-A:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvnt:m:xc:g:",
+ "-:A:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvnt:m:xc:g:",
opts, NULL)) != -1) {
switch (cs.c) {
/*
--
1.7.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: iptables: clean up main command loop
2011-02-09 1:48 iptables: clean up main command loop Jan Engelhardt
` (10 preceding siblings ...)
2011-02-09 1:48 ` [PATCH 11/11] iptables: fix error message for unknown options Jan Engelhardt
@ 2011-02-09 7:13 ` Patrick McHardy
11 siblings, 0 replies; 13+ messages in thread
From: Patrick McHardy @ 2011-02-09 7:13 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: netfilter-devel
Am 09.02.2011 02:48, schrieb Jan Engelhardt:
> This is a respin of the earlier patch. Now the cases for -j and -m
> are also in their own functions, and the shared code has
> moved to xshared.c.
>
>
> The following changes since commit e76ec99b48745b0e3c8aecbc91ed5bba186cf25f:
>
> libxt_cluster: fix inversion in the cluster match (2011-02-06 21:34:33 +0100)
>
> are available in the git repository at:
> git://dev.medozas.de/iptables master
>
> Jan Engelhardt (11):
> src: collect do_command variables in a struct
> src: move large default: block from do_command6 into its own function
> src: share iptables_command_state across the two programs
> src: deduplicate find_proto function
> src: move OPT_FRAGMENT to the end so the list can be shared
> src: put shared option flags into xshared
> src: deduplicate and simplify implicit protocol extension loading
> src: unclutter command_default function
> src: move jump option handling from do_command6 into its own function
> src: move match option handling from do_command6 into its own functions
> iptables: fix error message for unknown options
>
Pulled, thanks Jan!
^ permalink raw reply [flat|nested] 13+ messages in thread