13157ba21SRui Paulo /*
23157ba21SRui Paulo * WPA Supplicant - Windows/NDIS driver interface - event processing
33157ba21SRui Paulo * Copyright (c) 2004-2005, Jouni Malinen <j@w1.fi>
43157ba21SRui Paulo *
5*f05cddf9SRui Paulo * This software may be distributed under the terms of the BSD license.
6*f05cddf9SRui Paulo * See README for more details.
73157ba21SRui Paulo */
83157ba21SRui Paulo
93157ba21SRui Paulo #include "includes.h"
103157ba21SRui Paulo
113157ba21SRui Paulo #include "common.h"
123157ba21SRui Paulo #include "driver.h"
133157ba21SRui Paulo #include "eloop.h"
143157ba21SRui Paulo
153157ba21SRui Paulo /* Keep this event processing in a separate file and without WinPcap headers to
163157ba21SRui Paulo * avoid conflicts with some of the header files. */
173157ba21SRui Paulo struct _ADAPTER;
183157ba21SRui Paulo typedef struct _ADAPTER * LPADAPTER;
193157ba21SRui Paulo #include "driver_ndis.h"
203157ba21SRui Paulo
213157ba21SRui Paulo
223157ba21SRui Paulo void wpa_driver_ndis_event_connect(struct wpa_driver_ndis_data *drv);
233157ba21SRui Paulo void wpa_driver_ndis_event_disconnect(struct wpa_driver_ndis_data *drv);
243157ba21SRui Paulo void wpa_driver_ndis_event_media_specific(struct wpa_driver_ndis_data *drv,
253157ba21SRui Paulo const u8 *data, size_t data_len);
263157ba21SRui Paulo void wpa_driver_ndis_event_adapter_arrival(struct wpa_driver_ndis_data *drv);
273157ba21SRui Paulo void wpa_driver_ndis_event_adapter_removal(struct wpa_driver_ndis_data *drv);
283157ba21SRui Paulo
293157ba21SRui Paulo
303157ba21SRui Paulo enum event_types { EVENT_CONNECT, EVENT_DISCONNECT,
313157ba21SRui Paulo EVENT_MEDIA_SPECIFIC, EVENT_ADAPTER_ARRIVAL,
323157ba21SRui Paulo EVENT_ADAPTER_REMOVAL };
333157ba21SRui Paulo
343157ba21SRui Paulo /* Event data:
353157ba21SRui Paulo * enum event_types (as int, i.e., 4 octets)
363157ba21SRui Paulo * data length (2 octets (big endian), optional)
373157ba21SRui Paulo * data (variable len, optional)
383157ba21SRui Paulo */
393157ba21SRui Paulo
403157ba21SRui Paulo
wpa_driver_ndis_event_process(struct wpa_driver_ndis_data * drv,u8 * buf,size_t len)413157ba21SRui Paulo static void wpa_driver_ndis_event_process(struct wpa_driver_ndis_data *drv,
423157ba21SRui Paulo u8 *buf, size_t len)
433157ba21SRui Paulo {
443157ba21SRui Paulo u8 *pos, *data = NULL;
453157ba21SRui Paulo enum event_types type;
463157ba21SRui Paulo size_t data_len = 0;
473157ba21SRui Paulo
483157ba21SRui Paulo wpa_hexdump(MSG_MSGDUMP, "NDIS: received event data", buf, len);
493157ba21SRui Paulo if (len < sizeof(int))
503157ba21SRui Paulo return;
513157ba21SRui Paulo type = *((int *) buf);
523157ba21SRui Paulo pos = buf + sizeof(int);
533157ba21SRui Paulo wpa_printf(MSG_DEBUG, "NDIS: event - type %d", type);
543157ba21SRui Paulo
553157ba21SRui Paulo if (buf + len - pos > 2) {
563157ba21SRui Paulo data_len = (int) *pos++ << 8;
573157ba21SRui Paulo data_len += *pos++;
583157ba21SRui Paulo if (data_len > (size_t) (buf + len - pos)) {
593157ba21SRui Paulo wpa_printf(MSG_DEBUG, "NDIS: event data overflow");
603157ba21SRui Paulo return;
613157ba21SRui Paulo }
623157ba21SRui Paulo data = pos;
633157ba21SRui Paulo wpa_hexdump(MSG_MSGDUMP, "NDIS: event data", data, data_len);
643157ba21SRui Paulo }
653157ba21SRui Paulo
663157ba21SRui Paulo switch (type) {
673157ba21SRui Paulo case EVENT_CONNECT:
683157ba21SRui Paulo wpa_driver_ndis_event_connect(drv);
693157ba21SRui Paulo break;
703157ba21SRui Paulo case EVENT_DISCONNECT:
713157ba21SRui Paulo wpa_driver_ndis_event_disconnect(drv);
723157ba21SRui Paulo break;
733157ba21SRui Paulo case EVENT_MEDIA_SPECIFIC:
743157ba21SRui Paulo wpa_driver_ndis_event_media_specific(drv, data, data_len);
753157ba21SRui Paulo break;
763157ba21SRui Paulo case EVENT_ADAPTER_ARRIVAL:
773157ba21SRui Paulo wpa_driver_ndis_event_adapter_arrival(drv);
783157ba21SRui Paulo break;
793157ba21SRui Paulo case EVENT_ADAPTER_REMOVAL:
803157ba21SRui Paulo wpa_driver_ndis_event_adapter_removal(drv);
813157ba21SRui Paulo break;
823157ba21SRui Paulo }
833157ba21SRui Paulo }
843157ba21SRui Paulo
853157ba21SRui Paulo
wpa_driver_ndis_event_pipe_cb(void * eloop_data,void * user_data)863157ba21SRui Paulo void wpa_driver_ndis_event_pipe_cb(void *eloop_data, void *user_data)
873157ba21SRui Paulo {
883157ba21SRui Paulo struct wpa_driver_ndis_data *drv = eloop_data;
893157ba21SRui Paulo u8 buf[512];
903157ba21SRui Paulo DWORD len;
913157ba21SRui Paulo
923157ba21SRui Paulo ResetEvent(drv->event_avail);
933157ba21SRui Paulo if (ReadFile(drv->events_pipe, buf, sizeof(buf), &len, NULL))
943157ba21SRui Paulo wpa_driver_ndis_event_process(drv, buf, len);
953157ba21SRui Paulo else {
963157ba21SRui Paulo wpa_printf(MSG_DEBUG, "%s: ReadFile() failed: %d", __func__,
973157ba21SRui Paulo (int) GetLastError());
983157ba21SRui Paulo }
993157ba21SRui Paulo }
100