/*
 * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
 * Copyright (c) 2005 - 2010 CACE Technologies, Davis (California)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Politecnico di Torino, CACE Technologies
 * nor the names of its contributors may be used to endorse or promote
 * products derived from this software without specific prior written
 * permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "pcap-int.h"

#include <airpcap.h>

#include "pcap-airpcap.h"

/* Default size of the buffer we allocate in userland. */
#define	AIRPCAP_DEFAULT_USER_BUFFER_SIZE 256000

/* Default size of the buffer for the AirPcap adapter. */
#define	AIRPCAP_DEFAULT_KERNEL_BUFFER_SIZE 1000000

//
// We load the AirPcap DLL dynamically, so that the code will
// work whether you have it installed or not, and there don't
// have to be two different versions of the library, one linked
// to the AirPcap library and one not linked to it.
//
static pcap_code_handle_t airpcap_lib;

typedef PCHAR (*AirpcapGetLastErrorHandler)(PAirpcapHandle);
typedef BOOL (*AirpcapGetDeviceListHandler)(PAirpcapDeviceDescription *, PCHAR);
typedef VOID (*AirpcapFreeDeviceListHandler)(PAirpcapDeviceDescription);
typedef PAirpcapHandle (*AirpcapOpenHandler)(PCHAR, PCHAR);
typedef VOID (*AirpcapCloseHandler)(PAirpcapHandle);
typedef BOOL (*AirpcapSetDeviceMacFlagsHandler)(PAirpcapHandle, UINT);
typedef BOOL (*AirpcapSetLinkTypeHandler)(PAirpcapHandle, AirpcapLinkType);
typedef BOOL (*AirpcapGetLinkTypeHandler)(PAirpcapHandle, PAirpcapLinkType);
typedef BOOL (*AirpcapSetKernelBufferHandler)(PAirpcapHandle, UINT);
typedef BOOL (*AirpcapSetFilterHandler)(PAirpcapHandle, PVOID, UINT);
typedef BOOL (*AirpcapSetMinToCopyHandler)(PAirpcapHandle, UINT);
typedef BOOL (*AirpcapGetReadEventHandler)(PAirpcapHandle, HANDLE *);
typedef BOOL (*AirpcapReadHandler)(PAirpcapHandle, PBYTE, UINT, PUINT);
typedef BOOL (*AirpcapWriteHandler)(PAirpcapHandle, PCHAR, ULONG);
typedef BOOL (*AirpcapGetStatsHandler)(PAirpcapHandle, PAirpcapStats);

static AirpcapGetLastErrorHandler p_AirpcapGetLastError;
static AirpcapGetDeviceListHandler p_AirpcapGetDeviceList;
static AirpcapFreeDeviceListHandler p_AirpcapFreeDeviceList;
static AirpcapOpenHandler p_AirpcapOpen;
static AirpcapCloseHandler p_AirpcapClose;
static AirpcapSetDeviceMacFlagsHandler p_AirpcapSetDeviceMacFlags;
static AirpcapSetLinkTypeHandler p_AirpcapSetLinkType;
static AirpcapGetLinkTypeHandler p_AirpcapGetLinkType;
static AirpcapSetKernelBufferHandler p_AirpcapSetKernelBuffer;
static AirpcapSetFilterHandler p_AirpcapSetFilter;
static AirpcapSetMinToCopyHandler p_AirpcapSetMinToCopy;
static AirpcapGetReadEventHandler p_AirpcapGetReadEvent;
static AirpcapReadHandler p_AirpcapRead;
static AirpcapWriteHandler p_AirpcapWrite;
static AirpcapGetStatsHandler p_AirpcapGetStats;

typedef enum LONG
{
	AIRPCAP_API_UNLOADED = 0,
	AIRPCAP_API_LOADED,
	AIRPCAP_API_CANNOT_LOAD,
	AIRPCAP_API_LOADING
} AIRPCAP_API_LOAD_STATUS;

static AIRPCAP_API_LOAD_STATUS	airpcap_load_status;

/*
 * NOTE: this function should be called by the pcap functions that can
 *       theoretically deal with the AirPcap library for the first time,
 *       namely listing the adapters and creating a pcap_t for an adapter.
 *       All the other ones (activate, close, read, write, set parameters)
 *       work on a pcap_t for an AirPcap device, meaning we've already
 *       created the pcap_t and thus have loaded the functions, so we do
 *       not need to call this function.
 */
static AIRPCAP_API_LOAD_STATUS
load_airpcap_functions(void)
{
	AIRPCAP_API_LOAD_STATUS current_status;

	/*
	 * We don't use a mutex because there's no place that
	 * we can guarantee we'll be called before any threads
	 * other than the main thread exists.  (For example,
	 * this might be a static library, so we can't arrange
	 * to be called by DllMain(), and there's no guarantee
	 * that the application called pcap_init() - which is
	 * supposed to be called only from one thread - so
	 * we can't arrange to be called from it.)
	 *
	 * If nobody's tried to load it yet, mark it as
	 * loading; in any case, return the status before
	 * we modified it.
	 */
	current_status = InterlockedCompareExchange((LONG *)&airpcap_load_status,
	    AIRPCAP_API_LOADING, AIRPCAP_API_UNLOADED);

	/*
	 * If the status was AIRPCAP_API_UNLOADED, we've set it
	 * to AIRPCAP_API_LOADING, because we're going to be
	 * the ones to load the library but current_status is
	 * AIRPCAP_API_UNLOADED.
	 *
	 * if it was AIRPCAP_API_LOADING, meaning somebody else
	 * was trying to load it, spin until they finish and
	 * set the status to a value reflecting whether they
	 * succeeded.
	 */
	while (current_status == AIRPCAP_API_LOADING) {
		current_status = InterlockedCompareExchange((LONG*)&airpcap_load_status,
		    AIRPCAP_API_LOADING, AIRPCAP_API_LOADING);
		Sleep(10);
	}

	/*
	 * At this point, current_status is either:
	 *
	 *	AIRPCAP_API_LOADED, in which case another thread
	 *	loaded the library, so we're done;
	 *
	 *	AIRPCAP_API_CANNOT_LOAD, in which another thread
	 *	tried and failed to load the library, so we're
	 *	done - we won't try it ourselves;
	 *
	 *	AIRPCAP_API_LOADING, in which case *we're* the
	 *	ones loading it, and should now try to do so.
	 */
	if (current_status == AIRPCAP_API_LOADED)
		return AIRPCAP_API_LOADED;

	if (current_status == AIRPCAP_API_CANNOT_LOAD)
		return AIRPCAP_API_CANNOT_LOAD;

	/*
	 * Start out assuming we can't load it.
	 */
	current_status = AIRPCAP_API_CANNOT_LOAD;

	airpcap_lib = pcap_load_code("airpcap.dll");
	if (airpcap_lib != NULL) {
		/*
		 * OK, we've loaded the library; now try to find the
		 * functions we need in it.
		 */
		p_AirpcapGetLastError = (AirpcapGetLastErrorHandler) pcap_find_function(airpcap_lib, "AirpcapGetLastError");
		p_AirpcapGetDeviceList = (AirpcapGetDeviceListHandler) pcap_find_function(airpcap_lib, "AirpcapGetDeviceList");
		p_AirpcapFreeDeviceList = (AirpcapFreeDeviceListHandler) pcap_find_function(airpcap_lib, "AirpcapFreeDeviceList");
		p_AirpcapOpen = (AirpcapOpenHandler) pcap_find_function(airpcap_lib, "AirpcapOpen");
		p_AirpcapClose = (AirpcapCloseHandler) pcap_find_function(airpcap_lib, "AirpcapClose");
		p_AirpcapSetDeviceMacFlags = (AirpcapSetDeviceMacFlagsHandler) pcap_find_function(airpcap_lib, "AirpcapSetDeviceMacFlags");
		p_AirpcapSetLinkType = (AirpcapSetLinkTypeHandler) pcap_find_function(airpcap_lib, "AirpcapSetLinkType");
		p_AirpcapGetLinkType = (AirpcapGetLinkTypeHandler) pcap_find_function(airpcap_lib, "AirpcapGetLinkType");
		p_AirpcapSetKernelBuffer = (AirpcapSetKernelBufferHandler) pcap_find_function(airpcap_lib, "AirpcapSetKernelBuffer");
		p_AirpcapSetFilter = (AirpcapSetFilterHandler) pcap_find_function(airpcap_lib, "AirpcapSetFilter");
		p_AirpcapSetMinToCopy = (AirpcapSetMinToCopyHandler) pcap_find_function(airpcap_lib, "AirpcapSetMinToCopy");
		p_AirpcapGetReadEvent = (AirpcapGetReadEventHandler) pcap_find_function(airpcap_lib, "AirpcapGetReadEvent");
		p_AirpcapRead = (AirpcapReadHandler) pcap_find_function(airpcap_lib, "AirpcapRead");
		p_AirpcapWrite = (AirpcapWriteHandler) pcap_find_function(airpcap_lib, "AirpcapWrite");
		p_AirpcapGetStats = (AirpcapGetStatsHandler) pcap_find_function(airpcap_lib, "AirpcapGetStats");

		//
		// Make sure that we found everything
		//
		if (p_AirpcapGetLastError != NULL &&
		    p_AirpcapGetDeviceList != NULL &&
		    p_AirpcapFreeDeviceList != NULL &&
		    p_AirpcapOpen != NULL &&
		    p_AirpcapClose != NULL &&
		    p_AirpcapSetDeviceMacFlags != NULL &&
		    p_AirpcapSetLinkType != NULL &&
		    p_AirpcapGetLinkType != NULL &&
		    p_AirpcapSetKernelBuffer != NULL &&
		    p_AirpcapSetFilter != NULL &&
		    p_AirpcapSetMinToCopy != NULL &&
		    p_AirpcapGetReadEvent != NULL &&
		    p_AirpcapRead != NULL &&
		    p_AirpcapWrite != NULL &&
		    p_AirpcapGetStats != NULL) {
			/*
			 * We have all we need.
			 */
			current_status = AIRPCAP_API_LOADED;
		}
	}

	if (current_status != AIRPCAP_API_LOADED) {
		/*
		 * We failed; if we found the DLL, close the
		 * handle for it.
		 */
		if (airpcap_lib != NULL) {
			FreeLibrary(airpcap_lib);
			airpcap_lib = NULL;
		}
	}

	/*
	 * Now set the status appropriately - and atomically.
	 */
	InterlockedExchange((LONG *)&airpcap_load_status, current_status);

	return current_status;
}

/*
 * Private data for capturing on AirPcap devices.
 */
struct pcap_airpcap {
	PAirpcapHandle adapter;
	int filtering_in_kernel;
	int nonblock;
	int read_timeout;
	HANDLE read_event;
	struct pcap_stat stat;
};

static int
airpcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
	struct pcap_airpcap *pa = p->priv;

	if (!p_AirpcapSetFilter(pa->adapter, fp->bf_insns,
	    fp->bf_len * sizeof(struct bpf_insn))) {
		/*
		 * Kernel filter not installed.
		 *
		 * XXX - we don't know whether this failed because:
		 *
		 *  the kernel rejected the filter program as invalid,
		 *  in which case we should fall back on userland
		 *  filtering;
		 *
		 *  the kernel rejected the filter program as too big,
		 *  in which case we should again fall back on
		 *  userland filtering;
		 *
		 *  there was some other problem, in which case we
		 *  should probably report an error;
		 *
		 * So we just fall back on userland filtering in
		 * all cases.
		 */

		/*
		 * install_bpf_program() validates the program.
		 *
		 * XXX - what if we already have a filter in the kernel?
		 */
		if (install_bpf_program(p, fp) < 0)
			return (-1);
		pa->filtering_in_kernel = 0;	/* filtering in userland */
		return (0);
	}

	/*
	 * It worked.
	 */
	pa->filtering_in_kernel = 1;	/* filtering in the kernel */

	/*
	 * Discard any previously-received packets, as they might have
	 * passed whatever filter was formerly in effect, but might
	 * not pass this filter (BIOCSETF discards packets buffered
	 * in the kernel, so you can lose packets in any case).
	 */
	p->cc = 0;
	return (0);
}

static int
airpcap_set_datalink(pcap_t *p, int dlt)
{
	struct pcap_airpcap *pa = p->priv;
	AirpcapLinkType type;

	switch (dlt) {

	case DLT_IEEE802_11_RADIO:
		type = AIRPCAP_LT_802_11_PLUS_RADIO;
		break;

	case DLT_PPI:
		type = AIRPCAP_LT_802_11_PLUS_PPI;
		break;

	case DLT_IEEE802_11:
		type = AIRPCAP_LT_802_11;
		break;

	default:
		/* This can't happen; just return. */
		return (0);
	}
	if (!p_AirpcapSetLinkType(pa->adapter, type)) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "AirpcapSetLinkType() failed: %s",
		    p_AirpcapGetLastError(pa->adapter));
		return (-1);
	}
	p->linktype = dlt;
	return (0);
}

static int
airpcap_getnonblock(pcap_t *p)
{
	struct pcap_airpcap *pa = p->priv;

	return (pa->nonblock);
}

static int
airpcap_setnonblock(pcap_t *p, int nonblock)
{
	struct pcap_airpcap *pa = p->priv;
	int newtimeout;

	if (nonblock) {
		/*
		 * Set the packet buffer timeout to -1 for non-blocking
		 * mode.
		 */
		newtimeout = -1;
	} else {
		/*
		 * Restore the timeout set when the device was opened.
		 * (Note that this may be -1, in which case we're not
		 * really leaving non-blocking mode.  However, although
		 * the timeout argument to pcap_set_timeout() and
		 * pcap_open_live() is an int, you're not supposed to
		 * supply a negative value, so that "shouldn't happen".)
		 */
		newtimeout = p->opt.timeout;
	}
	pa->read_timeout = newtimeout;
	pa->nonblock = (newtimeout == -1);
	return (0);
}

static int
airpcap_stats(pcap_t *p, struct pcap_stat *ps)
{
	struct pcap_airpcap *pa = p->priv;
	AirpcapStats tas;

	/*
	 * Try to get statistics.
	 */
	if (!p_AirpcapGetStats(pa->adapter, &tas)) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "AirpcapGetStats() failed: %s",
		    p_AirpcapGetLastError(pa->adapter));
		return (-1);
	}

	ps->ps_drop = tas.Drops;
	ps->ps_recv = tas.Recvs;
	ps->ps_ifdrop = tas.IfDrops;

	return (0);
}

/*
 * Win32-only routine for getting statistics.
 *
 * This way is definitely safer than passing the pcap_stat * from the userland.
 * In fact, there could happen than the user allocates a variable which is not
 * big enough for the new structure, and the library will write in a zone
 * which is not allocated to this variable.
 *
 * In this way, we're pretty sure we are writing on memory allocated to this
 * variable.
 *
 * XXX - but this is the wrong way to handle statistics.  Instead, we should
 * have an API that returns data in a form like the Options section of a
 * pcapng Interface Statistics Block:
 *
 *    https://xml2rfc.tools.ietf.org/cgi-bin/xml2rfc.cgi?url=https://raw.githubusercontent.com/pcapng/pcapng/master/draft-tuexen-opsawg-pcapng.xml&modeAsFormat=html/ascii&type=ascii#rfc.section.4.6
 *
 * which would let us add new statistics straightforwardly and indicate which
 * statistics we are and are *not* providing, rather than having to provide
 * possibly-bogus values for statistics we can't provide.
 */
static struct pcap_stat *
airpcap_stats_ex(pcap_t *p, int *pcap_stat_size)
{
	struct pcap_airpcap *pa = p->priv;
	AirpcapStats tas;

	*pcap_stat_size = sizeof (p->stat);

	/*
	 * Try to get statistics.
	 */
	if (!p_AirpcapGetStats(pa->adapter, &tas)) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "AirpcapGetStats() failed: %s",
		    p_AirpcapGetLastError(pa->adapter));
		return (NULL);
	}

	p->stat.ps_recv = tas.Recvs;
	p->stat.ps_drop = tas.Drops;
	p->stat.ps_ifdrop = tas.IfDrops;
	/*
	 * Just in case this is ever compiled for a target other than
	 * Windows, which is extremely unlikely at best.
	 */
#ifdef _WIN32
	p->stat.ps_capt = tas.Capt;
#endif
	return (&p->stat);
}

/* Set the dimension of the kernel-level capture buffer */
static int
airpcap_setbuff(pcap_t *p, int dim)
{
	struct pcap_airpcap *pa = p->priv;

	if (!p_AirpcapSetKernelBuffer(pa->adapter, dim)) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "AirpcapSetKernelBuffer() failed: %s",
		    p_AirpcapGetLastError(pa->adapter));
		return (-1);
	}
	return (0);
}

/* Set the driver working mode */
static int
airpcap_setmode(pcap_t *p, int mode)
{
	 if (mode != MODE_CAPT) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "Only MODE_CAPT is supported on an AirPcap adapter");
		return (-1);
	 }
	 return (0);
}

/*set the minimum amount of data that will release a read call*/
static int
airpcap_setmintocopy(pcap_t *p, int size)
{
	struct pcap_airpcap *pa = p->priv;

	if (!p_AirpcapSetMinToCopy(pa->adapter, size)) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "AirpcapSetMinToCopy() failed: %s",
		    p_AirpcapGetLastError(pa->adapter));
		return (-1);
	}
	return (0);
}

static HANDLE
airpcap_getevent(pcap_t *p)
{
	struct pcap_airpcap *pa = p->priv;

	return (pa->read_event);
}

static int
airpcap_oid_get_request(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_,
    size_t *lenp _U_)
{
	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
	    "Getting OID values is not supported on an AirPcap adapter");
	return (PCAP_ERROR);
}

static int
airpcap_oid_set_request(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_,
    size_t *lenp _U_)
{
	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
	    "Setting OID values is not supported on an AirPcap adapter");
	return (PCAP_ERROR);
}

static u_int
airpcap_sendqueue_transmit(pcap_t *p, pcap_send_queue *queue _U_, int sync _U_)
{
	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
	    "Cannot queue packets for transmission on an AirPcap adapter");
	return (0);
}

static int
airpcap_setuserbuffer(pcap_t *p, int size)
{
	unsigned char *new_buff;

	if (size <= 0) {
		/* Bogus parameter */
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "Error: invalid size %d",size);
		return (-1);
	}

	/* Allocate the buffer */
	new_buff = (unsigned char *)malloc(sizeof(char)*size);

	if (!new_buff) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "Error: not enough memory");
		return (-1);
	}

	free(p->buffer);

	p->buffer = new_buff;
	p->bufsize = size;

	return (0);
}

static int
airpcap_live_dump(pcap_t *p, char *filename _U_, int maxsize _U_,
    int maxpacks _U_)
{
	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
	    "AirPcap adapters don't support live dump");
	return (-1);
}

static int
airpcap_live_dump_ended(pcap_t *p, int sync _U_)
{
	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
	    "AirPcap adapters don't support live dump");
	return (-1);
}

static PAirpcapHandle
airpcap_get_airpcap_handle(pcap_t *p)
{
	struct pcap_airpcap *pa = p->priv;

	return (pa->adapter);
}

static int
airpcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
	struct pcap_airpcap *pa = p->priv;
	int cc;
	int n;
	register u_char *bp, *ep;
	UINT bytes_read;
	u_char *datap;

	cc = p->cc;
	if (cc == 0) {
		/*
		 * Has "pcap_breakloop()" been called?
		 */
		if (p->break_loop) {
			/*
			 * Yes - clear the flag that indicates that it
			 * has, and return PCAP_ERROR_BREAK to indicate
			 * that we were told to break out of the loop.
			 */
			p->break_loop = 0;
			return (PCAP_ERROR_BREAK);
		}

		//
		// If we're not in non-blocking mode, wait for data to
		// arrive.
		//
		if (pa->read_timeout != -1) {
			WaitForSingleObject(pa->read_event,
			    (pa->read_timeout ==0 )? INFINITE: pa->read_timeout);
		}

		//
		// Read the data.
		// p_AirpcapRead doesn't block.
		//
		if (!p_AirpcapRead(pa->adapter, (PBYTE)p->buffer,
		    p->bufsize, &bytes_read)) {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "AirpcapRead() failed: %s",
			    p_AirpcapGetLastError(pa->adapter));
			return (-1);
		}
		cc = bytes_read;
		bp = (u_char *)p->buffer;
	} else
		bp = p->bp;

	/*
	 * Loop through each packet.
	 */
#define bhp ((AirpcapBpfHeader *)bp)
	n = 0;
	ep = bp + cc;
	for (;;) {
		register u_int caplen, hdrlen;

		/*
		 * Has "pcap_breakloop()" been called?
		 * If so, return immediately - if we haven't read any
		 * packets, clear the flag and return PCAP_ERROR_BREAK
		 * to indicate that we were told to break out of the loop,
		 * otherwise leave the flag set, so that the *next* call
		 * will break out of the loop without having read any
		 * packets, and return the number of packets we've
		 * processed so far.
		 */
		if (p->break_loop) {
			if (n == 0) {
				p->break_loop = 0;
				return (PCAP_ERROR_BREAK);
			} else {
				p->bp = bp;
				p->cc = (int) (ep - bp);
				return (n);
			}
		}
		if (bp >= ep)
			break;

		caplen = bhp->Caplen;
		hdrlen = bhp->Hdrlen;
		datap = bp + hdrlen;
		/*
		 * Short-circuit evaluation: if using BPF filter
		 * in the AirPcap adapter, no need to do it now -
		 * we already know the packet passed the filter.
		 */
		if (pa->filtering_in_kernel ||
		    p->fcode.bf_insns == NULL ||
		    pcap_filter(p->fcode.bf_insns, datap, bhp->Originallen, caplen)) {
			struct pcap_pkthdr pkthdr;

			pkthdr.ts.tv_sec = bhp->TsSec;
			pkthdr.ts.tv_usec = bhp->TsUsec;
			pkthdr.caplen = caplen;
			pkthdr.len = bhp->Originallen;
			(*callback)(user, &pkthdr, datap);
			bp += AIRPCAP_WORDALIGN(caplen + hdrlen);
			if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) {
				p->bp = bp;
				p->cc = (int)(ep - bp);
				return (n);
			}
		} else {
			/*
			 * Skip this packet.
			 */
			bp += AIRPCAP_WORDALIGN(caplen + hdrlen);
		}
	}
#undef bhp
	p->cc = 0;
	return (n);
}

static int
airpcap_inject(pcap_t *p, const void *buf, int size)
{
	struct pcap_airpcap *pa = p->priv;

	/*
	 * XXX - the second argument to AirpcapWrite() *should* have
	 * been declared as a const pointer - a write function that
	 * stomps on what it writes is *extremely* rude - but such
	 * is life.  We assume it is, in fact, not going to write on
	 * our buffer.
	 */
	if (!p_AirpcapWrite(pa->adapter, (void *)buf, size)) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "AirpcapWrite() failed: %s",
		    p_AirpcapGetLastError(pa->adapter));
		return (-1);
	}

	/*
	 * We assume it all got sent if "AirpcapWrite()" succeeded.
	 * "pcap_inject()" is expected to return the number of bytes
	 * sent.
	 */
	return (size);
}

static void
airpcap_cleanup(pcap_t *p)
{
	struct pcap_airpcap *pa = p->priv;

	if (pa->adapter != NULL) {
		p_AirpcapClose(pa->adapter);
		pa->adapter = NULL;
	}
	pcap_cleanup_live_common(p);
}

static void
airpcap_breakloop(pcap_t *p)
{
	HANDLE read_event;

	pcap_breakloop_common(p);
	struct pcap_airpcap *pa = p->priv;

	/* XXX - what if either of these fail? */
	/*
	 * XXX - will SetEvent() force a wakeup and, if so, will
	 * the AirPcap read code handle that sanely?
	 */
	if (!p_AirpcapGetReadEvent(pa->adapter, &read_event))
		return;
	SetEvent(read_event);
}

static int
airpcap_activate(pcap_t *p)
{
	struct pcap_airpcap *pa = p->priv;
	char *device = p->opt.device;
	char airpcap_errbuf[AIRPCAP_ERRBUF_SIZE];
	BOOL status;
	AirpcapLinkType link_type;

	pa->adapter = p_AirpcapOpen(device, airpcap_errbuf);
	if (pa->adapter == NULL) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s", airpcap_errbuf);
		return (PCAP_ERROR);
	}

	/*
	 * Set monitor mode appropriately.
	 * Always turn off the "ACK frames sent to the card" mode.
	 */
	if (p->opt.rfmon) {
		status = p_AirpcapSetDeviceMacFlags(pa->adapter,
		    AIRPCAP_MF_MONITOR_MODE_ON);
	} else
		status = p_AirpcapSetDeviceMacFlags(pa->adapter,
		    AIRPCAP_MF_ACK_FRAMES_ON);
	if (!status) {
		p_AirpcapClose(pa->adapter);
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "AirpcapSetDeviceMacFlags() failed: %s",
		    p_AirpcapGetLastError(pa->adapter));
		return (PCAP_ERROR);
	}

	/*
	 * Turn a negative snapshot value (invalid), a snapshot value of
	 * 0 (unspecified), or a value bigger than the normal maximum
	 * value, into the maximum allowed value.
	 *
	 * If some application really *needs* a bigger snapshot
	 * length, we should just increase MAXIMUM_SNAPLEN.
	 */
	if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
		p->snapshot = MAXIMUM_SNAPLEN;

	/*
	 * If the buffer size wasn't explicitly set, default to
	 * AIRPCAP_DEFAULT_KERNEL_BUFFER_SIZE.
	 */
	if (p->opt.buffer_size == 0)
		p->opt.buffer_size = AIRPCAP_DEFAULT_KERNEL_BUFFER_SIZE;

	if (!p_AirpcapSetKernelBuffer(pa->adapter, p->opt.buffer_size)) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "AirpcapSetKernelBuffer() failed: %s",
		    p_AirpcapGetLastError(pa->adapter));
		goto bad;
	}

	if(!p_AirpcapGetReadEvent(pa->adapter, &pa->read_event)) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "AirpcapGetReadEvent() failed: %s",
		    p_AirpcapGetLastError(pa->adapter));
		goto bad;
	}

	/* Set the buffer size */
	p->bufsize = AIRPCAP_DEFAULT_USER_BUFFER_SIZE;
	p->buffer = malloc(p->bufsize);
	if (p->buffer == NULL) {
		pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
		    errno, "malloc");
		goto bad;
	}

	if (p->opt.immediate) {
		/* Tell the driver to copy the buffer as soon as data arrives. */
		if (!p_AirpcapSetMinToCopy(pa->adapter, 0)) {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "AirpcapSetMinToCopy() failed: %s",
			    p_AirpcapGetLastError(pa->adapter));
			goto bad;
		}
	} else {
		/*
		 * Tell the driver to copy the buffer only if it contains
		 * at least 16K.
		 */
		if (!p_AirpcapSetMinToCopy(pa->adapter, 16000)) {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "AirpcapSetMinToCopy() failed: %s",
			    p_AirpcapGetLastError(pa->adapter));
			goto bad;
		}
	}

	/*
	 * Find out what the default link-layer header type is,
	 * and set p->datalink to that.
	 *
	 * We don't force it to another value because there
	 * might be some programs using WinPcap/Npcap that,
	 * when capturing on AirPcap devices, assume the
	 * default value set with the AirPcap configuration
	 * program is what you get.
	 *
	 * The out-of-the-box default appears to be radiotap.
	 */
	if (!p_AirpcapGetLinkType(pa->adapter, &link_type)) {
		/* That failed. */
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "AirpcapGetLinkType() failed: %s",
		    p_AirpcapGetLastError(pa->adapter));
		goto bad;
	}
	switch (link_type) {

	case AIRPCAP_LT_802_11_PLUS_RADIO:
		p->linktype = DLT_IEEE802_11_RADIO;
		break;

	case AIRPCAP_LT_802_11_PLUS_PPI:
		p->linktype = DLT_PPI;
		break;

	case AIRPCAP_LT_802_11:
		p->linktype = DLT_IEEE802_11;
		break;

	case AIRPCAP_LT_UNKNOWN:
	default:
		/* OK, what? */
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "AirpcapGetLinkType() returned unknown link type %u",
		    link_type);
		goto bad;
	}

	/*
	 * Now provide a list of all the supported types; we
	 * assume they all work.  We put radiotap at the top,
	 * followed by PPI, followed by "no radio metadata".
	 */
	p->dlt_list = (u_int *) malloc(sizeof(u_int) * 3);
	if (p->dlt_list == NULL)
		goto bad;
	p->dlt_list[0] = DLT_IEEE802_11_RADIO;
	p->dlt_list[1] = DLT_PPI;
	p->dlt_list[2] = DLT_IEEE802_11;
	p->dlt_count = 3;

	p->read_op = airpcap_read;
	p->inject_op = airpcap_inject;
	p->setfilter_op = airpcap_setfilter;
	p->setdirection_op = NULL;	/* Not implemented. */
	p->set_datalink_op = airpcap_set_datalink;
	p->getnonblock_op = airpcap_getnonblock;
	p->setnonblock_op = airpcap_setnonblock;
	p->breakloop_op = airpcap_breakloop;
	p->stats_op = airpcap_stats;
	p->stats_ex_op = airpcap_stats_ex;
	p->setbuff_op = airpcap_setbuff;
	p->setmode_op = airpcap_setmode;
	p->setmintocopy_op = airpcap_setmintocopy;
	p->getevent_op = airpcap_getevent;
	p->oid_get_request_op = airpcap_oid_get_request;
	p->oid_set_request_op = airpcap_oid_set_request;
	p->sendqueue_transmit_op = airpcap_sendqueue_transmit;
	p->setuserbuffer_op = airpcap_setuserbuffer;
	p->live_dump_op = airpcap_live_dump;
	p->live_dump_ended_op = airpcap_live_dump_ended;
	p->get_airpcap_handle_op = airpcap_get_airpcap_handle;
	p->cleanup_op = airpcap_cleanup;

	return (0);
 bad:
	airpcap_cleanup(p);
	return (PCAP_ERROR);
}

/*
 * Monitor mode is supported.
 */
static int
airpcap_can_set_rfmon(pcap_t *p)
{
	return (1);
}

int
device_is_airpcap(const char *device, char *ebuf)
{
	static const char airpcap_prefix[] = "\\\\.\\airpcap";

	/*
	 * We don't determine this by calling AirpcapGetDeviceList()
	 * and looking at the list, as that appears to be a costly
	 * operation.
	 *
	 * Instead, we just check whether it begins with "\\.\airpcap".
	 */
	if (strncmp(device, airpcap_prefix, sizeof airpcap_prefix - 1) == 0) {
		/*
		 * Yes, it's an AirPcap device.
		 */
		return (1);
	}

	/*
	 * No, it's not an AirPcap device.
	 */
	return (0);
}

pcap_t *
airpcap_create(const char *device, char *ebuf, int *is_ours)
{
	int ret;
	pcap_t *p;

	/*
	 * This can be called before we've tried loading the library,
	 * so do so if we haven't already tried to do so.
	 */
	if (load_airpcap_functions() != AIRPCAP_API_LOADED) {
		/*
		 * We assume this means that we don't have the AirPcap
		 * software installed, which probably means we don't
		 * have an AirPcap device.
		 *
		 * Don't treat that as an error.
		 */
		*is_ours = 0;
		return (NULL);
	}

	/*
	 * Is this an AirPcap device?
	 */
	ret = device_is_airpcap(device, ebuf);
	if (ret == 0) {
		/* No. */
		*is_ours = 0;
		return (NULL);
	}

	/*
	 * Yes.
	 */
	*is_ours = 1;
	p = PCAP_CREATE_COMMON(ebuf, struct pcap_airpcap);
	if (p == NULL)
		return (NULL);

	p->activate_op = airpcap_activate;
	p->can_set_rfmon_op = airpcap_can_set_rfmon;
	return (p);
}

/*
 * Add all AirPcap devices.
 */
int
airpcap_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
{
	AirpcapDeviceDescription *airpcap_devices, *airpcap_device;
	char airpcap_errbuf[AIRPCAP_ERRBUF_SIZE];

	/*
	 * This can be called before we've tried loading the library,
	 * so do so if we haven't already tried to do so.
	 */
	if (load_airpcap_functions() != AIRPCAP_API_LOADED) {
		/*
		 * XXX - unless the error is "no such DLL", report this
		 * as an error rather than as "no AirPcap devices"?
		 */
		return (0);
	}

	if (!p_AirpcapGetDeviceList(&airpcap_devices, airpcap_errbuf)) {
		snprintf(errbuf, PCAP_ERRBUF_SIZE,
		    "AirpcapGetDeviceList() failed: %s", airpcap_errbuf);
		return (-1);
	}

	for (airpcap_device = airpcap_devices; airpcap_device != NULL;
	    airpcap_device = airpcap_device->next) {
		if (add_dev(devlistp, airpcap_device->Name, 0,
		    airpcap_device->Description, errbuf) == NULL) {
			/*
			 * Failure.
			 */
			p_AirpcapFreeDeviceList(airpcap_devices);
			return (-1);
		}
	}
	p_AirpcapFreeDeviceList(airpcap_devices);
	return (0);
}
