* [iptables PATCH 0/7] De-duplicate code here and there
@ 2022-11-12 0:20 Phil Sutter
2022-11-12 0:20 ` [iptables PATCH 1/7] xshared: Share make_delete_mask() between ip{,6}tables Phil Sutter
` (7 more replies)
0 siblings, 8 replies; 9+ messages in thread
From: Phil Sutter @ 2022-11-12 0:20 UTC (permalink / raw)
To: netfilter-devel
A series of unrelated patches reducing code size in different ways:
Patch 1 is a typical "move function to xshared.c for common use", patch
2 eliminates some c'n'p programming in nft-shared.c, patch 3 merges
libipt_LOG.c and libip6t_LOG.c, patch 4 removes code from libebt_ip.c by
including the right header, patch 5 drops some local IP address parsers
in favor of the respective libxtables function and patches 6 and 7 move
duplicate definitions and code into a header shared by multiple
extensions.
Phil Sutter (7):
xshared: Share make_delete_mask() between ip{,6}tables
nft-shared: Introduce port_match_single_to_range()
extensions: libip*t_LOG: Merge extensions
extensions: libebt_ip: Include kernel header
extensions: libebt_arp, libebt_ip: Use xtables_ipparse_any()
extensions: Collate ICMP types/codes in libxt_icmp.h
extensions: Unify ICMP parser into libxt_icmp.h
extensions/libebt_arp.c | 89 +-------
extensions/libebt_arp.t | 3 +
extensions/libebt_ip.c | 262 ++--------------------
extensions/libebt_ip6.c | 111 +--------
extensions/libip6t_icmp6.c | 97 +-------
extensions/libipt_LOG.c | 250 ---------------------
extensions/libipt_icmp.c | 110 +--------
extensions/{libip6t_LOG.c => libxt_LOG.c} | 158 +++++--------
extensions/libxt_icmp.h | 242 +++++++++++++++++++-
include/linux/netfilter_bridge/ebt_ip.h | 15 +-
iptables/ip6tables.c | 38 +---
iptables/iptables.c | 38 +---
iptables/nft-shared.c | 130 +++--------
iptables/xshared.c | 34 +++
iptables/xshared.h | 4 +
15 files changed, 409 insertions(+), 1172 deletions(-)
delete mode 100644 extensions/libipt_LOG.c
rename extensions/{libip6t_LOG.c => libxt_LOG.c} (52%)
--
2.38.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [iptables PATCH 1/7] xshared: Share make_delete_mask() between ip{,6}tables
2022-11-12 0:20 [iptables PATCH 0/7] De-duplicate code here and there Phil Sutter
@ 2022-11-12 0:20 ` Phil Sutter
2022-11-12 0:20 ` [iptables PATCH 2/7] nft-shared: Introduce port_match_single_to_range() Phil Sutter
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Phil Sutter @ 2022-11-12 0:20 UTC (permalink / raw)
To: netfilter-devel
Function bodies were mostly identical, the only difference being the use
of struct ipt_entry or ip6t_entry for size calculation. Pass this value
via parameter to make them fully identical.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/ip6tables.c | 38 ++------------------------------------
iptables/iptables.c | 38 ++------------------------------------
iptables/xshared.c | 34 ++++++++++++++++++++++++++++++++++
iptables/xshared.h | 4 ++++
4 files changed, 42 insertions(+), 72 deletions(-)
diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
index 75984cc1bcdd8..ae2670357264b 100644
--- a/iptables/ip6tables.c
+++ b/iptables/ip6tables.c
@@ -277,40 +277,6 @@ insert_entry(const xt_chainlabel chain,
return ret;
}
-static unsigned char *
-make_delete_mask(const struct xtables_rule_match *matches,
- const struct xtables_target *target)
-{
- /* Establish mask for comparison */
- unsigned int size;
- const struct xtables_rule_match *matchp;
- unsigned char *mask, *mptr;
-
- size = sizeof(struct ip6t_entry);
- for (matchp = matches; matchp; matchp = matchp->next)
- size += XT_ALIGN(sizeof(struct xt_entry_match)) + matchp->match->size;
-
- mask = xtables_calloc(1, size
- + XT_ALIGN(sizeof(struct xt_entry_target))
- + target->size);
-
- memset(mask, 0xFF, sizeof(struct ip6t_entry));
- mptr = mask + sizeof(struct ip6t_entry);
-
- for (matchp = matches; matchp; matchp = matchp->next) {
- memset(mptr, 0xFF,
- XT_ALIGN(sizeof(struct xt_entry_match))
- + matchp->match->userspacesize);
- mptr += XT_ALIGN(sizeof(struct xt_entry_match)) + matchp->match->size;
- }
-
- memset(mptr, 0xFF,
- XT_ALIGN(sizeof(struct xt_entry_target))
- + target->userspacesize);
-
- return mask;
-}
-
static int
delete_entry(const xt_chainlabel chain,
struct ip6t_entry *fw,
@@ -329,7 +295,7 @@ delete_entry(const xt_chainlabel chain,
int ret = 1;
unsigned char *mask;
- mask = make_delete_mask(matches, target);
+ mask = make_delete_mask(matches, target, sizeof(*fw));
for (i = 0; i < nsaddrs; i++) {
fw->ipv6.src = saddrs[i];
fw->ipv6.smsk = smasks[i];
@@ -359,7 +325,7 @@ check_entry(const xt_chainlabel chain, struct ip6t_entry *fw,
int ret = 1;
unsigned char *mask;
- mask = make_delete_mask(matches, target);
+ mask = make_delete_mask(matches, target, sizeof(fw));
for (i = 0; i < nsaddrs; i++) {
fw->ipv6.src = saddrs[i];
fw->ipv6.smsk = smasks[i];
diff --git a/iptables/iptables.c b/iptables/iptables.c
index e5207ba106057..591ec17886562 100644
--- a/iptables/iptables.c
+++ b/iptables/iptables.c
@@ -276,40 +276,6 @@ insert_entry(const xt_chainlabel chain,
return ret;
}
-static unsigned char *
-make_delete_mask(const struct xtables_rule_match *matches,
- const struct xtables_target *target)
-{
- /* Establish mask for comparison */
- unsigned int size;
- const struct xtables_rule_match *matchp;
- unsigned char *mask, *mptr;
-
- size = sizeof(struct ipt_entry);
- for (matchp = matches; matchp; matchp = matchp->next)
- size += XT_ALIGN(sizeof(struct xt_entry_match)) + matchp->match->size;
-
- mask = xtables_calloc(1, size
- + XT_ALIGN(sizeof(struct xt_entry_target))
- + target->size);
-
- memset(mask, 0xFF, sizeof(struct ipt_entry));
- mptr = mask + sizeof(struct ipt_entry);
-
- for (matchp = matches; matchp; matchp = matchp->next) {
- memset(mptr, 0xFF,
- XT_ALIGN(sizeof(struct xt_entry_match))
- + matchp->match->userspacesize);
- mptr += XT_ALIGN(sizeof(struct xt_entry_match)) + matchp->match->size;
- }
-
- memset(mptr, 0xFF,
- XT_ALIGN(sizeof(struct xt_entry_target))
- + target->userspacesize);
-
- return mask;
-}
-
static int
delete_entry(const xt_chainlabel chain,
struct ipt_entry *fw,
@@ -328,7 +294,7 @@ delete_entry(const xt_chainlabel chain,
int ret = 1;
unsigned char *mask;
- mask = make_delete_mask(matches, target);
+ mask = make_delete_mask(matches, target, sizeof(*fw));
for (i = 0; i < nsaddrs; i++) {
fw->ip.src.s_addr = saddrs[i].s_addr;
fw->ip.smsk.s_addr = smasks[i].s_addr;
@@ -358,7 +324,7 @@ check_entry(const xt_chainlabel chain, struct ipt_entry *fw,
int ret = 1;
unsigned char *mask;
- mask = make_delete_mask(matches, target);
+ mask = make_delete_mask(matches, target, sizeof(*fw));
for (i = 0; i < nsaddrs; i++) {
fw->ip.src.s_addr = saddrs[i].s_addr;
fw->ip.smsk.s_addr = smasks[i].s_addr;
diff --git a/iptables/xshared.c b/iptables/xshared.c
index 695157896d521..0beacee61d487 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -2000,3 +2000,37 @@ void ipv6_post_parse(int command, struct iptables_command_state *cs,
"! not allowed with multiple"
" source or destination IP addresses");
}
+
+unsigned char *
+make_delete_mask(const struct xtables_rule_match *matches,
+ const struct xtables_target *target,
+ size_t entry_size)
+{
+ /* Establish mask for comparison */
+ unsigned int size = entry_size;
+ const struct xtables_rule_match *matchp;
+ unsigned char *mask, *mptr;
+
+ for (matchp = matches; matchp; matchp = matchp->next)
+ size += XT_ALIGN(sizeof(struct xt_entry_match)) + matchp->match->size;
+
+ mask = xtables_calloc(1, size
+ + XT_ALIGN(sizeof(struct xt_entry_target))
+ + target->size);
+
+ memset(mask, 0xFF, entry_size);
+ mptr = mask + entry_size;
+
+ for (matchp = matches; matchp; matchp = matchp->next) {
+ memset(mptr, 0xFF,
+ XT_ALIGN(sizeof(struct xt_entry_match))
+ + matchp->match->userspacesize);
+ mptr += XT_ALIGN(sizeof(struct xt_entry_match)) + matchp->match->size;
+ }
+
+ memset(mptr, 0xFF,
+ XT_ALIGN(sizeof(struct xt_entry_target))
+ + target->userspacesize);
+
+ return mask;
+}
diff --git a/iptables/xshared.h b/iptables/xshared.h
index f43c28f519a9c..bfae4b4e1b5d3 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -293,4 +293,8 @@ void ipv6_post_parse(int command, struct iptables_command_state *cs,
extern char *arp_opcodes[];
#define ARP_NUMOPCODES 9
+unsigned char *make_delete_mask(const struct xtables_rule_match *matches,
+ const struct xtables_target *target,
+ size_t entry_size);
+
#endif /* IPTABLES_XSHARED_H */
--
2.38.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [iptables PATCH 2/7] nft-shared: Introduce port_match_single_to_range()
2022-11-12 0:20 [iptables PATCH 0/7] De-duplicate code here and there Phil Sutter
2022-11-12 0:20 ` [iptables PATCH 1/7] xshared: Share make_delete_mask() between ip{,6}tables Phil Sutter
@ 2022-11-12 0:20 ` Phil Sutter
2022-11-12 0:20 ` [iptables PATCH 3/7] extensions: libip*t_LOG: Merge extensions Phil Sutter
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Phil Sutter @ 2022-11-12 0:20 UTC (permalink / raw)
To: netfilter-devel
The same algorithm was present four times, outsource it. Also use
max()/min() macros for a more readable boundary notation.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/nft-shared.c | 130 ++++++++++++------------------------------
1 file changed, 37 insertions(+), 93 deletions(-)
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
index 996cff996c151..e5e3ac0bada56 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -747,6 +747,35 @@ static void nft_parse_tcp_range(struct nft_xt_ctx *ctx,
}
}
+static void port_match_single_to_range(__u16 *ports, __u8 *invflags,
+ uint8_t op, int port, __u8 invflag)
+{
+ if (port < 0)
+ return;
+
+ switch (op) {
+ case NFT_CMP_NEQ:
+ *invflags |= invflag;
+ /* fallthrough */
+ case NFT_CMP_EQ:
+ ports[0] = port;
+ ports[1] = port;
+ break;
+ case NFT_CMP_LT:
+ ports[1] = max(port - 1, 1);
+ break;
+ case NFT_CMP_LTE:
+ ports[1] = port;
+ break;
+ case NFT_CMP_GT:
+ ports[0] = min(port + 1, UINT16_MAX);
+ break;
+ case NFT_CMP_GTE:
+ ports[0] = port;
+ break;
+ }
+}
+
static void nft_parse_udp(struct nft_xt_ctx *ctx,
struct iptables_command_state *cs,
int sport, int dport,
@@ -757,52 +786,10 @@ static void nft_parse_udp(struct nft_xt_ctx *ctx,
if (!udp)
return;
- if (sport >= 0) {
- switch (op) {
- case NFT_CMP_NEQ:
- udp->invflags |= XT_UDP_INV_SRCPT;
- /* fallthrough */
- case NFT_CMP_EQ:
- udp->spts[0] = sport;
- udp->spts[1] = sport;
- break;
- case NFT_CMP_LT:
- udp->spts[1] = sport > 1 ? sport - 1 : 1;
- break;
- case NFT_CMP_LTE:
- udp->spts[1] = sport;
- break;
- case NFT_CMP_GT:
- udp->spts[0] = sport < 0xffff ? sport + 1 : 0xffff;
- break;
- case NFT_CMP_GTE:
- udp->spts[0] = sport;
- break;
- }
- }
- if (dport >= 0) {
- switch (op) {
- case NFT_CMP_NEQ:
- udp->invflags |= XT_UDP_INV_DSTPT;
- /* fallthrough */
- case NFT_CMP_EQ:
- udp->dpts[0] = dport;
- udp->dpts[1] = dport;
- break;
- case NFT_CMP_LT:
- udp->dpts[1] = dport > 1 ? dport - 1 : 1;
- break;
- case NFT_CMP_LTE:
- udp->dpts[1] = dport;
- break;
- case NFT_CMP_GT:
- udp->dpts[0] = dport < 0xffff ? dport + 1 : 0xffff;
- break;
- case NFT_CMP_GTE:
- udp->dpts[0] = dport;
- break;
- }
- }
+ port_match_single_to_range(udp->spts, &udp->invflags,
+ op, sport, XT_UDP_INV_SRCPT);
+ port_match_single_to_range(udp->dpts, &udp->invflags,
+ op, dport, XT_UDP_INV_DSTPT);
}
static void nft_parse_tcp(struct nft_xt_ctx *ctx,
@@ -815,53 +802,10 @@ static void nft_parse_tcp(struct nft_xt_ctx *ctx,
if (!tcp)
return;
- if (sport >= 0) {
- switch (op) {
- case NFT_CMP_NEQ:
- tcp->invflags |= XT_TCP_INV_SRCPT;
- /* fallthrough */
- case NFT_CMP_EQ:
- tcp->spts[0] = sport;
- tcp->spts[1] = sport;
- break;
- case NFT_CMP_LT:
- tcp->spts[1] = sport > 1 ? sport - 1 : 1;
- break;
- case NFT_CMP_LTE:
- tcp->spts[1] = sport;
- break;
- case NFT_CMP_GT:
- tcp->spts[0] = sport < 0xffff ? sport + 1 : 0xffff;
- break;
- case NFT_CMP_GTE:
- tcp->spts[0] = sport;
- break;
- }
- }
-
- if (dport >= 0) {
- switch (op) {
- case NFT_CMP_NEQ:
- tcp->invflags |= XT_TCP_INV_DSTPT;
- /* fallthrough */
- case NFT_CMP_EQ:
- tcp->dpts[0] = dport;
- tcp->dpts[1] = dport;
- break;
- case NFT_CMP_LT:
- tcp->dpts[1] = dport > 1 ? dport - 1 : 1;
- break;
- case NFT_CMP_LTE:
- tcp->dpts[1] = dport;
- break;
- case NFT_CMP_GT:
- tcp->dpts[0] = dport < 0xffff ? dport + 1 : 0xffff;
- break;
- case NFT_CMP_GTE:
- tcp->dpts[0] = dport;
- break;
- }
- }
+ port_match_single_to_range(tcp->spts, &tcp->invflags,
+ op, sport, XT_TCP_INV_SRCPT);
+ port_match_single_to_range(tcp->dpts, &tcp->invflags,
+ op, dport, XT_TCP_INV_DSTPT);
}
static void nft_parse_th_port(struct nft_xt_ctx *ctx,
--
2.38.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [iptables PATCH 3/7] extensions: libip*t_LOG: Merge extensions
2022-11-12 0:20 [iptables PATCH 0/7] De-duplicate code here and there Phil Sutter
2022-11-12 0:20 ` [iptables PATCH 1/7] xshared: Share make_delete_mask() between ip{,6}tables Phil Sutter
2022-11-12 0:20 ` [iptables PATCH 2/7] nft-shared: Introduce port_match_single_to_range() Phil Sutter
@ 2022-11-12 0:20 ` Phil Sutter
2022-11-12 0:20 ` [iptables PATCH 4/7] extensions: libebt_ip: Include kernel header Phil Sutter
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Phil Sutter @ 2022-11-12 0:20 UTC (permalink / raw)
To: netfilter-devel
Data structures were identical already, make use of the names in
xt_LOG.h and merge all code into a single extension of family
NFPROTO_UNSPEC.
While being at it, define SYSLOG_NAMES and use the array in syslog.h
instead of dragging along an own level->name mapping two times.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
extensions/libipt_LOG.c | 250 ----------------------
extensions/{libip6t_LOG.c => libxt_LOG.c} | 158 +++++---------
2 files changed, 58 insertions(+), 350 deletions(-)
delete mode 100644 extensions/libipt_LOG.c
rename extensions/{libip6t_LOG.c => libxt_LOG.c} (52%)
diff --git a/extensions/libipt_LOG.c b/extensions/libipt_LOG.c
deleted file mode 100644
index 36e2e73b7e360..0000000000000
--- a/extensions/libipt_LOG.c
+++ /dev/null
@@ -1,250 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <syslog.h>
-#include <xtables.h>
-#include <linux/netfilter_ipv4/ipt_LOG.h>
-
-#define LOG_DEFAULT_LEVEL LOG_WARNING
-
-#ifndef IPT_LOG_UID /* Old kernel */
-#define IPT_LOG_UID 0x08 /* Log UID owning local socket */
-#undef IPT_LOG_MASK
-#define IPT_LOG_MASK 0x0f
-#endif
-
-enum {
- O_LOG_LEVEL = 0,
- O_LOG_PREFIX,
- O_LOG_TCPSEQ,
- O_LOG_TCPOPTS,
- O_LOG_IPOPTS,
- O_LOG_UID,
- O_LOG_MAC,
-};
-
-static void LOG_help(void)
-{
- printf(
-"LOG target options:\n"
-" --log-level level Level of logging (numeric or see syslog.conf)\n"
-" --log-prefix prefix Prefix log messages with this prefix.\n\n"
-" --log-tcp-sequence Log TCP sequence numbers.\n\n"
-" --log-tcp-options Log TCP options.\n\n"
-" --log-ip-options Log IP options.\n\n"
-" --log-uid Log UID owning the local socket.\n\n"
-" --log-macdecode Decode MAC addresses and protocol.\n\n");
-}
-
-#define s struct ipt_log_info
-static const struct xt_option_entry LOG_opts[] = {
- {.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL,
- .flags = XTOPT_PUT, XTOPT_POINTER(s, level)},
- {.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING,
- .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1},
- {.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE},
- {.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE},
- {.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE},
- {.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE},
- {.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE},
- XTOPT_TABLEEND,
-};
-#undef s
-
-static void LOG_init(struct xt_entry_target *t)
-{
- struct ipt_log_info *loginfo = (struct ipt_log_info *)t->data;
-
- loginfo->level = LOG_DEFAULT_LEVEL;
-
-}
-
-struct ipt_log_names {
- const char *name;
- unsigned int level;
-};
-
-struct ipt_log_xlate {
- const char *name;
- unsigned int level;
-};
-
-static const struct ipt_log_names ipt_log_names[]
-= { { .name = "alert", .level = LOG_ALERT },
- { .name = "crit", .level = LOG_CRIT },
- { .name = "debug", .level = LOG_DEBUG },
- { .name = "emerg", .level = LOG_EMERG },
- { .name = "error", .level = LOG_ERR }, /* DEPRECATED */
- { .name = "info", .level = LOG_INFO },
- { .name = "notice", .level = LOG_NOTICE },
- { .name = "panic", .level = LOG_EMERG }, /* DEPRECATED */
- { .name = "warning", .level = LOG_WARNING }
-};
-
-static void LOG_parse(struct xt_option_call *cb)
-{
- struct ipt_log_info *info = cb->data;
-
- xtables_option_parse(cb);
- switch (cb->entry->id) {
- case O_LOG_PREFIX:
- if (strchr(cb->arg, '\n') != NULL)
- xtables_error(PARAMETER_PROBLEM,
- "Newlines not allowed in --log-prefix");
- break;
- case O_LOG_TCPSEQ:
- info->logflags |= IPT_LOG_TCPSEQ;
- break;
- case O_LOG_TCPOPTS:
- info->logflags |= IPT_LOG_TCPOPT;
- break;
- case O_LOG_IPOPTS:
- info->logflags |= IPT_LOG_IPOPT;
- break;
- case O_LOG_UID:
- info->logflags |= IPT_LOG_UID;
- break;
- case O_LOG_MAC:
- info->logflags |= IPT_LOG_MACDECODE;
- break;
- }
-}
-
-static void LOG_print(const void *ip, const struct xt_entry_target *target,
- int numeric)
-{
- const struct ipt_log_info *loginfo
- = (const struct ipt_log_info *)target->data;
- unsigned int i = 0;
-
- printf(" LOG");
- if (numeric)
- printf(" flags %u level %u",
- loginfo->logflags, loginfo->level);
- else {
- for (i = 0; i < ARRAY_SIZE(ipt_log_names); ++i)
- if (loginfo->level == ipt_log_names[i].level) {
- printf(" level %s", ipt_log_names[i].name);
- break;
- }
- if (i == ARRAY_SIZE(ipt_log_names))
- printf(" UNKNOWN level %u", loginfo->level);
- if (loginfo->logflags & IPT_LOG_TCPSEQ)
- printf(" tcp-sequence");
- if (loginfo->logflags & IPT_LOG_TCPOPT)
- printf(" tcp-options");
- if (loginfo->logflags & IPT_LOG_IPOPT)
- printf(" ip-options");
- if (loginfo->logflags & IPT_LOG_UID)
- printf(" uid");
- if (loginfo->logflags & IPT_LOG_MACDECODE)
- printf(" macdecode");
- if (loginfo->logflags & ~(IPT_LOG_MASK))
- printf(" unknown-flags");
- }
-
- if (strcmp(loginfo->prefix, "") != 0)
- printf(" prefix \"%s\"", loginfo->prefix);
-}
-
-static void LOG_save(const void *ip, const struct xt_entry_target *target)
-{
- const struct ipt_log_info *loginfo
- = (const struct ipt_log_info *)target->data;
-
- if (strcmp(loginfo->prefix, "") != 0) {
- printf(" --log-prefix");
- xtables_save_string(loginfo->prefix);
- }
-
- if (loginfo->level != LOG_DEFAULT_LEVEL)
- printf(" --log-level %d", loginfo->level);
-
- if (loginfo->logflags & IPT_LOG_TCPSEQ)
- printf(" --log-tcp-sequence");
- if (loginfo->logflags & IPT_LOG_TCPOPT)
- printf(" --log-tcp-options");
- if (loginfo->logflags & IPT_LOG_IPOPT)
- printf(" --log-ip-options");
- if (loginfo->logflags & IPT_LOG_UID)
- printf(" --log-uid");
- if (loginfo->logflags & IPT_LOG_MACDECODE)
- printf(" --log-macdecode");
-}
-
-static const struct ipt_log_xlate ipt_log_xlate_names[] = {
- {"alert", LOG_ALERT },
- {"crit", LOG_CRIT },
- {"debug", LOG_DEBUG },
- {"emerg", LOG_EMERG },
- {"err", LOG_ERR },
- {"info", LOG_INFO },
- {"notice", LOG_NOTICE },
- {"warn", LOG_WARNING }
-};
-
-static int LOG_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct ipt_log_info *loginfo =
- (const struct ipt_log_info *)params->target->data;
- unsigned int i = 0;
-
- xt_xlate_add(xl, "log");
- if (strcmp(loginfo->prefix, "") != 0) {
- if (params->escape_quotes)
- xt_xlate_add(xl, " prefix \\\"%s\\\"", loginfo->prefix);
- else
- xt_xlate_add(xl, " prefix \"%s\"", loginfo->prefix);
- }
-
- for (i = 0; i < ARRAY_SIZE(ipt_log_xlate_names); ++i)
- if (loginfo->level != LOG_DEFAULT_LEVEL &&
- loginfo->level == ipt_log_xlate_names[i].level) {
- xt_xlate_add(xl, " level %s",
- ipt_log_xlate_names[i].name);
- break;
- }
-
- if ((loginfo->logflags & IPT_LOG_MASK) == IPT_LOG_MASK) {
- xt_xlate_add(xl, " flags all");
- } else {
- if (loginfo->logflags & (IPT_LOG_TCPSEQ | IPT_LOG_TCPOPT)) {
- const char *delim = " ";
-
- xt_xlate_add(xl, " flags tcp");
- if (loginfo->logflags & IPT_LOG_TCPSEQ) {
- xt_xlate_add(xl, " sequence");
- delim = ",";
- }
- if (loginfo->logflags & IPT_LOG_TCPOPT)
- xt_xlate_add(xl, "%soptions", delim);
- }
- if (loginfo->logflags & IPT_LOG_IPOPT)
- xt_xlate_add(xl, " flags ip options");
- if (loginfo->logflags & IPT_LOG_UID)
- xt_xlate_add(xl, " flags skuid");
- if (loginfo->logflags & IPT_LOG_MACDECODE)
- xt_xlate_add(xl, " flags ether");
- }
-
- return 1;
-}
-static struct xtables_target log_tg_reg = {
- .name = "LOG",
- .version = XTABLES_VERSION,
- .family = NFPROTO_IPV4,
- .size = XT_ALIGN(sizeof(struct ipt_log_info)),
- .userspacesize = XT_ALIGN(sizeof(struct ipt_log_info)),
- .help = LOG_help,
- .init = LOG_init,
- .print = LOG_print,
- .save = LOG_save,
- .x6_parse = LOG_parse,
- .x6_options = LOG_opts,
- .xlate = LOG_xlate,
-};
-
-void _init(void)
-{
- xtables_register_target(&log_tg_reg);
-}
diff --git a/extensions/libip6t_LOG.c b/extensions/libxt_LOG.c
similarity index 52%
rename from extensions/libip6t_LOG.c
rename to extensions/libxt_LOG.c
index 40adc69d85ed4..e3f4290ba003f 100644
--- a/extensions/libip6t_LOG.c
+++ b/extensions/libxt_LOG.c
@@ -1,25 +1,22 @@
#include <stdio.h>
#include <string.h>
+#define SYSLOG_NAMES
#include <syslog.h>
#include <xtables.h>
-#include <linux/netfilter_ipv6/ip6t_LOG.h>
-
-#ifndef IP6T_LOG_UID /* Old kernel */
-#define IP6T_LOG_UID 0x08
-#undef IP6T_LOG_MASK
-#define IP6T_LOG_MASK 0x0f
-#endif
+#include <linux/netfilter/xt_LOG.h>
#define LOG_DEFAULT_LEVEL LOG_WARNING
enum {
- O_LOG_LEVEL = 0,
- O_LOG_PREFIX,
- O_LOG_TCPSEQ,
+ /* make sure the values correspond with XT_LOG_* bit positions */
+ O_LOG_TCPSEQ = 0,
O_LOG_TCPOPTS,
O_LOG_IPOPTS,
O_LOG_UID,
+ __O_LOG_NFLOG,
O_LOG_MAC,
+ O_LOG_LEVEL,
+ O_LOG_PREFIX,
};
static void LOG_help(void)
@@ -35,7 +32,7 @@ static void LOG_help(void)
" --log-macdecode Decode MAC addresses and protocol.\n");
}
-#define s struct ip6t_log_info
+#define s struct xt_log_info
static const struct xt_option_entry LOG_opts[] = {
{.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL,
.flags = XTOPT_PUT, XTOPT_POINTER(s, level)},
@@ -52,37 +49,14 @@ static const struct xt_option_entry LOG_opts[] = {
static void LOG_init(struct xt_entry_target *t)
{
- struct ip6t_log_info *loginfo = (struct ip6t_log_info *)t->data;
+ struct xt_log_info *loginfo = (void *)t->data;
loginfo->level = LOG_DEFAULT_LEVEL;
-
}
-struct ip6t_log_names {
- const char *name;
- unsigned int level;
-};
-
-struct ip6t_log_xlate {
- const char *name;
- unsigned int level;
-};
-
-static const struct ip6t_log_names ip6t_log_names[]
-= { { .name = "alert", .level = LOG_ALERT },
- { .name = "crit", .level = LOG_CRIT },
- { .name = "debug", .level = LOG_DEBUG },
- { .name = "emerg", .level = LOG_EMERG },
- { .name = "error", .level = LOG_ERR }, /* DEPRECATED */
- { .name = "info", .level = LOG_INFO },
- { .name = "notice", .level = LOG_NOTICE },
- { .name = "panic", .level = LOG_EMERG }, /* DEPRECATED */
- { .name = "warning", .level = LOG_WARNING }
-};
-
static void LOG_parse(struct xt_option_call *cb)
{
- struct ip6t_log_info *info = cb->data;
+ struct xt_log_info *info = cb->data;
xtables_option_parse(cb);
switch (cb->entry->id) {
@@ -92,53 +66,53 @@ static void LOG_parse(struct xt_option_call *cb)
"Newlines not allowed in --log-prefix");
break;
case O_LOG_TCPSEQ:
- info->logflags |= IP6T_LOG_TCPSEQ;
- break;
case O_LOG_TCPOPTS:
- info->logflags |= IP6T_LOG_TCPOPT;
- break;
case O_LOG_IPOPTS:
- info->logflags |= IP6T_LOG_IPOPT;
- break;
case O_LOG_UID:
- info->logflags |= IP6T_LOG_UID;
- break;
case O_LOG_MAC:
- info->logflags |= IP6T_LOG_MACDECODE;
+ info->logflags |= 1 << cb->entry->id;
break;
}
}
+static const char *priority2name(unsigned char level)
+{
+ int i;
+
+ for (i = 0; prioritynames[i].c_name; ++i) {
+ if (level == prioritynames[i].c_val)
+ return prioritynames[i].c_name;
+ }
+ return NULL;
+}
+
static void LOG_print(const void *ip, const struct xt_entry_target *target,
int numeric)
{
- const struct ip6t_log_info *loginfo
- = (const struct ip6t_log_info *)target->data;
- unsigned int i = 0;
+ const struct xt_log_info *loginfo = (const void *)target->data;
printf(" LOG");
if (numeric)
printf(" flags %u level %u",
loginfo->logflags, loginfo->level);
else {
- for (i = 0; i < ARRAY_SIZE(ip6t_log_names); ++i)
- if (loginfo->level == ip6t_log_names[i].level) {
- printf(" level %s", ip6t_log_names[i].name);
- break;
- }
- if (i == ARRAY_SIZE(ip6t_log_names))
+ const char *pname = priority2name(loginfo->level);
+
+ if (pname)
+ printf(" level %s", pname);
+ else
printf(" UNKNOWN level %u", loginfo->level);
- if (loginfo->logflags & IP6T_LOG_TCPSEQ)
+ if (loginfo->logflags & XT_LOG_TCPSEQ)
printf(" tcp-sequence");
- if (loginfo->logflags & IP6T_LOG_TCPOPT)
+ if (loginfo->logflags & XT_LOG_TCPOPT)
printf(" tcp-options");
- if (loginfo->logflags & IP6T_LOG_IPOPT)
+ if (loginfo->logflags & XT_LOG_IPOPT)
printf(" ip-options");
- if (loginfo->logflags & IP6T_LOG_UID)
+ if (loginfo->logflags & XT_LOG_UID)
printf(" uid");
- if (loginfo->logflags & IP6T_LOG_MACDECODE)
+ if (loginfo->logflags & XT_LOG_MACDECODE)
printf(" macdecode");
- if (loginfo->logflags & ~(IP6T_LOG_MASK))
+ if (loginfo->logflags & ~(XT_LOG_MASK))
printf(" unknown-flags");
}
@@ -148,8 +122,7 @@ static void LOG_print(const void *ip, const struct xt_entry_target *target,
static void LOG_save(const void *ip, const struct xt_entry_target *target)
{
- const struct ip6t_log_info *loginfo
- = (const struct ip6t_log_info *)target->data;
+ const struct xt_log_info *loginfo = (const void *)target->data;
if (strcmp(loginfo->prefix, "") != 0) {
printf(" --log-prefix");
@@ -159,35 +132,23 @@ static void LOG_save(const void *ip, const struct xt_entry_target *target)
if (loginfo->level != LOG_DEFAULT_LEVEL)
printf(" --log-level %d", loginfo->level);
- if (loginfo->logflags & IP6T_LOG_TCPSEQ)
+ if (loginfo->logflags & XT_LOG_TCPSEQ)
printf(" --log-tcp-sequence");
- if (loginfo->logflags & IP6T_LOG_TCPOPT)
+ if (loginfo->logflags & XT_LOG_TCPOPT)
printf(" --log-tcp-options");
- if (loginfo->logflags & IP6T_LOG_IPOPT)
+ if (loginfo->logflags & XT_LOG_IPOPT)
printf(" --log-ip-options");
- if (loginfo->logflags & IP6T_LOG_UID)
+ if (loginfo->logflags & XT_LOG_UID)
printf(" --log-uid");
- if (loginfo->logflags & IP6T_LOG_MACDECODE)
+ if (loginfo->logflags & XT_LOG_MACDECODE)
printf(" --log-macdecode");
}
-static const struct ip6t_log_xlate ip6t_log_xlate_names[] = {
- {"alert", LOG_ALERT },
- {"crit", LOG_CRIT },
- {"debug", LOG_DEBUG },
- {"emerg", LOG_EMERG },
- {"err", LOG_ERR },
- {"info", LOG_INFO },
- {"notice", LOG_NOTICE },
- {"warn", LOG_WARNING }
-};
-
static int LOG_xlate(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
- const struct ip6t_log_info *loginfo =
- (const struct ip6t_log_info *)params->target->data;
- unsigned int i = 0;
+ const struct xt_log_info *loginfo = (const void *)params->target->data;
+ const char *pname = priority2name(loginfo->level);
xt_xlate_add(xl, "log");
if (strcmp(loginfo->prefix, "") != 0) {
@@ -197,44 +158,41 @@ static int LOG_xlate(struct xt_xlate *xl,
xt_xlate_add(xl, " prefix \"%s\"", loginfo->prefix);
}
- for (i = 0; i < ARRAY_SIZE(ip6t_log_xlate_names); ++i)
- if (loginfo->level == ip6t_log_xlate_names[i].level &&
- loginfo->level != LOG_DEFAULT_LEVEL) {
- xt_xlate_add(xl, " level %s",
- ip6t_log_xlate_names[i].name);
- break;
- }
+ if (loginfo->level != LOG_DEFAULT_LEVEL && pname)
+ xt_xlate_add(xl, " level %s", pname);
+ else if (!pname)
+ return 0;
- if ((loginfo->logflags & IP6T_LOG_MASK) == IP6T_LOG_MASK) {
+ if ((loginfo->logflags & XT_LOG_MASK) == XT_LOG_MASK) {
xt_xlate_add(xl, " flags all");
} else {
- if (loginfo->logflags & (IP6T_LOG_TCPSEQ | IP6T_LOG_TCPOPT)) {
+ if (loginfo->logflags & (XT_LOG_TCPSEQ | XT_LOG_TCPOPT)) {
const char *delim = " ";
xt_xlate_add(xl, " flags tcp");
- if (loginfo->logflags & IP6T_LOG_TCPSEQ) {
+ if (loginfo->logflags & XT_LOG_TCPSEQ) {
xt_xlate_add(xl, " sequence");
delim = ",";
}
- if (loginfo->logflags & IP6T_LOG_TCPOPT)
+ if (loginfo->logflags & XT_LOG_TCPOPT)
xt_xlate_add(xl, "%soptions", delim);
}
- if (loginfo->logflags & IP6T_LOG_IPOPT)
+ if (loginfo->logflags & XT_LOG_IPOPT)
xt_xlate_add(xl, " flags ip options");
- if (loginfo->logflags & IP6T_LOG_UID)
+ if (loginfo->logflags & XT_LOG_UID)
xt_xlate_add(xl, " flags skuid");
- if (loginfo->logflags & IP6T_LOG_MACDECODE)
+ if (loginfo->logflags & XT_LOG_MACDECODE)
xt_xlate_add(xl, " flags ether");
}
return 1;
}
-static struct xtables_target log_tg6_reg = {
+static struct xtables_target log_tg_reg = {
.name = "LOG",
.version = XTABLES_VERSION,
- .family = NFPROTO_IPV6,
- .size = XT_ALIGN(sizeof(struct ip6t_log_info)),
- .userspacesize = XT_ALIGN(sizeof(struct ip6t_log_info)),
+ .family = NFPROTO_UNSPEC,
+ .size = XT_ALIGN(sizeof(struct xt_log_info)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_log_info)),
.help = LOG_help,
.init = LOG_init,
.print = LOG_print,
@@ -246,5 +204,5 @@ static struct xtables_target log_tg6_reg = {
void _init(void)
{
- xtables_register_target(&log_tg6_reg);
+ xtables_register_target(&log_tg_reg);
}
--
2.38.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [iptables PATCH 4/7] extensions: libebt_ip: Include kernel header
2022-11-12 0:20 [iptables PATCH 0/7] De-duplicate code here and there Phil Sutter
` (2 preceding siblings ...)
2022-11-12 0:20 ` [iptables PATCH 3/7] extensions: libip*t_LOG: Merge extensions Phil Sutter
@ 2022-11-12 0:20 ` Phil Sutter
2022-11-12 0:20 ` [iptables PATCH 5/7] extensions: libebt_arp, libebt_ip: Use xtables_ipparse_any() Phil Sutter
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Phil Sutter @ 2022-11-12 0:20 UTC (permalink / raw)
To: netfilter-devel
Update the local copy of linux/netfilter_bridge/ebt_ip.h and include it
instead of keeping the local copy of struct ebt_ip_info et al.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
extensions/libebt_ip.c | 32 +------------------------
include/linux/netfilter_bridge/ebt_ip.h | 15 +++++++++---
2 files changed, 13 insertions(+), 34 deletions(-)
diff --git a/extensions/libebt_ip.c b/extensions/libebt_ip.c
index 51649ffb3c305..8413a5aa8dd57 100644
--- a/extensions/libebt_ip.c
+++ b/extensions/libebt_ip.c
@@ -20,40 +20,10 @@
#include <netdb.h>
#include <inttypes.h>
#include <xtables.h>
+#include <linux/netfilter_bridge/ebt_ip.h>
#include "libxt_icmp.h"
-#define EBT_IP_SOURCE 0x01
-#define EBT_IP_DEST 0x02
-#define EBT_IP_TOS 0x04
-#define EBT_IP_PROTO 0x08
-#define EBT_IP_SPORT 0x10
-#define EBT_IP_DPORT 0x20
-#define EBT_IP_ICMP 0x40
-#define EBT_IP_IGMP 0x80
-#define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\
- EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP | EBT_IP_IGMP)
-
-struct ebt_ip_info {
- __be32 saddr;
- __be32 daddr;
- __be32 smsk;
- __be32 dmsk;
- __u8 tos;
- __u8 protocol;
- __u8 bitmask;
- __u8 invflags;
- union {
- __u16 sport[2];
- __u8 icmp_type[2];
- __u8 igmp_type[2];
- };
- union {
- __u16 dport[2];
- __u8 icmp_code[2];
- };
-};
-
#define IP_SOURCE '1'
#define IP_DEST '2'
#define IP_EBT_TOS '3' /* include/bits/in.h seems to already define IP_TOS */
diff --git a/include/linux/netfilter_bridge/ebt_ip.h b/include/linux/netfilter_bridge/ebt_ip.h
index c4bbc41b0ea47..ae5d4d1084188 100644
--- a/include/linux/netfilter_bridge/ebt_ip.h
+++ b/include/linux/netfilter_bridge/ebt_ip.h
@@ -23,8 +23,10 @@
#define EBT_IP_PROTO 0x08
#define EBT_IP_SPORT 0x10
#define EBT_IP_DPORT 0x20
+#define EBT_IP_ICMP 0x40
+#define EBT_IP_IGMP 0x80
#define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\
- EBT_IP_SPORT | EBT_IP_DPORT )
+ EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP | EBT_IP_IGMP)
#define EBT_IP_MATCH "ip"
/* the same values are used for the invflags */
@@ -37,8 +39,15 @@ struct ebt_ip_info {
__u8 protocol;
__u8 bitmask;
__u8 invflags;
- __u16 sport[2];
- __u16 dport[2];
+ union {
+ __u16 sport[2];
+ __u8 icmp_type[2];
+ __u8 igmp_type[2];
+ };
+ union {
+ __u16 dport[2];
+ __u8 icmp_code[2];
+ };
};
#endif
--
2.38.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [iptables PATCH 5/7] extensions: libebt_arp, libebt_ip: Use xtables_ipparse_any()
2022-11-12 0:20 [iptables PATCH 0/7] De-duplicate code here and there Phil Sutter
` (3 preceding siblings ...)
2022-11-12 0:20 ` [iptables PATCH 4/7] extensions: libebt_ip: Include kernel header Phil Sutter
@ 2022-11-12 0:20 ` Phil Sutter
2022-11-12 0:20 ` [iptables PATCH 6/7] extensions: Collate ICMP types/codes in libxt_icmp.h Phil Sutter
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Phil Sutter @ 2022-11-12 0:20 UTC (permalink / raw)
To: netfilter-devel
The libxtables function covers all formerly supported inputs (and more).
The extended libebt_arp.t passes before and after this patch.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
extensions/libebt_arp.c | 89 ++++-------------------------------------
extensions/libebt_arp.t | 3 ++
extensions/libebt_ip.c | 86 +++++----------------------------------
3 files changed, 21 insertions(+), 157 deletions(-)
diff --git a/extensions/libebt_arp.c b/extensions/libebt_arp.c
index d5035b956cc15..63a953d4637da 100644
--- a/extensions/libebt_arp.c
+++ b/extensions/libebt_arp.c
@@ -87,91 +87,17 @@ static void brarp_print_help(void)
#define OPT_MAC_D 0x40
#define OPT_GRAT 0x80
-static int undot_ip(char *ip, unsigned char *ip2)
-{
- char *p, *q, *end;
- long int onebyte;
- int i;
- char buf[20];
-
- strncpy(buf, ip, sizeof(buf) - 1);
-
- p = buf;
- for (i = 0; i < 3; i++) {
- if ((q = strchr(p, '.')) == NULL)
- return -1;
- *q = '\0';
- onebyte = strtol(p, &end, 10);
- if (*end != '\0' || onebyte > 255 || onebyte < 0)
- return -1;
- ip2[i] = (unsigned char)onebyte;
- p = q + 1;
- }
-
- onebyte = strtol(p, &end, 10);
- if (*end != '\0' || onebyte > 255 || onebyte < 0)
- return -1;
- ip2[3] = (unsigned char)onebyte;
-
- return 0;
-}
-
-static int ip_mask(char *mask, unsigned char *mask2)
-{
- char *end;
- long int bits;
- uint32_t mask22;
-
- if (undot_ip(mask, mask2)) {
- /* not the /a.b.c.e format, maybe the /x format */
- bits = strtol(mask, &end, 10);
- if (*end != '\0' || bits > 32 || bits < 0)
- return -1;
- if (bits != 0) {
- mask22 = htonl(0xFFFFFFFF << (32 - bits));
- memcpy(mask2, &mask22, 4);
- } else {
- mask22 = 0xFFFFFFFF;
- memcpy(mask2, &mask22, 4);
- }
- }
- return 0;
-}
-
-static void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk)
-{
- char *p;
-
- /* first the mask */
- if ((p = strrchr(address, '/')) != NULL) {
- *p = '\0';
- if (ip_mask(p + 1, (unsigned char *)msk)) {
- xtables_error(PARAMETER_PROBLEM,
- "Problem with the IP mask '%s'", p + 1);
- return;
- }
- } else
- *msk = 0xFFFFFFFF;
-
- if (undot_ip(address, (unsigned char *)addr)) {
- xtables_error(PARAMETER_PROBLEM,
- "Problem with the IP address '%s'", address);
- return;
- }
- *addr = *addr & *msk;
-}
-
static int
brarp_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_match **match)
{
struct ebt_arp_info *arpinfo = (struct ebt_arp_info *)(*match)->data;
+ struct in_addr *ipaddr, ipmask;
long int i;
char *end;
- uint32_t *addr;
- uint32_t *mask;
unsigned char *maddr;
unsigned char *mmask;
+ unsigned int ipnr;
switch (c) {
case ARP_OPCODE:
@@ -231,24 +157,25 @@ brarp_parse(int c, char **argv, int invert, unsigned int *flags,
case ARP_IP_S:
case ARP_IP_D:
+ xtables_ipparse_any(optarg, &ipaddr, &ipmask, &ipnr);
if (c == ARP_IP_S) {
EBT_CHECK_OPTION(flags, OPT_IP_S);
- addr = &arpinfo->saddr;
- mask = &arpinfo->smsk;
+ arpinfo->saddr = ipaddr->s_addr;
+ arpinfo->smsk = ipmask.s_addr;
arpinfo->bitmask |= EBT_ARP_SRC_IP;
} else {
EBT_CHECK_OPTION(flags, OPT_IP_D);
- addr = &arpinfo->daddr;
- mask = &arpinfo->dmsk;
+ arpinfo->daddr = ipaddr->s_addr;
+ arpinfo->dmsk = ipmask.s_addr;
arpinfo->bitmask |= EBT_ARP_DST_IP;
}
+ free(ipaddr);
if (invert) {
if (c == ARP_IP_S)
arpinfo->invflags |= EBT_ARP_SRC_IP;
else
arpinfo->invflags |= EBT_ARP_DST_IP;
}
- ebt_parse_ip_address(optarg, addr, mask);
break;
case ARP_MAC_S:
case ARP_MAC_D:
diff --git a/extensions/libebt_arp.t b/extensions/libebt_arp.t
index 14ff0f097cfd8..96fbce906107c 100644
--- a/extensions/libebt_arp.t
+++ b/extensions/libebt_arp.t
@@ -6,6 +6,9 @@
-p ARP ! --arp-ip-dst 1.2.3.4;-p ARP --arp-ip-dst ! 1.2.3.4 -j CONTINUE;OK
-p ARP --arp-ip-src ! 0.0.0.0;=;OK
-p ARP --arp-ip-dst ! 0.0.0.0/8;=;OK
+-p ARP --arp-ip-src ! 1.2.3.4/32;-p ARP --arp-ip-src ! 1.2.3.4;OK
+-p ARP --arp-ip-src ! 1.2.3.4/255.255.255.0;-p ARP --arp-ip-src ! 1.2.3.0/24;OK
+-p ARP --arp-ip-src ! 1.2.3.4/255.0.255.255;-p ARP --arp-ip-src ! 1.0.3.4/255.0.255.255;OK
-p ARP --arp-mac-src 00:de:ad:be:ef:00;=;OK
-p ARP --arp-mac-dst de:ad:be:ef:00:00/ff:ff:ff:ff:00:00;=;OK
-p ARP --arp-gratuitous;=;OK
diff --git a/extensions/libebt_ip.c b/extensions/libebt_ip.c
index 8413a5aa8dd57..d13e83c06895d 100644
--- a/extensions/libebt_ip.c
+++ b/extensions/libebt_ip.c
@@ -164,80 +164,6 @@ parse_port_range(const char *protocol, const char *portstring, uint16_t *ports)
}
/* original code from ebtables: useful_functions.c */
-static int undot_ip(char *ip, unsigned char *ip2)
-{
- char *p, *q, *end;
- long int onebyte;
- int i;
- char buf[20];
-
- strncpy(buf, ip, sizeof(buf) - 1);
-
- p = buf;
- for (i = 0; i < 3; i++) {
- if ((q = strchr(p, '.')) == NULL)
- return -1;
- *q = '\0';
- onebyte = strtol(p, &end, 10);
- if (*end != '\0' || onebyte > 255 || onebyte < 0)
- return -1;
- ip2[i] = (unsigned char)onebyte;
- p = q + 1;
- }
-
- onebyte = strtol(p, &end, 10);
- if (*end != '\0' || onebyte > 255 || onebyte < 0)
- return -1;
- ip2[3] = (unsigned char)onebyte;
-
- return 0;
-}
-
-static int ip_mask(char *mask, unsigned char *mask2)
-{
- char *end;
- long int bits;
- uint32_t mask22;
-
- if (undot_ip(mask, mask2)) {
- /* not the /a.b.c.e format, maybe the /x format */
- bits = strtol(mask, &end, 10);
- if (*end != '\0' || bits > 32 || bits < 0)
- return -1;
- if (bits != 0) {
- mask22 = htonl(0xFFFFFFFF << (32 - bits));
- memcpy(mask2, &mask22, 4);
- } else {
- mask22 = 0xFFFFFFFF;
- memcpy(mask2, &mask22, 4);
- }
- }
- return 0;
-}
-
-static void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk)
-{
- char *p;
-
- /* first the mask */
- if ((p = strrchr(address, '/')) != NULL) {
- *p = '\0';
- if (ip_mask(p + 1, (unsigned char *)msk)) {
- xtables_error(PARAMETER_PROBLEM,
- "Problem with the IP mask '%s'", p + 1);
- return;
- }
- } else
- *msk = 0xFFFFFFFF;
-
- if (undot_ip(address, (unsigned char *)addr)) {
- xtables_error(PARAMETER_PROBLEM,
- "Problem with the IP address '%s'", address);
- return;
- }
- *addr = *addr & *msk;
-}
-
static char *parse_range(const char *str, unsigned int res[])
{
char *next;
@@ -355,18 +281,26 @@ brip_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_match **match)
{
struct ebt_ip_info *info = (struct ebt_ip_info *)(*match)->data;
+ struct in_addr *ipaddr, ipmask;
+ unsigned int ipnr;
switch (c) {
case IP_SOURCE:
if (invert)
info->invflags |= EBT_IP_SOURCE;
- ebt_parse_ip_address(optarg, &info->saddr, &info->smsk);
+ xtables_ipparse_any(optarg, &ipaddr, &ipmask, &ipnr);
+ info->saddr = ipaddr->s_addr;
+ info->smsk = ipmask.s_addr;
+ free(ipaddr);
info->bitmask |= EBT_IP_SOURCE;
break;
case IP_DEST:
if (invert)
info->invflags |= EBT_IP_DEST;
- ebt_parse_ip_address(optarg, &info->daddr, &info->dmsk);
+ xtables_ipparse_any(optarg, &ipaddr, &ipmask, &ipnr);
+ info->daddr = ipaddr->s_addr;
+ info->dmsk = ipmask.s_addr;
+ free(ipaddr);
info->bitmask |= EBT_IP_DEST;
break;
case IP_SPORT:
--
2.38.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [iptables PATCH 6/7] extensions: Collate ICMP types/codes in libxt_icmp.h
2022-11-12 0:20 [iptables PATCH 0/7] De-duplicate code here and there Phil Sutter
` (4 preceding siblings ...)
2022-11-12 0:20 ` [iptables PATCH 5/7] extensions: libebt_arp, libebt_ip: Use xtables_ipparse_any() Phil Sutter
@ 2022-11-12 0:20 ` Phil Sutter
2022-11-12 0:20 ` [iptables PATCH 7/7] extensions: Unify ICMP parser into libxt_icmp.h Phil Sutter
2022-11-15 16:33 ` [iptables PATCH 0/7] De-duplicate code here and there Phil Sutter
7 siblings, 0 replies; 9+ messages in thread
From: Phil Sutter @ 2022-11-12 0:20 UTC (permalink / raw)
To: netfilter-devel
Put the most extensive version of icmp_codes, icmpv6_codes and
igmp_codes into the header. Have to rename the function
xt_print_icmp_types's parameter to avoid a compiler warning.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
extensions/libebt_ip.c | 62 --------------------
extensions/libebt_ip6.c | 38 ------------
extensions/libip6t_icmp6.c | 42 --------------
extensions/libipt_icmp.c | 55 ------------------
extensions/libxt_icmp.h | 116 ++++++++++++++++++++++++++++++++++---
5 files changed, 107 insertions(+), 206 deletions(-)
diff --git a/extensions/libebt_ip.c b/extensions/libebt_ip.c
index d13e83c06895d..27ae84e9470d8 100644
--- a/extensions/libebt_ip.c
+++ b/extensions/libebt_ip.c
@@ -50,68 +50,6 @@ static const struct option brip_opts[] = {
XT_GETOPT_TABLEEND,
};
-static const struct xt_icmp_names icmp_codes[] = {
- { "echo-reply", 0, 0, 0xFF },
- /* Alias */ { "pong", 0, 0, 0xFF },
-
- { "destination-unreachable", 3, 0, 0xFF },
- { "network-unreachable", 3, 0, 0 },
- { "host-unreachable", 3, 1, 1 },
- { "protocol-unreachable", 3, 2, 2 },
- { "port-unreachable", 3, 3, 3 },
- { "fragmentation-needed", 3, 4, 4 },
- { "source-route-failed", 3, 5, 5 },
- { "network-unknown", 3, 6, 6 },
- { "host-unknown", 3, 7, 7 },
- { "network-prohibited", 3, 9, 9 },
- { "host-prohibited", 3, 10, 10 },
- { "TOS-network-unreachable", 3, 11, 11 },
- { "TOS-host-unreachable", 3, 12, 12 },
- { "communication-prohibited", 3, 13, 13 },
- { "host-precedence-violation", 3, 14, 14 },
- { "precedence-cutoff", 3, 15, 15 },
-
- { "source-quench", 4, 0, 0xFF },
-
- { "redirect", 5, 0, 0xFF },
- { "network-redirect", 5, 0, 0 },
- { "host-redirect", 5, 1, 1 },
- { "TOS-network-redirect", 5, 2, 2 },
- { "TOS-host-redirect", 5, 3, 3 },
-
- { "echo-request", 8, 0, 0xFF },
- /* Alias */ { "ping", 8, 0, 0xFF },
-
- { "router-advertisement", 9, 0, 0xFF },
-
- { "router-solicitation", 10, 0, 0xFF },
-
- { "time-exceeded", 11, 0, 0xFF },
- /* Alias */ { "ttl-exceeded", 11, 0, 0xFF },
- { "ttl-zero-during-transit", 11, 0, 0 },
- { "ttl-zero-during-reassembly", 11, 1, 1 },
-
- { "parameter-problem", 12, 0, 0xFF },
- { "ip-header-bad", 12, 0, 0 },
- { "required-option-missing", 12, 1, 1 },
-
- { "timestamp-request", 13, 0, 0xFF },
-
- { "timestamp-reply", 14, 0, 0xFF },
-
- { "address-mask-request", 17, 0, 0xFF },
-
- { "address-mask-reply", 18, 0, 0xFF }
-};
-
-static const struct xt_icmp_names igmp_types[] = {
- { "membership-query", 0x11 },
- { "membership-report-v1", 0x12 },
- { "membership-report-v2", 0x16 },
- { "leave-group", 0x17 },
- { "membership-report-v3", 0x22 },
-};
-
static void brip_print_help(void)
{
printf(
diff --git a/extensions/libebt_ip6.c b/extensions/libebt_ip6.c
index a686a285c3cb8..ac20666af5ba3 100644
--- a/extensions/libebt_ip6.c
+++ b/extensions/libebt_ip6.c
@@ -49,44 +49,6 @@ static const struct option brip6_opts[] = {
XT_GETOPT_TABLEEND,
};
-static const struct xt_icmp_names icmpv6_codes[] = {
- { "destination-unreachable", 1, 0, 0xFF },
- { "no-route", 1, 0, 0 },
- { "communication-prohibited", 1, 1, 1 },
- { "address-unreachable", 1, 3, 3 },
- { "port-unreachable", 1, 4, 4 },
-
- { "packet-too-big", 2, 0, 0xFF },
-
- { "time-exceeded", 3, 0, 0xFF },
- /* Alias */ { "ttl-exceeded", 3, 0, 0xFF },
- { "ttl-zero-during-transit", 3, 0, 0 },
- { "ttl-zero-during-reassembly", 3, 1, 1 },
-
- { "parameter-problem", 4, 0, 0xFF },
- { "bad-header", 4, 0, 0 },
- { "unknown-header-type", 4, 1, 1 },
- { "unknown-option", 4, 2, 2 },
-
- { "echo-request", 128, 0, 0xFF },
- /* Alias */ { "ping", 128, 0, 0xFF },
-
- { "echo-reply", 129, 0, 0xFF },
- /* Alias */ { "pong", 129, 0, 0xFF },
-
- { "router-solicitation", 133, 0, 0xFF },
-
- { "router-advertisement", 134, 0, 0xFF },
-
- { "neighbour-solicitation", 135, 0, 0xFF },
- /* Alias */ { "neighbor-solicitation", 135, 0, 0xFF },
-
- { "neighbour-advertisement", 136, 0, 0xFF },
- /* Alias */ { "neighbor-advertisement", 136, 0, 0xFF },
-
- { "redirect", 137, 0, 0xFF },
-};
-
static void
parse_port_range(const char *protocol, const char *portstring, uint16_t *ports)
{
diff --git a/extensions/libip6t_icmp6.c b/extensions/libip6t_icmp6.c
index cc7bfaeb72fd7..44f7109528166 100644
--- a/extensions/libip6t_icmp6.c
+++ b/extensions/libip6t_icmp6.c
@@ -12,48 +12,6 @@ enum {
O_ICMPV6_TYPE = 0,
};
-static const struct xt_icmp_names icmpv6_codes[] = {
- { "destination-unreachable", 1, 0, 0xFF },
- { "no-route", 1, 0, 0 },
- { "communication-prohibited", 1, 1, 1 },
- { "beyond-scope", 1, 2, 2 },
- { "address-unreachable", 1, 3, 3 },
- { "port-unreachable", 1, 4, 4 },
- { "failed-policy", 1, 5, 5 },
- { "reject-route", 1, 6, 6 },
-
- { "packet-too-big", 2, 0, 0xFF },
-
- { "time-exceeded", 3, 0, 0xFF },
- /* Alias */ { "ttl-exceeded", 3, 0, 0xFF },
- { "ttl-zero-during-transit", 3, 0, 0 },
- { "ttl-zero-during-reassembly", 3, 1, 1 },
-
- { "parameter-problem", 4, 0, 0xFF },
- { "bad-header", 4, 0, 0 },
- { "unknown-header-type", 4, 1, 1 },
- { "unknown-option", 4, 2, 2 },
-
- { "echo-request", 128, 0, 0xFF },
- /* Alias */ { "ping", 128, 0, 0xFF },
-
- { "echo-reply", 129, 0, 0xFF },
- /* Alias */ { "pong", 129, 0, 0xFF },
-
- { "router-solicitation", 133, 0, 0xFF },
-
- { "router-advertisement", 134, 0, 0xFF },
-
- { "neighbour-solicitation", 135, 0, 0xFF },
- /* Alias */ { "neighbor-solicitation", 135, 0, 0xFF },
-
- { "neighbour-advertisement", 136, 0, 0xFF },
- /* Alias */ { "neighbor-advertisement", 136, 0, 0xFF },
-
- { "redirect", 137, 0, 0xFF },
-
-};
-
static void icmp6_help(void)
{
printf(
diff --git a/extensions/libipt_icmp.c b/extensions/libipt_icmp.c
index e5e236613f39f..f0e838874286b 100644
--- a/extensions/libipt_icmp.c
+++ b/extensions/libipt_icmp.c
@@ -19,61 +19,6 @@ enum {
O_ICMP_TYPE = 0,
};
-static const struct xt_icmp_names icmp_codes[] = {
- { "any", 0xFF, 0, 0xFF },
- { "echo-reply", 0, 0, 0xFF },
- /* Alias */ { "pong", 0, 0, 0xFF },
-
- { "destination-unreachable", 3, 0, 0xFF },
- { "network-unreachable", 3, 0, 0 },
- { "host-unreachable", 3, 1, 1 },
- { "protocol-unreachable", 3, 2, 2 },
- { "port-unreachable", 3, 3, 3 },
- { "fragmentation-needed", 3, 4, 4 },
- { "source-route-failed", 3, 5, 5 },
- { "network-unknown", 3, 6, 6 },
- { "host-unknown", 3, 7, 7 },
- { "network-prohibited", 3, 9, 9 },
- { "host-prohibited", 3, 10, 10 },
- { "TOS-network-unreachable", 3, 11, 11 },
- { "TOS-host-unreachable", 3, 12, 12 },
- { "communication-prohibited", 3, 13, 13 },
- { "host-precedence-violation", 3, 14, 14 },
- { "precedence-cutoff", 3, 15, 15 },
-
- { "source-quench", 4, 0, 0xFF },
-
- { "redirect", 5, 0, 0xFF },
- { "network-redirect", 5, 0, 0 },
- { "host-redirect", 5, 1, 1 },
- { "TOS-network-redirect", 5, 2, 2 },
- { "TOS-host-redirect", 5, 3, 3 },
-
- { "echo-request", 8, 0, 0xFF },
- /* Alias */ { "ping", 8, 0, 0xFF },
-
- { "router-advertisement", 9, 0, 0xFF },
-
- { "router-solicitation", 10, 0, 0xFF },
-
- { "time-exceeded", 11, 0, 0xFF },
- /* Alias */ { "ttl-exceeded", 11, 0, 0xFF },
- { "ttl-zero-during-transit", 11, 0, 0 },
- { "ttl-zero-during-reassembly", 11, 1, 1 },
-
- { "parameter-problem", 12, 0, 0xFF },
- { "ip-header-bad", 12, 0, 0 },
- { "required-option-missing", 12, 1, 1 },
-
- { "timestamp-request", 13, 0, 0xFF },
-
- { "timestamp-reply", 14, 0, 0xFF },
-
- { "address-mask-request", 17, 0, 0xFF },
-
- { "address-mask-reply", 18, 0, 0xFF }
-};
-
static void icmp_help(void)
{
printf(
diff --git a/extensions/libxt_icmp.h b/extensions/libxt_icmp.h
index 5820206ef469e..d6d9f9b6ffc98 100644
--- a/extensions/libxt_icmp.h
+++ b/extensions/libxt_icmp.h
@@ -1,25 +1,123 @@
-struct xt_icmp_names {
+static const struct xt_icmp_names {
const char *name;
uint8_t type;
uint8_t code_min, code_max;
+} icmp_codes[] = {
+ { "any", 0xFF, 0, 0xFF },
+ { "echo-reply", 0, 0, 0xFF },
+ /* Alias */ { "pong", 0, 0, 0xFF },
+
+ { "destination-unreachable", 3, 0, 0xFF },
+ { "network-unreachable", 3, 0, 0 },
+ { "host-unreachable", 3, 1, 1 },
+ { "protocol-unreachable", 3, 2, 2 },
+ { "port-unreachable", 3, 3, 3 },
+ { "fragmentation-needed", 3, 4, 4 },
+ { "source-route-failed", 3, 5, 5 },
+ { "network-unknown", 3, 6, 6 },
+ { "host-unknown", 3, 7, 7 },
+ { "network-prohibited", 3, 9, 9 },
+ { "host-prohibited", 3, 10, 10 },
+ { "TOS-network-unreachable", 3, 11, 11 },
+ { "TOS-host-unreachable", 3, 12, 12 },
+ { "communication-prohibited", 3, 13, 13 },
+ { "host-precedence-violation", 3, 14, 14 },
+ { "precedence-cutoff", 3, 15, 15 },
+
+ { "source-quench", 4, 0, 0xFF },
+
+ { "redirect", 5, 0, 0xFF },
+ { "network-redirect", 5, 0, 0 },
+ { "host-redirect", 5, 1, 1 },
+ { "TOS-network-redirect", 5, 2, 2 },
+ { "TOS-host-redirect", 5, 3, 3 },
+
+ { "echo-request", 8, 0, 0xFF },
+ /* Alias */ { "ping", 8, 0, 0xFF },
+
+ { "router-advertisement", 9, 0, 0xFF },
+
+ { "router-solicitation", 10, 0, 0xFF },
+
+ { "time-exceeded", 11, 0, 0xFF },
+ /* Alias */ { "ttl-exceeded", 11, 0, 0xFF },
+ { "ttl-zero-during-transit", 11, 0, 0 },
+ { "ttl-zero-during-reassembly", 11, 1, 1 },
+
+ { "parameter-problem", 12, 0, 0xFF },
+ { "ip-header-bad", 12, 0, 0 },
+ { "required-option-missing", 12, 1, 1 },
+
+ { "timestamp-request", 13, 0, 0xFF },
+
+ { "timestamp-reply", 14, 0, 0xFF },
+
+ { "address-mask-request", 17, 0, 0xFF },
+
+ { "address-mask-reply", 18, 0, 0xFF }
+}, icmpv6_codes[] = {
+ { "destination-unreachable", 1, 0, 0xFF },
+ { "no-route", 1, 0, 0 },
+ { "communication-prohibited", 1, 1, 1 },
+ { "beyond-scope", 1, 2, 2 },
+ { "address-unreachable", 1, 3, 3 },
+ { "port-unreachable", 1, 4, 4 },
+ { "failed-policy", 1, 5, 5 },
+ { "reject-route", 1, 6, 6 },
+
+ { "packet-too-big", 2, 0, 0xFF },
+
+ { "time-exceeded", 3, 0, 0xFF },
+ /* Alias */ { "ttl-exceeded", 3, 0, 0xFF },
+ { "ttl-zero-during-transit", 3, 0, 0 },
+ { "ttl-zero-during-reassembly", 3, 1, 1 },
+
+ { "parameter-problem", 4, 0, 0xFF },
+ { "bad-header", 4, 0, 0 },
+ { "unknown-header-type", 4, 1, 1 },
+ { "unknown-option", 4, 2, 2 },
+
+ { "echo-request", 128, 0, 0xFF },
+ /* Alias */ { "ping", 128, 0, 0xFF },
+
+ { "echo-reply", 129, 0, 0xFF },
+ /* Alias */ { "pong", 129, 0, 0xFF },
+
+ { "router-solicitation", 133, 0, 0xFF },
+
+ { "router-advertisement", 134, 0, 0xFF },
+
+ { "neighbour-solicitation", 135, 0, 0xFF },
+ /* Alias */ { "neighbor-solicitation", 135, 0, 0xFF },
+
+ { "neighbour-advertisement", 136, 0, 0xFF },
+ /* Alias */ { "neighbor-advertisement", 136, 0, 0xFF },
+
+ { "redirect", 137, 0, 0xFF },
+}, igmp_types[] = {
+ { "membership-query", 0x11 },
+ { "membership-report-v1", 0x12 },
+ { "membership-report-v2", 0x16 },
+ { "leave-group", 0x17 },
+ { "membership-report-v3", 0x22 },
};
-static void xt_print_icmp_types(const struct xt_icmp_names *icmp_codes,
+static void xt_print_icmp_types(const struct xt_icmp_names *_icmp_codes,
unsigned int n_codes)
{
unsigned int i;
for (i = 0; i < n_codes; ++i) {
- if (i && icmp_codes[i].type == icmp_codes[i-1].type) {
- if (icmp_codes[i].code_min == icmp_codes[i-1].code_min
- && (icmp_codes[i].code_max
- == icmp_codes[i-1].code_max))
- printf(" (%s)", icmp_codes[i].name);
+ if (i && _icmp_codes[i].type == _icmp_codes[i-1].type) {
+ if (_icmp_codes[i].code_min == _icmp_codes[i-1].code_min
+ && (_icmp_codes[i].code_max
+ == _icmp_codes[i-1].code_max))
+ printf(" (%s)", _icmp_codes[i].name);
else
- printf("\n %s", icmp_codes[i].name);
+ printf("\n %s", _icmp_codes[i].name);
}
else
- printf("\n%s", icmp_codes[i].name);
+ printf("\n%s", _icmp_codes[i].name);
}
printf("\n");
}
--
2.38.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [iptables PATCH 7/7] extensions: Unify ICMP parser into libxt_icmp.h
2022-11-12 0:20 [iptables PATCH 0/7] De-duplicate code here and there Phil Sutter
` (5 preceding siblings ...)
2022-11-12 0:20 ` [iptables PATCH 6/7] extensions: Collate ICMP types/codes in libxt_icmp.h Phil Sutter
@ 2022-11-12 0:20 ` Phil Sutter
2022-11-15 16:33 ` [iptables PATCH 0/7] De-duplicate code here and there Phil Sutter
7 siblings, 0 replies; 9+ messages in thread
From: Phil Sutter @ 2022-11-12 0:20 UTC (permalink / raw)
To: netfilter-devel
Merge all four copies of the ICMP/ICMPv6/IGMP parameter parsing code.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
extensions/libebt_ip.c | 82 +-----------------------
extensions/libebt_ip6.c | 73 +--------------------
extensions/libip6t_icmp6.c | 55 +---------------
extensions/libipt_icmp.c | 55 +---------------
extensions/libxt_icmp.h | 126 +++++++++++++++++++++++++++++++++++++
5 files changed, 131 insertions(+), 260 deletions(-)
diff --git a/extensions/libebt_ip.c b/extensions/libebt_ip.c
index 27ae84e9470d8..fd87dae7e2c62 100644
--- a/extensions/libebt_ip.c
+++ b/extensions/libebt_ip.c
@@ -102,82 +102,6 @@ parse_port_range(const char *protocol, const char *portstring, uint16_t *ports)
}
/* original code from ebtables: useful_functions.c */
-static char *parse_range(const char *str, unsigned int res[])
-{
- char *next;
-
- if (!xtables_strtoui(str, &next, &res[0], 0, 255))
- return NULL;
-
- res[1] = res[0];
- if (*next == ':') {
- str = next + 1;
- if (!xtables_strtoui(str, &next, &res[1], 0, 255))
- return NULL;
- }
-
- return next;
-}
-
-static int ebt_parse_icmp(const struct xt_icmp_names *codes, size_t n_codes,
- const char *icmptype, uint8_t type[], uint8_t code[])
-{
- unsigned int match = n_codes;
- unsigned int i, number[2];
-
- for (i = 0; i < n_codes; i++) {
- if (strncasecmp(codes[i].name, icmptype, strlen(icmptype)))
- continue;
- if (match != n_codes)
- xtables_error(PARAMETER_PROBLEM, "Ambiguous ICMP type `%s':"
- " `%s' or `%s'?",
- icmptype, codes[match].name,
- codes[i].name);
- match = i;
- }
-
- if (match < n_codes) {
- type[0] = type[1] = codes[match].type;
- if (code) {
- code[0] = codes[match].code_min;
- code[1] = codes[match].code_max;
- }
- } else {
- char *next = parse_range(icmptype, number);
- if (!next) {
- xtables_error(PARAMETER_PROBLEM, "Unknown ICMP type `%s'",
- icmptype);
- return -1;
- }
-
- type[0] = (uint8_t) number[0];
- type[1] = (uint8_t) number[1];
- switch (*next) {
- case 0:
- if (code) {
- code[0] = 0;
- code[1] = 255;
- }
- return 0;
- case '/':
- if (code) {
- next = parse_range(next+1, number);
- code[0] = (uint8_t) number[0];
- code[1] = (uint8_t) number[1];
- if (next == NULL)
- return -1;
- if (next && *next == 0)
- return 0;
- }
- /* fallthrough */
- default:
- xtables_error(PARAMETER_PROBLEM, "unknown character %c", *next);
- return -1;
- }
- }
- return 0;
-}
-
static void print_icmp_code(uint8_t *code)
{
if (!code)
@@ -256,15 +180,13 @@ brip_parse(int c, char **argv, int invert, unsigned int *flags,
case IP_EBT_ICMP:
if (invert)
info->invflags |= EBT_IP_ICMP;
- ebt_parse_icmp(icmp_codes, ARRAY_SIZE(icmp_codes), optarg,
- info->icmp_type, info->icmp_code);
+ ebt_parse_icmp(optarg, info->icmp_type, info->icmp_code);
info->bitmask |= EBT_IP_ICMP;
break;
case IP_EBT_IGMP:
if (invert)
info->invflags |= EBT_IP_IGMP;
- ebt_parse_icmp(igmp_types, ARRAY_SIZE(igmp_types), optarg,
- info->igmp_type, NULL);
+ ebt_parse_igmp(optarg, info->igmp_type);
info->bitmask |= EBT_IP_IGMP;
break;
case IP_EBT_TOS: {
diff --git a/extensions/libebt_ip6.c b/extensions/libebt_ip6.c
index ac20666af5ba3..18bb2720ccbec 100644
--- a/extensions/libebt_ip6.c
+++ b/extensions/libebt_ip6.c
@@ -72,76 +72,6 @@ parse_port_range(const char *protocol, const char *portstring, uint16_t *ports)
free(buffer);
}
-static char *parse_range(const char *str, unsigned int res[])
-{
- char *next;
-
- if (!xtables_strtoui(str, &next, &res[0], 0, 255))
- return NULL;
-
- res[1] = res[0];
- if (*next == ':') {
- str = next + 1;
- if (!xtables_strtoui(str, &next, &res[1], 0, 255))
- return NULL;
- }
-
- return next;
-}
-
-static int
-parse_icmpv6(const char *icmpv6type, uint8_t type[], uint8_t code[])
-{
- static const unsigned int limit = ARRAY_SIZE(icmpv6_codes);
- unsigned int match = limit;
- unsigned int i, number[2];
-
- for (i = 0; i < limit; i++) {
- if (strncasecmp(icmpv6_codes[i].name, icmpv6type, strlen(icmpv6type)))
- continue;
- if (match != limit)
- xtables_error(PARAMETER_PROBLEM, "Ambiguous ICMPv6 type `%s':"
- " `%s' or `%s'?",
- icmpv6type, icmpv6_codes[match].name,
- icmpv6_codes[i].name);
- match = i;
- }
-
- if (match < limit) {
- type[0] = type[1] = icmpv6_codes[match].type;
- code[0] = icmpv6_codes[match].code_min;
- code[1] = icmpv6_codes[match].code_max;
- } else {
- char *next = parse_range(icmpv6type, number);
- if (!next) {
- xtables_error(PARAMETER_PROBLEM, "Unknown ICMPv6 type `%s'",
- icmpv6type);
- return -1;
- }
- type[0] = (uint8_t) number[0];
- type[1] = (uint8_t) number[1];
- switch (*next) {
- case 0:
- code[0] = 0;
- code[1] = 255;
- return 0;
- case '/':
- next = parse_range(next+1, number);
- code[0] = (uint8_t) number[0];
- code[1] = (uint8_t) number[1];
- if (next == NULL)
- return -1;
- if (next && *next == 0)
- return 0;
- /* fallthrough */
- default:
- xtables_error(PARAMETER_PROBLEM, "unknown character %c", *next);
- return -1;
- }
- }
- return 0;
-}
-
static void print_port_range(uint16_t *ports)
{
if (ports[0] == ports[1])
@@ -266,8 +196,7 @@ brip6_parse(int c, char **argv, int invert, unsigned int *flags,
case IP_ICMP6:
if (invert)
info->invflags |= EBT_IP6_ICMP6;
- if (parse_icmpv6(optarg, info->icmpv6_type, info->icmpv6_code))
- return 0;
+ ebt_parse_icmpv6(optarg, info->icmpv6_type, info->icmpv6_code);
info->bitmask |= EBT_IP6_ICMP6;
break;
case IP_TCLASS:
diff --git a/extensions/libip6t_icmp6.c b/extensions/libip6t_icmp6.c
index 44f7109528166..439291eaaaca5 100644
--- a/extensions/libip6t_icmp6.c
+++ b/extensions/libip6t_icmp6.c
@@ -28,59 +28,6 @@ static const struct xt_option_entry icmp6_opts[] = {
XTOPT_TABLEEND,
};
-static void
-parse_icmpv6(const char *icmpv6type, uint8_t *type, uint8_t code[])
-{
- static const unsigned int limit = ARRAY_SIZE(icmpv6_codes);
- unsigned int match = limit;
- unsigned int i;
-
- for (i = 0; i < limit; i++) {
- if (strncasecmp(icmpv6_codes[i].name, icmpv6type, strlen(icmpv6type))
- == 0) {
- if (match != limit)
- xtables_error(PARAMETER_PROBLEM,
- "Ambiguous ICMPv6 type `%s':"
- " `%s' or `%s'?",
- icmpv6type,
- icmpv6_codes[match].name,
- icmpv6_codes[i].name);
- match = i;
- }
- }
-
- if (match != limit) {
- *type = icmpv6_codes[match].type;
- code[0] = icmpv6_codes[match].code_min;
- code[1] = icmpv6_codes[match].code_max;
- } else {
- char *slash;
- char buffer[strlen(icmpv6type) + 1];
- unsigned int number;
-
- strcpy(buffer, icmpv6type);
- slash = strchr(buffer, '/');
-
- if (slash)
- *slash = '\0';
-
- if (!xtables_strtoui(buffer, NULL, &number, 0, UINT8_MAX))
- xtables_error(PARAMETER_PROBLEM,
- "Invalid ICMPv6 type `%s'\n", buffer);
- *type = number;
- if (slash) {
- if (!xtables_strtoui(slash+1, NULL, &number, 0, UINT8_MAX))
- xtables_error(PARAMETER_PROBLEM,
- "Invalid ICMPv6 code `%s'\n",
- slash+1);
- code[0] = code[1] = number;
- } else {
- code[0] = 0;
- code[1] = 0xFF;
- }
- }
-}
-
static void icmp6_init(struct xt_entry_match *m)
{
struct ip6t_icmp *icmpv6info = (struct ip6t_icmp *)m->data;
@@ -93,7 +40,7 @@ static void icmp6_parse(struct xt_option_call *cb)
struct ip6t_icmp *icmpv6info = cb->data;
xtables_option_parse(cb);
- parse_icmpv6(cb->arg, &icmpv6info->type, icmpv6info->code);
+ ipt_parse_icmpv6(cb->arg, &icmpv6info->type, icmpv6info->code);
if (cb->invert)
icmpv6info->invflags |= IP6T_ICMP_INV;
}
diff --git a/extensions/libipt_icmp.c b/extensions/libipt_icmp.c
index f0e838874286b..b0318aebc2c57 100644
--- a/extensions/libipt_icmp.c
+++ b/extensions/libipt_icmp.c
@@ -35,59 +35,6 @@ static const struct xt_option_entry icmp_opts[] = {
XTOPT_TABLEEND,
};
-static void
-parse_icmp(const char *icmptype, uint8_t *type, uint8_t code[])
-{
- static const unsigned int limit = ARRAY_SIZE(icmp_codes);
- unsigned int match = limit;
- unsigned int i;
-
- for (i = 0; i < limit; i++) {
- if (strncasecmp(icmp_codes[i].name, icmptype, strlen(icmptype))
- == 0) {
- if (match != limit)
- xtables_error(PARAMETER_PROBLEM,
- "Ambiguous ICMP type `%s':"
- " `%s' or `%s'?",
- icmptype,
- icmp_codes[match].name,
- icmp_codes[i].name);
- match = i;
- }
- }
-
- if (match != limit) {
- *type = icmp_codes[match].type;
- code[0] = icmp_codes[match].code_min;
- code[1] = icmp_codes[match].code_max;
- } else {
- char *slash;
- char buffer[strlen(icmptype) + 1];
- unsigned int number;
-
- strcpy(buffer, icmptype);
- slash = strchr(buffer, '/');
-
- if (slash)
- *slash = '\0';
-
- if (!xtables_strtoui(buffer, NULL, &number, 0, UINT8_MAX))
- xtables_error(PARAMETER_PROBLEM,
- "Invalid ICMP type `%s'\n", buffer);
- *type = number;
- if (slash) {
- if (!xtables_strtoui(slash+1, NULL, &number, 0, UINT8_MAX))
- xtables_error(PARAMETER_PROBLEM,
- "Invalid ICMP code `%s'\n",
- slash+1);
- code[0] = code[1] = number;
- } else {
- code[0] = 0;
- code[1] = 0xFF;
- }
- }
-}
-
static void icmp_init(struct xt_entry_match *m)
{
struct ipt_icmp *icmpinfo = (struct ipt_icmp *)m->data;
@@ -101,7 +48,7 @@ static void icmp_parse(struct xt_option_call *cb)
struct ipt_icmp *icmpinfo = cb->data;
xtables_option_parse(cb);
- parse_icmp(cb->arg, &icmpinfo->type, icmpinfo->code);
+ ipt_parse_icmp(cb->arg, &icmpinfo->type, icmpinfo->code);
if (cb->invert)
icmpinfo->invflags |= IPT_ICMP_INV;
}
diff --git a/extensions/libxt_icmp.h b/extensions/libxt_icmp.h
index d6d9f9b6ffc98..a763e50c1de32 100644
--- a/extensions/libxt_icmp.h
+++ b/extensions/libxt_icmp.h
@@ -102,6 +102,132 @@ static const struct xt_icmp_names {
{ "membership-report-v3", 0x22 },
};
+static inline char *parse_range(const char *str, unsigned int res[])
+{
+ char *next;
+
+ if (!xtables_strtoui(str, &next, &res[0], 0, 255))
+ return NULL;
+
+ res[1] = res[0];
+ if (*next == ':') {
+ str = next + 1;
+ if (!xtables_strtoui(str, &next, &res[1], 0, 255))
+ return NULL;
+ }
+
+ return next;
+}
+
+static void
+__parse_icmp(const struct xt_icmp_names codes[], size_t n_codes,
+ const char *codes_name, const char *fmtstring,
+ uint8_t type[], uint8_t code[])
+{
+ unsigned int match = n_codes;
+ unsigned int i, number[2];
+
+ for (i = 0; i < n_codes; i++) {
+ if (strncasecmp(codes[i].name, fmtstring, strlen(fmtstring)))
+ continue;
+ if (match != n_codes)
+ xtables_error(PARAMETER_PROBLEM,
+ "Ambiguous %s type `%s': `%s' or `%s'?",
+ codes_name, fmtstring, codes[match].name,
+ codes[i].name);
+ match = i;
+ }
+
+ if (match < n_codes) {
+ type[0] = type[1] = codes[match].type;
+ if (code) {
+ code[0] = codes[match].code_min;
+ code[1] = codes[match].code_max;
+ }
+ } else {
+ char *next = parse_range(fmtstring, number);
+ if (!next)
+ xtables_error(PARAMETER_PROBLEM, "Unknown %s type `%s'",
+ codes_name, fmtstring);
+ type[0] = (uint8_t) number[0];
+ type[1] = (uint8_t) number[1];
+ switch (*next) {
+ case 0:
+ if (code) {
+ code[0] = 0;
+ code[1] = 255;
+ }
+ return;
+ case '/':
+ if (!code)
+ break;
+
+ next = parse_range(next + 1, number);
+ if (!next)
+ xtables_error(PARAMETER_PROBLEM,
+ "Unknown %s code `%s'",
+ codes_name, fmtstring);
+ code[0] = (uint8_t) number[0];
+ code[1] = (uint8_t) number[1];
+ if (!*next)
+ break;
+ /* fallthrough */
+ default:
+ xtables_error(PARAMETER_PROBLEM,
+ "unknown character %c", *next);
+ }
+ }
+}
+
+static inline void
+__ipt_parse_icmp(const struct xt_icmp_names *codes, size_t n_codes,
+ const char *codes_name, const char *fmtstr,
+ uint8_t *type, uint8_t code[])
+{
+ uint8_t types[2];
+
+ __parse_icmp(codes, n_codes, codes_name, fmtstr, types, code);
+ if (types[1] != types[0])
+ xtables_error(PARAMETER_PROBLEM,
+ "%s type range not supported", codes_name);
+ *type = types[0];
+}
+
+static inline void
+ipt_parse_icmp(const char *str, uint8_t *type, uint8_t code[])
+{
+ __ipt_parse_icmp(icmp_codes, ARRAY_SIZE(icmp_codes),
+ "ICMP", str, type, code);
+}
+
+static inline void
+ipt_parse_icmpv6(const char *str, uint8_t *type, uint8_t code[])
+{
+ __ipt_parse_icmp(icmpv6_codes, ARRAY_SIZE(icmpv6_codes),
+ "ICMPv6", str, type, code);
+}
+
+static inline void
+ebt_parse_icmp(const char *str, uint8_t type[], uint8_t code[])
+{
+ __parse_icmp(icmp_codes, ARRAY_SIZE(icmp_codes),
+ "ICMP", str, type, code);
+}
+
+static inline void
+ebt_parse_icmpv6(const char *str, uint8_t type[], uint8_t code[])
+{
+ __parse_icmp(icmpv6_codes, ARRAY_SIZE(icmpv6_codes),
+ "ICMPv6", str, type, code);
+}
+
+static inline void
+ebt_parse_igmp(const char *str, uint8_t type[])
+{
+ __parse_icmp(igmp_types, ARRAY_SIZE(igmp_types),
+ "IGMP", str, type, NULL);
+}
+
static void xt_print_icmp_types(const struct xt_icmp_names *_icmp_codes,
unsigned int n_codes)
{
--
2.38.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [iptables PATCH 0/7] De-duplicate code here and there
2022-11-12 0:20 [iptables PATCH 0/7] De-duplicate code here and there Phil Sutter
` (6 preceding siblings ...)
2022-11-12 0:20 ` [iptables PATCH 7/7] extensions: Unify ICMP parser into libxt_icmp.h Phil Sutter
@ 2022-11-15 16:33 ` Phil Sutter
7 siblings, 0 replies; 9+ messages in thread
From: Phil Sutter @ 2022-11-15 16:33 UTC (permalink / raw)
To: netfilter-devel
On Sat, Nov 12, 2022 at 01:20:49AM +0100, Phil Sutter wrote:
> A series of unrelated patches reducing code size in different ways:
>
> Patch 1 is a typical "move function to xshared.c for common use", patch
> 2 eliminates some c'n'p programming in nft-shared.c, patch 3 merges
> libipt_LOG.c and libip6t_LOG.c, patch 4 removes code from libebt_ip.c by
> including the right header, patch 5 drops some local IP address parsers
> in favor of the respective libxtables function and patches 6 and 7 move
> duplicate definitions and code into a header shared by multiple
> extensions.
>
> Phil Sutter (7):
> xshared: Share make_delete_mask() between ip{,6}tables
> nft-shared: Introduce port_match_single_to_range()
> extensions: libip*t_LOG: Merge extensions
> extensions: libebt_ip: Include kernel header
> extensions: libebt_arp, libebt_ip: Use xtables_ipparse_any()
> extensions: Collate ICMP types/codes in libxt_icmp.h
> extensions: Unify ICMP parser into libxt_icmp.h
Series applied.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2022-11-15 16:34 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-11-12 0:20 [iptables PATCH 0/7] De-duplicate code here and there Phil Sutter
2022-11-12 0:20 ` [iptables PATCH 1/7] xshared: Share make_delete_mask() between ip{,6}tables Phil Sutter
2022-11-12 0:20 ` [iptables PATCH 2/7] nft-shared: Introduce port_match_single_to_range() Phil Sutter
2022-11-12 0:20 ` [iptables PATCH 3/7] extensions: libip*t_LOG: Merge extensions Phil Sutter
2022-11-12 0:20 ` [iptables PATCH 4/7] extensions: libebt_ip: Include kernel header Phil Sutter
2022-11-12 0:20 ` [iptables PATCH 5/7] extensions: libebt_arp, libebt_ip: Use xtables_ipparse_any() Phil Sutter
2022-11-12 0:20 ` [iptables PATCH 6/7] extensions: Collate ICMP types/codes in libxt_icmp.h Phil Sutter
2022-11-12 0:20 ` [iptables PATCH 7/7] extensions: Unify ICMP parser into libxt_icmp.h Phil Sutter
2022-11-15 16:33 ` [iptables PATCH 0/7] De-duplicate code here and there Phil Sutter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).