[PATCH RFC] src: support for arp ether and IP source and destination fields

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add ip-saddr, ip-daddr, ether-saddr, ether-daddr for arp, eg.

 # nft add table arp x
 # nft add chain arp x y { type filter hook input priority 0\; }
 # nft add rule arp x y arp ip-saddr 192.168.2.1 counter

Testing this:

 # ip neigh flush dev eth0
 # ping 8.8.8.8
 # nft list ruleset
 table arp x {
        chain y {
                type filter hook input priority filter; policy accept;
		arp ip-saddr 192.168.2.1 counter packets 1 bytes 46
        }
 }

Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
---
Documentation is still missing, and we should generate dependencies to
restrict htype and ptype.

 include/headers.h  | 12 ++++++++++++
 include/proto.h    |  4 ++++
 src/parser_bison.y |  8 ++++++++
 src/proto.c        | 22 ++++++++++++++--------
 src/scanner.l      |  4 ++++
 5 files changed, 42 insertions(+), 8 deletions(-)

diff --git a/include/headers.h b/include/headers.h
index 3d564debf8b0..759f93bf8c7a 100644
--- a/include/headers.h
+++ b/include/headers.h
@@ -78,6 +78,18 @@ struct sctphdr {
 	uint32_t	checksum;
 };
 
+struct arp_hdr {
+	uint16_t	htype;
+	uint16_t	ptype;
+	uint8_t		hlen;
+	uint8_t		plen;
+	uint16_t	oper;
+	uint8_t		sha[6];
+	uint32_t	spa;
+	uint8_t		tha[6];
+	uint32_t	tpa;
+} __attribute__((__packed__));
+
 struct ipv6hdr {
 	uint8_t		version:4,
 			priority:4;
diff --git a/include/proto.h b/include/proto.h
index 9a9f9255f047..b097e8fcbc2b 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -182,6 +182,10 @@ enum arp_hdr_fields {
 	ARPHDR_HLN,
 	ARPHDR_PLN,
 	ARPHDR_OP,
+	ARPHDR_IP_SADDR,
+	ARPHDR_IP_DADDR,
+	ARPHDR_ETHER_SADDR,
+	ARPHDR_ETHER_DADDR,
 };
 
 enum ip_hdr_fields {
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 34202b0415ec..e94282a43615 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -296,6 +296,10 @@ int nft_lex(void *, void *, void *);
 %token HLEN			"hlen"
 %token PLEN			"plen"
 %token OPERATION		"operation"
+%token ETHER_SADDR		"ether-saddr"
+%token ETHER_DADDR		"ether-daddr"
+%token IP_SADDR			"ip-saddr"
+%token IP_DADDR			"ip-daddr"
 
 %token IP			"ip"
 %token HDRVERSION		"version"
@@ -4204,6 +4208,10 @@ arp_hdr_field		:	HTYPE		{ $$ = ARPHDR_HRD; }
 			|	HLEN		{ $$ = ARPHDR_HLN; }
 			|	PLEN		{ $$ = ARPHDR_PLN; }
 			|	OPERATION	{ $$ = ARPHDR_OP; }
+			|	ETHER_SADDR	{ $$ = ARPHDR_ETHER_SADDR; }
+			|	ETHER_DADDR	{ $$ = ARPHDR_ETHER_DADDR; }
+			|	IP_SADDR	{ $$ = ARPHDR_IP_SADDR; }
+			|	IP_DADDR	{ $$ = ARPHDR_IP_DADDR; }
 			;
 
 ip_hdr_expr		:	IP	ip_hdr_field
diff --git a/src/proto.c b/src/proto.c
index d178bf39ea90..d52f11ce6f30 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -822,23 +822,29 @@ const struct datatype arpop_type = {
 };
 
 #define ARPHDR_TYPE(__name, __type, __member) \
-	HDR_TYPE(__name, __type, struct arphdr, __member)
+	HDR_TYPE(__name, __type, struct arp_hdr, __member)
 #define ARPHDR_FIELD(__name, __member) \
-	HDR_FIELD(__name, struct arphdr, __member)
+	HDR_FIELD(__name, struct arp_hdr, __member)
 
 const struct proto_desc proto_arp = {
 	.name		= "arp",
 	.base		= PROTO_BASE_NETWORK_HDR,
 	.templates	= {
-		[ARPHDR_HRD]		= ARPHDR_FIELD("htype",	ar_hrd),
-		[ARPHDR_PRO]		= ARPHDR_TYPE("ptype", &ethertype_type, ar_pro),
-		[ARPHDR_HLN]		= ARPHDR_FIELD("hlen", ar_hln),
-		[ARPHDR_PLN]		= ARPHDR_FIELD("plen", ar_pln),
-		[ARPHDR_OP]		= ARPHDR_TYPE("operation", &arpop_type, ar_op),
+		[ARPHDR_HRD]		= ARPHDR_FIELD("htype",	htype),
+		[ARPHDR_PRO]		= ARPHDR_TYPE("ptype", &ethertype_type, ptype),
+		[ARPHDR_HLN]		= ARPHDR_FIELD("hlen", hlen),
+		[ARPHDR_PLN]		= ARPHDR_FIELD("plen", plen),
+		[ARPHDR_OP]		= ARPHDR_TYPE("operation", &arpop_type, oper),
+		[ARPHDR_ETHER_SADDR]	= ARPHDR_TYPE("ether-saddr", &etheraddr_type, sha),
+		[ARPHDR_ETHER_DADDR]	= ARPHDR_TYPE("ether-daddr", &etheraddr_type, tha),
+		[ARPHDR_IP_SADDR]	= ARPHDR_TYPE("ip-saddr", &ipaddr_type, spa),
+		[ARPHDR_IP_DADDR]	= ARPHDR_TYPE("ip-daddr", &ipaddr_type, tpa),
 	},
 	.format		= {
 		.filter	= (1 << ARPHDR_HRD) | (1 << ARPHDR_PRO) |
-			  (1 << ARPHDR_HLN) | (1 << ARPHDR_PLN),
+			  (1 << ARPHDR_HLN) | (1 << ARPHDR_PLN) |
+			  (1 << ARPHDR_ETHER_SADDR) | (1 << ARPHDR_ETHER_DADDR) |
+			  (1 << ARPHDR_IP_SADDR) | (1 << ARPHDR_IP_DADDR),
 	},
 };
 
diff --git a/src/scanner.l b/src/scanner.l
index f96944e976b3..5221086e38e5 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -389,6 +389,10 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 "hlen"			{ return HLEN; }
 "plen"			{ return PLEN; }
 "operation"		{ return OPERATION; }
+"ip-saddr"		{ return IP_SADDR; }
+"ip-daddr"		{ return IP_DADDR; }
+"ether-saddr"		{ return ETHER_SADDR; }
+"ether-daddr"		{ return ETHER_DADDR; }
 
 "ip"			{ return IP; }
 "version"		{ return HDRVERSION; }
-- 
2.11.0




[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux