diff options
Diffstat (limited to 'wpa_supplicant/ctrl_iface.c')
-rw-r--r-- | wpa_supplicant/ctrl_iface.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index bf83e41686a0..ba91cfb11d14 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -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; |