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)
|
||||
{
|
||||
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) {
|
||||
if (hostapd_ctrl_iface_eapol_rx(hapd, buf + 9) < 0)
|
||||
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) {
|
||||
if (hostapd_ctrl_iface_data_test_config(hapd, buf + 17) < 0)
|
||||
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,
|
||||
struct wpa_state_machine *sm);
|
||||
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_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,
|
||||
const u8 *data, size_t data_len,
|
||||
int encrypt)
|
||||
int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr,
|
||||
const u8 *data, size_t data_len,
|
||||
int encrypt)
|
||||
{
|
||||
struct hostapd_data *hapd = ctx;
|
||||
struct sta_info *sta;
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "driver_i.h"
|
||||
#include "wps_supplicant.h"
|
||||
#include "ibss_rsn.h"
|
||||
#include "wpas_glue.h"
|
||||
#include "ap.h"
|
||||
#include "p2p_supplicant.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)
|
||||
{
|
||||
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) {
|
||||
if (wpas_ctrl_iface_eapol_rx(wpa_s, buf + 9) < 0)
|
||||
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) {
|
||||
if (wpas_ctrl_iface_data_test_config(wpa_s, buf + 17) < 0)
|
||||
reply_len = -1;
|
||||
|
|
|
@ -95,8 +95,8 @@ static u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type,
|
|||
* @len: Frame payload length
|
||||
* Returns: >=0 on success, <0 on failure
|
||||
*/
|
||||
static int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
|
||||
u16 proto, const u8 *buf, size_t len)
|
||||
int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
|
||||
u16 proto, const u8 *buf, size_t len)
|
||||
{
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
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);
|
||||
void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s,
|
||||
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 *default_txt,
|
||||
|
|
Loading…
Reference in a new issue