Home | History | Annotate | Download | only in drivers
      1 /*
      2  * WPA Supplicant - Windows/NDIS driver interface - event processing
      3  * Copyright (c) 2004-2005, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This program is free software; you can redistribute it and/or modify
      6  * it under the terms of the GNU General Public License version 2 as
      7  * published by the Free Software Foundation.
      8  *
      9  * Alternatively, this software may be distributed under the terms of BSD
     10  * license.
     11  *
     12  * See README and COPYING for more details.
     13  */
     14 
     15 #include "includes.h"
     16 
     17 #include "common.h"
     18 #include "driver.h"
     19 #include "eloop.h"
     20 
     21 /* Keep this event processing in a separate file and without WinPcap headers to
     22  * avoid conflicts with some of the header files. */
     23 struct _ADAPTER;
     24 typedef struct _ADAPTER * LPADAPTER;
     25 #include "driver_ndis.h"
     26 
     27 
     28 void wpa_driver_ndis_event_connect(struct wpa_driver_ndis_data *drv);
     29 void wpa_driver_ndis_event_disconnect(struct wpa_driver_ndis_data *drv);
     30 void wpa_driver_ndis_event_media_specific(struct wpa_driver_ndis_data *drv,
     31 					  const u8 *data, size_t data_len);
     32 void wpa_driver_ndis_event_adapter_arrival(struct wpa_driver_ndis_data *drv);
     33 void wpa_driver_ndis_event_adapter_removal(struct wpa_driver_ndis_data *drv);
     34 
     35 
     36 enum event_types { EVENT_CONNECT, EVENT_DISCONNECT,
     37 		   EVENT_MEDIA_SPECIFIC, EVENT_ADAPTER_ARRIVAL,
     38 		   EVENT_ADAPTER_REMOVAL };
     39 
     40 /* Event data:
     41  * enum event_types (as int, i.e., 4 octets)
     42  * data length (2 octets (big endian), optional)
     43  * data (variable len, optional)
     44  */
     45 
     46 
     47 static void wpa_driver_ndis_event_process(struct wpa_driver_ndis_data *drv,
     48 					  u8 *buf, size_t len)
     49 {
     50 	u8 *pos, *data = NULL;
     51 	enum event_types type;
     52 	size_t data_len = 0;
     53 
     54 	wpa_hexdump(MSG_MSGDUMP, "NDIS: received event data", buf, len);
     55 	if (len < sizeof(int))
     56 		return;
     57 	type = *((int *) buf);
     58 	pos = buf + sizeof(int);
     59 	wpa_printf(MSG_DEBUG, "NDIS: event - type %d", type);
     60 
     61 	if (buf + len - pos > 2) {
     62 		data_len = (int) *pos++ << 8;
     63 		data_len += *pos++;
     64 		if (data_len > (size_t) (buf + len - pos)) {
     65 			wpa_printf(MSG_DEBUG, "NDIS: event data overflow");
     66 			return;
     67 		}
     68 		data = pos;
     69 		wpa_hexdump(MSG_MSGDUMP, "NDIS: event data", data, data_len);
     70 	}
     71 
     72 	switch (type) {
     73 	case EVENT_CONNECT:
     74 		wpa_driver_ndis_event_connect(drv);
     75 		break;
     76 	case EVENT_DISCONNECT:
     77 		wpa_driver_ndis_event_disconnect(drv);
     78 		break;
     79 	case EVENT_MEDIA_SPECIFIC:
     80 		wpa_driver_ndis_event_media_specific(drv, data, data_len);
     81 		break;
     82 	case EVENT_ADAPTER_ARRIVAL:
     83 		wpa_driver_ndis_event_adapter_arrival(drv);
     84 		break;
     85 	case EVENT_ADAPTER_REMOVAL:
     86 		wpa_driver_ndis_event_adapter_removal(drv);
     87 		break;
     88 	}
     89 }
     90 
     91 
     92 void wpa_driver_ndis_event_pipe_cb(void *eloop_data, void *user_data)
     93 {
     94 	struct wpa_driver_ndis_data *drv = eloop_data;
     95 	u8 buf[512];
     96 	DWORD len;
     97 
     98 	ResetEvent(drv->event_avail);
     99 	if (ReadFile(drv->events_pipe, buf, sizeof(buf), &len, NULL))
    100 		wpa_driver_ndis_event_process(drv, buf, len);
    101 	else {
    102 		wpa_printf(MSG_DEBUG, "%s: ReadFile() failed: %d", __func__,
    103 			   (int) GetLastError());
    104 	}
    105 }
    106