Home | History | Annotate | Download | only in wpa_supplicant
      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 "wpa_supplicant.h"
     20 #include "l2_packet.h"
     21 #include "eloop.h"
     22 #include "wpa.h"
     23 
     24 /* Keep this event processing in a separate file and without WinPcap headers to
     25  * avoid conflicts with some of the header files. */
     26 struct _ADAPTER;
     27 typedef struct _ADAPTER * LPADAPTER;
     28 #include "driver_ndis.h"
     29 
     30 
     31 void wpa_driver_ndis_event_connect(struct wpa_driver_ndis_data *drv);
     32 void wpa_driver_ndis_event_disconnect(struct wpa_driver_ndis_data *drv);
     33 void wpa_driver_ndis_event_media_specific(struct wpa_driver_ndis_data *drv,
     34 					  const u8 *data, size_t data_len);
     35 void wpa_driver_ndis_event_adapter_arrival(struct wpa_driver_ndis_data *drv);
     36 void wpa_driver_ndis_event_adapter_removal(struct wpa_driver_ndis_data *drv);
     37 
     38 
     39 enum event_types { EVENT_CONNECT, EVENT_DISCONNECT,
     40 		   EVENT_MEDIA_SPECIFIC, EVENT_ADAPTER_ARRIVAL,
     41 		   EVENT_ADAPTER_REMOVAL };
     42 
     43 /* Event data:
     44  * enum event_types (as int, i.e., 4 octets)
     45  * data length (2 octets (big endian), optional)
     46  * data (variable len, optional)
     47  */
     48 
     49 
     50 static void wpa_driver_ndis_event_process(struct wpa_driver_ndis_data *drv,
     51 					  u8 *buf, size_t len)
     52 {
     53 	u8 *pos, *data = NULL;
     54 	enum event_types type;
     55 	size_t data_len = 0;
     56 
     57 	wpa_hexdump(MSG_MSGDUMP, "NDIS: received event data", buf, len);
     58 	if (len < sizeof(int))
     59 		return;
     60 	type = *((int *) buf);
     61 	pos = buf + sizeof(int);
     62 	wpa_printf(MSG_DEBUG, "NDIS: event - type %d", type);
     63 
     64 	if (buf + len - pos > 2) {
     65 		data_len = (int) *pos++ << 8;
     66 		data_len += *pos++;
     67 		if (data_len > (size_t) (buf + len - pos)) {
     68 			wpa_printf(MSG_DEBUG, "NDIS: event data overflow");
     69 			return;
     70 		}
     71 		data = pos;
     72 		wpa_hexdump(MSG_MSGDUMP, "NDIS: event data", data, data_len);
     73 	}
     74 
     75 	switch (type) {
     76 	case EVENT_CONNECT:
     77 		wpa_driver_ndis_event_connect(drv);
     78 		break;
     79 	case EVENT_DISCONNECT:
     80 		wpa_driver_ndis_event_disconnect(drv);
     81 		break;
     82 	case EVENT_MEDIA_SPECIFIC:
     83 		wpa_driver_ndis_event_media_specific(drv, data, data_len);
     84 		break;
     85 	case EVENT_ADAPTER_ARRIVAL:
     86 		wpa_driver_ndis_event_adapter_arrival(drv);
     87 		break;
     88 	case EVENT_ADAPTER_REMOVAL:
     89 		wpa_driver_ndis_event_adapter_removal(drv);
     90 		break;
     91 	}
     92 }
     93 
     94 
     95 void wpa_driver_ndis_event_pipe_cb(void *eloop_data, void *user_data)
     96 {
     97 	struct wpa_driver_ndis_data *drv = eloop_data;
     98 	u8 buf[512];
     99 	DWORD len;
    100 
    101 	ResetEvent(drv->event_avail);
    102 	if (ReadFile(drv->events_pipe, buf, sizeof(buf), &len, NULL))
    103 		wpa_driver_ndis_event_process(drv, buf, len);
    104 	else {
    105 		wpa_printf(MSG_DEBUG, "%s: ReadFile() failed: %d", __func__,
    106 			   (int) GetLastError());
    107 	}
    108 }
    109