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>
This commit is contained in:
parent
8fb2b35735
commit
d89edb6112
3 changed files with 29 additions and 0 deletions
|
@ -42,6 +42,7 @@ struct l2_ethhdr {
|
||||||
enum l2_packet_filter_type {
|
enum l2_packet_filter_type {
|
||||||
L2_PACKET_FILTER_DHCP,
|
L2_PACKET_FILTER_DHCP,
|
||||||
L2_PACKET_FILTER_NDISC,
|
L2_PACKET_FILTER_NDISC,
|
||||||
|
L2_PACKET_FILTER_PKTTYPE,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -84,6 +84,26 @@ static const struct sock_fprog ndisc_sock_filter = {
|
||||||
.filter = ndisc_sock_filter_insns,
|
.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)
|
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:
|
case L2_PACKET_FILTER_NDISC:
|
||||||
sock_filter = &ndisc_sock_filter;
|
sock_filter = &ndisc_sock_filter;
|
||||||
break;
|
break;
|
||||||
|
case L2_PACKET_FILTER_PKTTYPE:
|
||||||
|
sock_filter = &pkt_type_sock_filter;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4014,6 +4014,11 @@ int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
|
||||||
wpa_supplicant_rx_eapol, wpa_s, 0);
|
wpa_supplicant_rx_eapol, wpa_s, 0);
|
||||||
if (wpa_s->l2 == NULL)
|
if (wpa_s->l2 == NULL)
|
||||||
return -1;
|
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 {
|
} else {
|
||||||
const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
|
const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
|
||||||
if (addr)
|
if (addr)
|
||||||
|
|
Loading…
Reference in a new issue