summaryrefslogtreecommitdiffstats
path: root/iptables/xtables.c
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2021-09-27 16:59:49 +0200
committerPhil Sutter <phil@nwl.cc>2021-10-20 11:32:54 +0200
commit0af80a91b0a98891d3cbc891a7377281b4080035 (patch)
tree75bb9416ae047dc947fd0dd35f850bc55f7b73f9 /iptables/xtables.c
parent142cf72442760ae8fc377bbfb54a913baf84742e (diff)
nft: Merge xtables-arp-standalone.c into xtables-standalone.c
By declaring the relevant family_ops callbacks for arptables, the code becomes ready to just use do_commandx() instead of a dedicated parser. As a side-effect, this enables a bunch of new features in arptables-nft: * Support '-C' command * Support '-S' command * Support rule indexes just like xtables, e.g. in '-I' or '-R' commands * Reject chain names starting with '!' * Support '-c N,M' counter syntax Since arptables still accepts intrapositioned negations, add code to cover that but print a warning like iptables did 12 years ago prior to removing the functionality. Signed-off-by: Phil Sutter <phil@nwl.cc>
Diffstat (limited to 'iptables/xtables.c')
-rw-r--r--iptables/xtables.c98
1 files changed, 89 insertions, 9 deletions
diff --git a/iptables/xtables.c b/iptables/xtables.c
index 075506f0..5c69af7e 100644
--- a/iptables/xtables.c
+++ b/iptables/xtables.c
@@ -36,11 +36,13 @@
#include <stdarg.h>
#include <limits.h>
#include <unistd.h>
+#include <netinet/ether.h>
#include <iptables.h>
#include <xtables.h>
#include <fcntl.h>
#include "xshared.h"
#include "nft-shared.h"
+#include "nft-arp.h"
#include "nft.h"
static struct option original_opts[] = {
@@ -273,6 +275,34 @@ static void check_empty_interface(struct nft_handle *h, const char *arg)
fprintf(stderr, "%s", msg);
}
+static void check_inverse(struct nft_handle *h, const char option[],
+ bool *invert, int *optidx, int argc)
+{
+ switch (h->family) {
+ case NFPROTO_ARP:
+ break;
+ default:
+ return;
+ }
+
+ if (!option || strcmp(option, "!"))
+ return;
+
+ fprintf(stderr, "Using intrapositioned negation (`--option ! this`) "
+ "is deprecated in favor of extrapositioned (`! --option this`).\n");
+
+ if (*invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "Multiple `!' flags not allowed");
+ *invert = true;
+ if (optidx) {
+ *optidx = *optidx + 1;
+ if (argc && *optidx > argc)
+ xtables_error(PARAMETER_PROBLEM,
+ "no argument following `!'");
+ }
+}
+
void do_parse(struct nft_handle *h, int argc, char *argv[],
struct nft_xt_cmd_parse *p, struct iptables_command_state *cs,
struct xtables_args *args)
@@ -458,14 +488,16 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
* Option selection
*/
case 'p':
+ check_inverse(h, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_PROTOCOL,
&args->invflags, invert);
/* Canonicalize into lower case */
- for (cs->protocol = optarg; *cs->protocol; cs->protocol++)
+ for (cs->protocol = argv[optind - 1];
+ *cs->protocol; cs->protocol++)
*cs->protocol = tolower(*cs->protocol);
- cs->protocol = optarg;
+ cs->protocol = argv[optind - 1];
args->proto = xtables_parse_protocol(cs->protocol);
if (args->proto == 0 &&
@@ -474,19 +506,22 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
"rule would never match protocol");
/* This needs to happen here to parse extensions */
- h->ops->proto_parse(cs, args);
+ if (h->ops->proto_parse)
+ h->ops->proto_parse(cs, args);
break;
case 's':
+ check_inverse(h, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_SOURCE,
&args->invflags, invert);
- args->shostnetworkmask = optarg;
+ args->shostnetworkmask = argv[optind - 1];
break;
case 'd':
+ check_inverse(h, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_DESTINATION,
&args->invflags, invert);
- args->dhostnetworkmask = optarg;
+ args->dhostnetworkmask = argv[optind - 1];
break;
#ifdef IPT_F_GOTO
@@ -498,27 +533,72 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
break;
#endif
+ case 2:/* src-mac */
+ check_inverse(h, optarg, &invert, &optind, argc);
+ set_option(&cs->options, OPT_S_MAC, &args->invflags,
+ invert);
+ args->src_mac = argv[optind - 1];
+ break;
+
+ case 3:/* dst-mac */
+ check_inverse(h, optarg, &invert, &optind, argc);
+ set_option(&cs->options, OPT_D_MAC, &args->invflags,
+ invert);
+ args->dst_mac = argv[optind - 1];
+ break;
+
+ case 'l':/* hardware length */
+ check_inverse(h, optarg, &invert, &optind, argc);
+ set_option(&cs->options, OPT_H_LENGTH, &args->invflags,
+ invert);
+ args->arp_hlen = argv[optind - 1];
+ break;
+
+ case 8: /* was never supported, not even in arptables-legacy */
+ xtables_error(PARAMETER_PROBLEM, "not supported");
+ case 4:/* opcode */
+ check_inverse(h, optarg, &invert, &optind, argc);
+ set_option(&cs->options, OPT_OPCODE, &args->invflags,
+ invert);
+ args->arp_opcode = argv[optind - 1];
+ break;
+
+ case 5:/* h-type */
+ check_inverse(h, optarg, &invert, &optind, argc);
+ set_option(&cs->options, OPT_H_TYPE, &args->invflags,
+ invert);
+ args->arp_htype = argv[optind - 1];
+ break;
+
+ case 6:/* proto-type */
+ check_inverse(h, optarg, &invert, &optind, argc);
+ set_option(&cs->options, OPT_P_TYPE, &args->invflags,
+ invert);
+ args->arp_ptype = argv[optind - 1];
+ break;
+
case 'j':
set_option(&cs->options, OPT_JUMP, &args->invflags,
invert);
- command_jump(cs, optarg);
+ command_jump(cs, argv[optind - 1]);
break;
-
case 'i':
check_empty_interface(h, optarg);
+ check_inverse(h, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_VIANAMEIN,
&args->invflags, invert);
- xtables_parse_interface(optarg,
+ xtables_parse_interface(argv[optind - 1],
args->iniface,
args->iniface_mask);
break;
case 'o':
check_empty_interface(h, optarg);
+ check_inverse(h, optarg, &invert, &optind, argc);
set_option(&cs->options, OPT_VIANAMEOUT,
&args->invflags, invert);
- xtables_parse_interface(optarg,
+ xtables_parse_interface(argv[optind - 1],
args->outiface,
args->outiface_mask);
break;