xref: /freebsd/contrib/wpa/src/drivers/driver_ndis_.c (revision 0bfd163f522701b486e066fa2e56624c02f5081a)
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