summaryrefslogtreecommitdiffstats
path: root/iptables/nft-arp.c
diff options
context:
space:
mode:
Diffstat (limited to 'iptables/nft-arp.c')
-rw-r--r--iptables/nft-arp.c111
1 files changed, 55 insertions, 56 deletions
diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
index f45ad0f7..503c65af 100644
--- a/iptables/nft-arp.c
+++ b/iptables/nft-arp.c
@@ -137,82 +137,78 @@ static void print_mac_and_mask(const unsigned char *mac, const unsigned char *ma
print_mac(mask, l);
}
-static uint8_t arpt_to_ipt_flags(uint16_t invflags)
-{
- uint8_t result = 0;
-
- if (invflags & ARPT_INV_VIA_IN)
- result |= IPT_INV_VIA_IN;
-
- if (invflags & ARPT_INV_VIA_OUT)
- result |= IPT_INV_VIA_OUT;
-
- if (invflags & ARPT_INV_SRCIP)
- result |= IPT_INV_SRCIP;
-
- if (invflags & ARPT_INV_TGTIP)
- result |= IPT_INV_DSTIP;
-
- if (invflags & ARPT_INV_ARPPRO)
- result |= IPT_INV_PROTO;
-
- return result;
-}
-
static int nft_arp_add(struct nft_rule *r, void *data)
{
struct arptables_command_state *cs = data;
struct arpt_entry *fw = &cs->fw;
- uint8_t flags = arpt_to_ipt_flags(fw->arp.invflags);
+ uint32_t op;
int ret = 0;
- if (fw->arp.iniface[0] != '\0')
- add_iniface(r, fw->arp.iniface, flags);
+ if (fw->arp.iniface[0] != '\0') {
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_VIA_IN);
+ add_iniface(r, fw->arp.iniface, op);
+ }
- if (fw->arp.outiface[0] != '\0')
- add_outiface(r, fw->arp.outiface, flags);
+ if (fw->arp.outiface[0] != '\0') {
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_VIA_OUT);
+ add_outiface(r, fw->arp.outiface, op);
+ }
if (fw->arp.arhrd != 0) {
- add_payload(r, offsetof(struct arphdr, ar_hrd), 2);
- add_cmp_u16(r, fw->arp.arhrd, NFT_CMP_EQ);
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_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) {
- add_payload(r, offsetof(struct arphdr, ar_pro), 2);
- add_cmp_u16(r, fw->arp.arpro, NFT_CMP_EQ);
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPPRO);
+ 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)
+ if (fw->arp.arhln != 0) {
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPHLN);
add_proto(r, offsetof(struct arphdr, ar_hln), 1,
- fw->arp.arhln, flags);
+ fw->arp.arhln, op);
+ }
- add_proto(r, offsetof(struct arphdr, ar_pln), 1, 4, 0);
+ add_proto(r, offsetof(struct arphdr, ar_pln), 1, 4, NFT_CMP_EQ);
if (fw->arp.arpop != 0) {
- add_payload(r, offsetof(struct arphdr, ar_op), 2);
- add_cmp_u16(r, fw->arp.arpop, NFT_CMP_EQ);
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPOP);
+ add_payload(r, offsetof(struct arphdr, ar_op), 2,
+ NFT_PAYLOAD_NETWORK_HEADER);
+ add_cmp_u16(r, fw->arp.arpop, op);
}
if (fw->arp.src_devaddr.addr[0] != '\0') {
- add_payload(r, sizeof(struct arphdr), fw->arp.arhln);
- add_cmp_ptr(r, NFT_CMP_EQ, fw->arp.src_devaddr.addr, fw->arp.arhln);
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCDEVADDR);
+ add_payload(r, sizeof(struct arphdr), fw->arp.arhln,
+ NFT_PAYLOAD_NETWORK_HEADER);
+ add_cmp_ptr(r, op, fw->arp.src_devaddr.addr, fw->arp.arhln);
}
if (fw->arp.src.s_addr != 0) {
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCIP);
add_addr(r, sizeof(struct arphdr) + fw->arp.arhln,
&fw->arp.src.s_addr, &fw->arp.smsk.s_addr,
- sizeof(struct in_addr), flags);
+ sizeof(struct in_addr), op);
}
if (fw->arp.tgt_devaddr.addr[0] != '\0') {
- add_payload(r, sizeof(struct arphdr) + fw->arp.arhln + 4, fw->arp.arhln);
- add_cmp_ptr(r, NFT_CMP_EQ, fw->arp.tgt_devaddr.addr, fw->arp.arhln);
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTDEVADDR);
+ add_payload(r, sizeof(struct arphdr) + fw->arp.arhln + 4,
+ fw->arp.arhln, NFT_PAYLOAD_NETWORK_HEADER);
+ add_cmp_ptr(r, op, fw->arp.tgt_devaddr.addr, fw->arp.arhln);
}
if (fw->arp.tgt.s_addr != 0) {
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTIP);
add_addr(r, sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr),
&fw->arp.tgt.s_addr, &fw->arp.tmsk.s_addr,
- sizeof(struct in_addr), flags);
+ sizeof(struct in_addr), op);
}
/* Counters need to me added before the target, otherwise they are
@@ -341,10 +337,12 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
fw->arp.arhln) {
get_cmp_data(e, &addr, sizeof(addr), &inv);
fw->arp.src.s_addr = addr.s_addr;
- if (ctx->flags & NFT_XT_CTX_BITWISE)
+ if (ctx->flags & NFT_XT_CTX_BITWISE) {
parse_mask_ipv4(ctx, &fw->arp.smsk);
- else
+ ctx->flags &= ~NFT_XT_CTX_BITWISE;
+ } else {
fw->arp.smsk.s_addr = 0xffffffff;
+ }
if (inv)
fw->arp.invflags |= ARPT_INV_SRCIP;
@@ -353,10 +351,12 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
sizeof(struct in_addr)) {
get_cmp_data(e, &addr, sizeof(addr), &inv);
fw->arp.tgt.s_addr = addr.s_addr;
- if (ctx->flags & NFT_XT_CTX_BITWISE)
+ if (ctx->flags & NFT_XT_CTX_BITWISE) {
parse_mask_ipv4(ctx, &fw->arp.tmsk);
- else
+ ctx->flags &= ~NFT_XT_CTX_BITWISE;
+ } else {
fw->arp.tmsk.s_addr = 0xffffffff;
+ }
if (inv)
fw->arp.invflags |= ARPT_INV_TGTIP;
@@ -406,10 +406,11 @@ void nft_rule_to_arptables_command_state(struct nft_rule *r,
nft_rule_expr_iter_destroy(iter);
- if (cs->target != NULL)
- cs->jumpto = cs->target->name;
- else if (cs->jumpto != NULL)
- cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
+ if (cs->jumpto != NULL)
+ return;
+
+ if (cs->target != NULL && cs->target->name != NULL)
+ cs->target = xtables_find_target(cs->target->name, XTF_TRY_LOAD);
else
cs->jumpto = "";
}
@@ -589,13 +590,11 @@ nft_arp_print_firewall(struct nft_rule *r, unsigned int num,
print_fw_details(&cs.fw, format);
- if (strlen(cs.jumpto) > 0) {
- printf("-j %s\n", cs.jumpto);
+ if (cs.jumpto != NULL && strcmp(cs.jumpto, "") != 0) {
+ printf("-j %s", cs.jumpto);
} else if (cs.target) {
- if (cs.target->print)
- /* Print the target information. */
- cs.target->print(&cs.fw, cs.target->t,
- format & FMT_NUMERIC);
+ printf("-j %s", cs.target->name);
+ cs.target->print(&cs.fw, cs.target->t, format & FMT_NUMERIC);
}
if (!(format & FMT_NOCOUNTS)) {