mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-22 12:52:49 +01:00
eapol: Add eapol_frame_watch_add / remove
Allow other files to receive EAPoL frames on specified interfaces.
This commit is contained in:
parent
509324666c
commit
f05c3c30d1
@ -113,6 +113,7 @@ monitor_iwmon_SOURCES = monitor/main.c linux/nl80211.h \
|
||||
src/mpdu.h src/mpdu.c \
|
||||
src/util.h src/util.c \
|
||||
src/crypto.h src/crypto.c \
|
||||
src/watchlist.h src/watchlist.c \
|
||||
src/eapol.h src/eapol.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/eap.h src/eap.c \
|
||||
@ -150,6 +151,7 @@ endif
|
||||
unit_test_eap_sim_SOURCES = unit/test-eap-sim.c \
|
||||
src/crypto.h src/crypto.c src/simutil.h src/simutil.c \
|
||||
src/ie.h src/ie.c \
|
||||
src/watchlist.h src/watchlist.c \
|
||||
src/eapol.h src/eapol.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/eap.h src/eap.c \
|
||||
@ -205,6 +207,7 @@ unit_test_mpdu_LDADD = ell/libell-internal.la
|
||||
unit_test_eapol_SOURCES = unit/test-eapol.c \
|
||||
src/crypto.h src/crypto.c \
|
||||
src/ie.h src/ie.c \
|
||||
src/watchlist.h src/watchlist.c \
|
||||
src/eapol.h src/eapol.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/eap.h src/eap.c \
|
||||
@ -223,6 +226,7 @@ unit_test_ssid_security_LDADD = ell/libell-internal.la
|
||||
unit_test_wsc_SOURCES = unit/test-wsc.c src/wscutil.h src/wscutil.c \
|
||||
src/crypto.h src/crypto.c \
|
||||
src/ie.h src/ie.c \
|
||||
src/watchlist.h src/watchlist.c \
|
||||
src/eapol.h src/eapol.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/eap.h src/eap.c \
|
||||
|
62
src/eapol.c
62
src/eapol.c
@ -42,9 +42,11 @@
|
||||
#include "mpdu.h"
|
||||
#include "eap.h"
|
||||
#include "handshake.h"
|
||||
#include "watchlist.h"
|
||||
|
||||
struct l_queue *state_machines;
|
||||
struct l_queue *preauths;
|
||||
struct watchlist frame_watches;
|
||||
|
||||
eapol_deauthenticate_func_t deauthenticate = NULL;
|
||||
eapol_rekey_offload_func_t rekey_offload = NULL;
|
||||
@ -53,6 +55,8 @@ static struct l_io *pae_io;
|
||||
eapol_tx_packet_func_t tx_packet = NULL;
|
||||
void *tx_user_data;
|
||||
|
||||
uint32_t next_frame_watch_id;
|
||||
|
||||
/*
|
||||
* BPF filter to match skb->dev->type == 1 (ARPHRD_ETHER) and
|
||||
* match skb->protocol == 0x888e (PAE) or 0x88c7 (preauthentication).
|
||||
@ -1747,6 +1751,41 @@ eap_error:
|
||||
(int) sm->handshake->ifindex);
|
||||
}
|
||||
|
||||
struct eapol_frame_watch {
|
||||
uint32_t ifindex;
|
||||
struct watchlist_item super;
|
||||
};
|
||||
|
||||
static void eapol_frame_watch_free(struct watchlist_item *item)
|
||||
{
|
||||
struct eapol_frame_watch *efw =
|
||||
container_of(item, struct eapol_frame_watch, super);
|
||||
|
||||
l_free(efw);
|
||||
}
|
||||
|
||||
static const struct watchlist_ops eapol_frame_watch_ops = {
|
||||
.item_free = eapol_frame_watch_free,
|
||||
};
|
||||
|
||||
uint32_t eapol_frame_watch_add(uint32_t ifindex,
|
||||
eapol_frame_watch_func_t handler,
|
||||
void *user_data)
|
||||
{
|
||||
struct eapol_frame_watch *efw;
|
||||
|
||||
efw = l_new(struct eapol_frame_watch, 1);
|
||||
efw->ifindex = ifindex;
|
||||
|
||||
return watchlist_link(&frame_watches, &efw->super,
|
||||
handler, user_data, NULL);
|
||||
}
|
||||
|
||||
bool eapol_frame_watch_remove(uint32_t id)
|
||||
{
|
||||
return watchlist_remove(&frame_watches, id);
|
||||
}
|
||||
|
||||
struct preauth_sm {
|
||||
uint32_t ifindex;
|
||||
uint8_t aa[6];
|
||||
@ -1962,7 +2001,15 @@ void eapol_preauth_cancel(uint32_t ifindex)
|
||||
L_UINT_TO_PTR(ifindex));
|
||||
}
|
||||
|
||||
void __eapol_rx_packet(uint32_t ifindex, const uint8_t *aa, uint16_t proto,
|
||||
static bool eapol_frame_watch_match_ifindex(const void *a, const void *b)
|
||||
{
|
||||
struct eapol_frame_watch *efw =
|
||||
container_of(a, struct eapol_frame_watch, super);
|
||||
|
||||
return efw->ifindex == L_PTR_TO_UINT(b);
|
||||
}
|
||||
|
||||
void __eapol_rx_packet(uint32_t ifindex, const uint8_t *src, uint16_t proto,
|
||||
const uint8_t *frame, size_t len)
|
||||
{
|
||||
const struct eapol_header *eh;
|
||||
@ -1984,15 +2031,21 @@ void __eapol_rx_packet(uint32_t ifindex, const uint8_t *aa, uint16_t proto,
|
||||
if (len < (size_t) 4 + L_BE16_TO_CPU(eh->packet_len))
|
||||
return;
|
||||
|
||||
WATCHLIST_NOTIFY_MATCHES(&frame_watches,
|
||||
eapol_frame_watch_match_ifindex,
|
||||
L_UINT_TO_PTR(ifindex),
|
||||
eapol_frame_watch_func_t, proto, src,
|
||||
(const struct eapol_frame *) eh);
|
||||
|
||||
if (proto == ETH_P_PAE) {
|
||||
struct eapol_sm *sm = eapol_find_sm(ifindex, aa);
|
||||
struct eapol_sm *sm = eapol_find_sm(ifindex, src);
|
||||
|
||||
if (!sm)
|
||||
return;
|
||||
|
||||
eapol_rx_packet(sm, frame, len);
|
||||
} else if (proto == 0x88c7) {
|
||||
struct preauth_sm *sm = preauth_find_sm(ifindex, aa);
|
||||
struct preauth_sm *sm = preauth_find_sm(ifindex, src);
|
||||
|
||||
if (!sm)
|
||||
return;
|
||||
@ -2005,6 +2058,7 @@ bool eapol_init()
|
||||
{
|
||||
state_machines = l_queue_new();
|
||||
preauths = l_queue_new();
|
||||
watchlist_init(&frame_watches, &eapol_frame_watch_ops);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -2021,5 +2075,7 @@ bool eapol_exit()
|
||||
|
||||
l_queue_destroy(preauths, preauth_sm_destroy);
|
||||
|
||||
watchlist_destroy(&frame_watches);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -124,6 +124,9 @@ typedef void (*eapol_deauthenticate_func_t)(uint32_t ifindex, const uint8_t *aa,
|
||||
void *user_data);
|
||||
typedef void (*eapol_preauth_cb_t)(const uint8_t *pmk, void *user_data);
|
||||
typedef void (*eapol_preauth_destroy_func_t)(void *user_data);
|
||||
typedef void (*eapol_frame_watch_func_t)(uint16_t proto, const uint8_t *from,
|
||||
const struct eapol_frame *frame,
|
||||
void *user_data);
|
||||
|
||||
bool eapol_calculate_mic(const uint8_t *kck, const struct eapol_key *frame,
|
||||
uint8_t *mic);
|
||||
@ -190,6 +193,11 @@ void eapol_sm_set_event_func(struct eapol_sm *sm, eapol_sm_event_func_t func);
|
||||
void eapol_register(struct eapol_sm *sm);
|
||||
void eapol_start(struct eapol_sm *sm);
|
||||
|
||||
uint32_t eapol_frame_watch_add(uint32_t ifindex,
|
||||
eapol_frame_watch_func_t handler,
|
||||
void *user_data);
|
||||
bool eapol_frame_watch_remove(uint32_t id);
|
||||
|
||||
struct preauth_sm *eapol_preauth_start(const uint8_t *aa,
|
||||
const struct handshake_state *hs,
|
||||
eapol_preauth_cb_t cb, void *user_data,
|
||||
|
Loading…
Reference in New Issue
Block a user