mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2025-01-02 09:22:32 +01:00
netdev: Move eapol_read to eapol.c
This commit is contained in:
parent
746b0e5cb1
commit
efe5bed7c5
58
src/eapol.c
58
src/eapol.c
@ -603,6 +603,7 @@ struct eapol_sm {
|
|||||||
void *user_data;
|
void *user_data;
|
||||||
void *tx_user_data;
|
void *tx_user_data;
|
||||||
struct l_timeout *timeout;
|
struct l_timeout *timeout;
|
||||||
|
struct l_io *io;
|
||||||
bool have_snonce:1;
|
bool have_snonce:1;
|
||||||
bool have_replay:1;
|
bool have_replay:1;
|
||||||
bool ptk_complete:1;
|
bool ptk_complete:1;
|
||||||
@ -619,6 +620,7 @@ static void eapol_sm_destroy(void *value)
|
|||||||
l_free(sm->own_ie);
|
l_free(sm->own_ie);
|
||||||
|
|
||||||
l_timeout_remove(sm->timeout);
|
l_timeout_remove(sm->timeout);
|
||||||
|
l_io_destroy(sm->io);
|
||||||
|
|
||||||
if (sm->eap)
|
if (sm->eap)
|
||||||
eap_free(sm->eap);
|
eap_free(sm->eap);
|
||||||
@ -1462,14 +1464,12 @@ void eapol_sm_set_8021x_config(struct eapol_sm *sm, struct l_settings *settings)
|
|||||||
eap_load_settings(sm->eap, settings, "EAP-");
|
eap_load_settings(sm->eap, settings, "EAP-");
|
||||||
}
|
}
|
||||||
|
|
||||||
void __eapol_rx_packet(uint32_t ifindex, const uint8_t *spa, const uint8_t *aa,
|
static void eapol_rx_packet(struct eapol_sm *sm,
|
||||||
const uint8_t *frame, size_t len)
|
const uint8_t *frame, size_t len)
|
||||||
{
|
{
|
||||||
const struct eapol_header *eh;
|
const struct eapol_header *eh;
|
||||||
struct eapol_sm *sm;
|
|
||||||
|
|
||||||
/* Validate Header */
|
/* Validate Header */
|
||||||
|
|
||||||
if (len < sizeof(struct eapol_header))
|
if (len < sizeof(struct eapol_header))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1482,10 +1482,6 @@ void __eapol_rx_packet(uint32_t ifindex, const uint8_t *spa, const uint8_t *aa,
|
|||||||
if (len < (size_t) 4 + L_BE16_TO_CPU(eh->packet_len))
|
if (len < (size_t) 4 + L_BE16_TO_CPU(eh->packet_len))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sm = eapol_find_sm(ifindex, spa, aa);
|
|
||||||
if (!sm)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (eh->packet_type) {
|
switch (eh->packet_type) {
|
||||||
case 0: /* EAPOL-EAP */
|
case 0: /* EAPOL-EAP */
|
||||||
if (!sm->eap) {
|
if (!sm->eap) {
|
||||||
@ -1512,7 +1508,7 @@ void __eapol_rx_packet(uint32_t ifindex, const uint8_t *spa, const uint8_t *aa,
|
|||||||
if (!sm->have_pmk)
|
if (!sm->have_pmk)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
eapol_key_handle(sm, ifindex, frame, len);
|
eapol_key_handle(sm, sm->ifindex, frame, len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1520,6 +1516,17 @@ void __eapol_rx_packet(uint32_t ifindex, const uint8_t *spa, const uint8_t *aa,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __eapol_rx_packet(uint32_t ifindex, const uint8_t *spa, const uint8_t *aa,
|
||||||
|
const uint8_t *frame, size_t len)
|
||||||
|
{
|
||||||
|
struct eapol_sm *sm = eapol_find_sm(ifindex, spa, aa);
|
||||||
|
|
||||||
|
if (!sm)
|
||||||
|
return;
|
||||||
|
|
||||||
|
eapol_rx_packet(sm, frame, len);
|
||||||
|
}
|
||||||
|
|
||||||
void __eapol_update_replay_counter(uint32_t ifindex, const uint8_t *spa,
|
void __eapol_update_replay_counter(uint32_t ifindex, const uint8_t *spa,
|
||||||
const uint8_t *aa, uint64_t replay_counter)
|
const uint8_t *aa, uint64_t replay_counter)
|
||||||
{
|
{
|
||||||
@ -1608,6 +1615,33 @@ struct l_io *eapol_open_pae(uint32_t index)
|
|||||||
return io;
|
return io;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool eapol_read(struct l_io *io, void *user_data)
|
||||||
|
{
|
||||||
|
struct eapol_sm *sm = user_data;
|
||||||
|
int fd = l_io_get_fd(io);
|
||||||
|
struct sockaddr_ll sll;
|
||||||
|
socklen_t sll_len;
|
||||||
|
ssize_t bytes;
|
||||||
|
uint8_t frame[2304]; /* IEEE Std 802.11 ch. 8.2.3 */
|
||||||
|
|
||||||
|
memset(&sll, 0, sizeof(sll));
|
||||||
|
sll_len = sizeof(sll);
|
||||||
|
|
||||||
|
bytes = recvfrom(fd, frame, sizeof(frame), 0,
|
||||||
|
(struct sockaddr *) &sll, &sll_len);
|
||||||
|
if (bytes <= 0) {
|
||||||
|
l_error("EAPoL read socket: %s", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(sm->aa, sll.sll_addr, 6))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
eapol_rx_packet(sm, frame, bytes);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default implementation of the frame transmission function.
|
* Default implementation of the frame transmission function.
|
||||||
* This function expects an fd to be passed as user_data
|
* This function expects an fd to be passed as user_data
|
||||||
@ -1649,6 +1683,12 @@ void eapol_start(uint32_t ifindex, struct l_io *io, struct eapol_sm *sm)
|
|||||||
{
|
{
|
||||||
sm->ifindex = ifindex;
|
sm->ifindex = ifindex;
|
||||||
sm->timeout = l_timeout_create(2, eapol_timeout, sm, NULL);
|
sm->timeout = l_timeout_create(2, eapol_timeout, sm, NULL);
|
||||||
|
|
||||||
|
if (io) {
|
||||||
|
sm->io = io;
|
||||||
|
l_io_set_read_handler(io, eapol_read, sm, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
l_queue_push_head(state_machines, sm);
|
l_queue_push_head(state_machines, sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ const uint8_t *eapol_sm_get_own_ie(struct eapol_sm *sm, size_t *out_ie_len);
|
|||||||
|
|
||||||
struct l_io *eapol_open_pae(uint32_t index);
|
struct l_io *eapol_open_pae(uint32_t index);
|
||||||
|
|
||||||
void eapol_start(uint32_t ifindex, struct eapol_sm *sm);
|
void eapol_start(uint32_t ifindex, struct l_io *io, struct eapol_sm *sm);
|
||||||
void eapol_cancel(uint32_t ifindex);
|
void eapol_cancel(uint32_t ifindex);
|
||||||
|
|
||||||
bool eapol_init();
|
bool eapol_init();
|
||||||
|
88
src/netdev.c
88
src/netdev.c
@ -53,7 +53,6 @@ struct netdev {
|
|||||||
char name[IFNAMSIZ];
|
char name[IFNAMSIZ];
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint8_t addr[ETH_ALEN];
|
uint8_t addr[ETH_ALEN];
|
||||||
struct l_io *eapol_io;
|
|
||||||
struct device *device;
|
struct device *device;
|
||||||
|
|
||||||
netdev_event_func_t event_filter;
|
netdev_event_func_t event_filter;
|
||||||
@ -62,6 +61,7 @@ struct netdev {
|
|||||||
void *user_data;
|
void *user_data;
|
||||||
struct l_genl_msg *associate_msg;
|
struct l_genl_msg *associate_msg;
|
||||||
struct eapol_sm *sm;
|
struct eapol_sm *sm;
|
||||||
|
struct l_io *eapol_io;
|
||||||
uint8_t remote_addr[ETH_ALEN];
|
uint8_t remote_addr[ETH_ALEN];
|
||||||
uint32_t pairwise_new_key_cmd_id;
|
uint32_t pairwise_new_key_cmd_id;
|
||||||
uint32_t pairwise_set_key_cmd_id;
|
uint32_t pairwise_set_key_cmd_id;
|
||||||
@ -93,31 +93,6 @@ static void do_debug(const char *str, void *user_data)
|
|||||||
l_info("%s%s", prefix, str);
|
l_info("%s%s", prefix, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool eapol_read(struct l_io *io, void *user_data)
|
|
||||||
{
|
|
||||||
struct netdev *netdev = user_data;
|
|
||||||
int fd = l_io_get_fd(io);
|
|
||||||
struct sockaddr_ll sll;
|
|
||||||
socklen_t sll_len;
|
|
||||||
ssize_t bytes;
|
|
||||||
uint8_t frame[2304]; /* IEEE Std 802.11 ch. 8.2.3 */
|
|
||||||
|
|
||||||
memset(&sll, 0, sizeof(sll));
|
|
||||||
sll_len = sizeof(sll);
|
|
||||||
|
|
||||||
bytes = recvfrom(fd, frame, sizeof(frame), 0,
|
|
||||||
(struct sockaddr *) &sll, &sll_len);
|
|
||||||
if (bytes <= 0) {
|
|
||||||
l_error("EAPoL read socket: %s", strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
__eapol_rx_packet(netdev->index, netdev->addr, sll.sll_addr,
|
|
||||||
frame, bytes);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cb_data {
|
struct cb_data {
|
||||||
netdev_command_func_t callback;
|
netdev_command_func_t callback;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
@ -233,6 +208,9 @@ static void netdev_free(void *data)
|
|||||||
if (netdev->sm) {
|
if (netdev->sm) {
|
||||||
eapol_sm_free(netdev->sm);
|
eapol_sm_free(netdev->sm);
|
||||||
netdev->sm = NULL;
|
netdev->sm = NULL;
|
||||||
|
|
||||||
|
l_io_destroy(netdev->eapol_io);
|
||||||
|
netdev->eapol_io = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netdev->associate_msg) {
|
if (netdev->associate_msg) {
|
||||||
@ -240,9 +218,6 @@ static void netdev_free(void *data)
|
|||||||
netdev->associate_msg = NULL;
|
netdev->associate_msg = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
l_io_destroy(netdev->eapol_io);
|
|
||||||
netdev->eapol_io = NULL;
|
|
||||||
|
|
||||||
netdev_set_linkmode_and_operstate(netdev->index, 0, IF_OPER_DOWN,
|
netdev_set_linkmode_and_operstate(netdev->index, 0, IF_OPER_DOWN,
|
||||||
netdev_operstate_down_cb,
|
netdev_operstate_down_cb,
|
||||||
L_UINT_TO_PTR(netdev->index));
|
L_UINT_TO_PTR(netdev->index));
|
||||||
@ -838,6 +813,21 @@ static void netdev_set_rekey_offload(uint32_t ifindex,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void netdev_connect_failed(struct netdev *netdev,
|
||||||
|
enum netdev_result result)
|
||||||
|
{
|
||||||
|
if (netdev->sm) {
|
||||||
|
eapol_sm_free(netdev->sm);
|
||||||
|
netdev->sm = NULL;
|
||||||
|
|
||||||
|
l_io_destroy(netdev->eapol_io);
|
||||||
|
netdev->eapol_io = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (netdev->connect_cb)
|
||||||
|
netdev->connect_cb(netdev, result, netdev->user_data);
|
||||||
|
}
|
||||||
|
|
||||||
static void netdev_connect_event(struct l_genl_msg *msg,
|
static void netdev_connect_event(struct l_genl_msg *msg,
|
||||||
struct netdev *netdev)
|
struct netdev *netdev)
|
||||||
{
|
{
|
||||||
@ -873,9 +863,10 @@ static void netdev_connect_event(struct l_genl_msg *msg,
|
|||||||
if (netdev->sm) {
|
if (netdev->sm) {
|
||||||
eapol_sm_set_tx_user_data(netdev->sm,
|
eapol_sm_set_tx_user_data(netdev->sm,
|
||||||
L_INT_TO_PTR(l_io_get_fd(netdev->eapol_io)));
|
L_INT_TO_PTR(l_io_get_fd(netdev->eapol_io)));
|
||||||
eapol_start(netdev->index, netdev->sm);
|
eapol_start(netdev->index, netdev->eapol_io, netdev->sm);
|
||||||
|
|
||||||
netdev->sm = NULL;
|
netdev->sm = NULL;
|
||||||
|
netdev->eapol_io = NULL;
|
||||||
|
|
||||||
if (netdev->event_filter)
|
if (netdev->event_filter)
|
||||||
netdev->event_filter(netdev,
|
netdev->event_filter(netdev,
|
||||||
@ -888,13 +879,7 @@ static void netdev_connect_event(struct l_genl_msg *msg,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (netdev->sm) {
|
netdev_connect_failed(netdev, NETDEV_RESULT_ASSOCIATION_FAILED);
|
||||||
eapol_sm_free(netdev->sm);
|
|
||||||
netdev->sm = NULL;
|
|
||||||
|
|
||||||
if (netdev->connect_cb)
|
|
||||||
netdev->connect_cb(netdev, NETDEV_RESULT_ASSOCIATION_FAILED,
|
|
||||||
netdev->user_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void netdev_authenticate_event(struct l_genl_msg *msg,
|
static void netdev_authenticate_event(struct l_genl_msg *msg,
|
||||||
@ -923,9 +908,7 @@ static void netdev_cmd_connect_cb(struct l_genl_msg *msg, void *user_data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netdev->connect_cb)
|
netdev_connect_failed(netdev, NETDEV_RESULT_ASSOCIATION_FAILED);
|
||||||
netdev->connect_cb(netdev, NETDEV_RESULT_ASSOCIATION_FAILED,
|
|
||||||
netdev->user_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct l_genl_msg *netdev_build_cmd_connect(struct netdev *netdev,
|
static struct l_genl_msg *netdev_build_cmd_connect(struct netdev *netdev,
|
||||||
@ -1003,9 +986,25 @@ int netdev_connect(struct netdev *netdev, struct scan_bss *bss,
|
|||||||
netdev->event_filter = event_filter;
|
netdev->event_filter = event_filter;
|
||||||
netdev->connect_cb = cb;
|
netdev->connect_cb = cb;
|
||||||
netdev->user_data = user_data;
|
netdev->user_data = user_data;
|
||||||
netdev->sm = sm;
|
|
||||||
memcpy(netdev->remote_addr, bss->addr, ETH_ALEN);
|
memcpy(netdev->remote_addr, bss->addr, ETH_ALEN);
|
||||||
|
|
||||||
|
netdev->sm = sm;
|
||||||
|
if (netdev->sm) {
|
||||||
|
/*
|
||||||
|
* Due to timing / race conditions, it is possible for
|
||||||
|
* EAPoL packets to arrive before the netdev events
|
||||||
|
* are received. Here we 'prime' the socket, so that
|
||||||
|
* the data is available as soon as we call eapol_start
|
||||||
|
*
|
||||||
|
* If this isn't done, then we might 'miss' the first EAPoL
|
||||||
|
* packet from the AP, and have to wait for the AP to
|
||||||
|
* retransmit. This delays our handshake by 1-2 seconds
|
||||||
|
*/
|
||||||
|
netdev->eapol_io = eapol_open_pae(netdev->index);
|
||||||
|
if (!netdev->eapol_io)
|
||||||
|
l_error("Failed to open PAE socket");
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1259,13 +1258,6 @@ static void netdev_get_interface_callback(struct l_genl_msg *msg,
|
|||||||
memcpy(netdev->addr, ifaddr, sizeof(netdev->addr));
|
memcpy(netdev->addr, ifaddr, sizeof(netdev->addr));
|
||||||
memcpy(netdev->name, ifname, ifname_len);
|
memcpy(netdev->name, ifname, ifname_len);
|
||||||
|
|
||||||
netdev->eapol_io = eapol_open_pae(netdev->index);
|
|
||||||
if (netdev->eapol_io)
|
|
||||||
l_io_set_read_handler(netdev->eapol_io, eapol_read,
|
|
||||||
netdev, NULL);
|
|
||||||
else
|
|
||||||
l_error("Failed to open PAE socket");
|
|
||||||
|
|
||||||
l_queue_push_tail(netdev_list, netdev);
|
l_queue_push_tail(netdev_list, netdev);
|
||||||
|
|
||||||
netdev_set_linkmode_and_operstate(netdev->index, 1,
|
netdev_set_linkmode_and_operstate(netdev->index, 1,
|
||||||
|
Loading…
Reference in New Issue
Block a user