1077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka/*
2077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org>
3077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka * (C) 2013 by Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
4077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka *
5077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka * This program is free software; you can redistribute it and/or modify
6077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka * it under the terms of the GNU General Public License as published by
7077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka * the Free Software Foundation; either version 2 of the License, or
8077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka * (at your option) any later version.
9077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka *
10077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka * This code has been sponsored by Sophos Astaro <http://www.sophos.com>
11077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka */
12077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
13077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka#include <string.h>
14077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka#include <stdio.h>
15e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka#include <stdlib.h>
16077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka#include <stdbool.h>
17077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka#include <netdb.h>
18e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka#include <errno.h>
19e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
20e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka#include <xtables.h>
21077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
22077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka#include <linux/netfilter/nf_tables.h>
23077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
24077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka#include <libmnl/libmnl.h>
25a4e1098169a67716a81316c36ce22ddcb33df1c0Tomasz Bursztyka#include <libnftnl/rule.h>
26a4e1098169a67716a81316c36ce22ddcb33df1c0Tomasz Bursztyka#include <libnftnl/expr.h>
27077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
28077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka#include "nft-shared.h"
2942cfeee024d0ba0c6b15645f829273ee3dcfa5c6Arturo Borrero#include "nft-bridge.h"
30077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka#include "xshared.h"
31ea23cfc0e663a934b05e5c09cbed5cda3c999f6fTomasz Bursztyka#include "nft.h"
32077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
33077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztykaextern struct nft_family_ops nft_family_ops_ipv4;
34077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztykaextern struct nft_family_ops nft_family_ops_ipv6;
3584909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longoextern struct nft_family_ops nft_family_ops_arp;
36da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayusoextern struct nft_family_ops nft_family_ops_bridge;
37077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
38742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid add_meta(struct nftnl_rule *r, uint32_t key)
39077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka{
40742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	struct nftnl_expr *expr;
41077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
42742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	expr = nftnl_expr_alloc("meta");
43077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	if (expr == NULL)
44077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		return;
45077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
46742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set_u32(expr, NFTNL_EXPR_META_KEY, key);
47742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set_u32(expr, NFTNL_EXPR_META_DREG, NFT_REG_1);
48077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
49742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_rule_add_expr(r, expr);
50077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka}
51077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
52742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid add_payload(struct nftnl_rule *r, int offset, int len, uint32_t base)
53077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka{
54742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	struct nftnl_expr *expr;
55077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
56742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	expr = nftnl_expr_alloc("payload");
57077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	if (expr == NULL)
58077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		return;
59077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
60742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set_u32(expr, NFTNL_EXPR_PAYLOAD_BASE, base);
61742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set_u32(expr, NFTNL_EXPR_PAYLOAD_DREG, NFT_REG_1);
62742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set_u32(expr, NFTNL_EXPR_PAYLOAD_OFFSET, offset);
63742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set_u32(expr, NFTNL_EXPR_PAYLOAD_LEN, len);
64077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
65742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_rule_add_expr(r, expr);
66077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka}
67077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
68077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka/* bitwise operation is = sreg & mask ^ xor */
69742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid add_bitwise_u16(struct nftnl_rule *r, int mask, int xor)
70077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka{
71742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	struct nftnl_expr *expr;
72077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
73742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	expr = nftnl_expr_alloc("bitwise");
74077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	if (expr == NULL)
75077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		return;
76077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
77742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set_u32(expr, NFTNL_EXPR_BITWISE_SREG, NFT_REG_1);
78742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set_u32(expr, NFTNL_EXPR_BITWISE_DREG, NFT_REG_1);
79742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set_u32(expr, NFTNL_EXPR_BITWISE_LEN, sizeof(uint16_t));
80742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set(expr, NFTNL_EXPR_BITWISE_MASK, &mask, sizeof(uint16_t));
81742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set(expr, NFTNL_EXPR_BITWISE_XOR, &xor, sizeof(uint16_t));
82077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
83742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_rule_add_expr(r, expr);
84077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka}
85077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
86742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic void add_bitwise(struct nftnl_rule *r, uint8_t *mask, size_t len)
872c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso{
88742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	struct nftnl_expr *expr;
892c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso	uint32_t xor[4] = { 0 };
902c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso
91742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	expr = nftnl_expr_alloc("bitwise");
922c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso	if (expr == NULL)
932c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso		return;
942c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso
95742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set_u32(expr, NFTNL_EXPR_BITWISE_SREG, NFT_REG_1);
96742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set_u32(expr, NFTNL_EXPR_BITWISE_DREG, NFT_REG_1);
97742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set_u32(expr, NFTNL_EXPR_BITWISE_LEN, len);
98742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set(expr, NFTNL_EXPR_BITWISE_MASK, mask, len);
99742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set(expr, NFTNL_EXPR_BITWISE_XOR, &xor, len);
1002c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso
101742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_rule_add_expr(r, expr);
1022c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso}
1032c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso
104742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid add_cmp_ptr(struct nftnl_rule *r, uint32_t op, void *data, size_t len)
105077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka{
106742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	struct nftnl_expr *expr;
107077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
108742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	expr = nftnl_expr_alloc("cmp");
109077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	if (expr == NULL)
110077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		return;
111077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
112742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set_u32(expr, NFTNL_EXPR_CMP_SREG, NFT_REG_1);
113742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set_u32(expr, NFTNL_EXPR_CMP_OP, op);
114742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_set(expr, NFTNL_EXPR_CMP_DATA, data, len);
115077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
116742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_rule_add_expr(r, expr);
117077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka}
118077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
119742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid add_cmp_u8(struct nftnl_rule *r, uint8_t val, uint32_t op)
120d801b9f3b8161752ea2358a0bfb614603d28a8e5Pablo Neira Ayuso{
121d801b9f3b8161752ea2358a0bfb614603d28a8e5Pablo Neira Ayuso	add_cmp_ptr(r, op, &val, sizeof(val));
122d801b9f3b8161752ea2358a0bfb614603d28a8e5Pablo Neira Ayuso}
123d801b9f3b8161752ea2358a0bfb614603d28a8e5Pablo Neira Ayuso
124742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid add_cmp_u16(struct nftnl_rule *r, uint16_t val, uint32_t op)
125077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka{
126077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	add_cmp_ptr(r, op, &val, sizeof(val));
127077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka}
128077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
129742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid add_cmp_u32(struct nftnl_rule *r, uint32_t val, uint32_t op)
130077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka{
131077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	add_cmp_ptr(r, op, &val, sizeof(val));
132077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka}
133077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
134742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid add_iniface(struct nftnl_rule *r, char *iface, uint32_t op)
135077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka{
136077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	int iface_len;
137077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
138077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	iface_len = strlen(iface);
139077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
14028dcf16384b223f9890567bd89056864a7e3c85dPablo Neira Ayuso	add_meta(r, NFT_META_IIFNAME);
14128dcf16384b223f9890567bd89056864a7e3c85dPablo Neira Ayuso	if (iface[iface_len - 1] == '+')
142077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		add_cmp_ptr(r, op, iface, iface_len - 1);
14328dcf16384b223f9890567bd89056864a7e3c85dPablo Neira Ayuso	else
14428dcf16384b223f9890567bd89056864a7e3c85dPablo Neira Ayuso		add_cmp_ptr(r, op, iface, iface_len + 1);
145077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka}
146077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
147742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid add_outiface(struct nftnl_rule *r, char *iface, uint32_t op)
148077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka{
149077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	int iface_len;
150077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
151077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	iface_len = strlen(iface);
152077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
15328dcf16384b223f9890567bd89056864a7e3c85dPablo Neira Ayuso	add_meta(r, NFT_META_OIFNAME);
15428dcf16384b223f9890567bd89056864a7e3c85dPablo Neira Ayuso	if (iface[iface_len - 1] == '+')
155077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		add_cmp_ptr(r, op, iface, iface_len - 1);
15628dcf16384b223f9890567bd89056864a7e3c85dPablo Neira Ayuso	else
15728dcf16384b223f9890567bd89056864a7e3c85dPablo Neira Ayuso		add_cmp_ptr(r, op, iface, iface_len + 1);
158077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka}
159077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
160742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid add_addr(struct nftnl_rule *r, int offset,
161c82bf9f79bbc299de428fdc2e204d571b6cbc50dArturo Borrero	      void *data, void *mask, size_t len, uint32_t op)
162077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka{
1638acf8315a44fbee8227433daabb262b6de1e70f6Arturo Borrero	add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER);
1642c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso	add_bitwise(r, mask, len);
165077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
166077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	add_cmp_ptr(r, op, data, len);
167077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka}
168077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
169742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid add_proto(struct nftnl_rule *r, int offset, size_t len,
170c82bf9f79bbc299de428fdc2e204d571b6cbc50dArturo Borrero	       uint8_t proto, uint32_t op)
171077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka{
1728acf8315a44fbee8227433daabb262b6de1e70f6Arturo Borrero	add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER);
173d801b9f3b8161752ea2358a0bfb614603d28a8e5Pablo Neira Ayuso	add_cmp_u8(r, proto, op);
174077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka}
175077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
176077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztykabool is_same_interfaces(const char *a_iniface, const char *a_outiface,
177077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			unsigned const char *a_iniface_mask,
178077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			unsigned const char *a_outiface_mask,
179077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			const char *b_iniface, const char *b_outiface,
180077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			unsigned const char *b_iniface_mask,
181077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			unsigned const char *b_outiface_mask)
182077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka{
183077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	int i;
184077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
185077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	for (i = 0; i < IFNAMSIZ; i++) {
186077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		if (a_iniface_mask[i] != b_iniface_mask[i]) {
187077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			DEBUGP("different iniface mask %x, %x (%d)\n",
188077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			a_iniface_mask[i] & 0xff, b_iniface_mask[i] & 0xff, i);
189077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			return false;
190077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		}
191077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		if ((a_iniface[i] & a_iniface_mask[i])
192077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		    != (b_iniface[i] & b_iniface_mask[i])) {
193077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			DEBUGP("different iniface\n");
194077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			return false;
195077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		}
196077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		if (a_outiface_mask[i] != b_outiface_mask[i]) {
197077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			DEBUGP("different outiface mask\n");
198077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			return false;
199077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		}
200077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		if ((a_outiface[i] & a_outiface_mask[i])
201077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		    != (b_outiface[i] & b_outiface_mask[i])) {
202077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			DEBUGP("different outiface\n");
203077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			return false;
204077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		}
205077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	}
206077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
207077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	return true;
208077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka}
209077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
210742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusoint parse_meta(struct nftnl_expr *e, uint8_t key, char *iniface,
211077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		unsigned char *iniface_mask, char *outiface,
212077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		unsigned char *outiface_mask, uint8_t *invflags)
213077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka{
214077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	uint32_t value;
215077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	const void *ifname;
2167c7dcb2f2b86f71578c4cfc810042c98a43ea70aPablo Neira Ayuso	uint32_t len;
217077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
218077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	switch(key) {
219077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	case NFT_META_IIF:
220742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso		value = nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_DATA);
221742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso		if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)
222077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			*invflags |= IPT_INV_VIA_IN;
223077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
224077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		if_indextoname(value, iniface);
225077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
226077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		memset(iniface_mask, 0xff, strlen(iniface)+1);
227077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		break;
228077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	case NFT_META_OIF:
229742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso		value = nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_DATA);
230742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso		if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)
231077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			*invflags |= IPT_INV_VIA_OUT;
232077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
233077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		if_indextoname(value, outiface);
234077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
235077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		memset(outiface_mask, 0xff, strlen(outiface)+1);
236077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		break;
237077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	case NFT_META_IIFNAME:
238742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso		ifname = nftnl_expr_get(e, NFTNL_EXPR_CMP_DATA, &len);
239742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso		if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)
240077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			*invflags |= IPT_INV_VIA_IN;
241077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
242077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		memcpy(iniface, ifname, len);
243077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
24428dcf16384b223f9890567bd89056864a7e3c85dPablo Neira Ayuso		if (iniface[len] == '\0')
24528dcf16384b223f9890567bd89056864a7e3c85dPablo Neira Ayuso			memset(iniface_mask, 0xff, len);
24628dcf16384b223f9890567bd89056864a7e3c85dPablo Neira Ayuso		else {
247077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			iniface[len] = '+';
248077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			iniface[len+1] = '\0';
24928dcf16384b223f9890567bd89056864a7e3c85dPablo Neira Ayuso			memset(iniface_mask, 0xff, len + 1);
250077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		}
251077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		break;
252077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	case NFT_META_OIFNAME:
253742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso		ifname = nftnl_expr_get(e, NFTNL_EXPR_CMP_DATA, &len);
254742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso		if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)
255077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			*invflags |= IPT_INV_VIA_OUT;
256077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
257077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		memcpy(outiface, ifname, len);
258077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
25928dcf16384b223f9890567bd89056864a7e3c85dPablo Neira Ayuso		if (outiface[len] == '\0')
26028dcf16384b223f9890567bd89056864a7e3c85dPablo Neira Ayuso			memset(outiface_mask, 0xff, len);
26128dcf16384b223f9890567bd89056864a7e3c85dPablo Neira Ayuso		else {
262077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			outiface[len] = '+';
263077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			outiface[len+1] = '\0';
26428dcf16384b223f9890567bd89056864a7e3c85dPablo Neira Ayuso			memset(outiface_mask, 0xff, len + 1);
265077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		}
266077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		break;
267077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	default:
268da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso		return -1;
269077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	}
270da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso
271da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso	return 0;
272077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka}
273077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
2741cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longostatic void *nft_get_data(struct nft_xt_ctx *ctx)
2751cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo{
2761cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo	switch(ctx->family) {
2771cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo	case NFPROTO_IPV4:
2781cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo	case NFPROTO_IPV6:
2791cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo		return ctx->state.cs;
2801cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo	case NFPROTO_ARP:
281ab1e03849d7fb60e861b9715d90681f7120c3bbbPablo Neira Ayuso		return ctx->state.cs_arp;
282da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso	case NFPROTO_BRIDGE:
283902e92ceedba96d3241fa8ff701c061cd53a197dPablo Neira Ayuso		return ctx->state.cs_eb;
2841cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo	default:
2851cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo		/* Should not happen */
2861cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo		return NULL;
2871cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo	}
2881cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo}
2891cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo
290742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid nft_parse_target(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
291e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka{
2927c7dcb2f2b86f71578c4cfc810042c98a43ea70aPablo Neira Ayuso	uint32_t tg_len;
293742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	const char *targname = nftnl_expr_get_str(e, NFTNL_EXPR_TG_NAME);
294742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	const void *targinfo = nftnl_expr_get(e, NFTNL_EXPR_TG_INFO, &tg_len);
295cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	struct xtables_target *target;
296cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	struct xt_entry_target *t;
297e8a218f27a3d7948697c1c1d8f364af6f65b5ac9Tomasz Bursztyka	size_t size;
2982c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso	struct nft_family_ops *ops;
2991cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo	void *data = nft_get_data(ctx);
300e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
301cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	target = xtables_find_target(targname, XTF_TRY_LOAD);
302cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	if (target == NULL)
303cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		return;
304e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
305e8a218f27a3d7948697c1c1d8f364af6f65b5ac9Tomasz Bursztyka	size = XT_ALIGN(sizeof(struct xt_entry_target)) + tg_len;
306e8a218f27a3d7948697c1c1d8f364af6f65b5ac9Tomasz Bursztyka
307e8a218f27a3d7948697c1c1d8f364af6f65b5ac9Tomasz Bursztyka	t = calloc(1, size);
308cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	if (t == NULL) {
309cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		fprintf(stderr, "OOM");
310cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		exit(EXIT_FAILURE);
311cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	}
312cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	memcpy(&t->data, targinfo, tg_len);
313e8a218f27a3d7948697c1c1d8f364af6f65b5ac9Tomasz Bursztyka	t->u.target_size = size;
314742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	t->u.user.revision = nftnl_expr_get_u32(e, NFTNL_EXPR_TG_REV);
315cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	strcpy(t->u.user.name, target->name);
316e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
317cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	target->t = t;
31804d9ad94a40e795dfa8d4cfd0bf3f092d60ecc47Giuseppe Longo
3191cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo	ops = nft_family_ops_lookup(ctx->family);
32004d9ad94a40e795dfa8d4cfd0bf3f092d60ecc47Giuseppe Longo	ops->parse_target(target, data);
321cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka}
322cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka
323742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
324cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka{
3257c7dcb2f2b86f71578c4cfc810042c98a43ea70aPablo Neira Ayuso	uint32_t mt_len;
326742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	const char *mt_name = nftnl_expr_get_str(e, NFTNL_EXPR_MT_NAME);
327742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	const void *mt_info = nftnl_expr_get(e, NFTNL_EXPR_MT_INFO, &mt_len);
328cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	struct xtables_match *match;
32942cfeee024d0ba0c6b15645f829273ee3dcfa5c6Arturo Borrero	struct xtables_rule_match **matches;
330cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	struct xt_entry_match *m;
331fe97f60e5d2a968638286036db67e3a4e17f095dArturo Borrero	struct nft_family_ops *ops;
332cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka
33342cfeee024d0ba0c6b15645f829273ee3dcfa5c6Arturo Borrero	switch (ctx->family) {
33442cfeee024d0ba0c6b15645f829273ee3dcfa5c6Arturo Borrero	case NFPROTO_IPV4:
33542cfeee024d0ba0c6b15645f829273ee3dcfa5c6Arturo Borrero	case NFPROTO_IPV6:
33642cfeee024d0ba0c6b15645f829273ee3dcfa5c6Arturo Borrero		matches = &ctx->state.cs->matches;
33742cfeee024d0ba0c6b15645f829273ee3dcfa5c6Arturo Borrero		break;
33842cfeee024d0ba0c6b15645f829273ee3dcfa5c6Arturo Borrero	case NFPROTO_BRIDGE:
33942cfeee024d0ba0c6b15645f829273ee3dcfa5c6Arturo Borrero		matches = &ctx->state.cs_eb->matches;
34042cfeee024d0ba0c6b15645f829273ee3dcfa5c6Arturo Borrero		break;
34142cfeee024d0ba0c6b15645f829273ee3dcfa5c6Arturo Borrero	default:
34242cfeee024d0ba0c6b15645f829273ee3dcfa5c6Arturo Borrero		fprintf(stderr, "BUG: nft_parse_match() unknown family %d\n",
34342cfeee024d0ba0c6b15645f829273ee3dcfa5c6Arturo Borrero			ctx->family);
34442cfeee024d0ba0c6b15645f829273ee3dcfa5c6Arturo Borrero		exit(EXIT_FAILURE);
34542cfeee024d0ba0c6b15645f829273ee3dcfa5c6Arturo Borrero	}
34642cfeee024d0ba0c6b15645f829273ee3dcfa5c6Arturo Borrero
34742cfeee024d0ba0c6b15645f829273ee3dcfa5c6Arturo Borrero	match = xtables_find_match(mt_name, XTF_TRY_LOAD, matches);
348cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	if (match == NULL)
349cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		return;
350cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka
351cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	m = calloc(1, sizeof(struct xt_entry_match) + mt_len);
352cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	if (m == NULL) {
353cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		fprintf(stderr, "OOM");
354cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		exit(EXIT_FAILURE);
355e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka	}
356e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
357cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	memcpy(&m->data, mt_info, mt_len);
358cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	m->u.match_size = mt_len + XT_ALIGN(sizeof(struct xt_entry_match));
359742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	m->u.user.revision = nftnl_expr_get_u32(e, NFTNL_EXPR_TG_REV);
360cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	strcpy(m->u.user.name, match->name);
361cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka
362cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	match->m = m;
363fe97f60e5d2a968638286036db67e3a4e17f095dArturo Borrero
364fe97f60e5d2a968638286036db67e3a4e17f095dArturo Borrero	ops = nft_family_ops_lookup(ctx->family);
365fe97f60e5d2a968638286036db67e3a4e17f095dArturo Borrero	if (ops->parse_match != NULL)
366fe97f60e5d2a968638286036db67e3a4e17f095dArturo Borrero		ops->parse_match(match, nft_get_data(ctx));
367e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka}
368e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
369077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztykavoid print_proto(uint16_t proto, int invert)
370077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka{
371077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	const struct protoent *pent = getprotobynumber(proto);
372077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
373077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	if (invert)
374077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		printf("! ");
375077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
376077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	if (pent) {
377077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		printf("-p %s ", pent->p_name);
378077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		return;
379077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	}
380077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
381077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	printf("-p %u ", proto);
382077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka}
383077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
384742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid get_cmp_data(struct nftnl_expr *e, void *data, size_t dlen, bool *inv)
385077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka{
3867c7dcb2f2b86f71578c4cfc810042c98a43ea70aPablo Neira Ayuso	uint32_t len;
387077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	uint8_t op;
388077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
389742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	memcpy(data, nftnl_expr_get(e, NFTNL_EXPR_CMP_DATA, &len), dlen);
390742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	op = nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP);
391077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	if (op == NFT_CMP_NEQ)
392077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		*inv = true;
393077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	else
394077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		*inv = false;
395077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka}
396077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
397742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid nft_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
398e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka{
399742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	ctx->reg = nftnl_expr_get_u32(e, NFTNL_EXPR_META_DREG);
400742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	ctx->meta.key = nftnl_expr_get_u32(e, NFTNL_EXPR_META_KEY);
4012c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso	ctx->flags |= NFT_XT_CTX_META;
4022c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso}
403e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
404742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid nft_parse_payload(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
4052c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso{
406742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	ctx->reg = nftnl_expr_get_u32(e, NFTNL_EXPR_META_DREG);
407742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	ctx->payload.offset = nftnl_expr_get_u32(e, NFTNL_EXPR_PAYLOAD_OFFSET);
4082c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso	ctx->flags |= NFT_XT_CTX_PAYLOAD;
4092c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso}
4102c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso
411742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid nft_parse_bitwise(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
4122c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso{
4132c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso	uint32_t reg, len;
4142c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso	const void *data;
415e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
416742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	reg = nftnl_expr_get_u32(e, NFTNL_EXPR_BITWISE_SREG);
4172c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso	if (ctx->reg && reg != ctx->reg)
418e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka		return;
419e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
420742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	data = nftnl_expr_get(e, NFTNL_EXPR_BITWISE_XOR, &len);
4212c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso	memcpy(ctx->bitwise.xor, data, len);
422742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	data = nftnl_expr_get(e, NFTNL_EXPR_BITWISE_MASK, &len);
4232c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso	memcpy(ctx->bitwise.mask, data, len);
4242c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso	ctx->flags |= NFT_XT_CTX_BITWISE;
425e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka}
426e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
427742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid nft_parse_cmp(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
428e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka{
4291cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo	struct nft_family_ops *ops = nft_family_ops_lookup(ctx->family);
4301cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo	void *data = nft_get_data(ctx);
4312c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso	uint32_t reg;
432e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
433742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	reg = nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_SREG);
4342c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso	if (ctx->reg && reg != ctx->reg)
4352c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso		return;
436e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
4376c8db125b258da070313f20cdf9bc4124bba5383Pablo Neira Ayuso	if (ctx->flags & NFT_XT_CTX_META) {
4382c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso		ops->parse_meta(ctx, e, data);
4396c8db125b258da070313f20cdf9bc4124bba5383Pablo Neira Ayuso		ctx->flags &= ~NFT_XT_CTX_META;
4406c8db125b258da070313f20cdf9bc4124bba5383Pablo Neira Ayuso	}
4412c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso	/* bitwise context is interpreted from payload */
4426c8db125b258da070313f20cdf9bc4124bba5383Pablo Neira Ayuso	if (ctx->flags & NFT_XT_CTX_PAYLOAD) {
4432c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso		ops->parse_payload(ctx, e, data);
4446c8db125b258da070313f20cdf9bc4124bba5383Pablo Neira Ayuso		ctx->flags &= ~NFT_XT_CTX_PAYLOAD;
4456c8db125b258da070313f20cdf9bc4124bba5383Pablo Neira Ayuso	}
446e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka}
447e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
448742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid nft_parse_counter(struct nftnl_expr *e, struct xt_counters *counters)
449e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka{
450742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	counters->pcnt = nftnl_expr_get_u64(e, NFTNL_EXPR_CTR_PACKETS);
451742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	counters->bcnt = nftnl_expr_get_u64(e, NFTNL_EXPR_CTR_BYTES);
452e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka}
453e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
454742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
455e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka{
456742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	int verdict = nftnl_expr_get_u32(e, NFTNL_EXPR_IMM_VERDICT);
457742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	const char *chain = nftnl_expr_get_str(e, NFTNL_EXPR_IMM_CHAIN);
458e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka	struct nft_family_ops *ops;
4597791905f7db3bce63d3316c5adaf2f735cff3c1dTomasz Bursztyka	const char *jumpto = NULL;
46004d9ad94a40e795dfa8d4cfd0bf3f092d60ecc47Giuseppe Longo	bool nft_goto = false;
4611cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo	void *data = nft_get_data(ctx);
462e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
463e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka	/* Standard target? */
464e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka	switch(verdict) {
465e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka	case NF_ACCEPT:
46604d9ad94a40e795dfa8d4cfd0bf3f092d60ecc47Giuseppe Longo		jumpto = "ACCEPT";
46704d9ad94a40e795dfa8d4cfd0bf3f092d60ecc47Giuseppe Longo		break;
468e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka	case NF_DROP:
46904d9ad94a40e795dfa8d4cfd0bf3f092d60ecc47Giuseppe Longo		jumpto = "DROP";
47004d9ad94a40e795dfa8d4cfd0bf3f092d60ecc47Giuseppe Longo		break;
471e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka	case NFT_RETURN:
47204d9ad94a40e795dfa8d4cfd0bf3f092d60ecc47Giuseppe Longo		jumpto = "RETURN";
47304d9ad94a40e795dfa8d4cfd0bf3f092d60ecc47Giuseppe Longo		break;;
474e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka	case NFT_GOTO:
47504d9ad94a40e795dfa8d4cfd0bf3f092d60ecc47Giuseppe Longo		nft_goto = true;
476e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka	case NFT_JUMP:
47704d9ad94a40e795dfa8d4cfd0bf3f092d60ecc47Giuseppe Longo		jumpto = chain;
47804d9ad94a40e795dfa8d4cfd0bf3f092d60ecc47Giuseppe Longo		break;
479e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka	}
48004d9ad94a40e795dfa8d4cfd0bf3f092d60ecc47Giuseppe Longo
4811cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo	ops = nft_family_ops_lookup(ctx->family);
48204d9ad94a40e795dfa8d4cfd0bf3f092d60ecc47Giuseppe Longo	ops->parse_immediate(jumpto, nft_goto, data);
483e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka}
484e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
485742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid nft_rule_to_iptables_command_state(struct nftnl_rule *r,
486e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka					struct iptables_command_state *cs)
487e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka{
488742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	struct nftnl_expr_iter *iter;
489742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	struct nftnl_expr *expr;
490742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	int family = nftnl_rule_get_u32(r, NFTNL_RULE_FAMILY);
4911cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo	struct nft_xt_ctx ctx = {
4921cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo		.state.cs = cs,
4931cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo		.family = family,
4941cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo	};
495e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
496742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	iter = nftnl_expr_iter_create(r);
497e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka	if (iter == NULL)
498e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka		return;
499e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
5001cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo	ctx.iter = iter;
501742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	expr = nftnl_expr_iter_next(iter);
502e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka	while (expr != NULL) {
503e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka		const char *name =
504742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso			nftnl_expr_get_str(expr, NFTNL_EXPR_NAME);
505e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
506cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		if (strcmp(name, "counter") == 0)
5071cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo			nft_parse_counter(expr, &ctx.state.cs->counters);
508cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		else if (strcmp(name, "payload") == 0)
5091cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo			nft_parse_payload(&ctx, expr);
510cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		else if (strcmp(name, "meta") == 0)
5111cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo			nft_parse_meta(&ctx, expr);
5122c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso		else if (strcmp(name, "bitwise") == 0)
5132c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso			nft_parse_bitwise(&ctx, expr);
5142c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso		else if (strcmp(name, "cmp") == 0)
5152c4a34c30cb4db93653dbd139e04f7df963c3a41Pablo Neira Ayuso			nft_parse_cmp(&ctx, expr);
516cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		else if (strcmp(name, "immediate") == 0)
5171cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo			nft_parse_immediate(&ctx, expr);
518cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		else if (strcmp(name, "match") == 0)
5191cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo			nft_parse_match(&ctx, expr);
520cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		else if (strcmp(name, "target") == 0)
5211cc84d47766ad74be8609477d3496544848b75b1Giuseppe Longo			nft_parse_target(&ctx, expr);
522e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
523742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso		expr = nftnl_expr_iter_next(iter);
524e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka	}
525e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
526742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso	nftnl_expr_iter_destroy(iter);
527e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
528a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay	if (nftnl_rule_is_set(r, NFTNL_RULE_USERDATA)) {
529a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay		const void *data;
530a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay		uint32_t len;
531a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay		struct xtables_match *match;
532a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay		struct xt_entry_match *m;
533a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay
534a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay		data = nftnl_rule_get_data(r, NFTNL_RULE_USERDATA, &len);
535a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay		match = xtables_find_match("comment", XTF_TRY_LOAD,
536a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay					   &cs->matches);
537a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay		if (match == NULL)
538a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay			return;
539a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay
540a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay		m = calloc(1, sizeof(struct xt_entry_match) + len);
541a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay		if (m == NULL) {
542a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay			fprintf(stderr, "OOM");
543a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay			exit(EXIT_FAILURE);
544a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay		}
545a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay
546a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay		memcpy(&m->data, get_comment(data, len), len);
547a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay		m->u.match_size = len + XT_ALIGN(sizeof(struct xt_entry_match));
548a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay		m->u.user.revision = 0;
549a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay		strcpy(m->u.user.name, match->name);
550a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay
551a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay		match->m = m;
552a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay	}
553a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay
554cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	if (cs->target != NULL)
555cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		cs->jumpto = cs->target->name;
556cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	else if (cs->jumpto != NULL)
557cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
558cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	else
559cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		cs->jumpto = "";
560e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka}
561e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka
5624272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayusovoid print_header(unsigned int format, const char *chain, const char *pol,
5634272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso		  const struct xt_counters *counters, bool basechain,
5644272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso		  uint32_t refs)
5654272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso{
5664272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso	printf("Chain %s", chain);
5674272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso	if (basechain) {
5684272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso		printf(" (policy %s", pol);
5694272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso		if (!(format & FMT_NOCOUNTS)) {
5704272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso			fputc(' ', stdout);
5714272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso			xtables_print_num(counters->pcnt, (format|FMT_NOTABLE));
5724272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso			fputs("packets, ", stdout);
5734272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso			xtables_print_num(counters->bcnt, (format|FMT_NOTABLE));
5744272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso			fputs("bytes", stdout);
5754272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso		}
5764272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso		printf(")\n");
5774272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso	} else {
5784272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso		printf(" (%u references)\n", refs);
5794272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso	}
5804272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso
5814272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso	if (format & FMT_LINENUMBERS)
5824272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso		printf(FMT("%-4s ", "%s "), "num");
5834272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso	if (!(format & FMT_NOCOUNTS)) {
5844272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso		if (format & FMT_KILOMEGAGIGA) {
5854272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso			printf(FMT("%5s ","%s "), "pkts");
5864272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso			printf(FMT("%5s ","%s "), "bytes");
5874272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso		} else {
5884272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso			printf(FMT("%8s ","%s "), "pkts");
5894272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso			printf(FMT("%10s ","%s "), "bytes");
5904272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso		}
5914272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso	}
5924272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso	if (!(format & FMT_NOTARGET))
5934272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso		printf(FMT("%-9s ","%s "), "target");
5944272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso	fputs(" prot ", stdout);
5954272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso	if (format & FMT_OPTIONS)
5964272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso		fputs("opt", stdout);
5974272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso	if (format & FMT_VIA) {
5984272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso		printf(FMT(" %-6s ","%s "), "in");
5994272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso		printf(FMT("%-6s ","%s "), "out");
6004272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso	}
6014272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso	printf(FMT(" %-19s ","%s "), "source");
6024272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso	printf(FMT(" %-19s "," %s "), "destination");
6034272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso	printf("\n");
6044272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso}
6054272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso
606077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztykavoid print_firewall_details(const struct iptables_command_state *cs,
607077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			    const char *targname, uint8_t flags,
608077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			    uint8_t invflags, uint8_t proto,
609077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			    unsigned int num, unsigned int format)
610077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka{
611077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	if (format & FMT_LINENUMBERS)
612077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		printf(FMT("%-4u ", "%u "), num);
613077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
614077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	if (!(format & FMT_NOCOUNTS)) {
61536cba824e1689c6255d4e33b7fa82541a774609bPablo Neira Ayuso		xtables_print_num(cs->counters.pcnt, format);
61636cba824e1689c6255d4e33b7fa82541a774609bPablo Neira Ayuso		xtables_print_num(cs->counters.bcnt, format);
617077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	}
618077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
619077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	if (!(format & FMT_NOTARGET))
620077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		printf(FMT("%-9s ", "%s "), targname ? targname : "");
621077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
622077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	fputc(invflags & XT_INV_PROTO ? '!' : ' ', stdout);
623077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	{
624077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		const char *pname =
625077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			proto_to_name(proto, format&FMT_NUMERIC);
626077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		if (pname)
627077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			printf(FMT("%-5s", "%s "), pname);
628077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		else
629077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka			printf(FMT("%-5hu", "%hu "), proto);
630077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	}
631eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso}
632077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
633eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayusovoid print_ifaces(const char *iniface, const char *outiface, uint8_t invflags,
634eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso		  unsigned int format)
635eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso{
636eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso	char iface[IFNAMSIZ+2];
637077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
638eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso	if (!(format & FMT_VIA))
639eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso		return;
640077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
641eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso	if (invflags & IPT_INV_VIA_IN) {
642eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso		iface[0] = '!';
643eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso		iface[1] = '\0';
644eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso	} else
645eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso		iface[0] = '\0';
646077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
647eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso	if (iniface[0] != '\0')
648eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso		strcat(iface, iniface);
649eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso	else if (format & FMT_NUMERIC)
650eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso		strcat(iface, "*");
651eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso	else
652eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso		strcat(iface, "any");
653077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
654eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso	printf(FMT(" %-6s ","in %s "), iface);
655eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso
656eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso	if (invflags & IPT_INV_VIA_OUT) {
657eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso		iface[0] = '!';
658eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso		iface[1] = '\0';
659eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso	} else
660eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso		iface[0] = '\0';
661eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso
662eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso	if (outiface[0] != '\0')
663eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso		strcat(iface, outiface);
664eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso	else if (format & FMT_NUMERIC)
665eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso		strcat(iface, "*");
666eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso	else
667eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso		strcat(iface, "any");
668eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso
669eb4b65c49994e44e6ad617fe3f60c063d0c331c4Pablo Neira Ayuso	printf(FMT("%-6s ","out %s "), iface);
670077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka}
671077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
672cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztykastatic void
673cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztykaprint_iface(char letter, const char *iface, const unsigned char *mask, int inv)
674cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka{
675cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	unsigned int i;
676cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka
677cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	if (mask[0] == 0)
678cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		return;
679cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka
680cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	printf("%s-%c ", inv ? "! " : "", letter);
681cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka
682cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	for (i = 0; i < IFNAMSIZ; i++) {
683cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		if (mask[i] != 0) {
684cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka			if (iface[i] != '\0')
685cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka				printf("%c", iface[i]);
686cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka			} else {
687cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka				if (iface[i-1] != '\0')
688cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka					printf("+");
689cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka				break;
690cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		}
691cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	}
692cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka
693cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	printf(" ");
694cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka}
695cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka
696cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztykavoid save_firewall_details(const struct iptables_command_state *cs,
697cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka			   uint8_t invflags, uint16_t proto,
698cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka			   const char *iniface,
699cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka			   unsigned const char *iniface_mask,
700cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka			   const char *outiface,
7011aefddd07ca8e51f0528366835cf466d57bd459fGiuseppe Longo			   unsigned const char *outiface_mask)
702cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka{
703cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	if (iniface != NULL) {
704cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		print_iface('i', iniface, iniface_mask,
705cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka			    invflags & IPT_INV_VIA_IN);
706cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	}
707cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	if (outiface != NULL) {
708cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		print_iface('o', outiface, outiface_mask,
709cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka			    invflags & IPT_INV_VIA_OUT);
710cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	}
711cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka
712cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	if (proto > 0) {
713cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		const struct protoent *pent = getprotobynumber(proto);
714cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka
715cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		if (invflags & XT_INV_PROTO)
716cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka			printf("! ");
717cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka
718cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		if (pent)
719cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka			printf("-p %s ", pent->p_name);
720cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		else
721cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka			printf("-p %u ", proto);
722cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	}
723cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka}
724cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka
7251aefddd07ca8e51f0528366835cf466d57bd459fGiuseppe Longovoid save_counters(uint64_t pcnt, uint64_t bcnt)
7261aefddd07ca8e51f0528366835cf466d57bd459fGiuseppe Longo{
7271aefddd07ca8e51f0528366835cf466d57bd459fGiuseppe Longo	printf("[%llu:%llu] ", (unsigned long long)pcnt,
7281aefddd07ca8e51f0528366835cf466d57bd459fGiuseppe Longo			       (unsigned long long)bcnt);
7291aefddd07ca8e51f0528366835cf466d57bd459fGiuseppe Longo}
7301aefddd07ca8e51f0528366835cf466d57bd459fGiuseppe Longo
7318877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longovoid save_matches_and_target(struct xtables_rule_match *m,
7328877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo			     struct xtables_target *target,
7338877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo			     const char *jumpto, uint8_t flags, const void *fw)
7348877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo{
7358877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo	struct xtables_rule_match *matchp;
7368877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo
7378877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo	for (matchp = m; matchp; matchp = matchp->next) {
7388877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo		if (matchp->match->alias) {
7398877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo			printf("-m %s",
7408877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo			       matchp->match->alias(matchp->match->m));
7418877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo		} else
7428877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo			printf("-m %s", matchp->match->name);
7438877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo
7448877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo		if (matchp->match->save != NULL) {
7458877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo			/* cs->fw union makes the trick */
7468877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo			matchp->match->save(fw, matchp->match->m);
7478877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo		}
7488877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo		printf(" ");
7498877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo	}
7508877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo
7518877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo	if (target != NULL) {
7528877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo		if (target->alias) {
7538877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo			printf("-j %s", target->alias(target->t));
7548877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo		} else
7558877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo			printf("-j %s", jumpto);
7568877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo
7578877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo		if (target->save != NULL)
7588877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo			target->save(fw, target->t);
759d007e1a59e4beaddab430992302d43b122ffc801Pablo Neira Ayuso	}
7608877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo}
7618877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo
762cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztykavoid print_matches_and_target(struct iptables_command_state *cs,
763cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka			      unsigned int format)
764cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka{
765cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	struct xtables_rule_match *matchp;
766cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka
767cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	for (matchp = cs->matches; matchp; matchp = matchp->next) {
768cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		if (matchp->match->print != NULL) {
7695f6e384ac2a3d7b647a909654a3bdee1c0bcb3ebPablo Neira Ayuso			matchp->match->print(&cs->fw, matchp->match->m,
770cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka					     format & FMT_NUMERIC);
771cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		}
772cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	}
773cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka
774cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	if (cs->target != NULL) {
775cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		if (cs->target->print != NULL) {
7765f6e384ac2a3d7b647a909654a3bdee1c0bcb3ebPablo Neira Ayuso			cs->target->print(&cs->fw, cs->target->t,
777cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka					  format & FMT_NUMERIC);
778cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka		}
779cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka	}
780cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka}
781cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka
782077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztykastruct nft_family_ops *nft_family_ops_lookup(int family)
783077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka{
784077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	switch (family) {
785077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	case AF_INET:
786077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		return &nft_family_ops_ipv4;
787077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	case AF_INET6:
788077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		return &nft_family_ops_ipv6;
78984909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo	case NFPROTO_ARP:
79084909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo		return &nft_family_ops_arp;
791da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso	case NFPROTO_BRIDGE:
792da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso		return &nft_family_ops_bridge;
793077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	default:
794077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka		break;
795077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	}
796077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
797077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka	return NULL;
798077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka}
799077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka
800da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayusobool compare_matches(struct xtables_rule_match *mt1,
801da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso		     struct xtables_rule_match *mt2)
802e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso{
803e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	struct xtables_rule_match *mp1;
804e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	struct xtables_rule_match *mp2;
805e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
806e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	for (mp1 = mt1, mp2 = mt2; mp1 && mp2; mp1 = mp1->next, mp2 = mp2->next) {
807e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		struct xt_entry_match *m1 = mp1->match->m;
808e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		struct xt_entry_match *m2 = mp2->match->m;
809e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
810e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		if (strcmp(m1->u.user.name, m2->u.user.name) != 0) {
811e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso			DEBUGP("mismatching match name\n");
812e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso			return false;
813e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		}
814e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
815e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		if (m1->u.user.match_size != m2->u.user.match_size) {
816e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso			DEBUGP("mismatching match size\n");
817e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso			return false;
818e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		}
819e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
820e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		if (memcmp(m1->data, m2->data,
8216cd426bc7593ecf04a02c901d94e04093bdf69e4Pablo Neira Ayuso			   mp1->match->userspacesize) != 0) {
822e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso			DEBUGP("mismatch match data\n");
823e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso			return false;
824e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		}
825e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	}
826e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
827e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	/* Both cursors should be NULL */
828e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	if (mp1 != mp2) {
829e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		DEBUGP("mismatch matches amount\n");
830e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		return false;
831e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	}
832e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
833e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	return true;
834e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso}
835e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
836e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayusobool compare_targets(struct xtables_target *tg1, struct xtables_target *tg2)
837e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso{
838e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	if (tg1 == NULL && tg2 == NULL)
839e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		return true;
840e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
841e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	if ((tg1 == NULL && tg2 != NULL) || (tg1 != NULL && tg2 == NULL))
842e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		return false;
843e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
844e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	if (strcmp(tg1->t->u.user.name, tg2->t->u.user.name) != 0)
845e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		return false;
846e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
8476cd426bc7593ecf04a02c901d94e04093bdf69e4Pablo Neira Ayuso	if (memcmp(tg1->t->data, tg2->t->data, tg1->userspacesize) != 0)
848e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		return false;
849e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
850e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	return true;
851e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso}
852e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
853e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayusobool nft_ipv46_rule_find(struct nft_family_ops *ops,
854742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso			 struct nftnl_rule *r, struct iptables_command_state *cs)
855e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso{
856e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	struct iptables_command_state this = {};
857e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
858e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	nft_rule_to_iptables_command_state(r, &this);
859e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
860e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	DEBUGP("comparing with... ");
861e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso#ifdef DEBUG_DEL
862e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	nft_rule_print_save(&this, r, NFT_RULE_APPEND, 0);
863e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso#endif
864e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	if (!ops->is_same(cs, &this))
865e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		return false;
866e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
867e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	if (!compare_matches(cs->matches, this.matches)) {
868e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		DEBUGP("Different matches\n");
869e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		return false;
870e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	}
871e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
872e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	if (!compare_targets(cs->target, this.target)) {
873e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		DEBUGP("Different target\n");
874e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		return false;
875e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	}
876e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
877e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	if (strcmp(cs->jumpto, this.jumpto) != 0) {
878e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		DEBUGP("Different verdict\n");
879e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso		return false;
880e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	}
881e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso
882e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso	return true;
883e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso}
884