All of lore.kernel.org
 help / color / mirror / Atom feed
* [iptables PATCH 0/3] Merge some common code
@ 2020-11-16 14:02 Phil Sutter
  2020-11-16 14:02 ` [iptables PATCH 1/3] libxtables: Extend MAC address printing/parsing support Phil Sutter
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Phil Sutter @ 2020-11-16 14:02 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

This is basically fallout from an upcoming larger code merge around
arptables:

Patch 1 extends MAC address parsing capabilities of libxtables so the
various implementations in extensions and xtables code may be dropped.

Patch 2 is a requirement for patch 3 but rather large: It changes the
code to not use arptables-specific inv-flags (ARPT_INV_*) anymore as
they clash badly with iptables-ones (IPT_INV_*).

Patch 3 merges the three copies of 'commands_v_options' table along with
generic_opt_check() routine as well as 'optflags' array and opt2char()
routine. Both are extended to work for arptables as well.

Phil Sutter (3):
  libxtables: Extend MAC address printing/parsing support
  xtables-arp: Don't use ARPT_INV_*
  xshared: Merge some command option-related code

 extensions/libarpt_mangle.c                   | 13 +--
 extensions/libebt_arp.c                       | 50 +---------
 extensions/libebt_stp.c                       | 60 ++----------
 extensions/libxt_mac.c                        | 15 +--
 include/xtables.h                             |  3 +
 iptables/ip6tables.c                          | 79 ----------------
 iptables/iptables.c                           | 80 ----------------
 iptables/nft-arp.c                            | 92 +++++++------------
 iptables/nft-arp.h                            |  7 ++
 iptables/nft-bridge.c                         | 37 +-------
 .../ipt-save/dumps/ipt-save-filter.txt        |  4 +-
 iptables/xshared.c                            | 74 +++++++++++++++
 iptables/xshared.h                            | 20 ++--
 iptables/xtables-arp.c                        | 86 +++--------------
 iptables/xtables-eb-translate.c               |  8 +-
 iptables/xtables-eb.c                         | 59 ++----------
 iptables/xtables.c                            | 80 ----------------
 libxtables/xtables.c                          | 73 +++++++++++++++
 18 files changed, 248 insertions(+), 592 deletions(-)

-- 
2.28.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [iptables PATCH 1/3] libxtables: Extend MAC address printing/parsing support
  2020-11-16 14:02 [iptables PATCH 0/3] Merge some common code Phil Sutter
@ 2020-11-16 14:02 ` Phil Sutter
  2020-11-16 14:02 ` [iptables PATCH 2/3] xtables-arp: Don't use ARPT_INV_* Phil Sutter
  2020-11-16 14:02 ` [iptables PATCH 3/3] xshared: Merge some command option-related code Phil Sutter
  2 siblings, 0 replies; 4+ messages in thread
From: Phil Sutter @ 2020-11-16 14:02 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

Adding a parser which supports common names for special MAC/mask
combinations and a print routine detecting those special addresses and
printing the respective name allows to consolidate all the various
duplicated implementations.

The side-effects of this change are manageable:

* arptables now accepts "BGA" as alias for the bridge group address
* "mac" match now prints MAC addresses in lower-case which is consistent
  with the remaining code at least

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 extensions/libarpt_mangle.c                   | 13 +---
 extensions/libebt_arp.c                       | 50 +------------
 extensions/libebt_stp.c                       | 60 ++-------------
 extensions/libxt_mac.c                        | 15 +---
 include/xtables.h                             |  3 +
 iptables/nft-bridge.c                         | 37 +---------
 .../ipt-save/dumps/ipt-save-filter.txt        |  4 +-
 iptables/xtables-arp.c                        | 50 +------------
 iptables/xtables-eb-translate.c               |  8 +-
 iptables/xtables-eb.c                         | 59 ++-------------
 libxtables/xtables.c                          | 73 +++++++++++++++++++
 11 files changed, 106 insertions(+), 266 deletions(-)

diff --git a/extensions/libarpt_mangle.c b/extensions/libarpt_mangle.c
index 2fea6185ca1b5..a2378a8ba6ccb 100644
--- a/extensions/libarpt_mangle.c
+++ b/extensions/libarpt_mangle.c
@@ -130,15 +130,6 @@ static void arpmangle_final_check(unsigned int flags)
 {
 }
 
-static void print_mac(const unsigned char *mac, int l)
-{
-	int j;
-
-	for (j = 0; j < l; j++)
-		printf("%02x%s", mac[j],
-			(j==l-1) ? "" : ":");
-}
-
 static const char *ipaddr_to(const struct in_addr *addrp, int numeric)
 {
 	if (numeric)
@@ -159,7 +150,7 @@ arpmangle_print(const void *ip, const struct xt_entry_target *target,
 	}
 	if (m->flags & ARPT_MANGLE_SDEV) {
 		printf(" --mangle-mac-s ");
-		print_mac((unsigned char *)m->src_devaddr, 6);
+		xtables_print_mac((unsigned char *)m->src_devaddr);
 	}
 	if (m->flags & ARPT_MANGLE_TIP) {
 		printf(" --mangle-ip-d %s",
@@ -167,7 +158,7 @@ arpmangle_print(const void *ip, const struct xt_entry_target *target,
 	}
 	if (m->flags & ARPT_MANGLE_TDEV) {
 		printf(" --mangle-mac-d ");
-		print_mac((unsigned char *)m->tgt_devaddr, 6);
+		xtables_print_mac((unsigned char *)m->tgt_devaddr);
 	}
 	if (m->target != NF_ACCEPT) {
 		printf(" --mangle-target %s",
diff --git a/extensions/libebt_arp.c b/extensions/libebt_arp.c
index a062b7e7e5864..d5035b956cc15 100644
--- a/extensions/libebt_arp.c
+++ b/extensions/libebt_arp.c
@@ -161,54 +161,6 @@ static void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk)
 	*addr = *addr & *msk;
 }
 
-static int brarp_get_mac_and_mask(const char *from, unsigned char *to, unsigned char *mask)
-{
-	char *p;
-	int i;
-	struct ether_addr *addr = NULL;
-
-	static const unsigned char mac_type_unicast[ETH_ALEN];
-	static const unsigned char msk_type_unicast[ETH_ALEN] =   {1,0,0,0,0,0};
-	static const unsigned char mac_type_multicast[ETH_ALEN] = {1,0,0,0,0,0};
-	static const unsigned char mac_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255};
-	static const unsigned char mac_type_bridge_group[ETH_ALEN] = {0x01,0x80,0xc2,0,0,0};
-	static const unsigned char msk_type_bridge_group[ETH_ALEN] = {255,255,255,255,255,255};
-
-	if (strcasecmp(from, "Unicast") == 0) {
-		memcpy(to, mac_type_unicast, ETH_ALEN);
-		memcpy(mask, msk_type_unicast, ETH_ALEN);
-		return 0;
-	}
-	if (strcasecmp(from, "Multicast") == 0) {
-		memcpy(to, mac_type_multicast, ETH_ALEN);
-		memcpy(mask, mac_type_multicast, ETH_ALEN);
-		return 0;
-	}
-	if (strcasecmp(from, "Broadcast") == 0) {
-		memcpy(to, mac_type_broadcast, ETH_ALEN);
-		memcpy(mask, mac_type_broadcast, ETH_ALEN);
-		return 0;
-	}
-	if (strcasecmp(from, "BGA") == 0) {
-		memcpy(to, mac_type_bridge_group, ETH_ALEN);
-		memcpy(mask, msk_type_bridge_group, ETH_ALEN);
-		return 0;
-	}
-	if ( (p = strrchr(from, '/')) != NULL) {
-		*p = '\0';
-		if (!(addr = ether_aton(p + 1)))
-			return -1;
-		memcpy(mask, addr, ETH_ALEN);
-	} else
-		memset(mask, 0xff, ETH_ALEN);
-	if (!(addr = ether_aton(from)))
-		return -1;
-	memcpy(to, addr, ETH_ALEN);
-	for (i = 0; i < ETH_ALEN; i++)
-		to[i] &= mask[i];
-	return 0;
-}
-
 static int
 brarp_parse(int c, char **argv, int invert, unsigned int *flags,
 	    const void *entry, struct xt_entry_match **match)
@@ -317,7 +269,7 @@ brarp_parse(int c, char **argv, int invert, unsigned int *flags,
 			else
 				arpinfo->invflags |= EBT_ARP_DST_MAC;
 		}
-		if (brarp_get_mac_and_mask(optarg, maddr, mmask))
+		if (xtables_parse_mac_and_mask(optarg, maddr, mmask))
 			xtables_error(PARAMETER_PROBLEM, "Problem with ARP MAC address argument");
 		break;
 	case ARP_GRAT:
diff --git a/extensions/libebt_stp.c b/extensions/libebt_stp.c
index 06cf93b8d8449..81ba572c33c1a 100644
--- a/extensions/libebt_stp.c
+++ b/extensions/libebt_stp.c
@@ -150,54 +150,6 @@ static void print_range(unsigned int l, unsigned int u)
 		printf("%u:%u ", l, u);
 }
 
-static int brstp_get_mac_and_mask(const char *from, unsigned char *to, unsigned char *mask)
-{
-	char *p;
-	int i;
-	struct ether_addr *addr = NULL;
-
-	static const unsigned char mac_type_unicast[ETH_ALEN];
-	static const unsigned char msk_type_unicast[ETH_ALEN] =   {1,0,0,0,0,0};
-	static const unsigned char mac_type_multicast[ETH_ALEN] = {1,0,0,0,0,0};
-	static const unsigned char mac_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255};
-	static const unsigned char mac_type_bridge_group[ETH_ALEN] = {0x01,0x80,0xc2,0,0,0};
-	static const unsigned char msk_type_bridge_group[ETH_ALEN] = {255,255,255,255,255,255};
-
-	if (strcasecmp(from, "Unicast") == 0) {
-		memcpy(to, mac_type_unicast, ETH_ALEN);
-		memcpy(mask, msk_type_unicast, ETH_ALEN);
-		return 0;
-	}
-	if (strcasecmp(from, "Multicast") == 0) {
-		memcpy(to, mac_type_multicast, ETH_ALEN);
-		memcpy(mask, mac_type_multicast, ETH_ALEN);
-		return 0;
-	}
-	if (strcasecmp(from, "Broadcast") == 0) {
-		memcpy(to, mac_type_broadcast, ETH_ALEN);
-		memcpy(mask, mac_type_broadcast, ETH_ALEN);
-		return 0;
-	}
-	if (strcasecmp(from, "BGA") == 0) {
-		memcpy(to, mac_type_bridge_group, ETH_ALEN);
-		memcpy(mask, msk_type_bridge_group, ETH_ALEN);
-		return 0;
-	}
-	if ( (p = strrchr(from, '/')) != NULL) {
-		*p = '\0';
-		if (!(addr = ether_aton(p + 1)))
-			return -1;
-		memcpy(mask, addr, ETH_ALEN);
-	} else
-		memset(mask, 0xff, ETH_ALEN);
-	if (!(addr = ether_aton(from)))
-		return -1;
-	memcpy(to, addr, ETH_ALEN);
-	for (i = 0; i < ETH_ALEN; i++)
-		to[i] &= mask[i];
-	return 0;
-}
-
 static int
 brstp_parse(int c, char **argv, int invert, unsigned int *flags,
 	    const void *entry, struct xt_entry_match **match)
@@ -280,15 +232,15 @@ brstp_parse(int c, char **argv, int invert, unsigned int *flags,
 			xtables_error(PARAMETER_PROBLEM, "Bad --stp-forward-delay range");
 		break;
 	case EBT_STP_ROOTADDR:
-		if (brstp_get_mac_and_mask(argv[optind-1],
-		    (unsigned char *)stpinfo->config.root_addr,
-		    (unsigned char *)stpinfo->config.root_addrmsk))
+		if (xtables_parse_mac_and_mask(argv[optind-1],
+					       stpinfo->config.root_addr,
+					       stpinfo->config.root_addrmsk))
 			xtables_error(PARAMETER_PROBLEM, "Bad --stp-root-addr address");
 		break;
 	case EBT_STP_SENDERADDR:
-		if (brstp_get_mac_and_mask(argv[optind-1],
-		    (unsigned char *)stpinfo->config.sender_addr,
-		    (unsigned char *)stpinfo->config.sender_addrmsk))
+		if (xtables_parse_mac_and_mask(argv[optind-1],
+					       stpinfo->config.sender_addr,
+					       stpinfo->config.sender_addrmsk))
 			xtables_error(PARAMETER_PROBLEM, "Bad --stp-sender-addr address");
 		break;
 	default:
diff --git a/extensions/libxt_mac.c b/extensions/libxt_mac.c
index b6d717bcf86f0..b90eef207c98e 100644
--- a/extensions/libxt_mac.c
+++ b/extensions/libxt_mac.c
@@ -37,15 +37,6 @@ static void mac_parse(struct xt_option_call *cb)
 		macinfo->invert = 1;
 }
 
-static void print_mac(const unsigned char *macaddress)
-{
-	unsigned int i;
-
-	printf(" %02X", macaddress[0]);
-	for (i = 1; i < ETH_ALEN; ++i)
-		printf(":%02X", macaddress[i]);
-}
-
 static void
 mac_print(const void *ip, const struct xt_entry_match *match, int numeric)
 {
@@ -56,7 +47,7 @@ mac_print(const void *ip, const struct xt_entry_match *match, int numeric)
 	if (info->invert)
 		printf(" !");
 
-	print_mac(info->srcaddr);
+	xtables_print_mac(info->srcaddr);
 }
 
 static void mac_save(const void *ip, const struct xt_entry_match *match)
@@ -66,8 +57,8 @@ static void mac_save(const void *ip, const struct xt_entry_match *match)
 	if (info->invert)
 		printf(" !");
 
-	printf(" --mac-source");
-	print_mac(info->srcaddr);
+	printf(" --mac-source ");
+	xtables_print_mac(info->srcaddr);
 }
 
 static void print_mac_xlate(const unsigned char *macaddress,
diff --git a/include/xtables.h b/include/xtables.h
index 5044dd08e86d3..df1eaee326643 100644
--- a/include/xtables.h
+++ b/include/xtables.h
@@ -557,6 +557,9 @@ extern void xtables_save_string(const char *value);
 #define FMT(tab,notab) ((format) & FMT_NOTABLE ? (notab) : (tab))
 
 extern void xtables_print_num(uint64_t number, unsigned int format);
+extern int xtables_parse_mac_and_mask(const char *from, void *to, void *mask);
+extern int xtables_print_well_known_mac_and_mask(const void *mac,
+						 const void *mask);
 extern void xtables_print_mac(const unsigned char *macaddress);
 extern void xtables_print_mac_and_mask(const unsigned char *mac,
 				       const unsigned char *mask);
diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c
index c1a2c209cc1aa..d98fd527d9549 100644
--- a/iptables/nft-bridge.c
+++ b/iptables/nft-bridge.c
@@ -58,44 +58,11 @@ void ebt_cs_clean(struct iptables_command_state *cs)
 	}
 }
 
-static void ebt_print_mac(const unsigned char *mac)
-{
-	int j;
-
-	for (j = 0; j < ETH_ALEN; j++)
-		printf("%02x%s", mac[j], (j==ETH_ALEN-1) ? "" : ":");
-}
-
-static bool mac_all_ones(const unsigned char *mac)
-{
-	static const char hlpmsk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
-	return memcmp(mac, hlpmsk, sizeof(hlpmsk)) == 0;
-}
-
 /* Put the mac address into 6 (ETH_ALEN) bytes returns 0 on success. */
 static void ebt_print_mac_and_mask(const unsigned char *mac, const unsigned char *mask)
 {
-
-	if (!memcmp(mac, eb_mac_type_unicast, 6) &&
-	    !memcmp(mask, eb_msk_type_unicast, 6))
-		printf("Unicast");
-	else if (!memcmp(mac, eb_mac_type_multicast, 6) &&
-	         !memcmp(mask, eb_msk_type_multicast, 6))
-		printf("Multicast");
-	else if (!memcmp(mac, eb_mac_type_broadcast, 6) &&
-	         !memcmp(mask, eb_msk_type_broadcast, 6))
-		printf("Broadcast");
-	else if (!memcmp(mac, eb_mac_type_bridge_group, 6) &&
-	         !memcmp(mask, eb_msk_type_bridge_group, 6))
-		printf("BGA");
-	else {
-		ebt_print_mac(mac);
-		if (!mac_all_ones(mask)) {
-			printf("/");
-			ebt_print_mac(mask);
-		}
-	}
+	if (xtables_print_well_known_mac_and_mask(mac, mask))
+		xtables_print_mac_and_mask(mac, mask);
 }
 
 static void add_logical_iniface(struct nftnl_rule *r, char *iface, uint32_t op)
diff --git a/iptables/tests/shell/testcases/ipt-save/dumps/ipt-save-filter.txt b/iptables/tests/shell/testcases/ipt-save/dumps/ipt-save-filter.txt
index bfb6bdda57faf..6e42de78433ec 100644
--- a/iptables/tests/shell/testcases/ipt-save/dumps/ipt-save-filter.txt
+++ b/iptables/tests/shell/testcases/ipt-save/dumps/ipt-save-filter.txt
@@ -40,8 +40,8 @@
 -A OUTPUT -s 127.0.0.1/32 -d 127.0.0.1/32 -o lo -j ACCEPT
 -A OUTPUT -o wlan0 -j wlanout
 -A OUTPUT -j block
--A WLAN -s 192.168.200.4/32 -m mac --mac-source 00:00:F1:05:A0:E0 -j RETURN
--A WLAN -s 192.168.200.9/32 -m mac --mac-source 00:00:F1:05:99:85 -j RETURN
+-A WLAN -s 192.168.200.4/32 -m mac --mac-source 00:00:f1:05:a0:e0 -j RETURN
+-A WLAN -s 192.168.200.9/32 -m mac --mac-source 00:00:f1:05:99:85 -j RETURN
 -A WLAN -m limit --limit 12/min -j LOG --log-prefix "UNKNOWN WLAN dropped:"
 -A WLAN -j DROP
 -A accept_log -i ppp0 -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -m limit --limit 1/sec -j LOG --log-prefix "TCPConnect on ppp0:"
diff --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c
index 8632774dfb705..e56bbb4dd0363 100644
--- a/iptables/xtables-arp.c
+++ b/iptables/xtables-arp.c
@@ -135,52 +135,6 @@ static int inverse_for_options[] =
 /* ARPTABLES SPECIFIC NEW FUNCTIONS ADDED HERE */
 /***********************************************/
 
-static unsigned char mac_type_unicast[ETH_ALEN] =   {0,0,0,0,0,0};
-static unsigned char msk_type_unicast[ETH_ALEN] =   {1,0,0,0,0,0};
-static unsigned char mac_type_multicast[ETH_ALEN] = {1,0,0,0,0,0};
-static unsigned char msk_type_multicast[ETH_ALEN] = {1,0,0,0,0,0};
-static unsigned char mac_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255};
-static unsigned char msk_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255};
-
-/*
- * put the mac address into 6 (ETH_ALEN) bytes
- */
-static int getmac_and_mask(char *from, char *to, char *mask)
-{
-	char *p;
-	int i;
-	struct ether_addr *addr;
-
-	if (strcasecmp(from, "Unicast") == 0) {
-		memcpy(to, mac_type_unicast, ETH_ALEN);
-		memcpy(mask, msk_type_unicast, ETH_ALEN);
-		return 0;
-	}
-	if (strcasecmp(from, "Multicast") == 0) {
-		memcpy(to, mac_type_multicast, ETH_ALEN);
-		memcpy(mask, msk_type_multicast, ETH_ALEN);
-		return 0;
-	}
-	if (strcasecmp(from, "Broadcast") == 0) {
-		memcpy(to, mac_type_broadcast, ETH_ALEN);
-		memcpy(mask, msk_type_broadcast, ETH_ALEN);
-		return 0;
-	}
-	if ( (p = strrchr(from, '/')) != NULL) {
-		*p = '\0';
-		if (!(addr = ether_aton(p + 1)))
-			return -1;
-		memcpy(mask, addr, ETH_ALEN);
-	} else
-		memset(mask, 0xff, ETH_ALEN);
-	if (!(addr = ether_aton(from)))
-		return -1;
-	memcpy(to, addr, ETH_ALEN);
-	for (i = 0; i < ETH_ALEN; i++)
-		to[i] &= mask[i];
-	return 0;
-}
-
 static int getlength_and_mask(char *from, uint8_t *to, uint8_t *mask)
 {
 	char *p, *buffer;
@@ -686,7 +640,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
 			check_inverse(optarg, &invert, &optind, argc);
 			set_option(&options, OPT_S_MAC, &cs.arp.arp.invflags,
 				   invert);
-			if (getmac_and_mask(argv[optind - 1],
+			if (xtables_parse_mac_and_mask(argv[optind - 1],
 			    cs.arp.arp.src_devaddr.addr, cs.arp.arp.src_devaddr.mask))
 				xtables_error(PARAMETER_PROBLEM, "Problem with specified "
 						"source mac");
@@ -697,7 +651,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
 			set_option(&options, OPT_D_MAC, &cs.arp.arp.invflags,
 				   invert);
 
-			if (getmac_and_mask(argv[optind - 1],
+			if (xtables_parse_mac_and_mask(argv[optind - 1],
 			    cs.arp.arp.tgt_devaddr.addr, cs.arp.arp.tgt_devaddr.mask))
 				xtables_error(PARAMETER_PROBLEM, "Problem with specified "
 						"destination mac");
diff --git a/iptables/xtables-eb-translate.c b/iptables/xtables-eb-translate.c
index 96b2730fa97ed..83ae77cb07fb2 100644
--- a/iptables/xtables-eb-translate.c
+++ b/iptables/xtables-eb-translate.c
@@ -397,7 +397,9 @@ print_zero:
 				if (ebt_check_inverse2(optarg, argc, argv))
 					cs.eb.invflags |= EBT_ISOURCE;
 
-				if (ebt_get_mac_and_mask(optarg, cs.eb.sourcemac, cs.eb.sourcemsk))
+				if (xtables_parse_mac_and_mask(optarg,
+							       cs.eb.sourcemac,
+							       cs.eb.sourcemsk))
 					xtables_error(PARAMETER_PROBLEM, "Problem with specified source mac '%s'", optarg);
 				cs.eb.bitmask |= EBT_SOURCEMAC;
 				break;
@@ -406,7 +408,9 @@ print_zero:
 				if (ebt_check_inverse2(optarg, argc, argv))
 					cs.eb.invflags |= EBT_IDEST;
 
-				if (ebt_get_mac_and_mask(optarg, cs.eb.destmac, cs.eb.destmsk))
+				if (xtables_parse_mac_and_mask(optarg,
+							       cs.eb.destmac,
+							       cs.eb.destmsk))
 					xtables_error(PARAMETER_PROBLEM, "Problem with specified destination mac '%s'", optarg);
 				cs.eb.bitmask |= EBT_DESTMAC;
 				break;
diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index 6641a21a72d32..b379c0e5119f1 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -55,57 +55,6 @@
  * 1: the inverse '!' of the option has already been specified */
 int ebt_invert = 0;
 
-unsigned char eb_mac_type_unicast[ETH_ALEN] =   {0,0,0,0,0,0};
-unsigned char eb_msk_type_unicast[ETH_ALEN] =   {1,0,0,0,0,0};
-unsigned char eb_mac_type_multicast[ETH_ALEN] = {1,0,0,0,0,0};
-unsigned char eb_msk_type_multicast[ETH_ALEN] = {1,0,0,0,0,0};
-unsigned char eb_mac_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255};
-unsigned char eb_msk_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255};
-unsigned char eb_mac_type_bridge_group[ETH_ALEN] = {0x01,0x80,0xc2,0,0,0};
-unsigned char eb_msk_type_bridge_group[ETH_ALEN] = {255,255,255,255,255,255};
-
-int ebt_get_mac_and_mask(const char *from, unsigned char *to,
-  unsigned char *mask)
-{
-	char *p;
-	int i;
-	struct ether_addr *addr = NULL;
-
-	if (strcasecmp(from, "Unicast") == 0) {
-		memcpy(to, eb_mac_type_unicast, ETH_ALEN);
-		memcpy(mask, eb_msk_type_unicast, ETH_ALEN);
-		return 0;
-	}
-	if (strcasecmp(from, "Multicast") == 0) {
-		memcpy(to, eb_mac_type_multicast, ETH_ALEN);
-		memcpy(mask, eb_msk_type_multicast, ETH_ALEN);
-		return 0;
-	}
-	if (strcasecmp(from, "Broadcast") == 0) {
-		memcpy(to, eb_mac_type_broadcast, ETH_ALEN);
-		memcpy(mask, eb_msk_type_broadcast, ETH_ALEN);
-		return 0;
-	}
-	if (strcasecmp(from, "BGA") == 0) {
-		memcpy(to, eb_mac_type_bridge_group, ETH_ALEN);
-		memcpy(mask, eb_msk_type_bridge_group, ETH_ALEN);
-		return 0;
-	}
-	if ( (p = strrchr(from, '/')) != NULL) {
-		*p = '\0';
-		if (!(addr = ether_aton(p + 1)))
-			return -1;
-		memcpy(mask, addr, ETH_ALEN);
-	} else
-		memset(mask, 0xff, ETH_ALEN);
-	if (!(addr = ether_aton(from)))
-		return -1;
-	memcpy(to, addr, ETH_ALEN);
-	for (i = 0; i < ETH_ALEN; i++)
-		to[i] &= mask[i];
-	return 0;
-}
-
 static int ebt_check_inverse2(const char option[], int argc, char **argv)
 {
 	if (!option)
@@ -1037,7 +986,9 @@ print_zero:
 				if (ebt_check_inverse2(optarg, argc, argv))
 					cs.eb.invflags |= EBT_ISOURCE;
 
-				if (ebt_get_mac_and_mask(optarg, cs.eb.sourcemac, cs.eb.sourcemsk))
+				if (xtables_parse_mac_and_mask(optarg,
+							       cs.eb.sourcemac,
+							       cs.eb.sourcemsk))
 					xtables_error(PARAMETER_PROBLEM, "Problem with specified source mac '%s'", optarg);
 				cs.eb.bitmask |= EBT_SOURCEMAC;
 				break;
@@ -1046,7 +997,9 @@ print_zero:
 				if (ebt_check_inverse2(optarg, argc, argv))
 					cs.eb.invflags |= EBT_IDEST;
 
-				if (ebt_get_mac_and_mask(optarg, cs.eb.destmac, cs.eb.destmsk))
+				if (xtables_parse_mac_and_mask(optarg,
+							       cs.eb.destmac,
+							       cs.eb.destmsk))
 					xtables_error(PARAMETER_PROBLEM, "Problem with specified destination mac '%s'", optarg);
 				cs.eb.bitmask |= EBT_DESTMAC;
 				break;
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
index 7152c6576cd63..bc42ba8221f3a 100644
--- a/libxtables/xtables.c
+++ b/libxtables/xtables.c
@@ -2137,6 +2137,79 @@ void xtables_print_num(uint64_t number, unsigned int format)
 	printf(FMT("%4lluT ","%lluT "), (unsigned long long)number);
 }
 
+#include <netinet/ether.h>
+
+static const unsigned char mac_type_unicast[ETH_ALEN] =   {};
+static const unsigned char msk_type_unicast[ETH_ALEN] =   {1};
+static const unsigned char mac_type_multicast[ETH_ALEN] = {1};
+static const unsigned char msk_type_multicast[ETH_ALEN] = {1};
+#define ALL_ONE_MAC {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
+static const unsigned char mac_type_broadcast[ETH_ALEN] = ALL_ONE_MAC;
+static const unsigned char msk_type_broadcast[ETH_ALEN] = ALL_ONE_MAC;
+static const unsigned char mac_type_bridge_group[ETH_ALEN] = {0x01, 0x80, 0xc2};
+static const unsigned char msk_type_bridge_group[ETH_ALEN] = ALL_ONE_MAC;
+#undef ALL_ONE_MAC
+
+int xtables_parse_mac_and_mask(const char *from, void *to, void *mask)
+{
+	char *p;
+	int i;
+	struct ether_addr *addr = NULL;
+
+	if (strcasecmp(from, "Unicast") == 0) {
+		memcpy(to, mac_type_unicast, ETH_ALEN);
+		memcpy(mask, msk_type_unicast, ETH_ALEN);
+		return 0;
+	}
+	if (strcasecmp(from, "Multicast") == 0) {
+		memcpy(to, mac_type_multicast, ETH_ALEN);
+		memcpy(mask, msk_type_multicast, ETH_ALEN);
+		return 0;
+	}
+	if (strcasecmp(from, "Broadcast") == 0) {
+		memcpy(to, mac_type_broadcast, ETH_ALEN);
+		memcpy(mask, msk_type_broadcast, ETH_ALEN);
+		return 0;
+	}
+	if (strcasecmp(from, "BGA") == 0) {
+		memcpy(to, mac_type_bridge_group, ETH_ALEN);
+		memcpy(mask, msk_type_bridge_group, ETH_ALEN);
+		return 0;
+	}
+	if ( (p = strrchr(from, '/')) != NULL) {
+		*p = '\0';
+		if (!(addr = ether_aton(p + 1)))
+			return -1;
+		memcpy(mask, addr, ETH_ALEN);
+	} else
+		memset(mask, 0xff, ETH_ALEN);
+	if (!(addr = ether_aton(from)))
+		return -1;
+	memcpy(to, addr, ETH_ALEN);
+	for (i = 0; i < ETH_ALEN; i++)
+		((char *)to)[i] &= ((char *)mask)[i];
+	return 0;
+}
+
+int xtables_print_well_known_mac_and_mask(const void *mac, const void *mask)
+{
+	if (!memcmp(mac, mac_type_unicast, ETH_ALEN) &&
+	    !memcmp(mask, msk_type_unicast, ETH_ALEN))
+		printf("Unicast");
+	else if (!memcmp(mac, mac_type_multicast, ETH_ALEN) &&
+	         !memcmp(mask, msk_type_multicast, ETH_ALEN))
+		printf("Multicast");
+	else if (!memcmp(mac, mac_type_broadcast, ETH_ALEN) &&
+	         !memcmp(mask, msk_type_broadcast, ETH_ALEN))
+		printf("Broadcast");
+	else if (!memcmp(mac, mac_type_bridge_group, ETH_ALEN) &&
+	         !memcmp(mask, msk_type_bridge_group, ETH_ALEN))
+		printf("BGA");
+	else
+		return -1;
+	return 0;
+}
+
 void xtables_print_mac(const unsigned char *macaddress)
 {
 	unsigned int i;
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [iptables PATCH 2/3] xtables-arp: Don't use ARPT_INV_*
  2020-11-16 14:02 [iptables PATCH 0/3] Merge some common code Phil Sutter
  2020-11-16 14:02 ` [iptables PATCH 1/3] libxtables: Extend MAC address printing/parsing support Phil Sutter
@ 2020-11-16 14:02 ` Phil Sutter
  2020-11-16 14:02 ` [iptables PATCH 3/3] xshared: Merge some command option-related code Phil Sutter
  2 siblings, 0 replies; 4+ messages in thread
From: Phil Sutter @ 2020-11-16 14:02 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

Arptables invflags are partly identical to IPT_INV_* ones but the bits
are differently assigned. Eliminate this incompatibility by definition
of the unique invflags in nft-arp.h on bits that don't collide with
IPT_INV_* ones, then use those in combination with IPT_INV_* ones in
arptables-specific code.

Note that ARPT_INV_ARPPRO is replaced by IPT_INV_PROTO although these
are in fact different options - yet since '-p' option is not supported
by arptables, this does not lead to a collision.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 iptables/nft-arp.c     | 92 ++++++++++++++++--------------------------
 iptables/nft-arp.h     |  7 ++++
 iptables/xtables-arp.c | 22 +++++-----
 3 files changed, 53 insertions(+), 68 deletions(-)

diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
index 5dc38da831aa0..c82ffdc95e300 100644
--- a/iptables/nft-arp.c
+++ b/iptables/nft-arp.c
@@ -134,34 +134,34 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
 	int ret = 0;
 
 	if (fw->arp.iniface[0] != '\0') {
-		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_VIA_IN);
+		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_VIA_IN);
 		add_iniface(r, fw->arp.iniface, op);
 	}
 
 	if (fw->arp.outiface[0] != '\0') {
-		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_VIA_OUT);
+		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_VIA_OUT);
 		add_outiface(r, fw->arp.outiface, op);
 	}
 
 	if (fw->arp.arhrd != 0 ||
-	    fw->arp.invflags & ARPT_INV_ARPHRD) {
-		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPHRD);
+	    fw->arp.invflags & IPT_INV_ARPHRD) {
+		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPHRD);
 		add_payload(r, offsetof(struct arphdr, ar_hrd), 2,
 			    NFT_PAYLOAD_NETWORK_HEADER);
 		add_cmp_u16(r, fw->arp.arhrd, op);
 	}
 
 	if (fw->arp.arpro != 0 ||
-	    fw->arp.invflags & ARPT_INV_ARPPRO) {
-		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPPRO);
+	    fw->arp.invflags & IPT_INV_PROTO) {
+		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_PROTO);
 	        add_payload(r, offsetof(struct arphdr, ar_pro), 2,
 			    NFT_PAYLOAD_NETWORK_HEADER);
 		add_cmp_u16(r, fw->arp.arpro, op);
 	}
 
 	if (fw->arp.arhln != 0 ||
-	    fw->arp.invflags & ARPT_INV_ARPHLN) {
-		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPHLN);
+	    fw->arp.invflags & IPT_INV_ARPHLN) {
+		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPHLN);
 		add_proto(r, offsetof(struct arphdr, ar_hln), 1,
 			  fw->arp.arhln, op);
 	}
@@ -169,15 +169,15 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
 	add_proto(r, offsetof(struct arphdr, ar_pln), 1, 4, NFT_CMP_EQ);
 
 	if (fw->arp.arpop != 0 ||
-	    fw->arp.invflags & ARPT_INV_ARPOP) {
-		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPOP);
+	    fw->arp.invflags & IPT_INV_ARPOP) {
+		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPOP);
 		add_payload(r, offsetof(struct arphdr, ar_op), 2,
 			    NFT_PAYLOAD_NETWORK_HEADER);
 		add_cmp_u16(r, fw->arp.arpop, op);
 	}
 
 	if (need_devaddr(&fw->arp.src_devaddr)) {
-		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCDEVADDR);
+		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_SRCDEVADDR);
 		add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
 			 sizeof(struct arphdr),
 			 &fw->arp.src_devaddr.addr,
@@ -188,8 +188,8 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
 
 	if (fw->arp.src.s_addr != 0 ||
 	    fw->arp.smsk.s_addr != 0 ||
-	    fw->arp.invflags & ARPT_INV_SRCIP) {
-		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCIP);
+	    fw->arp.invflags & IPT_INV_SRCIP) {
+		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_SRCIP);
 		add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
 			 sizeof(struct arphdr) + fw->arp.arhln,
 			 &fw->arp.src.s_addr, &fw->arp.smsk.s_addr,
@@ -198,7 +198,7 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
 
 
 	if (need_devaddr(&fw->arp.tgt_devaddr)) {
-		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTDEVADDR);
+		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_TGTDEVADDR);
 		add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
 			 sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr),
 			 &fw->arp.tgt_devaddr.addr,
@@ -208,8 +208,8 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
 
 	if (fw->arp.tgt.s_addr != 0 ||
 	    fw->arp.tmsk.s_addr != 0 ||
-	    fw->arp.invflags & ARPT_INV_TGTIP) {
-		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTIP);
+	    fw->arp.invflags & IPT_INV_DSTIP) {
+		op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_DSTIP);
 		add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
 			 sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr) + fw->arp.arhln,
 			 &fw->arp.tgt.s_addr, &fw->arp.tmsk.s_addr,
@@ -240,28 +240,6 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
 	return ret;
 }
 
-static uint16_t ipt_to_arpt_flags(uint8_t invflags)
-{
-	uint16_t result = 0;
-
-	if (invflags & IPT_INV_VIA_IN)
-		result |= ARPT_INV_VIA_IN;
-
-	if (invflags & IPT_INV_VIA_OUT)
-		result |= ARPT_INV_VIA_OUT;
-
-	if (invflags & IPT_INV_SRCIP)
-		result |= ARPT_INV_SRCIP;
-
-	if (invflags & IPT_INV_DSTIP)
-		result |= ARPT_INV_TGTIP;
-
-	if (invflags & IPT_INV_PROTO)
-		result |= ARPT_INV_ARPPRO;
-
-	return result;
-}
-
 static void nft_arp_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e,
 			       void *data)
 {
@@ -273,7 +251,7 @@ static void nft_arp_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e,
 		   fw->arp.outiface, fw->arp.outiface_mask,
 		   &flags);
 
-	fw->arp.invflags |= ipt_to_arpt_flags(flags);
+	fw->arp.invflags |= flags;
 }
 
 static void nft_arp_parse_immediate(const char *jumpto, bool nft_goto,
@@ -330,33 +308,33 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
 		fw->arp.arhrd = ar_hrd;
 		fw->arp.arhrd_mask = 0xffff;
 		if (inv)
-			fw->arp.invflags |= ARPT_INV_ARPHRD;
+			fw->arp.invflags |= IPT_INV_ARPHRD;
 		break;
 	case offsetof(struct arphdr, ar_pro):
 		get_cmp_data(e, &ar_pro, sizeof(ar_pro), &inv);
 		fw->arp.arpro = ar_pro;
 		fw->arp.arpro_mask = 0xffff;
 		if (inv)
-			fw->arp.invflags |= ARPT_INV_ARPPRO;
+			fw->arp.invflags |= IPT_INV_PROTO;
 		break;
 	case offsetof(struct arphdr, ar_op):
 		get_cmp_data(e, &ar_op, sizeof(ar_op), &inv);
 		fw->arp.arpop = ar_op;
 		fw->arp.arpop_mask = 0xffff;
 		if (inv)
-			fw->arp.invflags |= ARPT_INV_ARPOP;
+			fw->arp.invflags |= IPT_INV_ARPOP;
 		break;
 	case offsetof(struct arphdr, ar_hln):
 		get_cmp_data(e, &ar_hln, sizeof(ar_hln), &inv);
 		fw->arp.arhln = ar_hln;
 		fw->arp.arhln_mask = 0xff;
 		if (inv)
-			fw->arp.invflags |= ARPT_INV_ARPOP;
+			fw->arp.invflags |= IPT_INV_ARPOP;
 		break;
 	default:
 		if (ctx->payload.offset == sizeof(struct arphdr)) {
 			if (nft_arp_parse_devaddr(ctx, e, &fw->arp.src_devaddr))
-				fw->arp.invflags |= ARPT_INV_SRCDEVADDR;
+				fw->arp.invflags |= IPT_INV_SRCDEVADDR;
 		} else if (ctx->payload.offset == sizeof(struct arphdr) +
 					   fw->arp.arhln) {
 			get_cmp_data(e, &addr, sizeof(addr), &inv);
@@ -371,12 +349,12 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
 			}
 
 			if (inv)
-				fw->arp.invflags |= ARPT_INV_SRCIP;
+				fw->arp.invflags |= IPT_INV_SRCIP;
 		} else if (ctx->payload.offset == sizeof(struct arphdr) +
 						  fw->arp.arhln +
 						  sizeof(struct in_addr)) {
 			if (nft_arp_parse_devaddr(ctx, e, &fw->arp.tgt_devaddr))
-				fw->arp.invflags |= ARPT_INV_TGTDEVADDR;
+				fw->arp.invflags |= IPT_INV_TGTDEVADDR;
 		} else if (ctx->payload.offset == sizeof(struct arphdr) +
 						  fw->arp.arhln +
 						  sizeof(struct in_addr) +
@@ -393,7 +371,7 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
 			}
 
 			if (inv)
-				fw->arp.invflags |= ARPT_INV_TGTIP;
+				fw->arp.invflags |= IPT_INV_DSTIP;
 		}
 		break;
 	}
@@ -448,7 +426,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs,
 		else strcat(iface, "any");
 	}
 	if (print_iface) {
-		printf("%s%s-i %s", sep, fw->arp.invflags & ARPT_INV_VIA_IN ?
+		printf("%s%s-i %s", sep, fw->arp.invflags & IPT_INV_VIA_IN ?
 				   "! " : "", iface);
 		sep = " ";
 	}
@@ -466,13 +444,13 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs,
 		else strcat(iface, "any");
 	}
 	if (print_iface) {
-		printf("%s%s-o %s", sep, fw->arp.invflags & ARPT_INV_VIA_OUT ?
+		printf("%s%s-o %s", sep, fw->arp.invflags & IPT_INV_VIA_OUT ?
 				   "! " : "", iface);
 		sep = " ";
 	}
 
 	if (fw->arp.smsk.s_addr != 0L) {
-		printf("%s%s", sep, fw->arp.invflags & ARPT_INV_SRCIP
+		printf("%s%s", sep, fw->arp.invflags & IPT_INV_SRCIP
 			? "! " : "");
 		if (format & FMT_NUMERIC)
 			sprintf(buf, "%s", addr_to_dotted(&(fw->arp.src)));
@@ -489,7 +467,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs,
 			break;
 	if (i == ARPT_DEV_ADDR_LEN_MAX)
 		goto after_devsrc;
-	printf("%s%s", sep, fw->arp.invflags & ARPT_INV_SRCDEVADDR
+	printf("%s%s", sep, fw->arp.invflags & IPT_INV_SRCDEVADDR
 		? "! " : "");
 	printf("--src-mac ");
 	xtables_print_mac_and_mask((unsigned char *)fw->arp.src_devaddr.addr,
@@ -498,7 +476,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs,
 after_devsrc:
 
 	if (fw->arp.tmsk.s_addr != 0L) {
-		printf("%s%s", sep, fw->arp.invflags & ARPT_INV_TGTIP
+		printf("%s%s", sep, fw->arp.invflags & IPT_INV_DSTIP
 			? "! " : "");
 		if (format & FMT_NUMERIC)
 			sprintf(buf, "%s", addr_to_dotted(&(fw->arp.tgt)));
@@ -515,7 +493,7 @@ after_devsrc:
 			break;
 	if (i == ARPT_DEV_ADDR_LEN_MAX)
 		goto after_devdst;
-	printf("%s%s", sep, fw->arp.invflags & ARPT_INV_TGTDEVADDR
+	printf("%s%s", sep, fw->arp.invflags & IPT_INV_TGTDEVADDR
 		? "! " : "");
 	printf("--dst-mac ");
 	xtables_print_mac_and_mask((unsigned char *)fw->arp.tgt_devaddr.addr,
@@ -525,7 +503,7 @@ after_devsrc:
 after_devdst:
 
 	if (fw->arp.arhln_mask != 255 || fw->arp.arhln != 6) {
-		printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPHLN
+		printf("%s%s", sep, fw->arp.invflags & IPT_INV_ARPHLN
 			? "! " : "");
 		printf("--h-length %d", fw->arp.arhln);
 		if (fw->arp.arhln_mask != 255)
@@ -536,7 +514,7 @@ after_devdst:
 	if (fw->arp.arpop_mask != 0) {
 		int tmp = ntohs(fw->arp.arpop);
 
-		printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPOP
+		printf("%s%s", sep, fw->arp.invflags & IPT_INV_ARPOP
 			? "! " : "");
 		if (tmp <= NUMOPCODES && !(format & FMT_NUMERIC))
 			printf("--opcode %s", arp_opcodes[tmp-1]);
@@ -551,7 +529,7 @@ after_devdst:
 	if (fw->arp.arhrd_mask != 65535 || fw->arp.arhrd != htons(1)) {
 		uint16_t tmp = ntohs(fw->arp.arhrd);
 
-		printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPHRD
+		printf("%s%s", sep, fw->arp.invflags & IPT_INV_ARPHRD
 			? "! " : "");
 		if (tmp == 1 && !(format & FMT_NUMERIC))
 			printf("--h-type %s", "Ethernet");
@@ -565,7 +543,7 @@ after_devdst:
 	if (fw->arp.arpro_mask != 0) {
 		int tmp = ntohs(fw->arp.arpro);
 
-		printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPPRO
+		printf("%s%s", sep, fw->arp.invflags & IPT_INV_PROTO
 			? "! " : "");
 		if (tmp == 0x0800 && !(format & FMT_NUMERIC))
 			printf("--proto-type %s", "IPv4");
diff --git a/iptables/nft-arp.h b/iptables/nft-arp.h
index 3411fc3d7c7b3..0d93a31f563b1 100644
--- a/iptables/nft-arp.h
+++ b/iptables/nft-arp.h
@@ -4,4 +4,11 @@
 extern char *arp_opcodes[];
 #define NUMOPCODES 9
 
+/* define invflags which won't collide with IPT ones */
+#define IPT_INV_SRCDEVADDR	0x0080
+#define IPT_INV_TGTDEVADDR	0x0100
+#define IPT_INV_ARPHLN		0x0200
+#define IPT_INV_ARPOP		0x0400
+#define IPT_INV_ARPHRD		0x0800
+
 #endif
diff --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c
index e56bbb4dd0363..a557f258b437a 100644
--- a/iptables/xtables-arp.c
+++ b/iptables/xtables-arp.c
@@ -113,22 +113,22 @@ struct xtables_globals arptables_globals = {
 static int inverse_for_options[] =
 {
 /* -n */ 0,
-/* -s */ ARPT_INV_SRCIP,
-/* -d */ ARPT_INV_TGTIP,
+/* -s */ IPT_INV_SRCIP,
+/* -d */ IPT_INV_DSTIP,
 /* -p */ 0,
 /* -j */ 0,
 /* -v */ 0,
 /* -x */ 0,
-/* -i */ ARPT_INV_VIA_IN,
-/* -o */ ARPT_INV_VIA_OUT,
+/* -i */ IPT_INV_VIA_IN,
+/* -o */ IPT_INV_VIA_OUT,
 /*--line*/ 0,
 /* -c */ 0,
-/* 2 */ ARPT_INV_SRCDEVADDR,
-/* 3 */ ARPT_INV_TGTDEVADDR,
-/* -l */ ARPT_INV_ARPHLN,
-/* 4 */ ARPT_INV_ARPOP,
-/* 5 */ ARPT_INV_ARPHRD,
-/* 6 */ ARPT_INV_ARPPRO,
+/* 2 */ IPT_INV_SRCDEVADDR,
+/* 3 */ IPT_INV_TGTDEVADDR,
+/* -l */ IPT_INV_ARPHLN,
+/* 4 */ IPT_INV_ARPOP,
+/* 5 */ IPT_INV_ARPHRD,
+/* 6 */ IPT_INV_PROTO,
 };
 
 /***********************************************/
@@ -855,7 +855,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
 					 &dmasks, &ndaddrs);
 
 	if ((nsaddrs > 1 || ndaddrs > 1) &&
-	    (cs.arp.arp.invflags & (ARPT_INV_SRCIP | ARPT_INV_TGTIP)))
+	    (cs.arp.arp.invflags & (IPT_INV_SRCIP | IPT_INV_DSTIP)))
 		xtables_error(PARAMETER_PROBLEM, "! not allowed with multiple"
 				" source or destination IP addresses");
 
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [iptables PATCH 3/3] xshared: Merge some command option-related code
  2020-11-16 14:02 [iptables PATCH 0/3] Merge some common code Phil Sutter
  2020-11-16 14:02 ` [iptables PATCH 1/3] libxtables: Extend MAC address printing/parsing support Phil Sutter
  2020-11-16 14:02 ` [iptables PATCH 2/3] xtables-arp: Don't use ARPT_INV_* Phil Sutter
@ 2020-11-16 14:02 ` Phil Sutter
  2 siblings, 0 replies; 4+ messages in thread
From: Phil Sutter @ 2020-11-16 14:02 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

Add OPT_FRAGMENT define into the enum of other OPT_* defines at the
right position and adjust the arptables-specific ones that follow
accordingly. Appropriately adjust inverse_for_options array in
xtables-arp.c.

Extend optflags from iptables.c by the arptables values for the sake of
completeness, then move it to xshared.h along with NUMBER_OF_OPT
definition. As a side-effect, this fixes for wrong ordering of entries
in arptables' 'optflags' copy.

Add arptables-specific bits to commands_v_options table (the speicific
options are matches on ARP header fields, just treat them like '-s'
option. This is also just a cosmetic change, arptables doesn't have a
generic_opt_check() implementation and hence doesn't use such a table.

With things potentially ready for common use, move commands_v_options
table along with generic_opt_check() and opt2char() into xshared.c and
drop the local (identical) implementations from iptables.c, ip6tables.c
xtables.c and xtables-arp.c. While doing so, fix ordering of entries in
that table: the row for CMD_ZERO_NUM was in the wrong position. Since
all moved rows though are identical, this had no effect in practice.

Fixes: d960a991350ca ("xtables-arp: Integrate OPT_* defines into xshared.h")
Fixes: 384958620abab ("use nf_tables and nf_tables compatibility interface")
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 iptables/ip6tables.c   | 79 -----------------------------------------
 iptables/iptables.c    | 80 ------------------------------------------
 iptables/xshared.c     | 74 ++++++++++++++++++++++++++++++++++++++
 iptables/xshared.h     | 20 +++++++----
 iptables/xtables-arp.c | 14 +-------
 iptables/xtables.c     | 80 ------------------------------------------
 6 files changed, 89 insertions(+), 258 deletions(-)

diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
index 576c2cf8b0d9f..c95355b091568 100644
--- a/iptables/ip6tables.c
+++ b/iptables/ip6tables.c
@@ -45,10 +45,6 @@
 #include "ip6tables-multi.h"
 #include "xshared.h"
 
-#define NUMBER_OF_OPT	ARRAY_SIZE(optflags)
-static const char optflags[]
-= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c'};
-
 static const char unsupported_rev[] = " [unsupported revision]";
 
 static struct option original_opts[] = {
@@ -100,36 +96,6 @@ struct xtables_globals ip6tables_globals = {
 	.compat_rev = xtables_compatible_revision,
 };
 
-/* Table of legal combinations of commands and options.  If any of the
- * given commands make an option legal, that option is legal (applies to
- * CMD_LIST and CMD_ZERO only).
- * Key:
- *  +  compulsory
- *  x  illegal
- *     optional
- */
-
-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 --line -c */
-/*INSERT*/    {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' '},
-/*DELETE*/    {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x'},
-/*DELETE_NUM*/{'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'},
-/*FLUSH*/     {'x','x','x','x','x',' ','x','x','x','x','x'},
-/*ZERO*/      {'x','x','x','x','x',' ','x','x','x','x','x'},
-/*NEW_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x'},
-/*DEL_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x'},
-/*SET_POLICY*/{'x','x','x','x','x',' ','x','x','x','x',' '},
-/*RENAME*/    {'x','x','x','x','x',' ','x','x','x','x','x'},
-/*LIST_RULES*/{'x','x','x','x','x',' ','x','x','x','x','x'},
-/*ZERO_NUM*/  {'x','x','x','x','x',' ','x','x','x','x','x'},
-/*CHECK*/     {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x'},
-};
-
 static const unsigned int inverse_for_options[NUMBER_OF_OPT] =
 {
 /* -n */ 0,
@@ -264,51 +230,6 @@ ip6tables_exit_error(enum xtables_exittype status, const char *msg, ...)
 	exit(status);
 }
 
-static void
-generic_opt_check(int command, int options)
-{
-	int i, j, legal = 0;
-
-	/* Check that commands are valid with options.  Complicated by the
-	 * fact that if an option is legal with *any* command given, it is
-	 * legal overall (ie. -z and -l).
-	 */
-	for (i = 0; i < NUMBER_OF_OPT; i++) {
-		legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */
-
-		for (j = 0; j < NUMBER_OF_CMD; j++) {
-			if (!(command & (1<<j)))
-				continue;
-
-			if (!(options & (1<<i))) {
-				if (commands_v_options[j][i] == '+')
-					xtables_error(PARAMETER_PROBLEM,
-						   "You need to supply the `-%c' "
-						   "option for this command\n",
-						   optflags[i]);
-			} else {
-				if (commands_v_options[j][i] != 'x')
-					legal = 1;
-				else if (legal == 0)
-					legal = -1;
-			}
-		}
-		if (legal == -1)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Illegal option `-%c' with this command\n",
-				   optflags[i]);
-	}
-}
-
-static char
-opt2char(int option)
-{
-	const char *ptr;
-	for (ptr = optflags; option > 1; option >>= 1, ptr++);
-
-	return *ptr;
-}
-
 /*
  *	All functions starting with "parse" should succeed, otherwise
  *	the program fails.
diff --git a/iptables/iptables.c b/iptables/iptables.c
index 88ef6cf666d4b..7d6183116d265 100644
--- a/iptables/iptables.c
+++ b/iptables/iptables.c
@@ -41,11 +41,6 @@
 #include <fcntl.h>
 #include "xshared.h"
 
-#define OPT_FRAGMENT    0x00800U
-#define NUMBER_OF_OPT	ARRAY_SIZE(optflags)
-static const char optflags[]
-= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c', 'f'};
-
 static const char unsupported_rev[] = " [unsupported revision]";
 
 static struct option original_opts[] = {
@@ -99,36 +94,6 @@ struct xtables_globals iptables_globals = {
 	.compat_rev = xtables_compatible_revision,
 };
 
-/* Table of legal combinations of commands and options.  If any of the
- * given commands make an option legal, that option is legal (applies to
- * CMD_LIST and CMD_ZERO only).
- * Key:
- *  +  compulsory
- *  x  illegal
- *     optional
- */
-
-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 --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'},
-/*FLUSH*/     {'x','x','x','x','x',' ','x','x','x','x','x','x'},
-/*ZERO*/      {'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'},
-/*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'},
-/*ZERO_NUM*/  {'x','x','x','x','x',' ','x','x','x','x','x','x'},
-/*CHECK*/     {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' '},
-};
-
 static const int inverse_for_options[NUMBER_OF_OPT] =
 {
 /* -n */ 0,
@@ -263,51 +228,6 @@ iptables_exit_error(enum xtables_exittype status, const char *msg, ...)
 	exit(status);
 }
 
-static void
-generic_opt_check(int command, int options)
-{
-	int i, j, legal = 0;
-
-	/* Check that commands are valid with options.  Complicated by the
-	 * fact that if an option is legal with *any* command given, it is
-	 * legal overall (ie. -z and -l).
-	 */
-	for (i = 0; i < NUMBER_OF_OPT; i++) {
-		legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */
-
-		for (j = 0; j < NUMBER_OF_CMD; j++) {
-			if (!(command & (1<<j)))
-				continue;
-
-			if (!(options & (1<<i))) {
-				if (commands_v_options[j][i] == '+')
-					xtables_error(PARAMETER_PROBLEM,
-						   "You need to supply the `-%c' "
-						   "option for this command\n",
-						   optflags[i]);
-			} else {
-				if (commands_v_options[j][i] != 'x')
-					legal = 1;
-				else if (legal == 0)
-					legal = -1;
-			}
-		}
-		if (legal == -1)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Illegal option `-%c' with this command\n",
-				   optflags[i]);
-	}
-}
-
-static char
-opt2char(int option)
-{
-	const char *ptr;
-	for (ptr = optflags; option > 1; option >>= 1, ptr++);
-
-	return *ptr;
-}
-
 /*
  *	All functions starting with "parse" should succeed, otherwise
  *	the program fails.
diff --git a/iptables/xshared.c b/iptables/xshared.c
index 7d97637f7e129..71f689901e1d4 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -779,3 +779,77 @@ int parse_rulenumber(const char *rule)
 
 	return rulenum;
 }
+
+/* Table of legal combinations of commands and options.  If any of the
+ * given commands make an option legal, that option is legal (applies to
+ * CMD_LIST and CMD_ZERO only).
+ * Key:
+ *  +  compulsory
+ *  x  illegal
+ *     optional
+ */
+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 --line -c -f 2 3 l 4 5 6 */
+/*INSERT*/    {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' ',' ',' ',' ',' ',' ',' '},
+/*DELETE*/    {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' ',' ',' ',' ',' ',' ',' '},
+/*DELETE_NUM*/{'x','x','x','x','x',' ','x','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','x','x','x','x','x','x'},
+/*FLUSH*/     {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'},
+/*ZERO*/      {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'},
+/*NEW_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'},
+/*DEL_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'},
+/*SET_POLICY*/{'x','x','x','x','x',' ','x','x','x','x',' ','x','x','x','x','x','x','x'},
+/*RENAME*/    {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'},
+/*LIST_RULES*/{'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'},
+/*ZERO_NUM*/  {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'},
+/*CHECK*/     {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' ',' ',' ',' ',' ',' ',' '},
+};
+
+void generic_opt_check(int command, int options)
+{
+	int i, j, legal = 0;
+
+	/* Check that commands are valid with options. Complicated by the
+	 * fact that if an option is legal with *any* command given, it is
+	 * legal overall (ie. -z and -l).
+	 */
+	for (i = 0; i < NUMBER_OF_OPT; i++) {
+		legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */
+
+		for (j = 0; j < NUMBER_OF_CMD; j++) {
+			if (!(command & (1<<j)))
+				continue;
+
+			if (!(options & (1<<i))) {
+				if (commands_v_options[j][i] == '+')
+					xtables_error(PARAMETER_PROBLEM,
+						   "You need to supply the `-%c' "
+						   "option for this command\n",
+						   optflags[i]);
+			} else {
+				if (commands_v_options[j][i] != 'x')
+					legal = 1;
+				else if (legal == 0)
+					legal = -1;
+			}
+		}
+		if (legal == -1)
+			xtables_error(PARAMETER_PROBLEM,
+				   "Illegal option `-%c' with this command\n",
+				   optflags[i]);
+	}
+}
+
+char opt2char(int option)
+{
+	const char *ptr;
+
+	for (ptr = optflags; option > 1; option >>= 1, ptr++)
+		;
+
+	return *ptr;
+}
diff --git a/iptables/xshared.h b/iptables/xshared.h
index c41bd054bf36f..9159b2b1f3768 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -30,15 +30,20 @@ enum {
 	OPT_VIANAMEOUT  = 1 << 8,
 	OPT_LINENUMBERS = 1 << 9,
 	OPT_COUNTERS    = 1 << 10,
+	OPT_FRAGMENT	= 1 << 11,
 	/* below are for arptables only */
-	OPT_S_MAC	= 1 << 11,
-	OPT_D_MAC	= 1 << 12,
-	OPT_H_LENGTH	= 1 << 13,
-	OPT_OPCODE	= 1 << 14,
-	OPT_H_TYPE	= 1 << 15,
-	OPT_P_TYPE	= 1 << 16,
+	OPT_S_MAC	= 1 << 12,
+	OPT_D_MAC	= 1 << 13,
+	OPT_H_LENGTH	= 1 << 14,
+	OPT_OPCODE	= 1 << 15,
+	OPT_H_TYPE	= 1 << 16,
+	OPT_P_TYPE	= 1 << 17,
 };
 
+#define NUMBER_OF_OPT	ARRAY_SIZE(optflags)
+static const char optflags[]
+= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c', 'f', 2, 3, 'l', 4, 5, 6 };
+
 enum {
 	CMD_NONE		= 0,
 	CMD_INSERT		= 1 << 0,
@@ -216,4 +221,7 @@ void add_command(unsigned int *cmd, const int newcmd,
 		 const int othercmds, int invert);
 int parse_rulenumber(const char *rule);
 
+void generic_opt_check(int command, int options);
+char opt2char(int option);
+
 #endif /* IPTABLES_XSHARED_H */
diff --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c
index a557f258b437a..4a89ae9507051 100644
--- a/iptables/xtables-arp.c
+++ b/iptables/xtables-arp.c
@@ -53,10 +53,6 @@
 #include "nft-arp.h"
 #include <linux/netfilter_arp/arp_tables.h>
 
-#define NUMBER_OF_OPT	16
-static const char optflags[NUMBER_OF_OPT]
-= { 'n', 's', 'd', 2, 3, 7, 8, 4, 5, 6, 'j', 'v', 'i', 'o', '0', 'c'};
-
 static struct option original_opts[] = {
 	{ "append", 1, 0, 'A' },
 	{ "delete", 1, 0,  'D' },
@@ -123,6 +119,7 @@ static int inverse_for_options[] =
 /* -o */ IPT_INV_VIA_OUT,
 /*--line*/ 0,
 /* -c */ 0,
+/* -f */ 0,
 /* 2 */ IPT_INV_SRCDEVADDR,
 /* 3 */ IPT_INV_TGTDEVADDR,
 /* -l */ IPT_INV_ARPHLN,
@@ -281,15 +278,6 @@ printhelp(void)
 	}
 }
 
-static char
-opt2char(int option)
-{
-	const char *ptr;
-	for (ptr = optflags; option > 1; option >>= 1, ptr++);
-
-	return *ptr;
-}
-
 static int
 check_inverse(const char option[], int *invert, int *optidx, int argc)
 {
diff --git a/iptables/xtables.c b/iptables/xtables.c
index 9d2e441e0b773..9779bd83d53b3 100644
--- a/iptables/xtables.c
+++ b/iptables/xtables.c
@@ -43,11 +43,6 @@
 #include "nft-shared.h"
 #include "nft.h"
 
-#define OPT_FRAGMENT	0x00800U
-#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[] = {
 	{.name = "append",	  .has_arg = 1, .val = 'A'},
 	{.name = "delete",	  .has_arg = 1, .val = 'D'},
@@ -99,36 +94,6 @@ struct xtables_globals xtables_globals = {
 	.compat_rev = nft_compatible_revision,
 };
 
-/* Table of legal combinations of commands and options.  If any of the
- * given commands make an option legal, that option is legal (applies to
- * CMD_LIST and CMD_ZERO only).
- * Key:
- *  +  compulsory
- *  x  illegal
- *     optional
- */
-
-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 --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'},
-/*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'},
-/*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'},
-/*CHECK*/     {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' '},
-};
-
 static const int inverse_for_options[NUMBER_OF_OPT] =
 {
 /* -n */ 0,
@@ -262,51 +227,6 @@ xtables_exit_error(enum xtables_exittype status, const char *msg, ...)
 	exit(status);
 }
 
-static void
-generic_opt_check(int command, int options)
-{
-	int i, j, legal = 0;
-
-	/* Check that commands are valid with options.	Complicated by the
-	 * fact that if an option is legal with *any* command given, it is
-	 * legal overall (ie. -z and -l).
-	 */
-	for (i = 0; i < NUMBER_OF_OPT; i++) {
-		legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */
-
-		for (j = 0; j < NUMBER_OF_CMD; j++) {
-			if (!(command & (1<<j)))
-				continue;
-
-			if (!(options & (1<<i))) {
-				if (commands_v_options[j][i] == '+')
-					xtables_error(PARAMETER_PROBLEM,
-						   "You need to supply the `-%c' "
-						   "option for this command\n",
-						   optflags[i]);
-			} else {
-				if (commands_v_options[j][i] != 'x')
-					legal = 1;
-				else if (legal == 0)
-					legal = -1;
-			}
-		}
-		if (legal == -1)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Illegal option `-%c' with this command\n",
-				   optflags[i]);
-	}
-}
-
-static char
-opt2char(int option)
-{
-	const char *ptr;
-	for (ptr = optflags; option > 1; option >>= 1, ptr++);
-
-	return *ptr;
-}
-
 /*
  *	All functions starting with "parse" should succeed, otherwise
  *	the program fails.
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-11-16 14:03 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-16 14:02 [iptables PATCH 0/3] Merge some common code Phil Sutter
2020-11-16 14:02 ` [iptables PATCH 1/3] libxtables: Extend MAC address printing/parsing support Phil Sutter
2020-11-16 14:02 ` [iptables PATCH 2/3] xtables-arp: Don't use ARPT_INV_* Phil Sutter
2020-11-16 14:02 ` [iptables PATCH 3/3] xshared: Merge some command option-related code Phil Sutter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.