/*
 * WPA Supplicant - Layer2 packet handling with WinPcap RX thread
 * 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 l2_packet implementation is explicitly for WinPcap and Windows events.
 * l2_packet_pcap.c has support for WinPcap, but it requires polling to receive
 * frames which means relatively long latency for EAPOL RX processing. The
 * implementation here uses a separate thread to allow WinPcap to be receiving
 * all the time to reduce latency for EAPOL receiving from about 100 ms to 3 ms
 * when comparing l2_packet_pcap.c to l2_packet_winpcap.c. Extra sleep of 50 ms
 * is added in to receive thread whenever no EAPOL frames has been received for
 * a while. Whenever an EAPOL handshake is expected, this sleep is removed.
 *
 * The RX thread receives a frame and signals main thread through Windows event
 * about the availability of a new frame. Processing the received frame is
 * synchronized with pair of Windows events so that no extra buffer or queuing
 * mechanism is needed. This implementation requires Windows specific event
 * loop implementation, i.e., eloop_win.c.
 *
 * WinPcap has pcap_getevent() that could, in theory at least, be used to
 * implement this kind of waiting with a simpler single-thread design. However,
 * that event handle is not really signaled immediately when receiving each
 * frame, so it does not really work for this kind of use.
 */

#include "includes.h"
#include <pcap.h>

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


static const u8 pae_group_addr[ETH_ALEN] =
{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 };

/*
 * Number of pcap_dispatch() iterations to do without extra wait after each
 * received EAPOL packet or authentication notification. This is used to reduce
 * latency for EAPOL receive.
 */
static const size_t no_wait_count = 750;

struct l2_packet_data {
	pcap_t *pcap;
	unsigned int num_fast_poll;
	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() */
	int running;
	HANDLE rx_avail, rx_done, rx_thread, rx_thread_done, rx_notify;
	u8 *rx_buf, *rx_src;
	size_t rx_len;
	size_t rx_no_wait;
};


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)
{
	int ret;
	struct l2_ethhdr *eth;

	if (l2 == NULL)
		return -1;

	if (l2->l2_hdr) {
		ret = pcap_sendpacket(l2->pcap, buf, len);
	} 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);
		ret = pcap_sendpacket(l2->pcap, (u8 *) eth, mlen);
		os_free(eth);
	}

	return ret;
}


/* pcap_dispatch() callback for the RX thread */
static void l2_packet_receive_cb(u_char *user, const struct pcap_pkthdr *hdr,
				 const u_char *pkt_data)
{
	struct l2_packet_data *l2 = (struct l2_packet_data *) user;
	struct l2_ethhdr *ethhdr;

	if (pkt_data == NULL || hdr->caplen < sizeof(*ethhdr))
		return;

	ethhdr = (struct l2_ethhdr *) pkt_data;
	if (l2->l2_hdr) {
		l2->rx_buf = (u8 *) ethhdr;
		l2->rx_len = hdr->caplen;
	} else {
		l2->rx_buf = (u8 *) (ethhdr + 1);
		l2->rx_len = hdr->caplen - sizeof(*ethhdr);
	}
	l2->rx_src = ethhdr->h_source;
	SetEvent(l2->rx_avail);
	WaitForSingleObject(l2->rx_done, INFINITE);
	ResetEvent(l2->rx_done);
	l2->rx_no_wait = no_wait_count;
}


/* main RX loop that is running in a separate thread */
static DWORD WINAPI l2_packet_receive_thread(LPVOID arg)
{
	struct l2_packet_data *l2 = arg;

	while (l2->running) {
		pcap_dispatch(l2->pcap, 1, l2_packet_receive_cb,
			      (u_char *) l2);
		if (l2->rx_no_wait > 0)
			l2->rx_no_wait--;
		if (WaitForSingleObject(l2->rx_notify,
					l2->rx_no_wait ? 0 : 50) ==
		    WAIT_OBJECT_0) {
			l2->rx_no_wait = no_wait_count;
			ResetEvent(l2->rx_notify);
		}
	}
	SetEvent(l2->rx_thread_done);
	ExitThread(0);
	return 0;
}


/* main thread RX event handler */
static void l2_packet_rx_event(void *eloop_data, void *user_data)
{
	struct l2_packet_data *l2 = eloop_data;
	l2->rx_callback(l2->rx_callback_ctx, l2->rx_src, l2->rx_buf,
			l2->rx_len);
	ResetEvent(l2->rx_avail);
	SetEvent(l2->rx_done);
}


static int l2_packet_init_libpcap(struct l2_packet_data *l2,
				  unsigned short protocol)
{
	bpf_u_int32 pcap_maskp, pcap_netp;
	char pcap_filter[200], pcap_err[PCAP_ERRBUF_SIZE];
	struct bpf_program pcap_fp;

	pcap_lookupnet(l2->ifname, &pcap_netp, &pcap_maskp, pcap_err);
	l2->pcap = pcap_open_live(l2->ifname, 2500, 0, 1, pcap_err);
	if (l2->pcap == NULL) {
		fprintf(stderr, "pcap_open_live: %s\n", pcap_err);
		fprintf(stderr, "ifname='%s'\n", l2->ifname);
		return -1;
	}
	os_snprintf(pcap_filter, sizeof(pcap_filter),
		    "not ether src " MACSTR " and "
		    "( ether dst " MACSTR " or ether dst " MACSTR " ) and "
		    "ether proto 0x%x",
		    MAC2STR(l2->own_addr), /* do not receive own packets */
		    MAC2STR(l2->own_addr), MAC2STR(pae_group_addr),
		    protocol);
	if (pcap_compile(l2->pcap, &pcap_fp, pcap_filter, 1, pcap_netp) < 0) {
		fprintf(stderr, "pcap_compile: %s\n", pcap_geterr(l2->pcap));
		return -1;
	}

	if (pcap_setfilter(l2->pcap, &pcap_fp) < 0) {
		fprintf(stderr, "pcap_setfilter: %s\n", pcap_geterr(l2->pcap));
		return -1;
	}

	pcap_freecode(&pcap_fp);

	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;
	DWORD thread_id;

	l2 = os_zalloc(sizeof(struct l2_packet_data));
	if (l2 == NULL)
		return NULL;
	if (os_strncmp(ifname, "\\Device\\NPF_", 12) == 0)
		os_strlcpy(l2->ifname, ifname, sizeof(l2->ifname));
	else
		os_snprintf(l2->ifname, sizeof(l2->ifname), "\\Device\\NPF_%s",
			    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_packet_init_libpcap(l2, protocol)) {
		os_free(l2);
		return NULL;
	}

	l2->rx_avail = CreateEvent(NULL, TRUE, FALSE, NULL);
	l2->rx_done = CreateEvent(NULL, TRUE, FALSE, NULL);
	l2->rx_notify = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (l2->rx_avail == NULL || l2->rx_done == NULL ||
	    l2->rx_notify == NULL) {
		CloseHandle(l2->rx_avail);
		CloseHandle(l2->rx_done);
		CloseHandle(l2->rx_notify);
		pcap_close(l2->pcap);
		os_free(l2);
		return NULL;
	}

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

	l2->running = 1;
	l2->rx_thread = CreateThread(NULL, 0, l2_packet_receive_thread, l2, 0,
				     &thread_id);

	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);
}


static void l2_packet_deinit_timeout(void *eloop_ctx, void *timeout_ctx)
{
	struct l2_packet_data *l2 = eloop_ctx;

	if (l2->rx_thread_done &&
	    WaitForSingleObject(l2->rx_thread_done, 2000) != WAIT_OBJECT_0) {
		wpa_printf(MSG_DEBUG, "l2_packet_winpcap: RX thread did not "
			   "exit - kill it\n");
		TerminateThread(l2->rx_thread, 0);
	}
	CloseHandle(l2->rx_thread_done);
	CloseHandle(l2->rx_thread);
	if (l2->pcap)
		pcap_close(l2->pcap);
	eloop_unregister_event(l2->rx_avail, sizeof(l2->rx_avail));
	CloseHandle(l2->rx_avail);
	CloseHandle(l2->rx_done);
	CloseHandle(l2->rx_notify);
	os_free(l2);
}


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

	l2->rx_thread_done = CreateEvent(NULL, TRUE, FALSE, NULL);

	l2->running = 0;
	pcap_breakloop(l2->pcap);

	/*
	 * RX thread may be waiting in l2_packet_receive_cb() for l2->rx_done
	 * event and this event is set in l2_packet_rx_event(). However,
	 * l2_packet_deinit() may end up being called from l2->rx_callback(),
	 * so we need to return from here and complete deinitialization in
	 * a registered timeout to avoid having to forcefully kill the RX
	 * thread.
	 */
	eloop_register_timeout(0, 0, l2_packet_deinit_timeout, l2, NULL);
}


int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len)
{
	pcap_if_t *devs, *dev;
	struct pcap_addr *addr;
	struct sockaddr_in *saddr;
	int found = 0;
	char err[PCAP_ERRBUF_SIZE + 1];

	if (pcap_findalldevs(&devs, err) < 0) {
		wpa_printf(MSG_DEBUG, "pcap_findalldevs: %s\n", err);
		return -1;
	}

	for (dev = devs; dev && !found; dev = dev->next) {
		if (os_strcmp(dev->name, l2->ifname) != 0)
			continue;

		addr = dev->addresses;
		while (addr) {
			saddr = (struct sockaddr_in *) addr->addr;
			if (saddr && saddr->sin_family == AF_INET) {
				os_strlcpy(buf, inet_ntoa(saddr->sin_addr),
					   len);
				found = 1;
				break;
			}
			addr = addr->next;
		}
	}

	pcap_freealldevs(devs);

	return found ? 0 : -1;
}


void l2_packet_notify_auth_start(struct l2_packet_data *l2)
{
	if (l2)
		SetEvent(l2->rx_notify);
}
