/*
 *  ether_windows.cpp - Ethernet device driver
 *
 *  Basilisk II (C) 1997-2008 Christian Bauer
 *
 *  Windows platform specific code copyright (C) Lauri Pesonen
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "sysdeps.h"

#include <process.h>
#include <windowsx.h>
#include <winioctl.h>
#include <ctype.h>

#include "cpu_emulation.h"
#include "main.h"
#include "macos_util.h"
#include "prefs.h"
#include "user_strings.h"
#include "ether.h"
#include "ether_defs.h"
#include "b2ether/multiopt.h"
#include "b2ether/inc/b2ether_hl.h"
#include "ether_windows.h"
#include "router/router.h"
#include "util_windows.h"
#include "libslirp.h"

// Define to let the slirp library determine the right timeout for select()
#define USE_SLIRP_TIMEOUT 1


#define DEBUG 0
#define MONITOR 0

#if DEBUG
#pragma optimize("",off)
#endif

#include "debug.h"


// Ethernet device types
enum {
	NET_IF_B2ETHER,
	NET_IF_ROUTER,
	NET_IF_SLIRP,
	NET_IF_TAP,
	NET_IF_FAKE,
};

// TAP-Win32 constants
#define TAP_VERSION_MIN_MAJOR 7
#define TAP_VERSION_MIN_MINOR 1

#define TAP_CONTROL_CODE(request, method) \
		CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)

#define TAP_IOCTL_GET_MAC				TAP_CONTROL_CODE (1, METHOD_BUFFERED)
#define TAP_IOCTL_GET_VERSION			TAP_CONTROL_CODE (2, METHOD_BUFFERED)
#define TAP_IOCTL_GET_MTU				TAP_CONTROL_CODE (3, METHOD_BUFFERED)
#define TAP_IOCTL_GET_INFO				TAP_CONTROL_CODE (4, METHOD_BUFFERED)
#define TAP_IOCTL_CONFIG_POINT_TO_POINT	TAP_CONTROL_CODE (5, METHOD_BUFFERED)
#define TAP_IOCTL_SET_MEDIA_STATUS		TAP_CONTROL_CODE (6, METHOD_BUFFERED)
#define TAP_IOCTL_CONFIG_DHCP_MASQ		TAP_CONTROL_CODE (7, METHOD_BUFFERED)
#define TAP_IOCTL_GET_LOG_LINE			TAP_CONTROL_CODE (8, METHOD_BUFFERED)
#define TAP_IOCTL_CONFIG_DHCP_SET_OPT	TAP_CONTROL_CODE (9, METHOD_BUFFERED)

#define OLD_TAP_CONTROL_CODE(request, method) \
		CTL_CODE (FILE_DEVICE_PHYSICAL_NETCARD | 8000, request, method, FILE_ANY_ACCESS)

#define OLD_TAP_IOCTL_GET_VERSION		OLD_TAP_CONTROL_CODE (3, METHOD_BUFFERED)

// Options
bool ether_use_permanent = true;
static int16 ether_multi_mode = ETHER_MULTICAST_MAC;

// Global variables
HANDLE ether_th;
unsigned int ether_tid;
HANDLE ether_th1;
HANDLE ether_th2;
static int net_if_type = -1;	// Ethernet device type
#ifdef SHEEPSHAVER
static bool net_open = false;	// Flag: initialization succeeded, network device open
uint8 ether_addr[6];			// Our Ethernet address
#endif

// These are protected by queue_csection
// Controls transfer for read thread to feed thread
static CRITICAL_SECTION queue_csection;
typedef struct _win_queue_t {
	uint8 *buf;
	int sz;
} win_queue_t;
#define MAX_QUEUE_ITEMS 1024
static win_queue_t queue[MAX_QUEUE_ITEMS];
static int queue_head = 0;
static int queue_inx = 0;
static bool wait_request = true;



// Read thread protected packet pool
static CRITICAL_SECTION fetch_csection;
// Some people use pools as large as 64.
#define PACKET_POOL_COUNT 10
static LPPACKET packets[PACKET_POOL_COUNT];
static bool wait_request2 = false;



// Write thread packet queue
static CRITICAL_SECTION send_csection;
static LPPACKET send_queue = 0;


// Write thread free packet pool
static CRITICAL_SECTION wpool_csection;
static LPPACKET write_packet_pool = 0;



// Try to deal with echos. Protected by fetch_csection.
// The code should be moved to the driver. No need to lift
// the echo packets to the application level.
// MAX_ECHO must be a power of two.
#define MAX_ECHO (1<<2)
static int echo_count = 0;
typedef uint8 echo_t[1514];
static echo_t pending_packet[MAX_ECHO];
static int pending_packet_sz[MAX_ECHO];


// List of attached protocols
struct NetProtocol {
	NetProtocol *next;
	uint16 type;
	uint32 handler;
};

static NetProtocol *prot_list = NULL;


static LPADAPTER fd = 0;
static bool thread_active = false;
static bool thread_active_1 = false;
static bool thread_active_2 = false;
static bool thread_active_3 = false;
static HANDLE int_ack = 0;
static HANDLE int_sig = 0;
static HANDLE int_sig2 = 0;
static HANDLE int_send_now = 0;

// Prototypes
static LPADAPTER tap_open_adapter(LPCTSTR dev_name);
static void tap_close_adapter(LPADAPTER fd);
static bool tap_check_version(LPADAPTER fd);
static bool tap_set_status(LPADAPTER fd, ULONG status);
static bool tap_get_mac(LPADAPTER fd, LPBYTE addr);
static bool tap_receive_packet(LPADAPTER fd, LPPACKET lpPacket, BOOLEAN Sync);
static bool tap_send_packet(LPADAPTER fd, LPPACKET lpPacket, BOOLEAN Sync, BOOLEAN recycle);
static unsigned int WINAPI slirp_receive_func(void *arg);
static unsigned int WINAPI ether_thread_feed_int(void *arg);
static unsigned int WINAPI ether_thread_get_packets_nt(void *arg);
static unsigned int WINAPI ether_thread_write_packets(void *arg);
static void init_queue(void);
static void final_queue(void);
static bool allocate_read_packets(void);
static void free_read_packets(void);
static void free_write_packets(void);
static int16 ether_do_add_multicast(uint8 *addr);
static int16 ether_do_del_multicast(uint8 *addr);
static int16 ether_do_write(uint32 arg);
static void ether_do_interrupt(void);


/*
 *  Find protocol in list
 */

static NetProtocol *find_protocol(uint16 type)
{
	// All 802.2 types are the same
	if (type <= 1500)
		type = 0;

	// Search list (we could use hashing here but there are usually only three
	// handlers installed: 0x0000 for AppleTalk and 0x0800/0x0806 for TCP/IP)
	NetProtocol *p = prot_list;
	while (p) {
		if (p->type == type)
			return p;
		p = p->next;
	}
	return NULL;
}


/*
 *  Initialization
 */

bool ether_init(void)
{
	TCHAR buf[256];

	// Do nothing if no Ethernet device specified
	const char *name = PrefsFindString("ether");
	if (name == NULL)
		return false;

	ether_multi_mode = PrefsFindInt32("ethermulticastmode");
	ether_use_permanent = PrefsFindBool("etherpermanentaddress");

	// Determine Ethernet device type
	net_if_type = -1;
	if (PrefsFindBool("routerenabled") || strcmp(name, "router") == 0)
		net_if_type = NET_IF_ROUTER;
	else if (strcmp(name, "slirp") == 0)
		net_if_type = NET_IF_SLIRP;
	else if (strcmp(name, "tap") == 0)
		net_if_type = NET_IF_TAP;
	else
		net_if_type = NET_IF_B2ETHER;

	// Initialize NAT-Router
	if (net_if_type == NET_IF_ROUTER) {
		if (!router_init())
			net_if_type = NET_IF_FAKE;
	}

	// Initialize slirp library
	if (net_if_type == NET_IF_SLIRP) {
		if (slirp_init() < 0) {
			WarningAlert(GetString(STR_SLIRP_NO_DNS_FOUND_WARN));
			return false;
		}
	}

	// Open ethernet device
	decltype(tstr(std::declval<const char*>())) dev_name;
	switch (net_if_type) {
	case NET_IF_B2ETHER:
		dev_name = tstr(PrefsFindString("etherguid"));
		if (dev_name == NULL || strcmp(name, "b2ether") != 0)
			dev_name = tstr(name);
		break;
	case NET_IF_TAP:
		dev_name = tstr(PrefsFindString("etherguid"));
		break;
	}
	if (net_if_type == NET_IF_B2ETHER) {
		if (dev_name == NULL) {
			WarningAlert("No ethernet device GUID specified. Ethernet is not available.");
			goto open_error;
		}

		fd = PacketOpenAdapter( dev_name.get(), ether_multi_mode );
		if (!fd) {
			_sntprintf(buf, lengthof(buf), TEXT("Could not open ethernet adapter %s."), dev_name.get());
			WarningAlert(buf);
			goto open_error;
		}

		// Get Ethernet address
		if(!PacketGetMAC(fd,ether_addr,ether_use_permanent)) {
			_sntprintf(buf, lengthof(buf), TEXT("Could not get hardware address of device %s. Ethernet is not available."), dev_name.get());
			WarningAlert(buf);
			goto open_error;
		}
		D(bug("Real ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));

		const char *ether_fake_address;
		ether_fake_address = PrefsFindString("etherfakeaddress");
		if(ether_fake_address && strlen(ether_fake_address) == 12) {
			char sm[10];
			strcpy( sm, "0x00" );
			for( int i=0; i<6; i++ ) {
				sm[2] = ether_fake_address[i*2];
				sm[3] = ether_fake_address[i*2+1];
				ether_addr[i] = (uint8)strtoul(sm,0,0);
			}
			D(bug("Fake ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
		}
	}
	else if (net_if_type == NET_IF_TAP) {
		if (dev_name == NULL) {
			WarningAlert("No ethernet device GUID specified. Ethernet is not available.");
			goto open_error;
		}

		fd = tap_open_adapter(dev_name.get());
		if (!fd) {
			_sntprintf(buf, lengthof(buf), TEXT("Could not open ethernet adapter %s."), dev_name.get());
			WarningAlert(buf);
			goto open_error;
		}

		if (!tap_check_version(fd)) {
			_sntprintf(buf, lengthof(buf), TEXT("Minimal TAP-Win32 version supported is %d.%d."), TAP_VERSION_MIN_MAJOR, TAP_VERSION_MIN_MINOR);
			WarningAlert(buf);
			goto open_error;
		}

		if (!tap_set_status(fd, true)) {
			WarningAlert("Could not set media status to connected.");
			goto open_error;
		}

		if (!tap_get_mac(fd, ether_addr)) {
			_sntprintf(buf, lengthof(buf), TEXT("Could not get hardware address of device %s. Ethernet is not available."), dev_name.get());
			WarningAlert(buf);
			goto open_error;
		}
		D(bug("Real ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));

		const char *ether_fake_address;
		ether_fake_address = PrefsFindString("etherfakeaddress");
		if (ether_fake_address && strlen(ether_fake_address) == 12) {
			char sm[10];
			strcpy( sm, "0x00" );
			for( int i=0; i<6; i++ ) {
				sm[2] = ether_fake_address[i*2];
				sm[3] = ether_fake_address[i*2+1];
				ether_addr[i] = (uint8)strtoul(sm,0,0);
			}
		}
#if 1
		/*
		  If we bridge the underlying ethernet connection and the TAP
		  device altogether, we have to use a fake address.
		 */
		else {
			ether_addr[0] = 0x52;
			ether_addr[1] = 0x54;
			ether_addr[2] = 0x00;
		}
#endif
		D(bug("Fake ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
	}
	else if (net_if_type == NET_IF_SLIRP) {
		ether_addr[0] = 0x52;
		ether_addr[1] = 0x54;
		ether_addr[2] = 0x00;
		ether_addr[3] = 0x12;
		ether_addr[4] = 0x34;
		ether_addr[5] = 0x56;
		D(bug("Ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
	}
	else {
		memcpy( ether_addr, router_mac_addr, 6 );
		D(bug("Fake ethernet address (same as router) %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
	}

	// Start packet reception thread
	int_ack = CreateSemaphore( 0, 0, 1, NULL);
	if(!int_ack) {
		WarningAlert("WARNING: Cannot create int_ack semaphore");
		goto open_error;
	}

	// nonsignaled
	int_sig = CreateSemaphore( 0, 0, 1, NULL);
	if(!int_sig) {
		WarningAlert("WARNING: Cannot create int_sig semaphore");
		goto open_error;
	}

	int_sig2 = CreateSemaphore( 0, 0, 1, NULL);
	if(!int_sig2) {
		WarningAlert("WARNING: Cannot create int_sig2 semaphore");
		goto open_error;
	}

	int_send_now = CreateSemaphore( 0, 0, 1, NULL);
	if(!int_send_now) {
		WarningAlert("WARNING: Cannot create int_send_now semaphore");
		goto open_error;
	}

	init_queue();

	if(!allocate_read_packets()) goto open_error;

	// No need to enter wait state if we can avoid it.
	// These all terminate fast.

	InitializeCriticalSectionAndSpinCount( &fetch_csection, 5000 );
	InitializeCriticalSectionAndSpinCount( &queue_csection, 5000 );
	InitializeCriticalSectionAndSpinCount( &send_csection, 5000 );
	InitializeCriticalSectionAndSpinCount( &wpool_csection, 5000 );

	ether_th = (HANDLE)_beginthreadex( 0, 0, ether_thread_feed_int, 0, 0, &ether_tid );
	if (!ether_th) {
		D(bug("Failed to create ethernet thread\n"));
		goto open_error;
	}
	thread_active = true;

	unsigned int dummy;
	unsigned int (WINAPI *receive_func)(void *);
	switch (net_if_type) {
	case NET_IF_SLIRP:
	  receive_func = slirp_receive_func;
	  break;
	default:
	  receive_func = ether_thread_get_packets_nt;
	  break;
	}
	ether_th2 = (HANDLE)_beginthreadex( 0, 0, receive_func, 0, 0, &dummy );
	ether_th1 = (HANDLE)_beginthreadex( 0, 0, ether_thread_write_packets, 0, 0, &dummy );

	// Everything OK
	return true;

 open_error:
	if (thread_active) {
		TerminateThread(ether_th,0);
		ether_th = 0;
		if (int_ack)
			CloseHandle(int_ack);
		int_ack = 0;
		if(int_sig)
			CloseHandle(int_sig);
		int_sig = 0;
		if(int_sig2)
			CloseHandle(int_sig2);
		int_sig2 = 0;
		if(int_send_now)
			CloseHandle(int_send_now);
		int_send_now = 0;
		thread_active = false;
	}
	if (fd) {
		switch (net_if_type) {
		case NET_IF_B2ETHER:
			PacketCloseAdapter(fd);
			break;
		case NET_IF_TAP:
			tap_close_adapter(fd);
			break;
		}
		fd = 0;
	}
	return false;
}


/*
 *  Deinitialization
 */

void ether_exit(void)
{
	D(bug("EtherExit\n"));

	// Stop reception thread
	thread_active = false;

	if(int_ack) ReleaseSemaphore(int_ack,1,NULL);
	if(int_sig) ReleaseSemaphore(int_sig,1,NULL);
	if(int_sig2) ReleaseSemaphore(int_sig2,1,NULL);
	if(int_send_now) ReleaseSemaphore(int_send_now,1,NULL);

	D(bug("CancelIO if needed\n"));
	if (fd && fd->hFile)
		CancelIo(fd->hFile);

	// Wait max 2 secs to shut down pending io. After that, kill them.
	D(bug("Wait delay\n"));
	for( int i=0; i<10; i++ ) {
		if(!thread_active_1 && !thread_active_2 && !thread_active_3) break;
		Sleep(200);
	}

	if(thread_active_1) {
		D(bug("Ether killing ether_th1\n"));
		if(ether_th1) TerminateThread(ether_th1,0);
		thread_active_1 = false;
	}
	if(thread_active_2) {
		D(bug("Ether killing ether_th2\n"));
		if(ether_th2) TerminateThread(ether_th2,0);
		thread_active_2 = false;
	}
	if(thread_active_3) {
		D(bug("Ether killing thread\n"));
		if(ether_th) TerminateThread(ether_th,0);
		thread_active_3 = false;
	}

	ether_th1 = 0;
	ether_th2 = 0;
	ether_th = 0;

	D(bug("Closing semaphores\n"));
	if(int_ack) {
		CloseHandle(int_ack);
		int_ack = 0;
	}
	if(int_sig) {
		CloseHandle(int_sig);
		int_sig = 0;
	}
	if(int_sig2) {
		CloseHandle(int_sig2);
		int_sig2 = 0;
	}
	if(int_send_now) {
		CloseHandle(int_send_now);
		int_send_now = 0;
	}

	// Close ethernet device
	if (fd) {
		switch (net_if_type) {
		case NET_IF_B2ETHER:
			PacketCloseAdapter(fd);
			break;
		case NET_IF_TAP:
			tap_close_adapter(fd);
			break;
		}
		fd = 0;
	}

	// Remove all protocols
	D(bug("Removing protocols\n"));
	NetProtocol *p = prot_list;
	while (p) {
		NetProtocol *next = p->next;
		delete p;
		p = next;
	}
	prot_list = 0;

	D(bug("Deleting sections\n"));
	DeleteCriticalSection( &fetch_csection );
	DeleteCriticalSection( &queue_csection );
	DeleteCriticalSection( &send_csection );
	DeleteCriticalSection( &wpool_csection );

	D(bug("Freeing read packets\n"));
	free_read_packets();

	D(bug("Freeing write packets\n"));
	free_write_packets();

	D(bug("Finalizing queue\n"));
	final_queue();

	if (net_if_type == NET_IF_ROUTER) {
		D(bug("Stopping router\n"));
		router_final();
	}

	D(bug("EtherExit done\n"));
}


/*
 *  Glue around low-level implementation
 */

#ifdef SHEEPSHAVER
// Error codes
enum {
	eMultiErr		= -91,
	eLenErr			= -92,
	lapProtErr		= -94,
	excessCollsns	= -95
};

// Initialize ethernet
void EtherInit(void)
{
	net_open = false;

	// Do nothing if the user disabled the network
	if (PrefsFindBool("nonet"))
		return;

	net_open = ether_init();
}

// Exit ethernet
void EtherExit(void)
{
	ether_exit();
	net_open = false;
}

// Get ethernet hardware address
void AO_get_ethernet_address(uint32 arg)
{
	uint8 *addr = Mac2HostAddr(arg);
	if (net_open)
		OTCopy48BitAddress(ether_addr, addr);
	else {
		addr[0] = 0x12;
		addr[1] = 0x34;
		addr[2] = 0x56;
		addr[3] = 0x78;
		addr[4] = 0x9a;
		addr[5] = 0xbc;
	}
	D(bug("AO_get_ethernet_address: got address %02x%02x%02x%02x%02x%02x\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]));
}

// Add multicast address
void AO_enable_multicast(uint32 addr)
{
	if (net_open)
		ether_do_add_multicast(Mac2HostAddr(addr));
}

// Disable multicast address
void AO_disable_multicast(uint32 addr)
{
	if (net_open)
		ether_do_del_multicast(Mac2HostAddr(addr));
}

// Transmit one packet
void AO_transmit_packet(uint32 mp)
{
	if (net_open) {
		switch (ether_do_write(mp)) {
		case noErr:
			num_tx_packets++;
			break;
		case excessCollsns:
			num_tx_buffer_full++;
			break;
		}
	}
}

// Copy packet data from message block to linear buffer
static inline int ether_arg_to_buffer(uint32 mp, uint8 *p)
{
	return ether_msgb_to_buffer(mp, p);
}

// Ethernet interrupt
void EtherIRQ(void)
{
	D(bug("EtherIRQ\n"));
	num_ether_irq++;

	OTEnterInterrupt();
	ether_do_interrupt();
	OTLeaveInterrupt();

	// Acknowledge interrupt to reception thread
	D(bug(" EtherIRQ done\n"));
	ReleaseSemaphore(int_ack,1,NULL);
}
#else
// Add multicast address
int16 ether_add_multicast(uint32 pb)
{
	return ether_do_add_multicast(Mac2HostAddr(pb + eMultiAddr));
}

// Disable multicast address
int16 ether_del_multicast(uint32 pb)
{
	return ether_do_del_multicast(Mac2HostAddr(pb + eMultiAddr));
}

// Transmit one packet
int16 ether_write(uint32 wds)
{
	return ether_do_write(wds);
}

// Copy packet data from WDS to linear buffer
static inline int ether_arg_to_buffer(uint32 wds, uint8 *p)
{
	return ether_wds_to_buffer(wds, p);
}

// Dispatch packet to protocol handler
static void ether_dispatch_packet(uint32 packet, uint32 length)
{
	// Get packet type
	uint16 type = ReadMacInt16(packet + 12);

	// Look for protocol
	NetProtocol *prot = find_protocol(type);
	if (prot == NULL)
		return;

	// No default handler
	if (prot->handler == 0)
		return;

	// Copy header to RHA
	Mac2Mac_memcpy(ether_data + ed_RHA, packet, 14);
	D(bug(" header %08lx%04lx %08lx%04lx %04lx\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12)));

	// Call protocol handler
	M68kRegisters r;
	r.d[0] = type;								// Packet type
	r.d[1] = length - 14;						// Remaining packet length (without header, for ReadPacket)
	r.a[0] = packet + 14;						// Pointer to packet (Mac address, for ReadPacket)
	r.a[3] = ether_data + ed_RHA + 14;			// Pointer behind header in RHA
	r.a[4] = ether_data + ed_ReadPacket;		// Pointer to ReadPacket/ReadRest routines
	D(bug(" calling protocol handler %08lx, type %08lx, length %08lx, data %08lx, rha %08lx, read_packet %08lx\n", prot->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4]));
	Execute68k(prot->handler, &r);
}

// Ethernet interrupt
void EtherInterrupt(void)
{
	D(bug("EtherIRQ\n"));
	ether_do_interrupt();

	// Acknowledge interrupt to reception thread
	D(bug(" EtherIRQ done\n"));
	ReleaseSemaphore(int_ack,1,NULL);
}
#endif


/*
 *  Reset
 */

void ether_reset(void)
{
	D(bug("EtherReset\n"));

	// Remove all protocols
	NetProtocol *p = prot_list;
	while (p) {
		NetProtocol *next = p->next;
		delete p;
		p = next;
	}
	prot_list = NULL;
}


/*
 *  Add multicast address
 */

static int16 ether_do_add_multicast(uint8 *addr)
{
	D(bug("ether_add_multicast\n"));

	// We wouldn't need to do this
	// if(ether_multi_mode != ETHER_MULTICAST_MAC) return noErr;

	switch (net_if_type) {
	case NET_IF_B2ETHER:
		if (!PacketAddMulticast( fd, addr)) {
			D(bug("WARNING: couldn't enable multicast address\n"));
			return eMultiErr;
		}
	default:
		D(bug("ether_add_multicast: noErr\n"));
		return noErr;
	}
}


/*
 *  Delete multicast address
 */

int16 ether_do_del_multicast(uint8 *addr)
{
	D(bug("ether_del_multicast\n"));

	// We wouldn't need to do this
	// if(ether_multi_mode != ETHER_MULTICAST_MAC) return noErr;

	switch (net_if_type) {
	case NET_IF_B2ETHER:
		if (!PacketDelMulticast( fd, addr)) {
			D(bug("WARNING: couldn't disable multicast address\n"));
			return eMultiErr;
		}
	default:
		return noErr;
	}
}


/*
 *  Attach protocol handler
 */

int16 ether_attach_ph(uint16 type, uint32 handler)
{
	D(bug("ether_attach_ph type=0x%x, handler=0x%x\n",(int)type,handler));

	// Already attached?
	NetProtocol *p = find_protocol(type);
	if (p != NULL) {
		D(bug("ether_attach_ph: lapProtErr\n"));
		return lapProtErr;
	} else {
		// No, create and attach
		p = new NetProtocol;
		p->next = prot_list;
		p->type = type;
		p->handler = handler;
		prot_list = p;
		D(bug("ether_attach_ph: noErr\n"));
		return noErr;
	}
}


/*
 *  Detach protocol handler
 */

int16 ether_detach_ph(uint16 type)
{
	D(bug("ether_detach_ph type=%08lx\n",(int)type));

	NetProtocol *p = find_protocol(type);
	if (p != NULL) {
		NetProtocol *previous = 0;
		NetProtocol *q = prot_list;
		while(q) {
			if (q == p) {
				if(previous) {
					previous->next = q->next;
				} else {
					prot_list = q->next;
				}
				delete p;
				return noErr;
			}
			previous = q;
			q = q->next;
		}
	}
	return lapProtErr;
}

#if MONITOR
static void dump_packet( uint8 *packet, int length )
{
	char buf[1000], sm[10];

	*buf = 0;

	if(length > 256) length = 256;

	for (int i=0; i<length; i++) {
		sprintf(sm," %02x", (int)packet[i]);
		strcat( buf, sm );
	}
	strcat( buf, "\n" );
	bug(buf);
}
#endif


/*
 *  Transmit raw ethernet packet
 */

static void insert_send_queue( LPPACKET Packet )
{
	EnterCriticalSection( &send_csection );
	Packet->next = 0;
	if(send_queue) {
		LPPACKET p = send_queue;
		// The queue is short. It would be larger overhead to double-link it.
		while(p->next) p = p->next;
		p->next = Packet;
	} else {
		send_queue = Packet;
	}
	LeaveCriticalSection( &send_csection );
}

static LPPACKET get_send_head( void )
{
	LPPACKET Packet = 0;

	EnterCriticalSection( &send_csection );
	if(send_queue) {
		Packet = send_queue;
		send_queue = send_queue->next;
	}
	LeaveCriticalSection( &send_csection );

	return Packet;
}

static int get_write_packet_pool_sz( void )
{
	LPPACKET t = write_packet_pool;
	int sz = 0;

	while(t) {
		t = t->next;
		sz++;
	}
	return(sz);
}

static void free_write_packets( void )
{
	LPPACKET next;
	int i = 0;
	while(write_packet_pool) {
		next = write_packet_pool->next;
		D(bug("Freeing write packet %ld\n",++i));
		PacketFreePacket(write_packet_pool);
		write_packet_pool = next;
	}
}

void recycle_write_packet( LPPACKET Packet )
{
	EnterCriticalSection( &wpool_csection );
	Packet->next = write_packet_pool;
	write_packet_pool = Packet;
	D(bug("Pool size after recycling = %ld\n",get_write_packet_pool_sz()));
	LeaveCriticalSection( &wpool_csection );
}

static LPPACKET get_write_packet( UINT len )
{
	LPPACKET Packet = 0;

	EnterCriticalSection( &wpool_csection );
	if(write_packet_pool) {
		Packet = write_packet_pool;
		write_packet_pool = write_packet_pool->next;
		Packet->OverLapped.Offset = 0;
		Packet->OverLapped.OffsetHigh = 0;
		Packet->Length = len;
		Packet->BytesReceived	= 0;
		Packet->bIoComplete	= FALSE;
		Packet->free = TRUE;
		Packet->next = 0;
		// actually an auto-reset event.
		if(Packet->OverLapped.hEvent) ResetEvent(Packet->OverLapped.hEvent);
	} else {
		Packet = PacketAllocatePacket(fd,len);
	}

	D(bug("Pool size after get wr packet = %ld\n",get_write_packet_pool_sz()));

	LeaveCriticalSection( &wpool_csection );

	return Packet;
}

unsigned int WINAPI ether_thread_write_packets(void *arg)
{
	LPPACKET Packet;

	thread_active_1 = true;

	D(bug("ether_thread_write_packets start\n"));

	while(thread_active) {
		// must be alertable, otherwise write completion is never called
		WaitForSingleObjectEx(int_send_now,INFINITE,TRUE);
		while( thread_active && (Packet = get_send_head()) != 0 ) {
			switch (net_if_type) {
			case NET_IF_ROUTER:
				if(router_write_packet((uint8 *)Packet->Buffer, Packet->Length)) {
					Packet->bIoComplete = TRUE;
					recycle_write_packet(Packet);
				}
				break;
			case NET_IF_FAKE:
				Packet->bIoComplete = TRUE;
				recycle_write_packet(Packet);
				break;
			case NET_IF_B2ETHER:
				if(!PacketSendPacket( fd, Packet, FALSE, TRUE )) {
					// already recycled if async
				}
				break;
			case NET_IF_TAP:
				if (!tap_send_packet(fd, Packet, FALSE, TRUE)) {
					// already recycled if async
				}
				break;
			case NET_IF_SLIRP:
				slirp_input((uint8 *)Packet->Buffer, Packet->Length);
				Packet->bIoComplete = TRUE;
				recycle_write_packet(Packet);
				break;
			}
		}
	}

	D(bug("ether_thread_write_packets exit\n"));

	thread_active_1 = false;

	return(0);
}

static BOOL write_packet( uint8 *packet, int len )
{
	LPPACKET Packet;

	D(bug("write_packet\n"));

	Packet = get_write_packet(len);
	if(Packet) {
		memcpy( Packet->Buffer, packet, len );

		EnterCriticalSection( &fetch_csection );
		pending_packet_sz[echo_count] = min(sizeof(pending_packet),len);
		memcpy( pending_packet[echo_count], packet, pending_packet_sz[echo_count] );
		echo_count = (echo_count+1) & (~(MAX_ECHO-1));
		LeaveCriticalSection( &fetch_csection );

		insert_send_queue( Packet );

		ReleaseSemaphore(int_send_now,1,NULL);
		return(TRUE);
	} else {
		return(FALSE);
	}
}

static int16 ether_do_write(uint32 arg)
{
	D(bug("ether_write\n"));

	// Copy packet to buffer
	uint8 packet[1514], *p = packet;
	int len = ether_arg_to_buffer(arg, p);

	if(len > 1514) {
		D(bug("illegal packet length: %d\n",len));
		return eLenErr;
	} else {
#if MONITOR
		bug("Sending Ethernet packet (%d bytes):\n",(int)len);
		dump_packet( packet, len );
#endif
	}

	// Transmit packet
	if (!write_packet(packet, len)) {
		D(bug("WARNING: couldn't transmit packet\n"));
		return excessCollsns;
	} else {
		// It's up to the protocol drivers to do the error checking. Even if the
		// i/o completion routine returns ok, there can be errors, so there is
		// no point to wait for write completion and try to make some sense of the
		// possible error codes.
		return noErr;
	}
}


static void init_queue(void)
{
	queue_inx = 0;
	queue_head = 0;

	for( int i=0; i<MAX_QUEUE_ITEMS; i++ ) {
		queue[i].buf = (uint8 *)malloc( 1514 );
		queue[i].sz = 0;
	}
}

static void final_queue(void)
{
	for( int i=0; i<MAX_QUEUE_ITEMS; i++ ) {
		if(queue[i].buf) free(queue[i].buf);
	}
}

void enqueue_packet( const uint8 *buf, int sz )
{
	EnterCriticalSection( &queue_csection );
	if(queue[queue_inx].sz > 0) {
		D(bug("ethernet queue full, packet dropped\n"));
	} else {
		if(sz > 1514) sz = 1514;
		queue[queue_inx].sz = sz;
		memcpy( queue[queue_inx].buf, buf, sz );
		queue_inx++;
		if(queue_inx >= MAX_QUEUE_ITEMS) queue_inx = 0;
		if(wait_request) {
			wait_request = false;
			ReleaseSemaphore(int_sig,1,NULL);
		}
	}
	LeaveCriticalSection( &queue_csection );
}

static int dequeue_packet( uint8 *buf )
{
	int sz;

	if(!thread_active) return(0);

	EnterCriticalSection( &queue_csection );
	sz = queue[queue_head].sz;
	if(sz > 0) {
		memcpy( buf, queue[queue_head].buf, sz );
		queue[queue_head].sz = 0;
		queue_head++;
		if(queue_head >= MAX_QUEUE_ITEMS) queue_head = 0;
	}
	LeaveCriticalSection( &queue_csection );
	return(sz);
}

static void trigger_queue(void)
{
	EnterCriticalSection( &queue_csection );
	if( queue[queue_head].sz > 0 ) {
		D(bug(" packet received, triggering Ethernet interrupt\n"));
		SetInterruptFlag(INTFLAG_ETHER);
		TriggerInterrupt();
		// of course can't wait here.
	}
	LeaveCriticalSection( &queue_csection );
}

static bool set_wait_request(void)
{
	bool result;
	EnterCriticalSection( &queue_csection );
	if(queue[queue_head].sz) {
		result = true;
	} else {
		result = false;
		wait_request = true;
	}
	LeaveCriticalSection( &queue_csection );
	return(result);
}


/*
 *  TAP-Win32 glue
 */

static LPADAPTER tap_open_adapter(LPCTSTR dev_name)
{
	fd = (LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(*fd));
	if (fd == NULL)
		return NULL;

	TCHAR dev_path[MAX_PATH];
	_sntprintf(dev_path, lengthof(dev_path),
			 TEXT("\\\\.\\Global\\%s.tap"), dev_name);

	HANDLE handle = CreateFile(
		dev_path,
		GENERIC_READ | GENERIC_WRITE,
		0,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
		NULL);
	if (handle == NULL || handle == INVALID_HANDLE_VALUE)
		return NULL;

	fd->hFile = handle;
	return fd;
}

static void tap_close_adapter(LPADAPTER fd)
{
	if (fd) {
		if (fd->hFile) {
			tap_set_status(fd, false);
			CloseHandle(fd->hFile);
		}
		GlobalFreePtr(fd);
	}
}

static bool tap_check_version(LPADAPTER fd)
{
	ULONG len;
	ULONG info[3] = { 0, };

	if (!DeviceIoControl(fd->hFile, TAP_IOCTL_GET_VERSION,
						 &info, sizeof(info),
						 &info, sizeof(info), &len, NULL)
		&& !DeviceIoControl(fd->hFile, OLD_TAP_IOCTL_GET_VERSION,
							&info, sizeof(info),
							&info, sizeof(info), &len, NULL))
		return false;

	if (info[0] > TAP_VERSION_MIN_MAJOR)
		return true;
	if (info[0] == TAP_VERSION_MIN_MAJOR && info[1] >= TAP_VERSION_MIN_MINOR)
		return true;

	return false;
}

static bool tap_set_status(LPADAPTER fd, ULONG status)
{
	DWORD len = 0;
	return DeviceIoControl(fd->hFile, TAP_IOCTL_SET_MEDIA_STATUS,
						   &status, sizeof (status),
						   &status, sizeof (status), &len, NULL) != FALSE;
}

static bool tap_get_mac(LPADAPTER fd, LPBYTE addr)
{
	DWORD len = 0;
	return DeviceIoControl(fd->hFile, TAP_IOCTL_GET_MAC,
						   addr, 6,
						   addr, 6, &len, NULL) != FALSE;
}

static VOID CALLBACK tap_write_completion(
	DWORD dwErrorCode,
	DWORD dwNumberOfBytesTransfered,
	LPOVERLAPPED lpOverLapped
	)
{
	LPPACKET lpPacket = CONTAINING_RECORD(lpOverLapped, PACKET, OverLapped);

	lpPacket->bIoComplete = TRUE;
	recycle_write_packet(lpPacket);
}

static bool tap_send_packet(
	LPADAPTER fd,
	LPPACKET lpPacket,
	BOOLEAN Sync,
	BOOLEAN RecyclingAllowed)
{
	BOOLEAN Result;

	lpPacket->OverLapped.Offset = 0;
	lpPacket->OverLapped.OffsetHigh = 0;
	lpPacket->bIoComplete = FALSE;

	if (Sync) {
		Result = WriteFile(fd->hFile,
						   lpPacket->Buffer,
						   lpPacket->Length,
						   &lpPacket->BytesReceived,
						   &lpPacket->OverLapped);
		if (Result) {
			GetOverlappedResult(fd->hFile,
								&lpPacket->OverLapped,
								&lpPacket->BytesReceived,
								TRUE);
		}
		lpPacket->bIoComplete = TRUE;
		if (RecyclingAllowed)
			PacketFreePacket(lpPacket);
	}
	else {
		Result = WriteFileEx(fd->hFile,
							 lpPacket->Buffer,
							 lpPacket->Length,
							 &lpPacket->OverLapped,
							 tap_write_completion);

		if (!Result && RecyclingAllowed)
			recycle_write_packet(lpPacket);
	}

	return Result != FALSE;
}

static bool tap_receive_packet(LPADAPTER fd, LPPACKET lpPacket, BOOLEAN Sync)
{
	BOOLEAN Result;

	lpPacket->OverLapped.Offset = 0;
	lpPacket->OverLapped.OffsetHigh = 0;
	lpPacket->bIoComplete = FALSE;

	if (Sync) {
		Result = ReadFile(fd->hFile,
						  lpPacket->Buffer,
						  lpPacket->Length,
						  &lpPacket->BytesReceived,
						  &lpPacket->OverLapped);
		if (Result) {
			Result = GetOverlappedResult(fd->hFile,
										 &lpPacket->OverLapped,
										 &lpPacket->BytesReceived,
										 TRUE);
			if (Result)
				lpPacket->bIoComplete = TRUE;
			else
				lpPacket->free = TRUE;
		}
	}
	else {
		Result = ReadFileEx(fd->hFile,
							lpPacket->Buffer,
							lpPacket->Length,
							&lpPacket->OverLapped,
							packet_read_completion);

		if (!Result)
			lpPacket->BytesReceived = 0;
	}

	return Result != FALSE;
}


/*
 *  SLIRP output buffer glue
 */

int slirp_can_output(void)
{
	return 1;
}

void slirp_output(const uint8 *packet, int len)
{
	enqueue_packet(packet, len);
}

unsigned int WINAPI slirp_receive_func(void *arg)
{
	D(bug("slirp_receive_func\n"));
	thread_active_2 = true;

	while (thread_active) {
		// Wait for packets to arrive
		fd_set rfds, wfds, xfds;
		int nfds, ret, timeout;

		// ... in the output queue
		nfds = -1;
		FD_ZERO(&rfds);
		FD_ZERO(&wfds);
		FD_ZERO(&xfds);
		timeout = slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
#if ! USE_SLIRP_TIMEOUT
		timeout = 10000;
#endif
		if (nfds < 0) {
			/* Windows does not honour the timeout if there is not
			   descriptor to wait for */
			Delay_usec(timeout);
			ret = 0;
		}
		else {
			struct timeval tv;
			tv.tv_sec = 0;
			tv.tv_usec = timeout;
			ret = select(0, &rfds, &wfds, &xfds, &tv);
		}
		if (ret >= 0)
			slirp_select_poll(&rfds, &wfds, &xfds);
	}

	D(bug("slirp_receive_func exit\n"));
	thread_active_2 = false;
	return 0;
}


/*
 *  Packet reception threads
 */

VOID CALLBACK packet_read_completion(
	DWORD dwErrorCode,
	DWORD dwNumberOfBytesTransfered,
	LPOVERLAPPED lpOverlapped
	)
{
	EnterCriticalSection( &fetch_csection );

	LPPACKET lpPacket = CONTAINING_RECORD(lpOverlapped,PACKET,OverLapped);

	D(bug("packet_read_completion bytes=%d, error code=%d\n",dwNumberOfBytesTransfered,dwErrorCode));

	if(thread_active && !dwErrorCode) {
		int count = min(dwNumberOfBytesTransfered,1514);
		if(count) {
			int j = echo_count;
			for(int i=MAX_ECHO; i; i--) {
				j--;
				if(j < 0) j = MAX_ECHO-1;
				if(count == pending_packet_sz[j] &&
				   memcmp(pending_packet[j],lpPacket->Buffer,count) == 0)
				{
					D(bug("packet_read_completion discarding own packet.\n"));
					dwNumberOfBytesTransfered = 0;

					j = (j+1) & (~(MAX_ECHO-1));
					if(j != echo_count) {
						D(bug("Wow, this fix made some good after all...\n"));
					}

					break;
				}
			}
			// XXX drop packets that are not for us
			if (net_if_type == NET_IF_TAP) {
				if (memcmp((LPBYTE)lpPacket->Buffer, ether_addr, 6) != 0)
					dwNumberOfBytesTransfered = 0;
			}
			if(dwNumberOfBytesTransfered) {
				if(net_if_type != NET_IF_ROUTER || !router_read_packet((uint8 *)lpPacket->Buffer, dwNumberOfBytesTransfered)) {
					enqueue_packet( (LPBYTE)lpPacket->Buffer, dwNumberOfBytesTransfered );
				}
			}
		}
	}

	// actually an auto-reset event.
	if(lpPacket->OverLapped.hEvent) ResetEvent(lpPacket->OverLapped.hEvent);

	lpPacket->free = TRUE;
	lpPacket->bIoComplete = TRUE;

	if(wait_request2) {
		wait_request2 = false;
		ReleaseSemaphore(int_sig2,1,NULL);
	}

	LeaveCriticalSection( &fetch_csection );
}

static BOOL has_no_completed_io(void)
{
	BOOL result = TRUE;

	EnterCriticalSection( &fetch_csection );

	for( int i=0; i<PACKET_POOL_COUNT; i++ ) {
		if(packets[i]->bIoComplete) {
			result = FALSE;
			break;
		}
	}
	if(result) wait_request2 = true;

	LeaveCriticalSection( &fetch_csection );
	return(result);
}

static bool allocate_read_packets(void)
{
	for( int i=0; i<PACKET_POOL_COUNT; i++ ) {
		packets[i] = PacketAllocatePacket(fd,1514);
		if(!packets[i]) {
			D(bug("allocate_read_packets: out of memory\n"));
			return(false);
		}
	}
	return(true);
}

static void free_read_packets(void)
{
	for( int i=0; i<PACKET_POOL_COUNT; i++ ) {
		PacketFreePacket(packets[i]);
	}
}

unsigned int WINAPI ether_thread_get_packets_nt(void *arg)
{
	static uint8 packet[1514];
	int i, packet_sz = 0;

	thread_active_2 = true;

	D(bug("ether_thread_get_packets_nt start\n"));

	// Wait for packets to arrive.
	// Obey the golden rules; keep the reads pending.
	while(thread_active) {

		if(net_if_type == NET_IF_B2ETHER || net_if_type == NET_IF_TAP) {
			D(bug("Pending reads\n"));
			for( i=0; thread_active && i<PACKET_POOL_COUNT; i++ ) {
				if(packets[i]->free) {
					packets[i]->free = FALSE;
					BOOLEAN Result;
					switch (net_if_type) {
					case NET_IF_B2ETHER:
						Result = PacketReceivePacket(fd, packets[i], FALSE);
						break;
					case NET_IF_TAP:
						Result = tap_receive_packet(fd, packets[i], FALSE);
						break;
					}
					if (Result) {
						if(packets[i]->bIoComplete) {
							D(bug("Early io completion...\n"));
							packet_read_completion(
								ERROR_SUCCESS,
								packets[i]->BytesReceived,
								&packets[i]->OverLapped
								);
						}
					} else {
						packets[i]->free = TRUE;
					}
				}
			}
		}

		if(thread_active && has_no_completed_io()) {
			D(bug("Waiting for int_sig2\n"));
			// "problem": awakens twice in a row. Fix if you increase the pool size.
			WaitForSingleObjectEx(int_sig2,INFINITE,TRUE);
		}
	}

	D(bug("ether_thread_get_packets_nt exit\n"));

	thread_active_2 = false;

	return 0;
}

unsigned int WINAPI ether_thread_feed_int(void *arg)
{
	bool looping;

	thread_active_3 = true;

	D(bug("ether_thread_feed_int start\n"));

	while(thread_active) {
		D(bug("Waiting for int_sig\n"));
		WaitForSingleObject(int_sig,INFINITE);
		// Looping this way to avoid a race condition.
		D(bug("Triggering\n"));
		looping = true;
		while(thread_active && looping) {
			trigger_queue();
			// Wait for interrupt acknowledge by EtherInterrupt()
			WaitForSingleObject(int_ack,INFINITE);
			if(thread_active) looping = set_wait_request();
		}
		D(bug("Queue empty.\n"));
	}

	D(bug("ether_thread_feed_int exit\n"));

	thread_active_3 = false;

	return 0;
}


/*
 *  Ethernet interrupt - activate deferred tasks to call IODone or protocol handlers
 */

static void ether_do_interrupt(void)
{
	// Call protocol handler for received packets
	EthernetPacket ether_packet;
	uint32 packet = ether_packet.addr();
	ssize_t length;
	for (;;) {

		// Read packet from Ethernet device
		length = dequeue_packet(Mac2HostAddr(packet));
		if (length < 14)
			break;

#if MONITOR
		bug("Receiving Ethernet packet (%d bytes):\n",(int)length);
		dump_packet( Mac2HostAddr(packet), length );
#endif

		// Dispatch packet
		ether_dispatch_packet(packet, length);
	}
}

#if DEBUG
#pragma optimize("",on)
#endif
