WPA - SUPPLICANT Code Introduction

You might also like

Download as odp, pdf, or txt
Download as odp, pdf, or txt
You are on page 1of 30

WPA_SUPPLICANT

code introduction
Linux +wired driver+TLS
version Feng
Fernado 2.9
Fernado.feng@Ericsson.com
0: How to introduce the code
ØWe use wide-searching and deep-searching to introduce the code.
First we introduce the main function and then we dig into each
function with deep-searching. Finally you will know everything. The
document is only for developer and you can follow the code with
the instruction to understand how wpa_supplicant works. Because
there are no too much descriptions and if you do not follow the
code, it is hard to understand. And it is hard to cover all the details,
so I ignore a lot of functions which are not that important. Please
notice this call flow is for configuration:
Linux+wired driver + TLS +IEEE8021X
Architecture
1.Main function struct wpa_interface {

Main arguments
const char *confname;---------c CONFIGURE FILE
const char *driver; ----------d DRIVER
const char *ctrl_interface; --- -C control interface
const char *ifname; ---- -I interface name
..}

struct wpa_global {
1 struct wpa_supplicant *ifaces;
wpa_supplicant_init struct wpa_params params;
struct ctrl_iface_global_priv *ctrl_iface;
struct wpas_dbus_priv *dbus;
struct wpas_binder_priv *binder;
void **drv_priv;
size_t drv_count;
…}

struct wpa_supplicant {
2 struct wpa_global *global;
wpa_supplicant_add_iface struct wpa_radio *radio; /* shared radio context */
struct dl_list radio_list; /* list head: struct wpa_radio::ifaces */
struct wpa_supplicant *parent;
struct wpa_supplicant *next;
struct l2_packet_data *l2;
char ifname[100];
int reassociate;
void *drv_priv;
3 void *global_drv_priv;
wpa_supplicant_run u8 bssid[ETH_ALEN];
const struct wpa_driver_ops *driver;
struct wpa_sm *wpa;
struct eapol_sm *eapol;
struct ctrl_iface_priv *ctrl_iface;
int scanning;
1.1 wpa_supplicant_init Register tls method
wpa_supplicant_init and callback function
1 eap_register_methods eap_peer_tls_register
Initialize event pool
list Struct eap_method {
2 eap->vendor = EAP_VENDOR_IETF
eloop_init eap->method = EAP_TYPE_TLS
eap->name = “TLS”
Initialize global eap->init = eap_tls_init;
control interface eap->deinit = eap_tls_deinit;
3 wpa_supplicant_global_ctrl_iface_init eap->process = eap_tls_process;
eap->isKeyAvailable = eap_tls_isKeyAvailable;
eap->getKey = eap_tls_getKey;
eap->getSessionId = eap_tls_get_session_id;
4 eap->get_status = eap_tls_get_status;
wpas_notify_supplicant_initialized eap->has_reauth_data = eap_tls_has_reauth_data;
eap->deinit_for_reauth = eap_tls_deinit_for_reauth;
eap->init_for_reauth = eap_tls_init_for_reauth;
eap->get_emsk = eap_tls_get_emsk;
}
1.1.1 wpa_supplicant_global_ctrl_iface_init
socket(PF_UNIX, SOCK_DGRAM, 0)
wpa_supplicant_global_ctrl_iface_init os_strlcpy(addr.sun_path, ctrl, sizeof(addr.sun_path));
1 wpas_global_ctrl_iface_open_sock bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr))

struct ctrl_iface_global_priv {
struct wpa_global *global;
int sock;
struct dl_list ctrl_dst;
struct dl_list msg_queue;
unsigned int throttle_count;
};

eloop_register_read_sock When there is message in the socket,


wpa_supplicant_global_ctrl_iface_receive
will be called

2 wpa_msg_register_cb
When call wpa_msg,
wpa_supplicant_ctrl_iface_msg_cb will be called to
send notification to all connections
1.1.1.1 wpa_supplicant_global_ctrl_iface_receive
wpa_supplicant_global_ctrl_iface_receive

wpa_supplicant_ctrl_iface_attach/detach wpa_supplicant_global_ctrl_iface_process

Add/remove conn to/from ctrl_dst wpas_global_ctrl_iface_ifname(IFNAME=)

struct ctrl_iface_global_priv { wpa_supplicant_ctrl_iface_process


struct wpa_global *global;
int sock;
struct dl_list ctrl_dst;
struct dl_list msg_queue; Control interface
unsigned int throttle_count; notification list.
};
1.2 wpa_supplicant_add_iface
static struct wpa_supplicant *
wpa_supplicant_add_iface wpa_supplicant_alloc(struct wpa_supplicant *parent)
{ struct wpa_supplicant *wpa_s;
wpa_s = os_zalloc(sizeof(*wpa_s)); Initialize
wpa_s->scan_req = INITIAL_SCAN_REQ;
wpa_s->scan_interval = 5; wpa_s
wpa_s->new_connection = 1;
wpa_s->parent = parent ? parent : wpa_s;
wpa_s->p2pdev = wpa_s->parent;
wpa_s->sched_scanning = 0;
dl_list_init(&wpa_s->bss_tmp_disallowed);
dl_list_init(&wpa_s->fils_hlp_req);
return wpa_s;
}

struct wpa_supplicant {
struct wpa_global *global;
struct wpa_radio *radio; /* shared radio context */
wpa_supplicant_init_iface struct dl_list radio_list
struct l2_packet_data *l2;
char ifname[100];
int reassociate;
void *drv_priv;
void *global_drv_priv;
u8 bssid[ETH_ALEN];
Return wpa_s const struct wpa_driver_ops *driver;
structure struct wpa_sm *wpa;
struct eapol_sm *eapol;
struct ctrl_iface_priv *ctrl_iface;
struct wpa_config *conf
int scanning;

}
1.2.1 wpa_supplicant_init_iface
wpa_supplicant_init_iface
1 wpa_config_read
Select and initialize
driver
2 wpas_init_driver
3 wpa_supplicant_init_wpa
4 wpa_supplicant_driver_init
5 wpas_wps_init

6 wpa_supplicant_init_eapol

7 wpa_supplicant_ctrl_iface_init

8 wpa_bss_init
1.2.1.1 wpas_init_driver const struct wpa_driver_ops *const
wpa_drivers[] ={&wpa_driver_wired_ops,..}

wpas_init_driver Driver name


const struct wpa_driver_ops wpa_driver_wired_ops = {
1 wpa_supplicant_set_driver .name = "wired",
.desc = "Wired Ethernet driver",
.hapd_init = wired_driver_hapd_init,
2 wpa_drv_init .hapd_deinit = wired_driver_hapd_deinit,
.hapd_send_eapol = wired_send_eapol,
.get_ssid = driver_wired_get_ssid,
.get_bssid = driver_wired_get_bssid,
wpa_driver_wired_init .get_capa = driver_wired_get_capa,
.init = wpa_driver_wired_init,
.deinit = wpa_driver_wired_deinit,
};
struct wpa_driver_wired_data {
struct driver_wired_common_data common;
Set io flag and MAC
static const u8 int dhcp_sock; /* socket for dhcp packets */
pae_group_addr[ETH_ALEN] = int use_pae_group_addr;
{ 0x01, 0x80, 0xc2, 0x00, 0x00, }
0x03 };

driver_wired_init_common
struct driver_wired_common_data {
char ifname[IFNAMSIZ + 1];
void *ctx;
int sock; /* raw packet socket for driver access */
int pf_sock;
int membership, multi, iff_allmulti, iff_up;
};
1.2.1.2 wpa_supplicant_init_wpa
wpa_supplicant_init_wpa struct wpa_sm_ctx *ctx
ctx = os_zalloc(sizeof(*ctx));
ctx->ctx = wpa_s;
ctx->msg_ctx = wpa_s;
ctx->set_state = _wpa_supplicant_set_state;
Initialize ctx->get_state = _wpa_supplicant_get_state;
wpa_sm and ctx->deauthenticate = _wpa_supplicant_deauthenticate;
ctx->set_key = wpa_supplicant_set_key;
wpa_sm_ctx ctx->get_network_ctx = wpa_supplicant_get_network_ctx;
wpa_sm_init ctx->get_bssid = wpa_supplicant_get_bssid;
ctx->ether_send = _wpa_ether_send;
ctx->get_beacon_ie = wpa_supplicant_get_beacon_ie;
ctx->alloc_eapol = _wpa_alloc_eapol;
ctx->cancel_auth_timeout = _wpa_supplicant_cancel_auth_timeout;
ctx->add_pmkid = wpa_supplicant_add_pmkid;
ctx->remove_pmkid = wpa_supplicant_remove_pmkid;
struct wpa_sm { ctx->set_rekey_offload = wpa_supplicant_set_rekey_offload;
struct eapol_sm *eapol; ctx->key_mgmt_set_pmk = wpa_supplicant_key_mgmt_set_pmk;
struct rsn_pmksa_cache *pmksa; ctx->fils_hlp_rx = wpa_supplicant_fils_hlp_rx;
struct rsn_pmksa_cache_entry *cur_pmksa; ctx->channel_info = wpa_supplicant_channel_info;
struct dl_list pmksa_candidates;
struct l2_packet_data *l2_preauth;
u8 preauth_bssid[ETH_ALEN];
struct eapol_sm *preauth_eapol;
struct wpa_sm_ctx *ctx;
int fast_reauth; -> conf
u8 ssid[32];
u8 own_addr[ETH_ALEN];
const char *ifname -> from wpa_s
…}
1.2.1.3 wpa_supplicant_driver_init
Socket(PF_PACKET, SOCK_DGRAM,
wpa_supplicant_driver_init htons(ETH_P_EAPOL))
1 wpa_supplicant_update_mac_addr
wpa_supplicant_rx_eapol

l2_package_init
Socket wpa_supplicant(wpa_s)

receiving eloop_register_read_sock(l2->fd,
callback l2_packet_receive, l2, NULL); struct l2_packet_data {
int fd; /* packet socket for EAPOL frames */
char ifname[IFNAMSIZ + 1];-from configuration
l2_packet_set_packet_filter int ifindex;
u8 own_addr[ETH_ALEN];
void (*rx_callback)(void *ctx, const u8 *src_addr,
static struct sock_filter const u8 *buf, size_t len);
Timeout function. pkt_type_filter_insns[] = { void *rx_callback_ctx;
Very important. { 0x30, 0, 0, 0xfffff004 },
{ 0x15, 1, 0, 0x00000003 },
int l2_hdr; = 0

It will trigger { 0x6, 0, 0, 0xffffffff },


{ 0x6, 0, 0, 0x00000000 },
association later };

2 wpa_supplicant_enabled_networks
3
wpa_supplicant_req_scan

wpa_supplicant_scan
1.2.1.3.1 l2_packet_receive
L2_packet_receive

wpa_supplicant_rx_eapol

eapol_sm_rx_eapol sm->eapReqData=msg Data(no hdr)

eapol_sm_step

Supp_PAE Supp_BE EAP(peer)

Three state
machines
1.2.1.4 wpas_wps_init
wpas_wps_init struct wps_context *wps;
struct wps_registrar_config rcfg;
wps->cred_cb = wpa_supplicant_wps_cred;
wps->event_cb = wpa_supplicant_wps_event;
wps->rf_band_cb = wpa_supplicant_wps_rf_band;
wps->cb_ctx = wpa_s;
wps->dev.device_name = wpa_s->conf->device_name;
wps->dev.manufacturer = wpa_s->conf->manufacturer;
wps->dev.model_name = wpa_s->conf->model_name;
wps->dev.model_number = wpa_s->conf->model_number;
wps->dev.serial_number = wpa_s->conf->serial_number;

os_memset(&rcfg, 0, sizeof(rcfg)); struct wpa_supplicant {
rcfg.new_psk_cb = wpas_wps_new_psk_cb; struct wpa_global *global;
rcfg.pin_needed_cb = wpas_wps_pin_needed_cb; struct wpa_radio *radio; /* shared radio context */
rcfg.set_sel_reg_cb = wpas_wps_set_sel_reg_cb; struct dl_list radio_list; /* list head: struct wpa_radio::ifaces */
rcfg.cb_ctx = wpa_s; struct wpa_supplicant *parent;
wps->registrar = wps_registrar_init(wps, &rcfg); struct wpa_supplicant *next;
struct l2_packet_data *l2;
char ifname[100];
int reassociate;
Initialize void *drv_priv;
void *global_drv_priv;
wpas_context of u8 bssid[ETH_ALEN];
wps const struct wpa_driver_ops *driver;
struct wpa_sm *wpa;
struct eapol_sm *eapol;
struct ctrl_iface_priv *ctrl_iface;
struct wps_context *wps;
int scanning;
…}
1.2.1.5 wpa_supplicant_init_eapol
wpa_supplicant_init_eapol struct eapol_ctx *ctx;
ctx->ctx = wpa_s;
ctx->msg_ctx = wpa_s;
ctx->eapol_send_ctx = wpa_s;
ctx->preauth = 0;
ctx->eapol_done_cb = wpa_supplicant_notify_eapol_done;
Initialize eapol_sm_init
ctx->eapol_send = wpa_supplicant_eapol_send;
ctx->set_wep_key = wpa_eapol_set_wep_key;
eapol_sm ctx->aborted_cached = wpa_supplicant_aborted_cached;
ctx->wps = wpa_s->wps;
ctx->eap_param_needed = wpa_supplicant_eap_param_needed;
ctx->port_cb = wpa_supplicant_port_cb;
ctx->cb = wpa_supplicant_eapol_cb;
ctx->cert_cb = wpa_supplicant_cert_cb;
ctx->cert_in_cb = wpa_s->conf->cert_in_cb;
ctx->status_cb = wpa_supplicant_status_cb;
ctx->eap_error_cb = wpa_supplicant_eap_error_cb;
struct wpa_supplicant {
ctx->set_anon_id = wpa_supplicant_set_anon_id;
struct wpa_global *global;
ctx->cb_ctx = wpa_s;
struct wpa_radio *radio;
wpa_s->eapol = eapol_sm_init(ctx); //struct eapol_sm
struct l2_packet_data *l2;
char ifname[100];
int reassociate; struct eapol_sm *sm;
void *drv_priv; sm->ctx = ctx;
void *global_drv_priv; sm->portControl = Auto;
u8 bssid[ETH_ALEN]; sm->heldPeriod = 60;
const struct wpa_driver_ops *driver; sm->startPeriod = 30;
struct wpa_sm *wpa; sm->maxStart = 3;
struct eapol_sm *eapol; sm->authPeriod = 30;
struct wps_context *wps; os_memset(&conf, 0, sizeof(conf));
int scanning; conf.opensc_engine_path = ctx->opensc_engine_path;
…} conf.pkcs11_engine_path = ctx->pkcs11_engine_path;
conf.pkcs11_module_path = ctx->pkcs11_module_path;
conf.openssl_ciphers = ctx->openssl_ciphers;
conf.wps = ctx->wps;
conf.cert_in_cb = ctx->cert_in_cb;
sm->eap = eap_peer_sm_init(sm, &eapol_cb, sm->ctx->msg_ctx, &conf);
1.2.1.5.1 eapol_sm_init
eapol_sm_init Struct eap_sm:
sm->eapol_ctx = eapol_ctx;-eapol_sm
Initialize peer
1 eap_peer_sm_init sm->eapol_cb = eapol_cb;
sm->msg_ctx = msg_ctx;-eapol_sm->eapol_ctx->msg_cxwpa_s
eap_sm tlsconf.event_cb = eap_peer_sm_tls_event;
tlsconf.cb_ctx = sm;
2 eapol_sm_step with initialize=true tlsconf.cert_in_cb = conf->cert_in_cb;
&forece_authorized_update = true sm->ssl_ctx = tls_init(&tlsconf);
sm->ssl_ctx2 = tls_init(&tlsconf);

Step eapol eapol_sm_step with


3
state machines
initialize=false
static const struct eapol_callbacks eapol_cb =
{eapol_sm_get_config,
eloop_register_timeout-> eapol_sm_get_bool,
4 eapol_sm_set_bool,
Register timer to step eapol_port_timers_tick eapol_sm_get_int,
eapol state machines
eapol_sm_set_int,
every second eapol_sm_get_eapReqData,
eapol_sm_set_config_blob,
Eapol_sm_step is very eapol_sm_get_config_blob,
eapol_sm_notify_pending,
important. We wil
eapol_sm_eap_param_needed,
explain it later eapol_sm_notify_cert,
eapol_sm_notify_status,
eapol_sm_notify_eap_error,
eapol_sm_set_anon_id
};(eap_peer/eap.h)
1.3 wpa_supplicant_run Loop timer, singal, sockets
and so on.
wpa_supplicant_run

Eloop_run
Scan request
Now we already finished the initialization. When we init the driver, we
start one timer to trigger scan request(refer to 1.2.1.3) . And the scan
request will trigger association and step eapol state machines. And at
the same timer the l2_packet_receive begins to receive eapol frame
from authenticator. The scan will get the scan result from driver.
However for Weird drives, it does not need to real association. So the
scan result from driver is NULL.
2 wpa_supplicant_scan
The new bssid is from driver:driver-
wpa_supplicant_scan >get_bssid=driver_wired_get_bssid
pae_group_addr=0x0180c2000003
wpa_supplicant_gen_assoc_event

wpa_supplicant_initiate_eapol
wpa_supplicant_event

wpa_supplicant_event_assoc

wpa_supplicant_select_config
wpa_supplicant_set_non_wpa_policy
wpa_supplicant_update_current_bss wpa_supplicant_update_scan_results
wpa_supplicant_initiate_eapol wpa_supplicant_get_scan_results

eapol_sm_notify_portEnabled driver->get_scan_results2
Timeout
eapol_sm_step

wpa_supplicant_cancel_scan

eapol_port_timers_tick eapol_sm_step
3.Authentication procedure
3.1 eapol_sm_step
Eapol_sm_step is the core function. Which can be trigger when we
receives l2 packaet, control response and when we notify change for
some configuration or status( like portEnabled). The state machine
mainly includes SUPP_PAE, SUPP_BE and EAP. Actually some
configuration will also use KEY_RX. So we mainly focus on
SUPP_PAE,SUPP_BE and EAP.
3.2 eapol_sm_step
SM_STEP_RUN==SM_S
Eapol_sm_step TEP
SM_STEP_RUN(SUPP_PAE)

SM_STEP_RUN(KEY_RX)

SM_STEP_RUN(SUPP_BE)

Eap_peer_sm_step

This four steps will be done within a loop. When


there is no any state change for all the four state
machines, the loop will end.
3.3 State machines
SUPP_PAE DISCONNECTED CONNECTING RESTART AUTHENTICATING

portEnabled

Send EAPOl eapRestart suppStart =


Association Start = TRUE TRUE
set it
eapolEap = FALSE RECEIVE

eapolEap && suppStart

SUPP_BE INITIALIZE IDLE REQUEST eapResp=true RESPONSE

eapReq = eap_sm_txSuppRsp
TRUE
IDLE IDLE
EAP INITIALIZE RECEIVED IDENTITY SEND_RESPONSE IDLE
eapResp=False

eapRestart eap_sm_parseEapReq eapResp=true


= FALSE
rxReq = TRUE eapReq=False

Request Identity eap_sm_buildIdentity


L2 packet (eapolEap=true)
Request Identity reaponse
3.4 State machines(Cont&loop)
SUPP_PAE AUTHENTICATING

eapolEap = FALSE RECEIVE

eapolEap
SUPP_BE RECEIVE REQUEST
eapResp=true RESPONSE

eapReq =
TRUE eap_sm_txSuppRsp

IDLE RECEIVED GET_METHOD METHOD SEND_RESPONSE IDLE


EAP eapResp=False
Eap_peer_get_eap_method(tls)
eap_sm_parseEapReq
eapResp=true
eapRespData
rxReq = TRUE Eap_method->init =Eap_method->process
eapReq=False

EAPol request
eap_tls_init eap_tls_process
(eapolEap=true)
L2 packet
Send eapol request response

Before the authentication fail or succeed, if the authentication


needs more data, it will re-start the state machine in this picture
without get_method state.
3.5 State machine(Done)

SUPP_PAE AUTHENTICATING AUTHENTICATED

eapolEap
RECEIVE REQUEST RECEIVE SUCCESS
SUPP_BE

IDLE RECEIVED SUCCESS


EAP

eap_sm_parseEapReq
eapSuccess=true
eapNoResp =true
rxSuccess = TRUE
EAPol request
(eapolEap=true)
L2 packet
3.6 re-authentication
eapolEap

SUPP_PAE AUTHENTICATED RESTART AUTHENTICATING

eapRestart suppStart =
= TRUE TRUE eapolEap = FALSE RECEIVE

eapolEap
SUPP_BE RECEIVE REQUEST
eapResp=true RESPONSE

eapReq =
TRUE eap_sm_txSuppRsp

SUCCESS INITIALIZE IDLE RECEIVED GET_METHOD METHOD SEND_RESPONSE IDLE


EAP eapResp=False
Eap_peer_get_eap_method(tls)
eap_sm_parseEapReq
eapRestart Eap_tls_has_reauth_data eapResp=true
= FALSE rxReq = TRUE eapReq=False
Eap_method->init_for_reauth

eapRespData
=Eap_method->process
eap_tls_init_for_reauth
EAPol request
(eapolEap=true) eap_tls_process
L2 packet
Send eapol request response
3.7 User input request
1: When eap_tls_init needs user’s input, it will trigger user request by
control interface and set the response data to be NULL. So no Nak
response will be sent, When wpa_supplicant receives user’s input, EAP
will re-enter get_method state and call eap_tls_init again.
2: When eap_tls_process needs user’s input, it will trigger user request
by control interface and set the response data to be NULL. And no Nak
response will be sent. When the wap_supplicant receives user’s input,
EAP will re-enter method state again and call eap_tls_process and
continue the procedure.
3.8 User input request(Cont)
wpa_supplicant_global_ctrl_iface_receive
eap_sm_request
wpa_supplicant_global_ctrl_iface_process
eapol_sm_eap_param_needed
wpas_global_ctrl_iface_ifname(IFNAME=)
wpa_supplicant_eap_param_needed
User wpa_supplicant_ctrl_iface_process
wpas_send_ctrl_req wpa_supplicant_ctrl_iface_ctrl_rsp

wpa_msg wpa_supplicant_ctrl_iface_ctrl_rsp_handle

wpa_supplicant_ctrl_iface_msg_cb Eloop_register_timeout(
Timeout wpas_ctrl_eapol_response)
wpa_supplicant_ctrl_iface_send wpas_ctrl_eapol_response

eapol_sm_notify_ctrl_response eapol_sm_step
Send to all attached eapolEap=true
connections eapReq=True
4 status notification
When the eap status changed, it will notify all attached connections.
eap_notify_status
#define WPA_EVENT_CONNECTED "CTRL-EVENT-CONNECTED "
#define WPA_EVENT_DISCONNECTED "CTRL-EVENT-DISCONNECTED "
eapol_sm_notify_status #define WPA_EVENT_ASSOC_REJECT "CTRL-EVENT-ASSOC-REJECT "
Notification
#define WPA_EVENT_AUTH_REJECT "CTRL-EVENT-AUTH-REJECT "
#define WPA_EVENT_TERMINATING "CTRL-EVENT-TERMINATING "
list
wpa_supplicant_status_cb #define WPA_EVENT_PASSWORD_CHANGED "CTRL-EVENT-PASSWORD-CHANGED "
#define WPA_EVENT_EAP_NOTIFICATION "CTRL-EVENT-EAP-NOTIFICATION "
#define WPA_EVENT_EAP_STARTED "CTRL-EVENT-EAP-STARTED "
#define WPA_EVENT_EAP_PROPOSED_METHOD "CTRL-EVENT-EAP-PROPOSED-METHOD "
wpas_notify_eap_status #define WPA_EVENT_EAP_METHOD "CTRL-EVENT-EAP-METHOD "
#define WPA_EVENT_EAP_PEER_CERT "CTRL-EVENT-EAP-PEER-CERT "
#define WPA_EVENT_EAP_PEER_ALT "CTRL-EVENT-EAP-PEER-ALT "
wpa_msg_ctrl #define WPA_EVENT_EAP_TLS_CERT_ERROR "CTRL-EVENT-EAP-TLS-CERT-ERROR "
#define WPA_EVENT_EAP_STATUS "CTRL-EVENT-EAP-STATUS "
#define WPA_EVENT_EAP_RETRANSMIT "CTRL-EVENT-EAP-RETRANSMIT "
#define WPA_EVENT_EAP_RETRANSMIT2 "CTRL-EVENT-EAP-RETRANSMIT2 "
wpa_supplicant_ctrl_iface_msg_cb #define WPA_EVENT_EAP_SUCCESS "CTRL-EVENT-EAP-SUCCESS "
#define WPA_EVENT_EAP_SUCCESS2 "CTRL-EVENT-EAP-SUCCESS2 "
#define WPA_EVENT_EAP_FAILURE "CTRL-EVENT-EAP-FAILURE "
#define WPA_EVENT_EAP_FAILURE2 "CTRL-EVENT-EAP-FAILURE2 "
wpa_supplicant_ctrl_iface_send #define WPA_EVENT_EAP_TIMEOUT_FAILURE "CTRL-EVENT-EAP-TIMEOUT-FAILURE "
#define WPA_EVENT_EAP_TIMEOUT_FAILURE2 "CTRL-EVENT-EAP-TIMEOUT-FAILURE2 "
#define WPA_EVENT_EAP_ERROR_CODE "EAP-ERROR-CODE "
#define WPA_EVENT_TEMP_DISABLED "CTRL-EVENT-SSID-TEMP-DISABLED "
#define WPA_EVENT_REENABLED "CTRL-EVENT-SSID-REENABLED "
#define WPA_EVENT_SCAN_STARTED "CTRL-EVENT-SCAN-STARTED "
#define WPA_EVENT_SCAN_RESULTS "CTRL-EVENT-SCAN-RESULTS "
#define WPA_EVENT_SCAN_FAILED "CTRL-EVENT-SCAN-FAILED "
#define WPA_EVENT_STATE_CHANGE "CTRL-EVENT-STATE-CHANGE "
TLS

You might also like