You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
3.1 KiB
96 lines
3.1 KiB
From d89edb6112f54fb65036c31eba291bda5fcad2b3 Mon Sep 17 00:00:00 2001 |
|
Message-Id: <d89edb6112f54fb65036c31eba291bda5fcad2b3.1522770749.git.davide.caratti@gmail.com> |
|
From: Davide Caratti <davide.caratti@gmail.com> |
|
Date: Wed, 28 Mar 2018 16:34:56 +0200 |
|
Subject: [PATCH] wpa_supplicant: Don't reply to EAPOL if pkt_type is |
|
PACKET_OTHERHOST |
|
|
|
When wpa_supplicant is running on a Linux interface that is configured in |
|
promiscuous mode, and it is not a member of a bridge, incoming EAPOL |
|
packets are processed regardless of the Destination Address in the frame. |
|
As a consequence, there are situations where wpa_supplicant replies to |
|
EAPOL packets that are not destined for it. |
|
|
|
This behavior seems undesired (see IEEE Std 802.1X-2010, 11.4.a), and can |
|
be avoided by attaching a BPF filter that lets the kernel discard packets |
|
having pkt_type equal to PACKET_OTHERHOST. |
|
|
|
Signed-off-by: Davide Caratti <davide.caratti@gmail.com> |
|
--- |
|
src/l2_packet/l2_packet.h | 1 + |
|
src/l2_packet/l2_packet_linux.c | 23 +++++++++++++++++++++++ |
|
wpa_supplicant/wpa_supplicant.c | 5 +++++ |
|
3 files changed, 29 insertions(+) |
|
|
|
diff --git a/src/l2_packet/l2_packet.h b/src/l2_packet/l2_packet.h |
|
index 2a4524582..53871774b 100644 |
|
--- a/src/l2_packet/l2_packet.h |
|
+++ b/src/l2_packet/l2_packet.h |
|
@@ -42,6 +42,7 @@ struct l2_ethhdr { |
|
enum l2_packet_filter_type { |
|
L2_PACKET_FILTER_DHCP, |
|
L2_PACKET_FILTER_NDISC, |
|
+ L2_PACKET_FILTER_PKTTYPE, |
|
}; |
|
|
|
/** |
|
diff --git a/src/l2_packet/l2_packet_linux.c b/src/l2_packet/l2_packet_linux.c |
|
index 65b490679..291c9dd26 100644 |
|
--- a/src/l2_packet/l2_packet_linux.c |
|
+++ b/src/l2_packet/l2_packet_linux.c |
|
@@ -84,6 +84,26 @@ static const struct sock_fprog ndisc_sock_filter = { |
|
.filter = ndisc_sock_filter_insns, |
|
}; |
|
|
|
+/* drop packet if skb->pkt_type is PACKET_OTHERHOST (0x03). Generated by: |
|
+ * $ bpfc - <<EOF |
|
+ * > ldb #type |
|
+ * > jeq #0x03, drop |
|
+ * > pass: ret #-1 |
|
+ * > drop: ret #0 |
|
+ * > EOF |
|
+ */ |
|
+static struct sock_filter pkt_type_filter_insns[] = { |
|
+ { 0x30, 0, 0, 0xfffff004 }, |
|
+ { 0x15, 1, 0, 0x00000003 }, |
|
+ { 0x6, 0, 0, 0xffffffff }, |
|
+ { 0x6, 0, 0, 0x00000000 }, |
|
+}; |
|
+ |
|
+static const struct sock_fprog pkt_type_sock_filter = { |
|
+ .len = ARRAY_SIZE(pkt_type_filter_insns), |
|
+ .filter = pkt_type_filter_insns, |
|
+}; |
|
+ |
|
|
|
int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr) |
|
{ |
|
@@ -471,6 +491,9 @@ int l2_packet_set_packet_filter(struct l2_packet_data *l2, |
|
case L2_PACKET_FILTER_NDISC: |
|
sock_filter = &ndisc_sock_filter; |
|
break; |
|
+ case L2_PACKET_FILTER_PKTTYPE: |
|
+ sock_filter = &pkt_type_sock_filter; |
|
+ break; |
|
default: |
|
return -1; |
|
} |
|
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c |
|
index 2a05ef910..dcec68a03 100644 |
|
--- a/wpa_supplicant/wpa_supplicant.c |
|
+++ b/wpa_supplicant/wpa_supplicant.c |
|
@@ -4014,6 +4014,11 @@ int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s) |
|
wpa_supplicant_rx_eapol, wpa_s, 0); |
|
if (wpa_s->l2 == NULL) |
|
return -1; |
|
+ |
|
+ if (l2_packet_set_packet_filter(wpa_s->l2, |
|
+ L2_PACKET_FILTER_PKTTYPE)) |
|
+ wpa_dbg(wpa_s, MSG_DEBUG, |
|
+ "Failed to attach pkt_type filter"); |
|
} else { |
|
const u8 *addr = wpa_drv_get_mac_addr(wpa_s); |
|
if (addr) |
|
-- |
|
2.14.3 |
|
|
|
|