/*
 * WPA Supplicant - Layer2 packet handling with Microsoft NDISUIO
 * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 *
 * This implementation requires Windows specific event loop implementation,
 * i.e., eloop_win.c. In addition, the NDISUIO connection is shared with
 * driver_ndis.c, so only that driver interface can be used and
 * CONFIG_USE_NDISUIO must be defined.
 *
 * WinXP version of the code uses overlapped I/O and a single threaded design
 * with callback functions from I/O code. WinCE version uses a separate RX
 * thread that blocks on ReadFile() whenever the media status is connected.
 */

#include "includes.h"
#include <winsock2.h>
#include <ntddndis.h>

#ifdef _WIN32_WCE
#include <winioctl.h>
#include <nuiouser.h>
#endif /* _WIN32_WCE */

#include "common.h"
#include "eloop.h"
#include "l2_packet.h"

#ifndef _WIN32_WCE
/* from nuiouser.h */
#define FSCTL_NDISUIO_BASE      FILE_DEVICE_NETWORK
#define _NDISUIO_CTL_CODE(_Function, _Method, _Access) \
	CTL_CODE(FSCTL_NDISUIO_BASE, _Function, _Method, _Access)
#define IOCTL_NDISUIO_SET_ETHER_TYPE \
	_NDISUIO_CTL_CODE(0x202, METHOD_BUFFERED, \
			  FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#endif /* _WIN32_WCE */

/* From driver_ndis.c to shared the handle to NDISUIO */
HANDLE driver_ndis_get_ndisuio_handle(void);

/*
 * NDISUIO supports filtering of only one ethertype at the time, so we must
 * fake support for two (EAPOL and RSN pre-auth) by switching to pre-auth
 * whenever wpa_supplicant is trying to pre-authenticate and then switching
 * back to EAPOL when pre-authentication has been completed.
 */

struct l2_packet_data;

struct l2_packet_ndisuio_global {
	int refcount;
	unsigned short first_proto;
	struct l2_packet_data *l2[2];
#ifdef _WIN32_WCE
	HANDLE rx_thread;
	HANDLE stop_request;
	HANDLE ready_for_read;
	HANDLE rx_processed;
#endif /* _WIN32_WCE */
};

static struct l2_packet_ndisuio_global *l2_ndisuio_global = NULL;

struct l2_packet_data {
	char ifname[100];
	u8 own_addr[ETH_ALEN];
	void (*rx_callback)(void *ctx, const u8 *src_addr,
			    const u8 *buf, size_t len);
	void *rx_callback_ctx;
	int l2_hdr; /* whether to include layer 2 (Ethernet) header in calls to
		     * rx_callback and l2_packet_send() */
	HANDLE rx_avail;
#ifndef _WIN32_WCE
	OVERLAPPED rx_overlapped;
#endif /* _WIN32_WCE */
	u8 rx_buf[1514];
	DWORD rx_written;
};


int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr)
{
	os_memcpy(addr, l2->own_addr, ETH_ALEN);
	return 0;
}


int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto,
		   const u8 *buf, size_t len)
{
	BOOL res;
	DWORD written;
	struct l2_ethhdr *eth;
#ifndef _WIN32_WCE
	OVERLAPPED overlapped;
#endif /* _WIN32_WCE */
	OVERLAPPED *o;

	if (l2 == NULL)
		return -1;

#ifdef _WIN32_WCE
	o = NULL;
#else /* _WIN32_WCE */
	os_memset(&overlapped, 0, sizeof(overlapped));
	o = &overlapped;
#endif /* _WIN32_WCE */

	if (l2->l2_hdr) {
		res = WriteFile(driver_ndis_get_ndisuio_handle(), buf, len,
				&written, o);
	} else {
		size_t mlen = sizeof(*eth) + len;
		eth = os_malloc(mlen);
		if (eth == NULL)
			return -1;

		os_memcpy(eth->h_dest, dst_addr, ETH_ALEN);
		os_memcpy(eth->h_source, l2->own_addr, ETH_ALEN);
		eth->h_proto = htons(proto);
		os_memcpy(eth + 1, buf, len);
		res = WriteFile(driver_ndis_get_ndisuio_handle(), eth, mlen,
				&written, o);
		os_free(eth);
	}

	if (!res) {
		DWORD err = GetLastError();
#ifndef _WIN32_WCE
		if (err == ERROR_IO_PENDING) {
			wpa_printf(MSG_DEBUG, "L2(NDISUIO): Wait for pending "
				   "write to complete");
			res = GetOverlappedResult(
				driver_ndis_get_ndisuio_handle(), &overlapped,
				&written, TRUE);
			if (!res) {
				wpa_printf(MSG_DEBUG, "L2(NDISUIO): "
					   "GetOverlappedResult failed: %d",
					   (int) GetLastError());
				return -1;
			}
			return 0;
		}
#endif /* _WIN32_WCE */
		wpa_printf(MSG_DEBUG, "L2(NDISUIO): WriteFile failed: %d",
			   (int) GetLastError());
		return -1;
	}

	return 0;
}


static void l2_packet_callback(struct l2_packet_data *l2);

#ifdef _WIN32_WCE
static void l2_packet_rx_thread_try_read(struct l2_packet_data *l2)
{
	HANDLE handles[2];

	wpa_printf(MSG_MSGDUMP, "l2_packet_rx_thread: -> ReadFile");
	if (!ReadFile(driver_ndis_get_ndisuio_handle(), l2->rx_buf,
		      sizeof(l2->rx_buf), &l2->rx_written, NULL)) {
		DWORD err = GetLastError();
		wpa_printf(MSG_DEBUG, "l2_packet_rx_thread: ReadFile failed: "
			   "%d", (int) err);
		/*
		 * ReadFile on NDISUIO/WinCE returns ERROR_DEVICE_NOT_CONNECTED
		 * error whenever the connection is not up. Yield the thread to
		 * avoid triggering a busy loop. Connection event should stop
		 * us from looping for long, but we need to allow enough CPU
		 * for the main thread to process the media disconnection.
		 */
		Sleep(100);
		return;
	}

	wpa_printf(MSG_DEBUG, "l2_packet_rx_thread: Read %d byte packet",
		   (int) l2->rx_written);

	/*
	 * Notify the main thread about the availability of a frame and wait
	 * for the frame to be processed.
	 */
	SetEvent(l2->rx_avail);
	handles[0] = l2_ndisuio_global->stop_request;
	handles[1] = l2_ndisuio_global->rx_processed;
	WaitForMultipleObjects(2, handles, FALSE, INFINITE);
	ResetEvent(l2_ndisuio_global->rx_processed);
}


static DWORD WINAPI l2_packet_rx_thread(LPVOID arg)
{
	struct l2_packet_data *l2 = arg;
	DWORD res;
	HANDLE handles[2];
	int run = 1;

	wpa_printf(MSG_DEBUG, "L2(NDISUIO): RX thread started");
	handles[0] = l2_ndisuio_global->stop_request;
	handles[1] = l2_ndisuio_global->ready_for_read;

	/*
	 * Unfortunately, NDISUIO on WinCE does not seem to support waiting
	 * on the handle. There do not seem to be anything else that we could
	 * wait for either. If one were to modify NDISUIO to set a named event
	 * whenever packets are available, this event could be used here to
	 * avoid having to poll for new packets or we could even move to use a
	 * single threaded design.
	 *
	 * In addition, NDISUIO on WinCE is returning
	 * ERROR_DEVICE_NOT_CONNECTED whenever ReadFile() is attempted while
	 * the adapter is not in connected state. For now, we are just using a
	 * local event to allow ReadFile calls only after having received NDIS
	 * media connect event. This event could be easily converted to handle
	 * another event if the protocol driver is replaced with somewhat more
	 * useful design.
	 */

	while (l2_ndisuio_global && run) {
		res = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
		switch (res) {
		case WAIT_OBJECT_0:
			wpa_printf(MSG_DEBUG, "l2_packet_rx_thread: Received "
				   "request to stop RX thread");
			run = 0;
			break;
		case WAIT_OBJECT_0 + 1:
			l2_packet_rx_thread_try_read(l2);
			break;
		case WAIT_FAILED:
		default:
			wpa_printf(MSG_DEBUG, "l2_packet_rx_thread: "
				   "WaitForMultipleObjects failed: %d",
				   (int) GetLastError());
			run = 0;
			break;
		}
	}

	wpa_printf(MSG_DEBUG, "L2(NDISUIO): RX thread stopped");

	return 0;
}
#else /* _WIN32_WCE */
static int l2_ndisuio_start_read(struct l2_packet_data *l2, int recursive)
{
	os_memset(&l2->rx_overlapped, 0, sizeof(l2->rx_overlapped));
	l2->rx_overlapped.hEvent = l2->rx_avail;
	if (!ReadFile(driver_ndis_get_ndisuio_handle(), l2->rx_buf,
		      sizeof(l2->rx_buf), &l2->rx_written, &l2->rx_overlapped))
	{
		DWORD err = GetLastError();
		if (err != ERROR_IO_PENDING) {
			wpa_printf(MSG_DEBUG, "L2(NDISUIO): ReadFile failed: "
				   "%d", (int) err);
			return -1;
		}
		/*
		 * Once read is completed, l2_packet_rx_event() will be
		 * called.
		 */
	} else {
		wpa_printf(MSG_DEBUG, "L2(NDISUIO): ReadFile returned data "
			   "without wait for completion");
		if (!recursive)
			l2_packet_callback(l2);
	}

	return 0;
}
#endif /* _WIN32_WCE */


static void l2_packet_callback(struct l2_packet_data *l2)
{
	const u8 *rx_buf, *rx_src;
	size_t rx_len;
	struct l2_ethhdr *ethhdr = (struct l2_ethhdr *) l2->rx_buf;

	wpa_printf(MSG_DEBUG, "L2(NDISUIO): Read %d bytes",
		   (int) l2->rx_written);

	if (l2->l2_hdr || l2->rx_written < sizeof(*ethhdr)) {
		rx_buf = (u8 *) ethhdr;
		rx_len = l2->rx_written;
	} else {
		rx_buf = (u8 *) (ethhdr + 1);
		rx_len = l2->rx_written - sizeof(*ethhdr);
	}
	rx_src = ethhdr->h_source;

	if (l2->rx_callback)
		l2->rx_callback(l2->rx_callback_ctx, rx_src, rx_buf, rx_len);
#ifndef _WIN32_WCE
	l2_ndisuio_start_read(l2, 1);
#endif /* _WIN32_WCE */
}


static void l2_packet_rx_event(void *eloop_data, void *user_data)
{
	struct l2_packet_data *l2 = eloop_data;

	if (l2_ndisuio_global)
		l2 = l2_ndisuio_global->l2[l2_ndisuio_global->refcount - 1];

	ResetEvent(l2->rx_avail);

#ifndef _WIN32_WCE
	if (!GetOverlappedResult(driver_ndis_get_ndisuio_handle(),
				 &l2->rx_overlapped, &l2->rx_written, FALSE)) {
		wpa_printf(MSG_DEBUG, "L2(NDISUIO): GetOverlappedResult "
			   "failed: %d", (int) GetLastError());
		return;
	}
#endif /* _WIN32_WCE */

	l2_packet_callback(l2);

#ifdef _WIN32_WCE
	SetEvent(l2_ndisuio_global->rx_processed);
#endif /* _WIN32_WCE */
}


static int l2_ndisuio_set_ether_type(unsigned short protocol)
{
	USHORT proto = htons(protocol);
	DWORD written;

	if (!DeviceIoControl(driver_ndis_get_ndisuio_handle(),
			     IOCTL_NDISUIO_SET_ETHER_TYPE, &proto,
			     sizeof(proto), NULL, 0, &written, NULL)) {
		wpa_printf(MSG_ERROR, "L2(NDISUIO): "
			   "IOCTL_NDISUIO_SET_ETHER_TYPE failed: %d",
			   (int) GetLastError());
		return -1;
	}

	return 0;
}


struct l2_packet_data * l2_packet_init(
	const char *ifname, const u8 *own_addr, unsigned short protocol,
	void (*rx_callback)(void *ctx, const u8 *src_addr,
			    const u8 *buf, size_t len),
	void *rx_callback_ctx, int l2_hdr)
{
	struct l2_packet_data *l2;

	if (l2_ndisuio_global == NULL) {
		l2_ndisuio_global = os_zalloc(sizeof(*l2_ndisuio_global));
		if (l2_ndisuio_global == NULL)
			return NULL;
		l2_ndisuio_global->first_proto = protocol;
	}
	if (l2_ndisuio_global->refcount >= 2) {
		wpa_printf(MSG_ERROR, "L2(NDISUIO): Not more than two "
			   "simultaneous connections allowed");
		return NULL;
	}
	l2_ndisuio_global->refcount++;

	l2 = os_zalloc(sizeof(struct l2_packet_data));
	if (l2 == NULL)
		return NULL;
	l2_ndisuio_global->l2[l2_ndisuio_global->refcount - 1] = l2;

	os_strlcpy(l2->ifname, ifname, sizeof(l2->ifname));
	l2->rx_callback = rx_callback;
	l2->rx_callback_ctx = rx_callback_ctx;
	l2->l2_hdr = l2_hdr;

	if (own_addr)
		os_memcpy(l2->own_addr, own_addr, ETH_ALEN);

	if (l2_ndisuio_set_ether_type(protocol) < 0) {
		os_free(l2);
		return NULL;
	}

	if (l2_ndisuio_global->refcount > 1) {
		wpa_printf(MSG_DEBUG, "L2(NDISUIO): Temporarily setting "
			   "filtering ethertype to %04x", protocol);
		if (l2_ndisuio_global->l2[0])
			l2->rx_avail = l2_ndisuio_global->l2[0]->rx_avail;
		return l2;
	}

	l2->rx_avail = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (l2->rx_avail == NULL) {
		os_free(l2);
		return NULL;
	}

	eloop_register_event(l2->rx_avail, sizeof(l2->rx_avail),
			     l2_packet_rx_event, l2, NULL);

#ifdef _WIN32_WCE
	l2_ndisuio_global->stop_request = CreateEvent(NULL, TRUE, FALSE, NULL);
	/*
	 * This event is being set based on media connect/disconnect
	 * notifications in driver_ndis.c.
	 */
	l2_ndisuio_global->ready_for_read =
		CreateEvent(NULL, TRUE, FALSE, TEXT("WpaSupplicantConnected"));
	l2_ndisuio_global->rx_processed = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (l2_ndisuio_global->stop_request == NULL ||
	    l2_ndisuio_global->ready_for_read == NULL ||
	    l2_ndisuio_global->rx_processed == NULL) {
		if (l2_ndisuio_global->stop_request) {
			CloseHandle(l2_ndisuio_global->stop_request);
			l2_ndisuio_global->stop_request = NULL;
		}
		if (l2_ndisuio_global->ready_for_read) {
			CloseHandle(l2_ndisuio_global->ready_for_read);
			l2_ndisuio_global->ready_for_read = NULL;
		}
		if (l2_ndisuio_global->rx_processed) {
			CloseHandle(l2_ndisuio_global->rx_processed);
			l2_ndisuio_global->rx_processed = NULL;
		}
		eloop_unregister_event(l2->rx_avail, sizeof(l2->rx_avail));
		os_free(l2);
		return NULL;
	}

	l2_ndisuio_global->rx_thread = CreateThread(NULL, 0,
						    l2_packet_rx_thread, l2, 0,
						    NULL);
	if (l2_ndisuio_global->rx_thread == NULL) {
		wpa_printf(MSG_INFO, "L2(NDISUIO): Failed to create RX "
			   "thread: %d", (int) GetLastError());
		eloop_unregister_event(l2->rx_avail, sizeof(l2->rx_avail));
		CloseHandle(l2_ndisuio_global->stop_request);
		l2_ndisuio_global->stop_request = NULL;
		os_free(l2);
		return NULL;
	}
#else /* _WIN32_WCE */
	l2_ndisuio_start_read(l2, 0);
#endif /* _WIN32_WCE */

	return l2;
}


struct l2_packet_data * l2_packet_init_bridge(
	const char *br_ifname, const char *ifname, const u8 *own_addr,
	unsigned short protocol,
	void (*rx_callback)(void *ctx, const u8 *src_addr,
			    const u8 *buf, size_t len),
	void *rx_callback_ctx, int l2_hdr)
{
	return l2_packet_init(br_ifname, own_addr, protocol, rx_callback,
			      rx_callback_ctx, l2_hdr);
}


void l2_packet_deinit(struct l2_packet_data *l2)
{
	if (l2 == NULL)
		return;

	if (l2_ndisuio_global) {
		l2_ndisuio_global->refcount--;
		l2_ndisuio_global->l2[l2_ndisuio_global->refcount] = NULL;
		if (l2_ndisuio_global->refcount) {
			wpa_printf(MSG_DEBUG, "L2(NDISUIO): restore filtering "
				   "ethertype to %04x",
				   l2_ndisuio_global->first_proto);
			l2_ndisuio_set_ether_type(
				l2_ndisuio_global->first_proto);
			return;
		}

#ifdef _WIN32_WCE
		wpa_printf(MSG_DEBUG, "L2(NDISUIO): Waiting for RX thread to "
			   "stop");
		SetEvent(l2_ndisuio_global->stop_request);
		/*
		 * Cancel pending ReadFile() in the RX thread (if we were still
		 * connected at this point).
		 */
		if (!DeviceIoControl(driver_ndis_get_ndisuio_handle(),
				     IOCTL_CANCEL_READ, NULL, 0, NULL, 0, NULL,
				     NULL)) {
			wpa_printf(MSG_DEBUG, "L2(NDISUIO): IOCTL_CANCEL_READ "
				   "failed: %d", (int) GetLastError());
			/* RX thread will exit blocking ReadFile once NDISUIO
			 * notices that the adapter is disconnected. */
		}
		WaitForSingleObject(l2_ndisuio_global->rx_thread, INFINITE);
		wpa_printf(MSG_DEBUG, "L2(NDISUIO): RX thread exited");
		CloseHandle(l2_ndisuio_global->rx_thread);
		CloseHandle(l2_ndisuio_global->stop_request);
		CloseHandle(l2_ndisuio_global->ready_for_read);
		CloseHandle(l2_ndisuio_global->rx_processed);
#endif /* _WIN32_WCE */

		os_free(l2_ndisuio_global);
		l2_ndisuio_global = NULL;
	}

#ifndef _WIN32_WCE
	CancelIo(driver_ndis_get_ndisuio_handle());
#endif /* _WIN32_WCE */

	eloop_unregister_event(l2->rx_avail, sizeof(l2->rx_avail));
	CloseHandle(l2->rx_avail);
	os_free(l2);
}


int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len)
{
	return -1;
}


void l2_packet_notify_auth_start(struct l2_packet_data *l2)
{
}


int l2_packet_set_packet_filter(struct l2_packet_data *l2,
				enum l2_packet_filter_type type)
{
	return -1;
}
