]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: support for arp sender and target ethernet and IPv4 addresses
authorPablo Neira Ayuso <pablo@netfilter.org>
Wed, 22 May 2019 20:06:16 +0000 (22:06 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 24 May 2019 19:14:30 +0000 (21:14 +0200)
 # nft add table arp x
 # nft add chain arp x y { type filter hook input priority 0\; }
 # nft add rule arp x y arp saddr ip 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 saddr ip 192.168.2.1 counter packets 1 bytes 46
        }
 }

You can also specify hardware sender address, eg.

 # nft add rule arp x y arp saddr ether aa:bb:cc:aa:bb:cc drop counter

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
doc/payload-expression.txt
include/headers.h
include/proto.h
src/parser_bison.y
src/proto.c
tests/py/arp/arp.t
tests/py/arp/arp.t.payload
tests/py/arp/arp.t.payload.netdev

index 7f3ca42d460562d67fba6fa8a9decb5b669448f3..ebbffe50b1e162bcb350424c340e777571f9f834 100644 (file)
@@ -44,7 +44,7 @@ ether_type
 ARP HEADER EXPRESSION
 ~~~~~~~~~~~~~~~~~~~~~
 [verse]
-*arp* {*htype* | *ptype* | *hlen* | *plen* | *operation*}
+*arp* {*htype* | *ptype* | *hlen* | *plen* | *operation* | *saddr* { *ip* | *ether* } | *daddr* { *ip* | *ether* }
 
 .ARP header expression
 [options="header"]
@@ -65,6 +65,18 @@ integer (8 bit)
 |operation|
 Operation |
 arp_op
+|saddr ether|
+Ethernet sender address|
+ether_addr
+|daddr ether|
+Ethernet target address|
+ether_addr
+|saddr ip|
+IPv4 sender address|
+ipv4_addr
+|daddr ip|
+IPv4 target address|
+ipv4_addr
 |======================
 
 IPV4 HEADER EXPRESSION
index 3d564debf8b0916df5b61e56d49b661cab3773c1..759f93bf8c7a9e3928f49cfd809e8cbe0645090e 100644 (file)
@@ -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;
index 99c57a7997cccb41c60f526ca635dff6cfced340..92b25edbd3da7cb37c2d9bd612f94902943b6a39 100644 (file)
@@ -182,6 +182,10 @@ enum arp_hdr_fields {
        ARPHDR_HLN,
        ARPHDR_PLN,
        ARPHDR_OP,
+       ARPHDR_SADDR_ETHER,
+       ARPHDR_DADDR_ETHER,
+       ARPHDR_SADDR_IP,
+       ARPHDR_DADDR_IP,
 };
 
 enum ip_hdr_fields {
index 9e632c0d1f6e90225d6d37aa87c82e1651ecb5b4..8c8cd43264cff39d73b2a856f73edfb0d4924fc7 100644 (file)
@@ -4243,6 +4243,10 @@ arp_hdr_field            :       HTYPE           { $$ = ARPHDR_HRD; }
                        |       HLEN            { $$ = ARPHDR_HLN; }
                        |       PLEN            { $$ = ARPHDR_PLN; }
                        |       OPERATION       { $$ = ARPHDR_OP; }
+                       |       SADDR ETHER     { $$ = ARPHDR_SADDR_ETHER; }
+                       |       DADDR ETHER     { $$ = ARPHDR_DADDR_ETHER; }
+                       |       SADDR IP        { $$ = ARPHDR_SADDR_IP; }
+                       |       DADDR IP        { $$ = ARPHDR_DADDR_IP; }
                        ;
 
 ip_hdr_expr            :       IP      ip_hdr_field
index f68fb68436b61b440d0e6669b689e78f49804d31..67e86f2070c12a6c9c10db96b9aba79fcd51b203 100644 (file)
@@ -874,23 +874,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_SADDR_ETHER]    = ARPHDR_TYPE("saddr ether", &etheraddr_type, sha),
+               [ARPHDR_DADDR_ETHER]    = ARPHDR_TYPE("daddr ether", &etheraddr_type, tha),
+               [ARPHDR_SADDR_IP]       = ARPHDR_TYPE("saddr ip", &ipaddr_type, spa),
+               [ARPHDR_DADDR_IP]       = ARPHDR_TYPE("daddr ip", &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_SADDR_ETHER) | (1 << ARPHDR_DADDR_ETHER) |
+                         (1 << ARPHDR_SADDR_IP) | (1 << ARPHDR_DADDR_IP),
        },
 };
 
index d62cc546f24d5a814b561162ad90313549872fbf..86bab5232eaf35cfaabd258c4162c1abe1b979d8 100644 (file)
@@ -55,4 +55,9 @@ arp operation != inreply;ok
 arp operation != nak;ok
 arp operation != reply;ok
 
-meta iifname "invalid" arp ptype 0x0800 arp htype 1 arp hlen 6 arp plen 4 @nh,192,32 0xc0a88f10 @nh,144,48 set 0x112233445566;ok;iifname "invalid" arp htype 1 arp ptype ip arp hlen 6 arp plen 4 @nh,192,32 3232272144 @nh,144,48 set 18838586676582
+arp saddr ip 1.2.3.4;ok
+arp daddr ip 4.3.2.1;ok
+arp saddr ether aa:bb:cc:aa:bb:cc;ok
+arp daddr ether aa:bb:cc:aa:bb:cc;ok
+
+meta iifname "invalid" arp ptype 0x0800 arp htype 1 arp hlen 6 arp plen 4 @nh,192,32 0xc0a88f10 @nh,144,48 set 0x112233445566;ok;iifname "invalid" arp htype 1 arp ptype ip arp hlen 6 arp plen 4 arp daddr ip 192.168.143.16 arp daddr ether set 11:22:33:44:55:66
index 33e7341716d198c6fd71c4fdce9f3e93c3381144..d36bef183396ffc3e61b48fc24e676b649517dac 100644 (file)
@@ -280,3 +280,24 @@ arp test-arp input
   [ cmp eq reg 1 0x108fa8c0 ]
   [ immediate reg 1 0x44332211 0x00006655 ]
   [ payload write reg 1 => 6b @ network header + 18 csum_type 0 csum_off 0 csum_flags 0x0 ]
+
+# arp saddr ip 1.2.3.4
+arp test-arp input 
+  [ payload load 4b @ network header + 14 => reg 1 ]
+  [ cmp eq reg 1 0x04030201 ]
+
+# arp daddr ip 4.3.2.1
+arp test-arp input 
+  [ payload load 4b @ network header + 24 => reg 1 ]
+  [ cmp eq reg 1 0x01020304 ]
+
+# arp saddr ether aa:bb:cc:aa:bb:cc
+arp test-arp input 
+  [ payload load 6b @ network header + 8 => reg 1 ]
+  [ cmp eq reg 1 0xaaccbbaa 0x0000ccbb ]
+
+# arp daddr ether aa:bb:cc:aa:bb:cc
+arp test-arp input 
+  [ payload load 6b @ network header + 18 => reg 1 ]
+  [ cmp eq reg 1 0xaaccbbaa 0x0000ccbb ]
+
index 4fcf35049de222ea740279ac2ffebdd7ce7c5f97..0146cf500ee2150f273f6e8c35da929863d63379 100644 (file)
@@ -373,3 +373,31 @@ netdev test-netdev ingress
   [ immediate reg 1 0x44332211 0x00006655 ]
   [ payload write reg 1 => 6b @ network header + 18 csum_type 0 csum_off 0 csum_flags 0x0 ]
 
+# arp saddr ip 1.2.3.4
+netdev test-netdev ingress 
+  [ meta load protocol => reg 1 ]
+  [ cmp eq reg 1 0x00000608 ]
+  [ payload load 4b @ network header + 14 => reg 1 ]
+  [ cmp eq reg 1 0x04030201 ]
+
+# arp daddr ip 4.3.2.1
+netdev test-netdev ingress 
+  [ meta load protocol => reg 1 ]
+  [ cmp eq reg 1 0x00000608 ]
+  [ payload load 4b @ network header + 24 => reg 1 ]
+  [ cmp eq reg 1 0x01020304 ]
+
+# arp saddr ether aa:bb:cc:aa:bb:cc
+netdev test-netdev ingress 
+  [ meta load protocol => reg 1 ]
+  [ cmp eq reg 1 0x00000608 ]
+  [ payload load 6b @ network header + 8 => reg 1 ]
+  [ cmp eq reg 1 0xaaccbbaa 0x0000ccbb ]
+
+# arp daddr ether aa:bb:cc:aa:bb:cc
+netdev test-netdev ingress 
+  [ meta load protocol => reg 1 ]
+  [ cmp eq reg 1 0x00000608 ]
+  [ payload load 6b @ network header + 18 => reg 1 ]
+  [ cmp eq reg 1 0xaaccbbaa 0x0000ccbb ]
+