Add EAPOL_TX command to extend ext_eapol_frame_io possibilities
This makes it convenient for an external test script to use ext_eapol_frame_io=1 to delay and/or modify transmission of EAPOL-Key msg 1/4 without having to use separate frame injection mechanisms. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
7f0a2e4225
commit
1c5aa2579d
6 changed files with 102 additions and 5 deletions
|
@ -1946,6 +1946,52 @@ static int hostapd_ctrl_iface_eapol_rx(struct hostapd_data *hapd, char *cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_ctrl_iface_eapol_tx(struct hostapd_data *hapd, char *cmd)
|
||||||
|
{
|
||||||
|
char *pos, *pos2;
|
||||||
|
u8 dst[ETH_ALEN], *buf;
|
||||||
|
int used, ret;
|
||||||
|
size_t len;
|
||||||
|
unsigned int prev;
|
||||||
|
int encrypt = 0;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "External EAPOL TX: %s", cmd);
|
||||||
|
|
||||||
|
pos = cmd;
|
||||||
|
used = hwaddr_aton2(pos, dst);
|
||||||
|
if (used < 0)
|
||||||
|
return -1;
|
||||||
|
pos += used;
|
||||||
|
while (*pos == ' ')
|
||||||
|
pos++;
|
||||||
|
|
||||||
|
pos2 = os_strchr(pos, ' ');
|
||||||
|
if (pos2) {
|
||||||
|
len = pos2 - pos;
|
||||||
|
encrypt = os_strstr(pos2, "encrypt=1") != NULL;
|
||||||
|
} else {
|
||||||
|
len = os_strlen(pos);
|
||||||
|
}
|
||||||
|
if (len & 1)
|
||||||
|
return -1;
|
||||||
|
len /= 2;
|
||||||
|
|
||||||
|
buf = os_malloc(len);
|
||||||
|
if (!buf || hexstr2bin(pos, buf, len) < 0) {
|
||||||
|
os_free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = hapd->ext_eapol_frame_io;
|
||||||
|
hapd->ext_eapol_frame_io = 0;
|
||||||
|
ret = hostapd_wpa_auth_send_eapol(hapd, dst, buf, len, encrypt);
|
||||||
|
hapd->ext_eapol_frame_io = prev;
|
||||||
|
os_free(buf);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static u16 ipv4_hdr_checksum(const void *buf, size_t len)
|
static u16 ipv4_hdr_checksum(const void *buf, size_t len)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -3651,6 +3697,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
|
||||||
} else if (os_strncmp(buf, "EAPOL_RX ", 9) == 0) {
|
} else if (os_strncmp(buf, "EAPOL_RX ", 9) == 0) {
|
||||||
if (hostapd_ctrl_iface_eapol_rx(hapd, buf + 9) < 0)
|
if (hostapd_ctrl_iface_eapol_rx(hapd, buf + 9) < 0)
|
||||||
reply_len = -1;
|
reply_len = -1;
|
||||||
|
} else if (os_strncmp(buf, "EAPOL_TX ", 9) == 0) {
|
||||||
|
if (hostapd_ctrl_iface_eapol_tx(hapd, buf + 9) < 0)
|
||||||
|
reply_len = -1;
|
||||||
} else if (os_strncmp(buf, "DATA_TEST_CONFIG ", 17) == 0) {
|
} else if (os_strncmp(buf, "DATA_TEST_CONFIG ", 17) == 0) {
|
||||||
if (hostapd_ctrl_iface_data_test_config(hapd, buf + 17) < 0)
|
if (hostapd_ctrl_iface_data_test_config(hapd, buf + 17) < 0)
|
||||||
reply_len = -1;
|
reply_len = -1;
|
||||||
|
|
|
@ -556,6 +556,9 @@ int wpa_auth_resend_group_m1(struct wpa_state_machine *sm,
|
||||||
int wpa_auth_rekey_ptk(struct wpa_authenticator *wpa_auth,
|
int wpa_auth_rekey_ptk(struct wpa_authenticator *wpa_auth,
|
||||||
struct wpa_state_machine *sm);
|
struct wpa_state_machine *sm);
|
||||||
int wpa_auth_rekey_gtk(struct wpa_authenticator *wpa_auth);
|
int wpa_auth_rekey_gtk(struct wpa_authenticator *wpa_auth);
|
||||||
|
int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr,
|
||||||
|
const u8 *data, size_t data_len,
|
||||||
|
int encrypt);
|
||||||
void wpa_auth_set_ptk_rekey_timer(struct wpa_state_machine *sm);
|
void wpa_auth_set_ptk_rekey_timer(struct wpa_state_machine *sm);
|
||||||
void wpa_auth_set_ft_rsnxe_used(struct wpa_authenticator *wpa_auth, int val);
|
void wpa_auth_set_ft_rsnxe_used(struct wpa_authenticator *wpa_auth, int val);
|
||||||
|
|
||||||
|
|
|
@ -505,9 +505,9 @@ static int hostapd_wpa_auth_get_seqnum(void *ctx, const u8 *addr, int idx,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr,
|
int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr,
|
||||||
const u8 *data, size_t data_len,
|
const u8 *data, size_t data_len,
|
||||||
int encrypt)
|
int encrypt)
|
||||||
{
|
{
|
||||||
struct hostapd_data *hapd = ctx;
|
struct hostapd_data *hapd = ctx;
|
||||||
struct sta_info *sta;
|
struct sta_info *sta;
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "driver_i.h"
|
#include "driver_i.h"
|
||||||
#include "wps_supplicant.h"
|
#include "wps_supplicant.h"
|
||||||
#include "ibss_rsn.h"
|
#include "ibss_rsn.h"
|
||||||
|
#include "wpas_glue.h"
|
||||||
#include "ap.h"
|
#include "ap.h"
|
||||||
#include "p2p_supplicant.h"
|
#include "p2p_supplicant.h"
|
||||||
#include "p2p/p2p.h"
|
#include "p2p/p2p.h"
|
||||||
|
@ -9519,6 +9520,45 @@ static int wpas_ctrl_iface_eapol_rx(struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpas_ctrl_iface_eapol_tx(struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
|
{
|
||||||
|
char *pos;
|
||||||
|
u8 dst[ETH_ALEN], *buf;
|
||||||
|
int used, ret;
|
||||||
|
size_t len;
|
||||||
|
unsigned int prev;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "External EAPOL TX: %s", cmd);
|
||||||
|
|
||||||
|
pos = cmd;
|
||||||
|
used = hwaddr_aton2(pos, dst);
|
||||||
|
if (used < 0)
|
||||||
|
return -1;
|
||||||
|
pos += used;
|
||||||
|
while (*pos == ' ')
|
||||||
|
pos++;
|
||||||
|
|
||||||
|
len = os_strlen(pos);
|
||||||
|
if (len & 1)
|
||||||
|
return -1;
|
||||||
|
len /= 2;
|
||||||
|
|
||||||
|
buf = os_malloc(len);
|
||||||
|
if (!buf || hexstr2bin(pos, buf, len) < 0) {
|
||||||
|
os_free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = wpa_s->ext_eapol_frame_io;
|
||||||
|
wpa_s->ext_eapol_frame_io = 0;
|
||||||
|
ret = wpa_ether_send(wpa_s, dst, ETH_P_EAPOL, buf, len);
|
||||||
|
wpa_s->ext_eapol_frame_io = prev;
|
||||||
|
os_free(buf);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static u16 ipv4_hdr_checksum(const void *buf, size_t len)
|
static u16 ipv4_hdr_checksum(const void *buf, size_t len)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -11514,6 +11554,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
||||||
} else if (os_strncmp(buf, "EAPOL_RX ", 9) == 0) {
|
} else if (os_strncmp(buf, "EAPOL_RX ", 9) == 0) {
|
||||||
if (wpas_ctrl_iface_eapol_rx(wpa_s, buf + 9) < 0)
|
if (wpas_ctrl_iface_eapol_rx(wpa_s, buf + 9) < 0)
|
||||||
reply_len = -1;
|
reply_len = -1;
|
||||||
|
} else if (os_strncmp(buf, "EAPOL_TX ", 9) == 0) {
|
||||||
|
if (wpas_ctrl_iface_eapol_tx(wpa_s, buf + 9) < 0)
|
||||||
|
reply_len = -1;
|
||||||
} else if (os_strncmp(buf, "DATA_TEST_CONFIG ", 17) == 0) {
|
} else if (os_strncmp(buf, "DATA_TEST_CONFIG ", 17) == 0) {
|
||||||
if (wpas_ctrl_iface_data_test_config(wpa_s, buf + 17) < 0)
|
if (wpas_ctrl_iface_data_test_config(wpa_s, buf + 17) < 0)
|
||||||
reply_len = -1;
|
reply_len = -1;
|
||||||
|
|
|
@ -95,8 +95,8 @@ static u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type,
|
||||||
* @len: Frame payload length
|
* @len: Frame payload length
|
||||||
* Returns: >=0 on success, <0 on failure
|
* Returns: >=0 on success, <0 on failure
|
||||||
*/
|
*/
|
||||||
static int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
|
int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
|
||||||
u16 proto, const u8 *buf, size_t len)
|
u16 proto, const u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
if (wpa_s->ext_eapol_frame_io && proto == ETH_P_EAPOL) {
|
if (wpa_s->ext_eapol_frame_io && proto == ETH_P_EAPOL) {
|
||||||
|
|
|
@ -15,6 +15,8 @@ int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s);
|
||||||
int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s);
|
int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s);
|
||||||
void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s,
|
void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_ssid *ssid);
|
struct wpa_ssid *ssid);
|
||||||
|
int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
|
||||||
|
u16 proto, const u8 *buf, size_t len);
|
||||||
|
|
||||||
const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field,
|
const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field,
|
||||||
const char *default_txt,
|
const char *default_txt,
|
||||||
|
|
Loading…
Reference in a new issue