Home | History | Annotate | Line # | Download | only in dist
      1      1.1  christos /*
      2      1.1  christos  * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
      3      1.1  christos  * Copyright (c) 2005 - 2010 CACE Technologies, Davis (California)
      4      1.1  christos  * All rights reserved.
      5      1.1  christos  *
      6      1.1  christos  * Redistribution and use in source and binary forms, with or without
      7      1.1  christos  * modification, are permitted provided that the following conditions
      8      1.1  christos  * are met:
      9      1.1  christos  *
     10      1.1  christos  * 1. Redistributions of source code must retain the above copyright
     11      1.1  christos  * notice, this list of conditions and the following disclaimer.
     12      1.1  christos  * 2. Redistributions in binary form must reproduce the above copyright
     13      1.1  christos  * notice, this list of conditions and the following disclaimer in the
     14      1.1  christos  * documentation and/or other materials provided with the distribution.
     15      1.1  christos  * 3. Neither the name of the Politecnico di Torino, CACE Technologies
     16      1.1  christos  * nor the names of its contributors may be used to endorse or promote
     17      1.1  christos  * products derived from this software without specific prior written
     18      1.1  christos  * permission.
     19      1.1  christos  *
     20      1.1  christos  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21      1.1  christos  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     22      1.1  christos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     23      1.1  christos  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     24      1.1  christos  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     25      1.1  christos  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     26      1.1  christos  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27      1.1  christos  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28      1.1  christos  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29      1.1  christos  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     30      1.1  christos  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31      1.1  christos  *
     32      1.1  christos  */
     33      1.1  christos 
     34      1.1  christos #include <config.h>
     35      1.1  christos 
     36      1.1  christos #include <errno.h>
     37  1.1.1.3  christos #include <limits.h> /* for INT_MAX */
     38      1.1  christos #define PCAP_DONT_INCLUDE_PCAP_BPF_H
     39      1.1  christos #include <Packet32.h>
     40      1.1  christos #include <pcap-int.h>
     41      1.1  christos #include <pcap/dlt.h>
     42      1.1  christos 
     43  1.1.1.3  christos /*
     44  1.1.1.3  christos  * XXX - Packet32.h defines bpf_program, so we can't include
     45  1.1.1.3  christos  * <pcap/bpf.h>, which also defines it; that's why we define
     46  1.1.1.3  christos  * PCAP_DONT_INCLUDE_PCAP_BPF_H,
     47  1.1.1.3  christos  *
     48  1.1.1.3  christos  * However, no header in the WinPcap or Npcap SDKs defines the
     49  1.1.1.3  christos  * macros for BPF code, so we have to define them ourselves.
     50  1.1.1.3  christos  */
     51  1.1.1.3  christos #define		BPF_RET		0x06
     52  1.1.1.3  christos #define		BPF_K		0x00
     53  1.1.1.3  christos 
     54      1.1  christos /* Old-school MinGW have these headers in a different place.
     55      1.1  christos  */
     56      1.1  christos #if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
     57      1.1  christos   #include <ddk/ntddndis.h>
     58      1.1  christos   #include <ddk/ndis.h>
     59      1.1  christos #else
     60      1.1  christos   #include <ntddndis.h>  /* MSVC/TDM-MinGW/MinGW64 */
     61      1.1  christos #endif
     62      1.1  christos 
     63      1.1  christos #ifdef HAVE_DAG_API
     64      1.1  christos   #include <dagnew.h>
     65      1.1  christos   #include <dagapi.h>
     66      1.1  christos #endif /* HAVE_DAG_API */
     67      1.1  christos 
     68  1.1.1.3  christos #include "diag-control.h"
     69  1.1.1.3  christos 
     70  1.1.1.3  christos #include "pcap-airpcap.h"
     71  1.1.1.3  christos 
     72      1.1  christos static int pcap_setfilter_npf(pcap_t *, struct bpf_program *);
     73      1.1  christos static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *);
     74      1.1  christos static int pcap_getnonblock_npf(pcap_t *);
     75      1.1  christos static int pcap_setnonblock_npf(pcap_t *, int);
     76      1.1  christos 
     77      1.1  christos /*dimension of the buffer in the pcap_t structure*/
     78      1.1  christos #define	WIN32_DEFAULT_USER_BUFFER_SIZE 256000
     79      1.1  christos 
     80      1.1  christos /*dimension of the buffer in the kernel driver NPF */
     81      1.1  christos #define	WIN32_DEFAULT_KERNEL_BUFFER_SIZE 1000000
     82      1.1  christos 
     83      1.1  christos /* Equivalent to ntohs(), but a lot faster under Windows */
     84      1.1  christos #define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8)
     85      1.1  christos 
     86      1.1  christos /*
     87  1.1.1.2  christos  * Private data for capturing on WinPcap/Npcap devices.
     88      1.1  christos  */
     89      1.1  christos struct pcap_win {
     90      1.1  christos 	ADAPTER *adapter;		/* the packet32 ADAPTER for the device */
     91      1.1  christos 	int nonblock;
     92      1.1  christos 	int rfmon_selfstart;		/* a flag tells whether the monitor mode is set by itself */
     93      1.1  christos 	int filtering_in_kernel;	/* using kernel filter */
     94      1.1  christos 
     95      1.1  christos #ifdef HAVE_DAG_API
     96      1.1  christos 	int	dag_fcs_bits;		/* Number of checksum bits from link layer */
     97      1.1  christos #endif
     98      1.1  christos 
     99      1.1  christos #ifdef ENABLE_REMOTE
    100      1.1  christos 	int samp_npkt;			/* parameter needed for sampling, with '1 out of N' method has been requested */
    101      1.1  christos 	struct timeval samp_time;	/* parameter needed for sampling, with '1 every N ms' method has been requested */
    102      1.1  christos #endif
    103      1.1  christos };
    104      1.1  christos 
    105      1.1  christos /*
    106      1.1  christos  * Define stub versions of the monitor-mode support routines if this
    107      1.1  christos  * isn't Npcap. HAVE_NPCAP_PACKET_API is defined by Npcap but not
    108      1.1  christos  * WinPcap.
    109      1.1  christos  */
    110      1.1  christos #ifndef HAVE_NPCAP_PACKET_API
    111      1.1  christos static int
    112      1.1  christos PacketIsMonitorModeSupported(PCHAR AdapterName _U_)
    113      1.1  christos {
    114      1.1  christos 	/*
    115      1.1  christos 	 * We don't support monitor mode.
    116      1.1  christos 	 */
    117      1.1  christos 	return (0);
    118      1.1  christos }
    119      1.1  christos 
    120      1.1  christos static int
    121      1.1  christos PacketSetMonitorMode(PCHAR AdapterName _U_, int mode _U_)
    122      1.1  christos {
    123      1.1  christos 	/*
    124      1.1  christos 	 * This should never be called, as PacketIsMonitorModeSupported()
    125      1.1  christos 	 * will return 0, meaning "we don't support monitor mode, so
    126      1.1  christos 	 * don't try to turn it on or off".
    127      1.1  christos 	 */
    128      1.1  christos 	return (0);
    129      1.1  christos }
    130      1.1  christos 
    131      1.1  christos static int
    132      1.1  christos PacketGetMonitorMode(PCHAR AdapterName _U_)
    133      1.1  christos {
    134      1.1  christos 	/*
    135      1.1  christos 	 * This should fail, so that pcap_activate_npf() returns
    136      1.1  christos 	 * PCAP_ERROR_RFMON_NOTSUP if our caller requested monitor
    137      1.1  christos 	 * mode.
    138      1.1  christos 	 */
    139      1.1  christos 	return (-1);
    140      1.1  christos }
    141      1.1  christos #endif
    142      1.1  christos 
    143      1.1  christos /*
    144  1.1.1.4  christos  * If a driver returns an NTSTATUS value:
    145  1.1.1.4  christos  *
    146  1.1.1.4  christos  *    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/87fba13e-bf06-450e-83b1-9241dc81e781
    147  1.1.1.4  christos  *
    148  1.1.1.4  christos  * with the "Customer" bit set, it will not be mapped to a Windows error
    149  1.1.1.4  christos  * value in userland, so it will be returned by GetLastError().
    150  1.1.1.4  christos  *
    151  1.1.1.4  christos  * Note that "driver" here includes the Npcap NPF driver, as various
    152  1.1.1.4  christos  * versions would take NT status values and set the "Customer" bit
    153  1.1.1.4  christos  * before returning the status code.  The commit message for the
    154  1.1.1.4  christos  * change that started doing that is
    155  1.1.1.4  christos  *
    156  1.1.1.4  christos  *    Returned a customer-defined NTSTATUS in OID requests to avoid
    157  1.1.1.4  christos  *    NTSTATUS-to-Win32 Error code translation.
    158  1.1.1.4  christos  *
    159  1.1.1.4  christos  * but I don't know why the goal was to avoid that translation.  For
    160  1.1.1.4  christos  * a while, I suspected that the NT status STATUS_NOT_SUPPORTED was
    161  1.1.1.4  christos  * getting mapped to ERROR_GEN_FAILURE, but, in the cases where
    162  1.1.1.4  christos  * attempts to set promiscuous mode on regular Ethernet devices were
    163  1.1.1.4  christos  * failing with ERROR_GEN_FAILURE, it turns out that the drivers for
    164  1.1.1.4  christos  * those devices were NetAdapterCx drivers, and Microsoft's NetAdapterCx
    165  1.1.1.4  christos  * mechanism wasn't providing the correct "bytes processed" value on
    166  1.1.1.4  christos  * attempts to set OIDs, and the Npcap NPF driver was checking for
    167  1.1.1.4  christos  * that and returning STATUS_UNSUCCESSFUL, which gets mapped to
    168  1.1.1.4  christos  * ERROR_GEN_FAILURE, so perhaps there's no need to avoid that
    169  1.1.1.4  christos  * translation.
    170  1.1.1.4  christos  *
    171  1.1.1.4  christos  * Attempting to set the hardware filter on a Microsoft Surface Pro's
    172  1.1.1.4  christos  * Mobile Broadband Adapter returns an error that appears to be
    173  1.1.1.4  christos  * NDIS_STATUS_NOT_SUPPORTED ORed with the "Customer" bit, so it's
    174  1.1.1.4  christos  * probably indicating that it doesn't support that.  It was probably
    175  1.1.1.4  christos  * the NPF driver setting that bit.
    176  1.1.1.4  christos  */
    177  1.1.1.4  christos #define NT_STATUS_CUSTOMER_DEFINED	0x20000000
    178  1.1.1.4  christos 
    179  1.1.1.4  christos /*
    180  1.1.1.4  christos  * PacketRequest() makes a DeviceIoControl() call to the NPF driver to
    181  1.1.1.4  christos  * perform the OID request, with a BIOCQUERYOID ioctl.  The kernel code
    182  1.1.1.4  christos  * should get back one of NDIS_STATUS_INVALID_OID, NDIS_STATUS_NOT_SUPPORTED,
    183  1.1.1.4  christos  * or NDIS_STATUS_NOT_RECOGNIZED if the OID request isn't supported by
    184  1.1.1.4  christos  * the OS or the driver.
    185  1.1.1.4  christos  *
    186  1.1.1.4  christos  * Currently, that code may be returned by the Npcap NPF driver with the
    187  1.1.1.4  christos  * NT_STATUS_CUSTOMER_DEFINED bit.  That prevents the return status from
    188  1.1.1.4  christos  * being mapped to a Windows error code; if the NPF driver were to stop
    189  1.1.1.4  christos  * ORing in the NT_STATUS_CUSTOMER_DEFINED bit, it's not obvious how those
    190  1.1.1.4  christos  * the NDIS_STATUS_ values that don't correspond to NTSTATUS values would
    191  1.1.1.4  christos  * be translated to Windows error values (NDIS_STATUS_NOT_SUPPORTED is
    192  1.1.1.4  christos  * the same as STATUS_NOT_SUPPORTED, which is an NTSTATUS value that is
    193  1.1.1.4  christos  * mapped to ERROR_NOT_SUPPORTED).
    194      1.1  christos  */
    195      1.1  christos #define NDIS_STATUS_INVALID_OID		0xc0010017
    196      1.1  christos #define NDIS_STATUS_NOT_SUPPORTED	0xc00000bb	/* STATUS_NOT_SUPPORTED */
    197      1.1  christos #define NDIS_STATUS_NOT_RECOGNIZED	0x00010001
    198      1.1  christos 
    199      1.1  christos static int
    200      1.1  christos oid_get_request(ADAPTER *adapter, bpf_u_int32 oid, void *data, size_t *lenp,
    201      1.1  christos     char *errbuf)
    202      1.1  christos {
    203      1.1  christos 	PACKET_OID_DATA *oid_data_arg;
    204      1.1  christos 
    205      1.1  christos 	/*
    206      1.1  christos 	 * Allocate a PACKET_OID_DATA structure to hand to PacketRequest().
    207      1.1  christos 	 * It should be big enough to hold "*lenp" bytes of data; it
    208      1.1  christos 	 * will actually be slightly larger, as PACKET_OID_DATA has a
    209      1.1  christos 	 * 1-byte data array at the end, standing in for the variable-length
    210      1.1  christos 	 * data that's actually there.
    211      1.1  christos 	 */
    212      1.1  christos 	oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp);
    213      1.1  christos 	if (oid_data_arg == NULL) {
    214  1.1.1.3  christos 		snprintf(errbuf, PCAP_ERRBUF_SIZE,
    215      1.1  christos 		    "Couldn't allocate argument buffer for PacketRequest");
    216      1.1  christos 		return (PCAP_ERROR);
    217      1.1  christos 	}
    218      1.1  christos 
    219      1.1  christos 	/*
    220      1.1  christos 	 * No need to copy the data - we're doing a fetch.
    221      1.1  christos 	 */
    222      1.1  christos 	oid_data_arg->Oid = oid;
    223      1.1  christos 	oid_data_arg->Length = (ULONG)(*lenp);	/* XXX - check for ridiculously large value? */
    224      1.1  christos 	if (!PacketRequest(adapter, FALSE, oid_data_arg)) {
    225  1.1.1.4  christos 		pcapint_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
    226  1.1.1.2  christos 		    GetLastError(), "Error calling PacketRequest");
    227      1.1  christos 		free(oid_data_arg);
    228      1.1  christos 		return (-1);
    229      1.1  christos 	}
    230      1.1  christos 
    231      1.1  christos 	/*
    232      1.1  christos 	 * Get the length actually supplied.
    233      1.1  christos 	 */
    234      1.1  christos 	*lenp = oid_data_arg->Length;
    235      1.1  christos 
    236      1.1  christos 	/*
    237      1.1  christos 	 * Copy back the data we fetched.
    238      1.1  christos 	 */
    239      1.1  christos 	memcpy(data, oid_data_arg->Data, *lenp);
    240      1.1  christos 	free(oid_data_arg);
    241      1.1  christos 	return (0);
    242      1.1  christos }
    243      1.1  christos 
    244      1.1  christos static int
    245      1.1  christos pcap_stats_npf(pcap_t *p, struct pcap_stat *ps)
    246      1.1  christos {
    247      1.1  christos 	struct pcap_win *pw = p->priv;
    248      1.1  christos 	struct bpf_stat bstats;
    249      1.1  christos 
    250      1.1  christos 	/*
    251      1.1  christos 	 * Try to get statistics.
    252      1.1  christos 	 *
    253      1.1  christos 	 * (Please note - "struct pcap_stat" is *not* the same as
    254      1.1  christos 	 * WinPcap's "struct bpf_stat". It might currently have the
    255      1.1  christos 	 * same layout, but let's not cheat.
    256      1.1  christos 	 *
    257      1.1  christos 	 * Note also that we don't fill in ps_capt, as we might have
    258      1.1  christos 	 * been called by code compiled against an earlier version of
    259      1.1  christos 	 * WinPcap that didn't have ps_capt, in which case filling it
    260      1.1  christos 	 * in would stomp on whatever comes after the structure passed
    261      1.1  christos 	 * to us.
    262      1.1  christos 	 */
    263      1.1  christos 	if (!PacketGetStats(pw->adapter, &bstats)) {
    264  1.1.1.4  christos 		pcapint_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
    265  1.1.1.2  christos 		    GetLastError(), "PacketGetStats error");
    266      1.1  christos 		return (-1);
    267      1.1  christos 	}
    268      1.1  christos 	ps->ps_recv = bstats.bs_recv;
    269      1.1  christos 	ps->ps_drop = bstats.bs_drop;
    270      1.1  christos 
    271      1.1  christos 	/*
    272      1.1  christos 	 * XXX - PacketGetStats() doesn't fill this in, so we just
    273      1.1  christos 	 * return 0.
    274      1.1  christos 	 */
    275      1.1  christos #if 0
    276      1.1  christos 	ps->ps_ifdrop = bstats.ps_ifdrop;
    277      1.1  christos #else
    278      1.1  christos 	ps->ps_ifdrop = 0;
    279      1.1  christos #endif
    280      1.1  christos 
    281      1.1  christos 	return (0);
    282      1.1  christos }
    283      1.1  christos 
    284      1.1  christos /*
    285      1.1  christos  * Win32-only routine for getting statistics.
    286      1.1  christos  *
    287      1.1  christos  * This way is definitely safer than passing the pcap_stat * from the userland.
    288      1.1  christos  * In fact, there could happen than the user allocates a variable which is not
    289      1.1  christos  * big enough for the new structure, and the library will write in a zone
    290      1.1  christos  * which is not allocated to this variable.
    291      1.1  christos  *
    292      1.1  christos  * In this way, we're pretty sure we are writing on memory allocated to this
    293      1.1  christos  * variable.
    294      1.1  christos  *
    295      1.1  christos  * XXX - but this is the wrong way to handle statistics.  Instead, we should
    296      1.1  christos  * have an API that returns data in a form like the Options section of a
    297      1.1  christos  * pcapng Interface Statistics Block:
    298      1.1  christos  *
    299  1.1.1.3  christos  *    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
    300      1.1  christos  *
    301      1.1  christos  * which would let us add new statistics straightforwardly and indicate which
    302      1.1  christos  * statistics we are and are *not* providing, rather than having to provide
    303      1.1  christos  * possibly-bogus values for statistics we can't provide.
    304      1.1  christos  */
    305  1.1.1.3  christos static struct pcap_stat *
    306      1.1  christos pcap_stats_ex_npf(pcap_t *p, int *pcap_stat_size)
    307      1.1  christos {
    308      1.1  christos 	struct pcap_win *pw = p->priv;
    309      1.1  christos 	struct bpf_stat bstats;
    310      1.1  christos 
    311      1.1  christos 	*pcap_stat_size = sizeof (p->stat);
    312      1.1  christos 
    313      1.1  christos 	/*
    314      1.1  christos 	 * Try to get statistics.
    315      1.1  christos 	 *
    316      1.1  christos 	 * (Please note - "struct pcap_stat" is *not* the same as
    317      1.1  christos 	 * WinPcap's "struct bpf_stat". It might currently have the
    318      1.1  christos 	 * same layout, but let's not cheat.)
    319      1.1  christos 	 */
    320      1.1  christos 	if (!PacketGetStatsEx(pw->adapter, &bstats)) {
    321  1.1.1.4  christos 		pcapint_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
    322  1.1.1.2  christos 		    GetLastError(), "PacketGetStatsEx error");
    323      1.1  christos 		return (NULL);
    324      1.1  christos 	}
    325      1.1  christos 	p->stat.ps_recv = bstats.bs_recv;
    326      1.1  christos 	p->stat.ps_drop = bstats.bs_drop;
    327      1.1  christos 	p->stat.ps_ifdrop = bstats.ps_ifdrop;
    328  1.1.1.3  christos 	/*
    329  1.1.1.3  christos 	 * Just in case this is ever compiled for a target other than
    330  1.1.1.3  christos 	 * Windows, which is somewhere between extremely unlikely and
    331  1.1.1.3  christos 	 * impossible.
    332  1.1.1.3  christos 	 */
    333  1.1.1.3  christos #ifdef _WIN32
    334      1.1  christos 	p->stat.ps_capt = bstats.bs_capt;
    335      1.1  christos #endif
    336      1.1  christos 	return (&p->stat);
    337      1.1  christos }
    338      1.1  christos 
    339      1.1  christos /* Set the dimension of the kernel-level capture buffer */
    340      1.1  christos static int
    341      1.1  christos pcap_setbuff_npf(pcap_t *p, int dim)
    342      1.1  christos {
    343      1.1  christos 	struct pcap_win *pw = p->priv;
    344      1.1  christos 
    345      1.1  christos 	if(PacketSetBuff(pw->adapter,dim)==FALSE)
    346      1.1  christos 	{
    347  1.1.1.3  christos 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
    348      1.1  christos 		return (-1);
    349      1.1  christos 	}
    350      1.1  christos 	return (0);
    351      1.1  christos }
    352      1.1  christos 
    353      1.1  christos /* Set the driver working mode */
    354      1.1  christos static int
    355      1.1  christos pcap_setmode_npf(pcap_t *p, int mode)
    356      1.1  christos {
    357      1.1  christos 	struct pcap_win *pw = p->priv;
    358      1.1  christos 
    359      1.1  christos 	if(PacketSetMode(pw->adapter,mode)==FALSE)
    360      1.1  christos 	{
    361  1.1.1.3  christos 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized");
    362      1.1  christos 		return (-1);
    363      1.1  christos 	}
    364      1.1  christos 
    365      1.1  christos 	return (0);
    366      1.1  christos }
    367      1.1  christos 
    368      1.1  christos /*set the minimum amount of data that will release a read call*/
    369      1.1  christos static int
    370      1.1  christos pcap_setmintocopy_npf(pcap_t *p, int size)
    371      1.1  christos {
    372      1.1  christos 	struct pcap_win *pw = p->priv;
    373      1.1  christos 
    374      1.1  christos 	if(PacketSetMinToCopy(pw->adapter, size)==FALSE)
    375      1.1  christos 	{
    376  1.1.1.3  christos 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size");
    377      1.1  christos 		return (-1);
    378      1.1  christos 	}
    379      1.1  christos 	return (0);
    380      1.1  christos }
    381      1.1  christos 
    382      1.1  christos static HANDLE
    383      1.1  christos pcap_getevent_npf(pcap_t *p)
    384      1.1  christos {
    385      1.1  christos 	struct pcap_win *pw = p->priv;
    386      1.1  christos 
    387      1.1  christos 	return (PacketGetReadEvent(pw->adapter));
    388      1.1  christos }
    389      1.1  christos 
    390      1.1  christos static int
    391      1.1  christos pcap_oid_get_request_npf(pcap_t *p, bpf_u_int32 oid, void *data, size_t *lenp)
    392      1.1  christos {
    393      1.1  christos 	struct pcap_win *pw = p->priv;
    394      1.1  christos 
    395      1.1  christos 	return (oid_get_request(pw->adapter, oid, data, lenp, p->errbuf));
    396      1.1  christos }
    397      1.1  christos 
    398      1.1  christos static int
    399      1.1  christos pcap_oid_set_request_npf(pcap_t *p, bpf_u_int32 oid, const void *data,
    400      1.1  christos     size_t *lenp)
    401      1.1  christos {
    402      1.1  christos 	struct pcap_win *pw = p->priv;
    403      1.1  christos 	PACKET_OID_DATA *oid_data_arg;
    404      1.1  christos 
    405      1.1  christos 	/*
    406      1.1  christos 	 * Allocate a PACKET_OID_DATA structure to hand to PacketRequest().
    407      1.1  christos 	 * It should be big enough to hold "*lenp" bytes of data; it
    408      1.1  christos 	 * will actually be slightly larger, as PACKET_OID_DATA has a
    409      1.1  christos 	 * 1-byte data array at the end, standing in for the variable-length
    410      1.1  christos 	 * data that's actually there.
    411      1.1  christos 	 */
    412      1.1  christos 	oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp);
    413      1.1  christos 	if (oid_data_arg == NULL) {
    414  1.1.1.3  christos 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    415      1.1  christos 		    "Couldn't allocate argument buffer for PacketRequest");
    416      1.1  christos 		return (PCAP_ERROR);
    417      1.1  christos 	}
    418      1.1  christos 
    419      1.1  christos 	oid_data_arg->Oid = oid;
    420      1.1  christos 	oid_data_arg->Length = (ULONG)(*lenp);	/* XXX - check for ridiculously large value? */
    421      1.1  christos 	memcpy(oid_data_arg->Data, data, *lenp);
    422      1.1  christos 	if (!PacketRequest(pw->adapter, TRUE, oid_data_arg)) {
    423  1.1.1.4  christos 		pcapint_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
    424  1.1.1.2  christos 		    GetLastError(), "Error calling PacketRequest");
    425      1.1  christos 		free(oid_data_arg);
    426      1.1  christos 		return (PCAP_ERROR);
    427      1.1  christos 	}
    428      1.1  christos 
    429      1.1  christos 	/*
    430      1.1  christos 	 * Get the length actually copied.
    431      1.1  christos 	 */
    432      1.1  christos 	*lenp = oid_data_arg->Length;
    433      1.1  christos 
    434      1.1  christos 	/*
    435      1.1  christos 	 * No need to copy the data - we're doing a set.
    436      1.1  christos 	 */
    437      1.1  christos 	free(oid_data_arg);
    438      1.1  christos 	return (0);
    439      1.1  christos }
    440      1.1  christos 
    441      1.1  christos static u_int
    442      1.1  christos pcap_sendqueue_transmit_npf(pcap_t *p, pcap_send_queue *queue, int sync)
    443      1.1  christos {
    444      1.1  christos 	struct pcap_win *pw = p->priv;
    445      1.1  christos 	u_int res;
    446      1.1  christos 
    447      1.1  christos 	res = PacketSendPackets(pw->adapter,
    448      1.1  christos 		queue->buffer,
    449      1.1  christos 		queue->len,
    450      1.1  christos 		(BOOLEAN)sync);
    451      1.1  christos 
    452      1.1  christos 	if(res != queue->len){
    453  1.1.1.4  christos 		pcapint_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
    454  1.1.1.3  christos 		    GetLastError(), "Error queueing packets");
    455      1.1  christos 	}
    456      1.1  christos 
    457      1.1  christos 	return (res);
    458      1.1  christos }
    459      1.1  christos 
    460      1.1  christos static int
    461      1.1  christos pcap_setuserbuffer_npf(pcap_t *p, int size)
    462      1.1  christos {
    463      1.1  christos 	unsigned char *new_buff;
    464      1.1  christos 
    465      1.1  christos 	if (size<=0) {
    466      1.1  christos 		/* Bogus parameter */
    467  1.1.1.3  christos 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    468      1.1  christos 		    "Error: invalid size %d",size);
    469      1.1  christos 		return (-1);
    470      1.1  christos 	}
    471      1.1  christos 
    472      1.1  christos 	/* Allocate the buffer */
    473      1.1  christos 	new_buff=(unsigned char*)malloc(sizeof(char)*size);
    474      1.1  christos 
    475      1.1  christos 	if (!new_buff) {
    476  1.1.1.3  christos 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    477      1.1  christos 		    "Error: not enough memory");
    478      1.1  christos 		return (-1);
    479      1.1  christos 	}
    480      1.1  christos 
    481      1.1  christos 	free(p->buffer);
    482      1.1  christos 
    483      1.1  christos 	p->buffer=new_buff;
    484      1.1  christos 	p->bufsize=size;
    485      1.1  christos 
    486      1.1  christos 	return (0);
    487      1.1  christos }
    488      1.1  christos 
    489  1.1.1.3  christos #ifdef HAVE_NPCAP_PACKET_API
    490  1.1.1.3  christos /*
    491  1.1.1.3  christos  * Kernel dump mode isn't supported in Npcap; calls to PacketSetDumpName(),
    492  1.1.1.3  christos  * PacketSetDumpLimits(), and PacketIsDumpEnded() will get compile-time
    493  1.1.1.3  christos  * deprecation warnings.
    494  1.1.1.3  christos  *
    495  1.1.1.3  christos  * Avoid calling them; just return errors indicating that kernel dump
    496  1.1.1.3  christos  * mode isn't supported in Npcap.
    497  1.1.1.3  christos  */
    498  1.1.1.3  christos static int
    499  1.1.1.3  christos pcap_live_dump_npf(pcap_t *p, char *filename _U_, int maxsize _U_,
    500  1.1.1.3  christos     int maxpacks _U_)
    501  1.1.1.3  christos {
    502  1.1.1.3  christos 	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    503  1.1.1.3  christos 	    "Npcap doesn't support kernel dump mode");
    504  1.1.1.3  christos 	return (-1);
    505  1.1.1.3  christos }
    506  1.1.1.3  christos static int
    507  1.1.1.3  christos pcap_live_dump_ended_npf(pcap_t *p, int sync)
    508  1.1.1.3  christos {
    509  1.1.1.3  christos 	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    510  1.1.1.3  christos 	    "Npcap doesn't support kernel dump mode");
    511  1.1.1.3  christos 	return (-1);
    512  1.1.1.3  christos }
    513  1.1.1.3  christos #else /* HAVE_NPCAP_PACKET_API */
    514      1.1  christos static int
    515      1.1  christos pcap_live_dump_npf(pcap_t *p, char *filename, int maxsize, int maxpacks)
    516      1.1  christos {
    517      1.1  christos 	struct pcap_win *pw = p->priv;
    518      1.1  christos 	BOOLEAN res;
    519      1.1  christos 
    520      1.1  christos 	/* Set the packet driver in dump mode */
    521      1.1  christos 	res = PacketSetMode(pw->adapter, PACKET_MODE_DUMP);
    522      1.1  christos 	if(res == FALSE){
    523  1.1.1.3  christos 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    524      1.1  christos 		    "Error setting dump mode");
    525      1.1  christos 		return (-1);
    526      1.1  christos 	}
    527      1.1  christos 
    528      1.1  christos 	/* Set the name of the dump file */
    529      1.1  christos 	res = PacketSetDumpName(pw->adapter, filename, (int)strlen(filename));
    530      1.1  christos 	if(res == FALSE){
    531  1.1.1.3  christos 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    532      1.1  christos 		    "Error setting kernel dump file name");
    533      1.1  christos 		return (-1);
    534      1.1  christos 	}
    535      1.1  christos 
    536      1.1  christos 	/* Set the limits of the dump file */
    537      1.1  christos 	res = PacketSetDumpLimits(pw->adapter, maxsize, maxpacks);
    538      1.1  christos 	if(res == FALSE) {
    539  1.1.1.3  christos 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    540  1.1.1.3  christos 				"Error setting dump limit");
    541      1.1  christos 		return (-1);
    542      1.1  christos 	}
    543      1.1  christos 
    544      1.1  christos 	return (0);
    545      1.1  christos }
    546      1.1  christos 
    547      1.1  christos static int
    548      1.1  christos pcap_live_dump_ended_npf(pcap_t *p, int sync)
    549      1.1  christos {
    550      1.1  christos 	struct pcap_win *pw = p->priv;
    551      1.1  christos 
    552      1.1  christos 	return (PacketIsDumpEnded(pw->adapter, (BOOLEAN)sync));
    553      1.1  christos }
    554  1.1.1.3  christos #endif /* HAVE_NPCAP_PACKET_API */
    555      1.1  christos 
    556  1.1.1.3  christos #ifdef HAVE_AIRPCAP_API
    557      1.1  christos static PAirpcapHandle
    558      1.1  christos pcap_get_airpcap_handle_npf(pcap_t *p)
    559      1.1  christos {
    560      1.1  christos 	struct pcap_win *pw = p->priv;
    561      1.1  christos 
    562      1.1  christos 	return (PacketGetAirPcapHandle(pw->adapter));
    563  1.1.1.3  christos }
    564  1.1.1.3  christos #else /* HAVE_AIRPCAP_API */
    565  1.1.1.3  christos static PAirpcapHandle
    566  1.1.1.3  christos pcap_get_airpcap_handle_npf(pcap_t *p _U_)
    567  1.1.1.3  christos {
    568      1.1  christos 	return (NULL);
    569      1.1  christos }
    570  1.1.1.3  christos #endif /* HAVE_AIRPCAP_API */
    571      1.1  christos 
    572      1.1  christos static int
    573      1.1  christos pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
    574      1.1  christos {
    575      1.1  christos 	PACKET Packet;
    576      1.1  christos 	int cc;
    577  1.1.1.3  christos 	int n;
    578      1.1  christos 	register u_char *bp, *ep;
    579      1.1  christos 	u_char *datap;
    580      1.1  christos 	struct pcap_win *pw = p->priv;
    581      1.1  christos 
    582      1.1  christos 	cc = p->cc;
    583  1.1.1.3  christos 	if (cc == 0) {
    584      1.1  christos 		/*
    585      1.1  christos 		 * Has "pcap_breakloop()" been called?
    586      1.1  christos 		 */
    587      1.1  christos 		if (p->break_loop) {
    588      1.1  christos 			/*
    589      1.1  christos 			 * Yes - clear the flag that indicates that it
    590      1.1  christos 			 * has, and return PCAP_ERROR_BREAK to indicate
    591      1.1  christos 			 * that we were told to break out of the loop.
    592      1.1  christos 			 */
    593      1.1  christos 			p->break_loop = 0;
    594      1.1  christos 			return (PCAP_ERROR_BREAK);
    595      1.1  christos 		}
    596      1.1  christos 
    597      1.1  christos 		/*
    598      1.1  christos 		 * Capture the packets.
    599      1.1  christos 		 *
    600      1.1  christos 		 * The PACKET structure had a bunch of extra stuff for
    601      1.1  christos 		 * Windows 9x/Me, but the only interesting data in it
    602      1.1  christos 		 * in the versions of Windows that we support is just
    603      1.1  christos 		 * a copy of p->buffer, a copy of p->buflen, and the
    604      1.1  christos 		 * actual number of bytes read returned from
    605      1.1  christos 		 * PacketReceivePacket(), none of which has to be
    606      1.1  christos 		 * retained from call to call, so we just keep one on
    607      1.1  christos 		 * the stack.
    608      1.1  christos 		 */
    609      1.1  christos 		PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
    610      1.1  christos 		if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
    611  1.1.1.2  christos 			/*
    612  1.1.1.2  christos 			 * Did the device go away?
    613  1.1.1.3  christos 			 * If so, the error we get can either be
    614  1.1.1.3  christos 			 * ERROR_GEN_FAILURE or ERROR_DEVICE_REMOVED.
    615  1.1.1.2  christos 			 */
    616  1.1.1.2  christos 			DWORD errcode = GetLastError();
    617  1.1.1.2  christos 
    618  1.1.1.3  christos 			if (errcode == ERROR_GEN_FAILURE ||
    619  1.1.1.3  christos 			    errcode == ERROR_DEVICE_REMOVED) {
    620  1.1.1.2  christos 				/*
    621  1.1.1.2  christos 				 * The device on which we're capturing
    622  1.1.1.2  christos 				 * went away, or it became unusable
    623  1.1.1.2  christos 				 * by NPF due to a suspend/resume.
    624  1.1.1.2  christos 				 *
    625  1.1.1.3  christos 				 * ERROR_GEN_FAILURE comes from
    626  1.1.1.3  christos 				 * STATUS_UNSUCCESSFUL, as well as some
    627  1.1.1.3  christos 				 * other NT status codes that the Npcap
    628  1.1.1.3  christos 				 * driver is unlikely to return.
    629  1.1.1.2  christos 				 * XXX - hopefully no other error
    630  1.1.1.2  christos 				 * conditions are indicated by this.
    631  1.1.1.2  christos 				 *
    632  1.1.1.3  christos 				 * ERROR_DEVICE_REMOVED comes from
    633  1.1.1.3  christos 				 * STATUS_DEVICE_REMOVED.
    634  1.1.1.3  christos 				 *
    635  1.1.1.3  christos 				 * We report the Windows status code
    636  1.1.1.3  christos 				 * name and the corresponding NT status
    637  1.1.1.3  christos 				 * code name, for the benefit of attempts
    638  1.1.1.3  christos 				 * to debug cases where this error is
    639  1.1.1.3  christos 				 * reported when the device *wasn't*
    640  1.1.1.3  christos 				 * removed, either because it's not
    641  1.1.1.3  christos 				 * removable, it's removable but wasn't
    642  1.1.1.3  christos 				 * removed, or it's a device that doesn't
    643  1.1.1.3  christos 				 * correspond to a physical device.
    644  1.1.1.3  christos 				 *
    645  1.1.1.2  christos 				 * XXX - we really should return an
    646  1.1.1.2  christos 				 * appropriate error for that, but
    647  1.1.1.2  christos 				 * pcap_dispatch() etc. aren't
    648  1.1.1.2  christos 				 * documented as having error returns
    649  1.1.1.2  christos 				 * other than PCAP_ERROR or PCAP_ERROR_BREAK.
    650  1.1.1.2  christos 				 */
    651  1.1.1.3  christos 				const char *errcode_msg;
    652  1.1.1.3  christos 
    653  1.1.1.3  christos 				if (errcode == ERROR_GEN_FAILURE)
    654  1.1.1.3  christos 					errcode_msg = "ERROR_GEN_FAILURE/STATUS_UNSUCCESSFUL";
    655  1.1.1.3  christos 				else
    656  1.1.1.3  christos 					errcode_msg = "ERROR_DEVICE_REMOVED/STATUS_DEVICE_REMOVED";
    657  1.1.1.3  christos 				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    658  1.1.1.3  christos 				    "The interface disappeared (error code %s)",
    659  1.1.1.3  christos 				    errcode_msg);
    660  1.1.1.2  christos 			} else {
    661  1.1.1.4  christos 				pcapint_fmt_errmsg_for_win32_err(p->errbuf,
    662  1.1.1.2  christos 				    PCAP_ERRBUF_SIZE, errcode,
    663  1.1.1.2  christos 				    "PacketReceivePacket error");
    664  1.1.1.2  christos 			}
    665      1.1  christos 			return (PCAP_ERROR);
    666      1.1  christos 		}
    667      1.1  christos 
    668      1.1  christos 		cc = Packet.ulBytesReceived;
    669      1.1  christos 
    670      1.1  christos 		bp = p->buffer;
    671      1.1  christos 	}
    672      1.1  christos 	else
    673      1.1  christos 		bp = p->bp;
    674      1.1  christos 
    675      1.1  christos 	/*
    676      1.1  christos 	 * Loop through each packet.
    677  1.1.1.3  christos 	 *
    678  1.1.1.3  christos 	 * This assumes that a single buffer of packets will have
    679  1.1.1.3  christos 	 * <= INT_MAX packets, so the packet count doesn't overflow.
    680      1.1  christos 	 */
    681      1.1  christos #define bhp ((struct bpf_hdr *)bp)
    682  1.1.1.3  christos 	n = 0;
    683      1.1  christos 	ep = bp + cc;
    684      1.1  christos 	for (;;) {
    685  1.1.1.3  christos 		register u_int caplen, hdrlen;
    686      1.1  christos 
    687      1.1  christos 		/*
    688      1.1  christos 		 * Has "pcap_breakloop()" been called?
    689      1.1  christos 		 * If so, return immediately - if we haven't read any
    690      1.1  christos 		 * packets, clear the flag and return PCAP_ERROR_BREAK
    691      1.1  christos 		 * to indicate that we were told to break out of the loop,
    692      1.1  christos 		 * otherwise leave the flag set, so that the *next* call
    693      1.1  christos 		 * will break out of the loop without having read any
    694      1.1  christos 		 * packets, and return the number of packets we've
    695      1.1  christos 		 * processed so far.
    696      1.1  christos 		 */
    697      1.1  christos 		if (p->break_loop) {
    698      1.1  christos 			if (n == 0) {
    699      1.1  christos 				p->break_loop = 0;
    700      1.1  christos 				return (PCAP_ERROR_BREAK);
    701      1.1  christos 			} else {
    702      1.1  christos 				p->bp = bp;
    703      1.1  christos 				p->cc = (int) (ep - bp);
    704      1.1  christos 				return (n);
    705      1.1  christos 			}
    706      1.1  christos 		}
    707      1.1  christos 		if (bp >= ep)
    708      1.1  christos 			break;
    709      1.1  christos 
    710      1.1  christos 		caplen = bhp->bh_caplen;
    711      1.1  christos 		hdrlen = bhp->bh_hdrlen;
    712      1.1  christos 		datap = bp + hdrlen;
    713      1.1  christos 
    714      1.1  christos 		/*
    715      1.1  christos 		 * Short-circuit evaluation: if using BPF filter
    716      1.1  christos 		 * in kernel, no need to do it now - we already know
    717      1.1  christos 		 * the packet passed the filter.
    718      1.1  christos 		 *
    719  1.1.1.4  christos 		 * XXX - pcapint_filter() should always return TRUE if
    720      1.1  christos 		 * handed a null pointer for the program, but it might
    721      1.1  christos 		 * just try to "run" the filter, so we check here.
    722      1.1  christos 		 */
    723      1.1  christos 		if (pw->filtering_in_kernel ||
    724      1.1  christos 		    p->fcode.bf_insns == NULL ||
    725  1.1.1.4  christos 		    pcapint_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) {
    726      1.1  christos #ifdef ENABLE_REMOTE
    727      1.1  christos 			switch (p->rmt_samp.method) {
    728      1.1  christos 
    729      1.1  christos 			case PCAP_SAMP_1_EVERY_N:
    730      1.1  christos 				pw->samp_npkt = (pw->samp_npkt + 1) % p->rmt_samp.value;
    731      1.1  christos 
    732      1.1  christos 				/* Discard all packets that are not '1 out of N' */
    733      1.1  christos 				if (pw->samp_npkt != 0) {
    734      1.1  christos 					bp += Packet_WORDALIGN(caplen + hdrlen);
    735      1.1  christos 					continue;
    736      1.1  christos 				}
    737      1.1  christos 				break;
    738      1.1  christos 
    739      1.1  christos 			case PCAP_SAMP_FIRST_AFTER_N_MS:
    740      1.1  christos 			    {
    741      1.1  christos 				struct pcap_pkthdr *pkt_header = (struct pcap_pkthdr*) bp;
    742      1.1  christos 
    743      1.1  christos 				/*
    744      1.1  christos 				 * Check if the timestamp of the arrived
    745      1.1  christos 				 * packet is smaller than our target time.
    746      1.1  christos 				 */
    747      1.1  christos 				if (pkt_header->ts.tv_sec < pw->samp_time.tv_sec ||
    748      1.1  christos 				   (pkt_header->ts.tv_sec == pw->samp_time.tv_sec && pkt_header->ts.tv_usec < pw->samp_time.tv_usec)) {
    749      1.1  christos 					bp += Packet_WORDALIGN(caplen + hdrlen);
    750      1.1  christos 					continue;
    751      1.1  christos 				}
    752      1.1  christos 
    753      1.1  christos 				/*
    754      1.1  christos 				 * The arrived packet is suitable for being
    755      1.1  christos 				 * delivered to our caller, so let's update
    756      1.1  christos 				 * the target time.
    757      1.1  christos 				 */
    758      1.1  christos 				pw->samp_time.tv_usec = pkt_header->ts.tv_usec + p->rmt_samp.value * 1000;
    759      1.1  christos 				if (pw->samp_time.tv_usec > 1000000) {
    760      1.1  christos 					pw->samp_time.tv_sec = pkt_header->ts.tv_sec + pw->samp_time.tv_usec / 1000000;
    761      1.1  christos 					pw->samp_time.tv_usec = pw->samp_time.tv_usec % 1000000;
    762      1.1  christos 				}
    763      1.1  christos 			    }
    764      1.1  christos 			}
    765      1.1  christos #endif	/* ENABLE_REMOTE */
    766      1.1  christos 
    767      1.1  christos 			/*
    768      1.1  christos 			 * XXX A bpf_hdr matches a pcap_pkthdr.
    769      1.1  christos 			 */
    770      1.1  christos 			(*callback)(user, (struct pcap_pkthdr*)bp, datap);
    771      1.1  christos 			bp += Packet_WORDALIGN(caplen + hdrlen);
    772      1.1  christos 			if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) {
    773      1.1  christos 				p->bp = bp;
    774      1.1  christos 				p->cc = (int) (ep - bp);
    775      1.1  christos 				return (n);
    776      1.1  christos 			}
    777      1.1  christos 		} else {
    778      1.1  christos 			/*
    779      1.1  christos 			 * Skip this packet.
    780      1.1  christos 			 */
    781      1.1  christos 			bp += Packet_WORDALIGN(caplen + hdrlen);
    782      1.1  christos 		}
    783      1.1  christos 	}
    784      1.1  christos #undef bhp
    785      1.1  christos 	p->cc = 0;
    786      1.1  christos 	return (n);
    787      1.1  christos }
    788      1.1  christos 
    789      1.1  christos #ifdef HAVE_DAG_API
    790      1.1  christos static int
    791      1.1  christos pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
    792      1.1  christos {
    793      1.1  christos 	struct pcap_win *pw = p->priv;
    794      1.1  christos 	PACKET Packet;
    795      1.1  christos 	u_char *dp = NULL;
    796      1.1  christos 	int	packet_len = 0, caplen = 0;
    797      1.1  christos 	struct pcap_pkthdr	pcap_header;
    798      1.1  christos 	u_char *endofbuf;
    799      1.1  christos 	int n = 0;
    800      1.1  christos 	dag_record_t *header;
    801      1.1  christos 	unsigned erf_record_len;
    802      1.1  christos 	ULONGLONG ts;
    803      1.1  christos 	int cc;
    804      1.1  christos 	unsigned swt;
    805      1.1  christos 	unsigned dfp = pw->adapter->DagFastProcess;
    806      1.1  christos 
    807      1.1  christos 	cc = p->cc;
    808      1.1  christos 	if (cc == 0) /* Get new packets only if we have processed all the ones of the previous read */
    809      1.1  christos 	{
    810      1.1  christos 		/*
    811      1.1  christos 		 * Get new packets from the network.
    812      1.1  christos 		 *
    813      1.1  christos 		 * The PACKET structure had a bunch of extra stuff for
    814      1.1  christos 		 * Windows 9x/Me, but the only interesting data in it
    815      1.1  christos 		 * in the versions of Windows that we support is just
    816      1.1  christos 		 * a copy of p->buffer, a copy of p->buflen, and the
    817      1.1  christos 		 * actual number of bytes read returned from
    818      1.1  christos 		 * PacketReceivePacket(), none of which has to be
    819      1.1  christos 		 * retained from call to call, so we just keep one on
    820      1.1  christos 		 * the stack.
    821      1.1  christos 		 */
    822      1.1  christos 		PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
    823      1.1  christos 		if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
    824  1.1.1.3  christos 			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
    825      1.1  christos 			return (-1);
    826      1.1  christos 		}
    827      1.1  christos 
    828      1.1  christos 		cc = Packet.ulBytesReceived;
    829      1.1  christos 		if(cc == 0)
    830      1.1  christos 			/* The timeout has expired but we no packets arrived */
    831      1.1  christos 			return (0);
    832      1.1  christos 		header = (dag_record_t*)pw->adapter->DagBuffer;
    833      1.1  christos 	}
    834      1.1  christos 	else
    835      1.1  christos 		header = (dag_record_t*)p->bp;
    836      1.1  christos 
    837      1.1  christos 	endofbuf = (char*)header + cc;
    838      1.1  christos 
    839      1.1  christos 	/*
    840  1.1.1.3  christos 	 * This can conceivably process more than INT_MAX packets,
    841  1.1.1.3  christos 	 * which would overflow the packet count, causing it either
    842  1.1.1.3  christos 	 * to look like a negative number, and thus cause us to
    843  1.1.1.3  christos 	 * return a value that looks like an error, or overflow
    844  1.1.1.3  christos 	 * back into positive territory, and thus cause us to
    845  1.1.1.3  christos 	 * return a too-low count.
    846  1.1.1.3  christos 	 *
    847  1.1.1.3  christos 	 * Therefore, if the packet count is unlimited, we clip
    848  1.1.1.3  christos 	 * it at INT_MAX; this routine is not expected to
    849  1.1.1.3  christos 	 * process packets indefinitely, so that's not an issue.
    850  1.1.1.3  christos 	 */
    851  1.1.1.3  christos 	if (PACKET_COUNT_IS_UNLIMITED(cnt))
    852  1.1.1.3  christos 		cnt = INT_MAX;
    853  1.1.1.3  christos 
    854  1.1.1.3  christos 	/*
    855      1.1  christos 	 * Cycle through the packets
    856      1.1  christos 	 */
    857      1.1  christos 	do
    858      1.1  christos 	{
    859      1.1  christos 		erf_record_len = SWAPS(header->rlen);
    860      1.1  christos 		if((char*)header + erf_record_len > endofbuf)
    861      1.1  christos 			break;
    862      1.1  christos 
    863      1.1  christos 		/* Increase the number of captured packets */
    864      1.1  christos 		p->stat.ps_recv++;
    865      1.1  christos 
    866      1.1  christos 		/* Find the beginning of the packet */
    867      1.1  christos 		dp = ((u_char *)header) + dag_record_size;
    868      1.1  christos 
    869      1.1  christos 		/* Determine actual packet len */
    870      1.1  christos 		switch(header->type)
    871      1.1  christos 		{
    872      1.1  christos 		case TYPE_ATM:
    873      1.1  christos 			packet_len = ATM_SNAPLEN;
    874      1.1  christos 			caplen = ATM_SNAPLEN;
    875      1.1  christos 			dp += 4;
    876      1.1  christos 
    877      1.1  christos 			break;
    878      1.1  christos 
    879      1.1  christos 		case TYPE_ETH:
    880      1.1  christos 			swt = SWAPS(header->wlen);
    881      1.1  christos 			packet_len = swt - (pw->dag_fcs_bits);
    882      1.1  christos 			caplen = erf_record_len - dag_record_size - 2;
    883      1.1  christos 			if (caplen > packet_len)
    884      1.1  christos 			{
    885      1.1  christos 				caplen = packet_len;
    886      1.1  christos 			}
    887      1.1  christos 			dp += 2;
    888      1.1  christos 
    889      1.1  christos 			break;
    890      1.1  christos 
    891      1.1  christos 		case TYPE_HDLC_POS:
    892      1.1  christos 			swt = SWAPS(header->wlen);
    893      1.1  christos 			packet_len = swt - (pw->dag_fcs_bits);
    894      1.1  christos 			caplen = erf_record_len - dag_record_size;
    895      1.1  christos 			if (caplen > packet_len)
    896      1.1  christos 			{
    897      1.1  christos 				caplen = packet_len;
    898      1.1  christos 			}
    899      1.1  christos 
    900      1.1  christos 			break;
    901      1.1  christos 		}
    902      1.1  christos 
    903      1.1  christos 		if(caplen > p->snapshot)
    904      1.1  christos 			caplen = p->snapshot;
    905      1.1  christos 
    906      1.1  christos 		/*
    907      1.1  christos 		 * Has "pcap_breakloop()" been called?
    908      1.1  christos 		 * If so, return immediately - if we haven't read any
    909      1.1  christos 		 * packets, clear the flag and return -2 to indicate
    910      1.1  christos 		 * that we were told to break out of the loop, otherwise
    911      1.1  christos 		 * leave the flag set, so that the *next* call will break
    912      1.1  christos 		 * out of the loop without having read any packets, and
    913      1.1  christos 		 * return the number of packets we've processed so far.
    914      1.1  christos 		 */
    915      1.1  christos 		if (p->break_loop)
    916      1.1  christos 		{
    917      1.1  christos 			if (n == 0)
    918      1.1  christos 			{
    919      1.1  christos 				p->break_loop = 0;
    920      1.1  christos 				return (-2);
    921      1.1  christos 			}
    922      1.1  christos 			else
    923      1.1  christos 			{
    924      1.1  christos 				p->bp = (char*)header;
    925      1.1  christos 				p->cc = endofbuf - (char*)header;
    926      1.1  christos 				return (n);
    927      1.1  christos 			}
    928      1.1  christos 		}
    929      1.1  christos 
    930      1.1  christos 		if(!dfp)
    931      1.1  christos 		{
    932      1.1  christos 			/* convert between timestamp formats */
    933      1.1  christos 			ts = header->ts;
    934      1.1  christos 			pcap_header.ts.tv_sec = (int)(ts >> 32);
    935      1.1  christos 			ts = (ts & 0xffffffffi64) * 1000000;
    936      1.1  christos 			ts += 0x80000000; /* rounding */
    937      1.1  christos 			pcap_header.ts.tv_usec = (int)(ts >> 32);
    938      1.1  christos 			if (pcap_header.ts.tv_usec >= 1000000) {
    939      1.1  christos 				pcap_header.ts.tv_usec -= 1000000;
    940      1.1  christos 				pcap_header.ts.tv_sec++;
    941      1.1  christos 			}
    942      1.1  christos 		}
    943      1.1  christos 
    944  1.1.1.3  christos 		/* No underlying filtering system. We need to filter on our own */
    945      1.1  christos 		if (p->fcode.bf_insns)
    946      1.1  christos 		{
    947  1.1.1.4  christos 			if (pcapint_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0)
    948      1.1  christos 			{
    949      1.1  christos 				/* Move to next packet */
    950      1.1  christos 				header = (dag_record_t*)((char*)header + erf_record_len);
    951      1.1  christos 				continue;
    952      1.1  christos 			}
    953      1.1  christos 		}
    954      1.1  christos 
    955  1.1.1.3  christos 		/* Fill the header for the user supplied callback function */
    956      1.1  christos 		pcap_header.caplen = caplen;
    957      1.1  christos 		pcap_header.len = packet_len;
    958      1.1  christos 
    959      1.1  christos 		/* Call the callback function */
    960      1.1  christos 		(*callback)(user, &pcap_header, dp);
    961      1.1  christos 
    962      1.1  christos 		/* Move to next packet */
    963      1.1  christos 		header = (dag_record_t*)((char*)header + erf_record_len);
    964      1.1  christos 
    965      1.1  christos 		/* Stop if the number of packets requested by user has been reached*/
    966      1.1  christos 		if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt))
    967      1.1  christos 		{
    968      1.1  christos 			p->bp = (char*)header;
    969      1.1  christos 			p->cc = endofbuf - (char*)header;
    970      1.1  christos 			return (n);
    971      1.1  christos 		}
    972      1.1  christos 	}
    973      1.1  christos 	while((u_char*)header < endofbuf);
    974      1.1  christos 
    975      1.1  christos 	return (1);
    976      1.1  christos }
    977      1.1  christos #endif /* HAVE_DAG_API */
    978      1.1  christos 
    979      1.1  christos /* Send a packet to the network */
    980      1.1  christos static int
    981  1.1.1.3  christos pcap_inject_npf(pcap_t *p, const void *buf, int size)
    982      1.1  christos {
    983      1.1  christos 	struct pcap_win *pw = p->priv;
    984      1.1  christos 	PACKET pkt;
    985      1.1  christos 
    986      1.1  christos 	PacketInitPacket(&pkt, (PVOID)buf, size);
    987      1.1  christos 	if(PacketSendPacket(pw->adapter,&pkt,TRUE) == FALSE) {
    988  1.1.1.4  christos 		pcapint_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
    989  1.1.1.3  christos 		    GetLastError(), "send error: PacketSendPacket failed");
    990      1.1  christos 		return (-1);
    991      1.1  christos 	}
    992      1.1  christos 
    993      1.1  christos 	/*
    994      1.1  christos 	 * We assume it all got sent if "PacketSendPacket()" succeeded.
    995      1.1  christos 	 * "pcap_inject()" is expected to return the number of bytes
    996      1.1  christos 	 * sent.
    997      1.1  christos 	 */
    998  1.1.1.3  christos 	return (size);
    999      1.1  christos }
   1000      1.1  christos 
   1001      1.1  christos static void
   1002      1.1  christos pcap_cleanup_npf(pcap_t *p)
   1003      1.1  christos {
   1004      1.1  christos 	struct pcap_win *pw = p->priv;
   1005      1.1  christos 
   1006      1.1  christos 	if (pw->adapter != NULL) {
   1007      1.1  christos 		PacketCloseAdapter(pw->adapter);
   1008      1.1  christos 		pw->adapter = NULL;
   1009      1.1  christos 	}
   1010      1.1  christos 	if (pw->rfmon_selfstart)
   1011      1.1  christos 	{
   1012      1.1  christos 		PacketSetMonitorMode(p->opt.device, 0);
   1013      1.1  christos 	}
   1014  1.1.1.4  christos 	pcapint_cleanup_live_common(p);
   1015      1.1  christos }
   1016      1.1  christos 
   1017  1.1.1.3  christos static void
   1018  1.1.1.3  christos pcap_breakloop_npf(pcap_t *p)
   1019  1.1.1.3  christos {
   1020  1.1.1.4  christos 	pcapint_breakloop_common(p);
   1021  1.1.1.3  christos 	struct pcap_win *pw = p->priv;
   1022  1.1.1.3  christos 
   1023  1.1.1.3  christos 	/* XXX - what if this fails? */
   1024  1.1.1.3  christos 	SetEvent(PacketGetReadEvent(pw->adapter));
   1025  1.1.1.3  christos }
   1026  1.1.1.3  christos 
   1027      1.1  christos static int
   1028      1.1  christos pcap_activate_npf(pcap_t *p)
   1029      1.1  christos {
   1030      1.1  christos 	struct pcap_win *pw = p->priv;
   1031      1.1  christos 	NetType type;
   1032      1.1  christos 	int res;
   1033  1.1.1.2  christos 	int status = 0;
   1034  1.1.1.3  christos 	struct bpf_insn total_insn;
   1035  1.1.1.3  christos 	struct bpf_program total_prog;
   1036      1.1  christos 
   1037      1.1  christos 	if (p->opt.rfmon) {
   1038      1.1  christos 		/*
   1039      1.1  christos 		 * Monitor mode is supported on Windows Vista and later.
   1040      1.1  christos 		 */
   1041      1.1  christos 		if (PacketGetMonitorMode(p->opt.device) == 1)
   1042      1.1  christos 		{
   1043      1.1  christos 			pw->rfmon_selfstart = 0;
   1044      1.1  christos 		}
   1045      1.1  christos 		else
   1046      1.1  christos 		{
   1047      1.1  christos 			if ((res = PacketSetMonitorMode(p->opt.device, 1)) != 1)
   1048      1.1  christos 			{
   1049      1.1  christos 				pw->rfmon_selfstart = 0;
   1050      1.1  christos 				// Monitor mode is not supported.
   1051      1.1  christos 				if (res == 0)
   1052      1.1  christos 				{
   1053      1.1  christos 					return PCAP_ERROR_RFMON_NOTSUP;
   1054      1.1  christos 				}
   1055      1.1  christos 				else
   1056      1.1  christos 				{
   1057      1.1  christos 					return PCAP_ERROR;
   1058      1.1  christos 				}
   1059      1.1  christos 			}
   1060      1.1  christos 			else
   1061      1.1  christos 			{
   1062      1.1  christos 				pw->rfmon_selfstart = 1;
   1063      1.1  christos 			}
   1064      1.1  christos 		}
   1065      1.1  christos 	}
   1066      1.1  christos 
   1067  1.1.1.3  christos 	/* Init Winsock if it hasn't already been initialized */
   1068      1.1  christos 	pcap_wsockinit();
   1069      1.1  christos 
   1070      1.1  christos 	pw->adapter = PacketOpenAdapter(p->opt.device);
   1071      1.1  christos 
   1072      1.1  christos 	if (pw->adapter == NULL)
   1073      1.1  christos 	{
   1074  1.1.1.2  christos 		DWORD errcode = GetLastError();
   1075  1.1.1.2  christos 
   1076  1.1.1.2  christos 		/*
   1077  1.1.1.2  christos 		 * What error did we get when trying to open the adapter?
   1078  1.1.1.2  christos 		 */
   1079  1.1.1.3  christos 		switch (errcode) {
   1080  1.1.1.3  christos 
   1081  1.1.1.3  christos 		case ERROR_BAD_UNIT:
   1082  1.1.1.2  christos 			/*
   1083  1.1.1.2  christos 			 * There's no such device.
   1084  1.1.1.3  christos 			 * There's nothing to add, so clear the error
   1085  1.1.1.3  christos 			 * message.
   1086  1.1.1.2  christos 			 */
   1087  1.1.1.3  christos 			p->errbuf[0] = '\0';
   1088  1.1.1.2  christos 			return (PCAP_ERROR_NO_SUCH_DEVICE);
   1089  1.1.1.3  christos 
   1090  1.1.1.3  christos 		case ERROR_ACCESS_DENIED:
   1091  1.1.1.3  christos 			/*
   1092  1.1.1.3  christos 			 * There is, but we don't have permission to
   1093  1.1.1.3  christos 			 * use it.
   1094  1.1.1.3  christos 			 *
   1095  1.1.1.3  christos 			 * XXX - we currently get ERROR_BAD_UNIT if the
   1096  1.1.1.3  christos 			 * user says "no" to the UAC prompt.
   1097  1.1.1.3  christos 			 */
   1098  1.1.1.3  christos 			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
   1099  1.1.1.3  christos 			    "The helper program for \"Admin-only Mode\" must be allowed to make changes to your device");
   1100  1.1.1.3  christos 			return (PCAP_ERROR_PERM_DENIED);
   1101  1.1.1.3  christos 
   1102  1.1.1.3  christos 		default:
   1103  1.1.1.2  christos 			/*
   1104  1.1.1.2  christos 			 * Unknown - report details.
   1105  1.1.1.2  christos 			 */
   1106  1.1.1.4  christos 			pcapint_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
   1107  1.1.1.2  christos 			    errcode, "Error opening adapter");
   1108  1.1.1.2  christos 			if (pw->rfmon_selfstart)
   1109  1.1.1.2  christos 			{
   1110  1.1.1.2  christos 				PacketSetMonitorMode(p->opt.device, 0);
   1111  1.1.1.2  christos 			}
   1112  1.1.1.2  christos 			return (PCAP_ERROR);
   1113      1.1  christos 		}
   1114      1.1  christos 	}
   1115      1.1  christos 
   1116      1.1  christos 	/*get network type*/
   1117      1.1  christos 	if(PacketGetNetType (pw->adapter,&type) == FALSE)
   1118      1.1  christos 	{
   1119  1.1.1.4  christos 		pcapint_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
   1120  1.1.1.2  christos 		    GetLastError(), "Cannot determine the network type");
   1121      1.1  christos 		goto bad;
   1122      1.1  christos 	}
   1123      1.1  christos 
   1124      1.1  christos 	/*Set the linktype*/
   1125      1.1  christos 	switch (type.LinkType)
   1126      1.1  christos 	{
   1127  1.1.1.3  christos 	/*
   1128  1.1.1.3  christos 	 * NDIS-defined medium types.
   1129  1.1.1.3  christos 	 */
   1130      1.1  christos 	case NdisMedium802_3:
   1131      1.1  christos 		p->linktype = DLT_EN10MB;
   1132      1.1  christos 		/*
   1133      1.1  christos 		 * This is (presumably) a real Ethernet capture; give it a
   1134      1.1  christos 		 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
   1135      1.1  christos 		 * that an application can let you choose it, in case you're
   1136      1.1  christos 		 * capturing DOCSIS traffic that a Cisco Cable Modem
   1137      1.1  christos 		 * Termination System is putting out onto an Ethernet (it
   1138      1.1  christos 		 * doesn't put an Ethernet header onto the wire, it puts raw
   1139      1.1  christos 		 * DOCSIS frames out on the wire inside the low-level
   1140      1.1  christos 		 * Ethernet framing).
   1141      1.1  christos 		 */
   1142      1.1  christos 		p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
   1143  1.1.1.4  christos 		if (p->dlt_list == NULL)
   1144  1.1.1.4  christos 		{
   1145  1.1.1.4  christos 			pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
   1146  1.1.1.4  christos 			    errno, "malloc");
   1147  1.1.1.4  christos 			goto bad;
   1148      1.1  christos 		}
   1149  1.1.1.4  christos 		p->dlt_list[0] = DLT_EN10MB;
   1150  1.1.1.4  christos 		p->dlt_list[1] = DLT_DOCSIS;
   1151  1.1.1.4  christos 		p->dlt_count = 2;
   1152      1.1  christos 		break;
   1153      1.1  christos 
   1154  1.1.1.3  christos 	case NdisMedium802_5:
   1155  1.1.1.3  christos 		/*
   1156  1.1.1.3  christos 		 * Token Ring.
   1157  1.1.1.3  christos 		 */
   1158  1.1.1.3  christos 		p->linktype = DLT_IEEE802;
   1159  1.1.1.3  christos 		break;
   1160  1.1.1.3  christos 
   1161      1.1  christos 	case NdisMediumFddi:
   1162      1.1  christos 		p->linktype = DLT_FDDI;
   1163      1.1  christos 		break;
   1164      1.1  christos 
   1165  1.1.1.3  christos 	case NdisMediumWan:
   1166  1.1.1.3  christos 		p->linktype = DLT_EN10MB;
   1167      1.1  christos 		break;
   1168      1.1  christos 
   1169      1.1  christos 	case NdisMediumArcnetRaw:
   1170      1.1  christos 		p->linktype = DLT_ARCNET;
   1171      1.1  christos 		break;
   1172      1.1  christos 
   1173      1.1  christos 	case NdisMediumArcnet878_2:
   1174      1.1  christos 		p->linktype = DLT_ARCNET;
   1175      1.1  christos 		break;
   1176      1.1  christos 
   1177      1.1  christos 	case NdisMediumAtm:
   1178      1.1  christos 		p->linktype = DLT_ATM_RFC1483;
   1179      1.1  christos 		break;
   1180      1.1  christos 
   1181  1.1.1.3  christos 	case NdisMediumWirelessWan:
   1182  1.1.1.3  christos 		p->linktype = DLT_RAW;
   1183      1.1  christos 		break;
   1184      1.1  christos 
   1185  1.1.1.3  christos 	case NdisMediumIP:
   1186  1.1.1.3  christos 		p->linktype = DLT_RAW;
   1187      1.1  christos 		break;
   1188      1.1  christos 
   1189  1.1.1.3  christos 	/*
   1190  1.1.1.3  christos 	 * Npcap-defined medium types.
   1191  1.1.1.3  christos 	 */
   1192      1.1  christos 	case NdisMediumNull:
   1193      1.1  christos 		p->linktype = DLT_NULL;
   1194      1.1  christos 		break;
   1195      1.1  christos 
   1196  1.1.1.3  christos 	case NdisMediumCHDLC:
   1197  1.1.1.3  christos 		p->linktype = DLT_CHDLC;
   1198  1.1.1.3  christos 		break;
   1199  1.1.1.3  christos 
   1200  1.1.1.3  christos 	case NdisMediumPPPSerial:
   1201  1.1.1.3  christos 		p->linktype = DLT_PPP_SERIAL;
   1202  1.1.1.3  christos 		break;
   1203  1.1.1.3  christos 
   1204      1.1  christos 	case NdisMediumBare80211:
   1205      1.1  christos 		p->linktype = DLT_IEEE802_11;
   1206      1.1  christos 		break;
   1207      1.1  christos 
   1208      1.1  christos 	case NdisMediumRadio80211:
   1209      1.1  christos 		p->linktype = DLT_IEEE802_11_RADIO;
   1210      1.1  christos 		break;
   1211      1.1  christos 
   1212      1.1  christos 	case NdisMediumPpi:
   1213      1.1  christos 		p->linktype = DLT_PPI;
   1214      1.1  christos 		break;
   1215      1.1  christos 
   1216      1.1  christos 	default:
   1217  1.1.1.2  christos 		/*
   1218  1.1.1.2  christos 		 * An unknown medium type is assumed to supply Ethernet
   1219  1.1.1.2  christos 		 * headers; if not, the user will have to report it,
   1220  1.1.1.2  christos 		 * so that the medium type and link-layer header type
   1221  1.1.1.2  christos 		 * can be determined.  If we were to fail here, we
   1222  1.1.1.2  christos 		 * might get the link-layer type in the error, but
   1223  1.1.1.2  christos 		 * the user wouldn't get a capture, so we wouldn't
   1224  1.1.1.2  christos 		 * be able to determine the link-layer type; we report
   1225  1.1.1.2  christos 		 * a warning with the link-layer type, so at least
   1226  1.1.1.2  christos 		 * some programs will report the warning.
   1227  1.1.1.2  christos 		 */
   1228  1.1.1.2  christos 		p->linktype = DLT_EN10MB;
   1229  1.1.1.3  christos 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
   1230  1.1.1.2  christos 		    "Unknown NdisMedium value %d, defaulting to DLT_EN10MB",
   1231  1.1.1.2  christos 		    type.LinkType);
   1232  1.1.1.2  christos 		status = PCAP_WARNING;
   1233      1.1  christos 		break;
   1234      1.1  christos 	}
   1235      1.1  christos 
   1236  1.1.1.3  christos #ifdef HAVE_PACKET_GET_TIMESTAMP_MODES
   1237  1.1.1.3  christos 	/*
   1238  1.1.1.3  christos 	 * Set the timestamp type.
   1239  1.1.1.3  christos 	 * (Yes, we require PacketGetTimestampModes(), not just
   1240  1.1.1.3  christos 	 * PacketSetTimestampMode().  If we have the former, we
   1241  1.1.1.3  christos 	 * have the latter, unless somebody's using a version
   1242  1.1.1.3  christos 	 * of Npcap that they've hacked to provide the former
   1243  1.1.1.3  christos 	 * but not the latter; if they've done that, either
   1244  1.1.1.3  christos 	 * they're confused or they're trolling us.)
   1245  1.1.1.3  christos 	 */
   1246  1.1.1.3  christos 	switch (p->opt.tstamp_type) {
   1247  1.1.1.3  christos 
   1248  1.1.1.3  christos 	case PCAP_TSTAMP_HOST_HIPREC_UNSYNCED:
   1249  1.1.1.3  christos 		/*
   1250  1.1.1.3  christos 		 * Better than low-res, but *not* synchronized with
   1251  1.1.1.3  christos 		 * the OS clock.
   1252  1.1.1.3  christos 		 */
   1253  1.1.1.3  christos 		if (!PacketSetTimestampMode(pw->adapter, TIMESTAMPMODE_SINGLE_SYNCHRONIZATION))
   1254  1.1.1.3  christos 		{
   1255  1.1.1.4  christos 			pcapint_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
   1256  1.1.1.3  christos 			    GetLastError(), "Cannot set the time stamp mode to TIMESTAMPMODE_SINGLE_SYNCHRONIZATION");
   1257  1.1.1.3  christos 			goto bad;
   1258  1.1.1.3  christos 		}
   1259  1.1.1.3  christos 		break;
   1260  1.1.1.3  christos 
   1261  1.1.1.3  christos 	case PCAP_TSTAMP_HOST_LOWPREC:
   1262  1.1.1.3  christos 		/*
   1263  1.1.1.3  christos 		 * Low-res, but synchronized with the OS clock.
   1264  1.1.1.3  christos 		 */
   1265  1.1.1.3  christos 		if (!PacketSetTimestampMode(pw->adapter, TIMESTAMPMODE_QUERYSYSTEMTIME))
   1266  1.1.1.3  christos 		{
   1267  1.1.1.4  christos 			pcapint_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
   1268  1.1.1.3  christos 			    GetLastError(), "Cannot set the time stamp mode to TIMESTAMPMODE_QUERYSYSTEMTIME");
   1269  1.1.1.3  christos 			goto bad;
   1270  1.1.1.3  christos 		}
   1271  1.1.1.3  christos 		break;
   1272  1.1.1.3  christos 
   1273  1.1.1.3  christos 	case PCAP_TSTAMP_HOST_HIPREC:
   1274  1.1.1.3  christos 		/*
   1275  1.1.1.3  christos 		 * High-res, and synchronized with the OS clock.
   1276  1.1.1.3  christos 		 */
   1277  1.1.1.3  christos 		if (!PacketSetTimestampMode(pw->adapter, TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE))
   1278  1.1.1.3  christos 		{
   1279  1.1.1.4  christos 			pcapint_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
   1280  1.1.1.3  christos 			    GetLastError(), "Cannot set the time stamp mode to TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE");
   1281  1.1.1.3  christos 			goto bad;
   1282  1.1.1.3  christos 		}
   1283  1.1.1.3  christos 		break;
   1284  1.1.1.3  christos 
   1285  1.1.1.3  christos 	case PCAP_TSTAMP_HOST:
   1286  1.1.1.3  christos 		/*
   1287  1.1.1.3  christos 		 * XXX - do whatever the default is, for now.
   1288  1.1.1.3  christos 		 * Set to the highest resolution that's synchronized
   1289  1.1.1.3  christos 		 * with the system clock?
   1290  1.1.1.3  christos 		 */
   1291  1.1.1.3  christos 		break;
   1292  1.1.1.3  christos 	}
   1293  1.1.1.3  christos #endif /* HAVE_PACKET_GET_TIMESTAMP_MODES */
   1294  1.1.1.3  christos 
   1295      1.1  christos 	/*
   1296      1.1  christos 	 * Turn a negative snapshot value (invalid), a snapshot value of
   1297      1.1  christos 	 * 0 (unspecified), or a value bigger than the normal maximum
   1298      1.1  christos 	 * value, into the maximum allowed value.
   1299      1.1  christos 	 *
   1300      1.1  christos 	 * If some application really *needs* a bigger snapshot
   1301      1.1  christos 	 * length, we should just increase MAXIMUM_SNAPLEN.
   1302      1.1  christos 	 */
   1303      1.1  christos 	if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
   1304      1.1  christos 		p->snapshot = MAXIMUM_SNAPLEN;
   1305      1.1  christos 
   1306      1.1  christos 	/* Set promiscuous mode */
   1307      1.1  christos 	if (p->opt.promisc)
   1308      1.1  christos 	{
   1309  1.1.1.4  christos 		/*
   1310  1.1.1.4  christos 		 * For future reference, in case we ever want to query
   1311  1.1.1.4  christos 		 * whether an adapter supports promiscuous mode, that
   1312  1.1.1.4  christos 		 * would be done on Windows by querying the value
   1313  1.1.1.4  christos 		 * of the OID_GEN_SUPPORTED_PACKET_FILTERS OID.
   1314  1.1.1.4  christos 		 */
   1315      1.1  christos 		if (PacketSetHwFilter(pw->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
   1316      1.1  christos 		{
   1317  1.1.1.3  christos 			DWORD errcode = GetLastError();
   1318  1.1.1.3  christos 
   1319  1.1.1.3  christos 			/*
   1320  1.1.1.4  christos 			 * Suppress spurious error generated by non-compliant
   1321  1.1.1.3  christos 			 * MS Surface mobile adapters that appear to
   1322  1.1.1.3  christos 			 * return NDIS_STATUS_NOT_SUPPORTED for attempts
   1323  1.1.1.3  christos 			 * to set the hardware filter.
   1324  1.1.1.3  christos 			 *
   1325  1.1.1.3  christos 			 * It appears to be reporting NDIS_STATUS_NOT_SUPPORTED,
   1326  1.1.1.3  christos 			 * but with the NT status value "Customer" bit set;
   1327  1.1.1.3  christos 			 * the Npcap NPF driver sets that bit in some cases.
   1328  1.1.1.3  christos 			 *
   1329  1.1.1.3  christos 			 * If we knew that this meant "promiscuous mode
   1330  1.1.1.3  christos 			 * isn't supported", we could add a "promiscuous
   1331  1.1.1.3  christos 			 * mode isn't supported" error code and return
   1332  1.1.1.3  christos 			 * that, but:
   1333  1.1.1.3  christos 			 *
   1334  1.1.1.3  christos 			 *    1) we don't know that it means that
   1335  1.1.1.3  christos 			 *    rather than meaning "we reject attempts
   1336  1.1.1.3  christos 			 *    to set the filter, even though the NDIS
   1337  1.1.1.3  christos 			 *    specifications say you shouldn't do that"
   1338  1.1.1.3  christos 			 *
   1339  1.1.1.3  christos 			 * and
   1340  1.1.1.3  christos 			 *
   1341  1.1.1.3  christos 			 *    2) other interface types that don't
   1342  1.1.1.3  christos 			 *    support promiscuous mode, at least
   1343  1.1.1.3  christos 			 *    on UN*Xes, just silently ignore
   1344  1.1.1.3  christos 			 *    attempts to set promiscuous mode
   1345  1.1.1.3  christos 			 *
   1346  1.1.1.3  christos 			 * and rejecting it with an error could disrupt
   1347  1.1.1.3  christos 			 * attempts to capture, as many programs (tcpdump,
   1348  1.1.1.3  christos 			 * *shark) default to promiscuous mode.
   1349  1.1.1.3  christos 			 *
   1350  1.1.1.3  christos 			 * Alternatively, we could return the "promiscuous
   1351  1.1.1.3  christos 			 * mode not supported" *warning* value, so that
   1352  1.1.1.3  christos 			 * correct code will either ignore it or report
   1353  1.1.1.3  christos 			 * it and continue capturing.  (This may require
   1354  1.1.1.3  christos 			 * a pcap_init() flag to request that return
   1355  1.1.1.3  christos 			 * value, so that old incorrect programs that
   1356  1.1.1.3  christos 			 * assume a non-zero return from pcap_activate()
   1357  1.1.1.3  christos 			 * is an error don't break.)
   1358  1.1.1.4  christos 			 *
   1359  1.1.1.4  christos 			 * We check here for ERROR_NOT_SUPPORTED, which
   1360  1.1.1.4  christos 			 * is what NDIS_STATUS_NOT_SUPPORTED (which is
   1361  1.1.1.4  christos 			 * the same value as the NTSTATUS value
   1362  1.1.1.4  christos 			 * STATUS_NOT_SUPPORTED) gets mapped to, as
   1363  1.1.1.4  christos 			 * well as NDIS_STATUS_NOT_SUPPORTED with the
   1364  1.1.1.4  christos 			 * "Customer" bit set.
   1365  1.1.1.3  christos 			 */
   1366  1.1.1.4  christos 			if (errcode != ERROR_NOT_SUPPORTED &&
   1367  1.1.1.4  christos 			    errcode != (NDIS_STATUS_NOT_SUPPORTED|NT_STATUS_CUSTOMER_DEFINED))
   1368  1.1.1.3  christos 			{
   1369  1.1.1.4  christos 				pcapint_fmt_errmsg_for_win32_err(p->errbuf,
   1370  1.1.1.3  christos 				    PCAP_ERRBUF_SIZE, errcode,
   1371  1.1.1.3  christos 				    "failed to set hardware filter to promiscuous mode");
   1372  1.1.1.3  christos 				goto bad;
   1373  1.1.1.3  christos 			}
   1374      1.1  christos 		}
   1375      1.1  christos 	}
   1376      1.1  christos 	else
   1377      1.1  christos 	{
   1378  1.1.1.3  christos 		/*
   1379  1.1.1.3  christos 		 * NDIS_PACKET_TYPE_ALL_LOCAL selects "All packets sent by
   1380  1.1.1.3  christos 		 * installed protocols and all packets indicated by the NIC",
   1381  1.1.1.3  christos 		 * but if no protocol drivers (like TCP/IP) are installed,
   1382  1.1.1.3  christos 		 * NDIS_PACKET_TYPE_DIRECTED, NDIS_PACKET_TYPE_BROADCAST,
   1383  1.1.1.3  christos 		 * and NDIS_PACKET_TYPE_MULTICAST are needed to capture
   1384  1.1.1.3  christos 		 * incoming frames.
   1385      1.1  christos 		 */
   1386      1.1  christos 		if (PacketSetHwFilter(pw->adapter,
   1387      1.1  christos 			NDIS_PACKET_TYPE_ALL_LOCAL |
   1388      1.1  christos 			NDIS_PACKET_TYPE_DIRECTED |
   1389      1.1  christos 			NDIS_PACKET_TYPE_BROADCAST |
   1390      1.1  christos 			NDIS_PACKET_TYPE_MULTICAST) == FALSE)
   1391      1.1  christos 		{
   1392  1.1.1.3  christos 			DWORD errcode = GetLastError();
   1393  1.1.1.3  christos 
   1394  1.1.1.3  christos 			/*
   1395  1.1.1.4  christos 			 * Suppress spurious error generated by non-compliant
   1396  1.1.1.3  christos 			 * MS Surface mobile adapters.
   1397  1.1.1.3  christos 			 */
   1398  1.1.1.3  christos 			if (errcode != (NDIS_STATUS_NOT_SUPPORTED|NT_STATUS_CUSTOMER_DEFINED))
   1399  1.1.1.3  christos 			{
   1400  1.1.1.4  christos 				pcapint_fmt_errmsg_for_win32_err(p->errbuf,
   1401  1.1.1.3  christos 				    PCAP_ERRBUF_SIZE, errcode,
   1402  1.1.1.3  christos 				    "failed to set hardware filter to non-promiscuous mode");
   1403  1.1.1.3  christos 				goto bad;
   1404  1.1.1.3  christos 			}
   1405      1.1  christos 		}
   1406      1.1  christos 	}
   1407      1.1  christos 
   1408      1.1  christos 	/* Set the buffer size */
   1409      1.1  christos 	p->bufsize = WIN32_DEFAULT_USER_BUFFER_SIZE;
   1410      1.1  christos 
   1411      1.1  christos 	if(!(pw->adapter->Flags & INFO_FLAG_DAG_CARD))
   1412      1.1  christos 	{
   1413      1.1  christos 	/*
   1414      1.1  christos 	 * Traditional Adapter
   1415      1.1  christos 	 */
   1416      1.1  christos 		/*
   1417      1.1  christos 		 * If the buffer size wasn't explicitly set, default to
   1418      1.1  christos 		 * WIN32_DEFAULT_KERNEL_BUFFER_SIZE.
   1419      1.1  christos 		 */
   1420  1.1.1.3  christos 		if (p->opt.buffer_size == 0)
   1421  1.1.1.3  christos 			p->opt.buffer_size = WIN32_DEFAULT_KERNEL_BUFFER_SIZE;
   1422      1.1  christos 
   1423      1.1  christos 		if(PacketSetBuff(pw->adapter,p->opt.buffer_size)==FALSE)
   1424      1.1  christos 		{
   1425  1.1.1.3  christos 			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
   1426      1.1  christos 			goto bad;
   1427      1.1  christos 		}
   1428      1.1  christos 
   1429      1.1  christos 		p->buffer = malloc(p->bufsize);
   1430      1.1  christos 		if (p->buffer == NULL)
   1431      1.1  christos 		{
   1432  1.1.1.4  christos 			pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
   1433      1.1  christos 			    errno, "malloc");
   1434      1.1  christos 			goto bad;
   1435      1.1  christos 		}
   1436      1.1  christos 
   1437      1.1  christos 		if (p->opt.immediate)
   1438      1.1  christos 		{
   1439      1.1  christos 			/* tell the driver to copy the buffer as soon as data arrives */
   1440      1.1  christos 			if(PacketSetMinToCopy(pw->adapter,0)==FALSE)
   1441      1.1  christos 			{
   1442  1.1.1.4  christos 				pcapint_fmt_errmsg_for_win32_err(p->errbuf,
   1443  1.1.1.2  christos 				    PCAP_ERRBUF_SIZE, GetLastError(),
   1444  1.1.1.2  christos 				    "Error calling PacketSetMinToCopy");
   1445      1.1  christos 				goto bad;
   1446      1.1  christos 			}
   1447      1.1  christos 		}
   1448      1.1  christos 		else
   1449      1.1  christos 		{
   1450      1.1  christos 			/* tell the driver to copy the buffer only if it contains at least 16K */
   1451      1.1  christos 			if(PacketSetMinToCopy(pw->adapter,16000)==FALSE)
   1452      1.1  christos 			{
   1453  1.1.1.4  christos 				pcapint_fmt_errmsg_for_win32_err(p->errbuf,
   1454  1.1.1.2  christos 				    PCAP_ERRBUF_SIZE, GetLastError(),
   1455  1.1.1.2  christos 				    "Error calling PacketSetMinToCopy");
   1456      1.1  christos 				goto bad;
   1457      1.1  christos 			}
   1458      1.1  christos 		}
   1459      1.1  christos 	} else {
   1460      1.1  christos 		/*
   1461      1.1  christos 		 * Dag Card
   1462      1.1  christos 		 */
   1463      1.1  christos #ifdef HAVE_DAG_API
   1464      1.1  christos 		/*
   1465      1.1  christos 		 * We have DAG support.
   1466      1.1  christos 		 */
   1467      1.1  christos 		LONG	status;
   1468      1.1  christos 		HKEY	dagkey;
   1469      1.1  christos 		DWORD	lptype;
   1470      1.1  christos 		DWORD	lpcbdata;
   1471      1.1  christos 		int		postype = 0;
   1472      1.1  christos 		char	keyname[512];
   1473      1.1  christos 
   1474  1.1.1.3  christos 		snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s",
   1475      1.1  christos 			"SYSTEM\\CurrentControlSet\\Services\\DAG",
   1476      1.1  christos 			strstr(_strlwr(p->opt.device), "dag"));
   1477      1.1  christos 		do
   1478      1.1  christos 		{
   1479      1.1  christos 			status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey);
   1480      1.1  christos 			if(status != ERROR_SUCCESS)
   1481      1.1  christos 				break;
   1482      1.1  christos 
   1483      1.1  christos 			status = RegQueryValueEx(dagkey,
   1484      1.1  christos 				"PosType",
   1485      1.1  christos 				NULL,
   1486      1.1  christos 				&lptype,
   1487      1.1  christos 				(char*)&postype,
   1488      1.1  christos 				&lpcbdata);
   1489      1.1  christos 
   1490      1.1  christos 			if(status != ERROR_SUCCESS)
   1491      1.1  christos 			{
   1492      1.1  christos 				postype = 0;
   1493      1.1  christos 			}
   1494      1.1  christos 
   1495      1.1  christos 			RegCloseKey(dagkey);
   1496      1.1  christos 		}
   1497      1.1  christos 		while(FALSE);
   1498      1.1  christos 
   1499      1.1  christos 
   1500      1.1  christos 		p->snapshot = PacketSetSnapLen(pw->adapter, p->snapshot);
   1501      1.1  christos 
   1502      1.1  christos 		/* Set the length of the FCS associated to any packet. This value
   1503      1.1  christos 		 * will be subtracted to the packet length */
   1504      1.1  christos 		pw->dag_fcs_bits = pw->adapter->DagFcsLen;
   1505      1.1  christos #else /* HAVE_DAG_API */
   1506      1.1  christos 		/*
   1507      1.1  christos 		 * No DAG support.
   1508      1.1  christos 		 */
   1509      1.1  christos 		goto bad;
   1510      1.1  christos #endif /* HAVE_DAG_API */
   1511      1.1  christos 	}
   1512      1.1  christos 
   1513  1.1.1.3  christos 	/*
   1514  1.1.1.3  christos 	 * If there's no filter program installed, there's
   1515  1.1.1.3  christos 	 * no indication to the kernel of what the snapshot
   1516  1.1.1.3  christos 	 * length should be, so no snapshotting is done.
   1517  1.1.1.3  christos 	 *
   1518  1.1.1.3  christos 	 * Therefore, when we open the device, we install
   1519  1.1.1.3  christos 	 * an "accept everything" filter with the specified
   1520  1.1.1.3  christos 	 * snapshot length.
   1521  1.1.1.3  christos 	 */
   1522  1.1.1.3  christos 	total_insn.code = (u_short)(BPF_RET | BPF_K);
   1523  1.1.1.3  christos 	total_insn.jt = 0;
   1524  1.1.1.3  christos 	total_insn.jf = 0;
   1525  1.1.1.3  christos 	total_insn.k = p->snapshot;
   1526  1.1.1.3  christos 
   1527  1.1.1.3  christos 	total_prog.bf_len = 1;
   1528  1.1.1.3  christos 	total_prog.bf_insns = &total_insn;
   1529  1.1.1.3  christos 	if (!PacketSetBpf(pw->adapter, &total_prog)) {
   1530  1.1.1.4  christos 		pcapint_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
   1531  1.1.1.3  christos 		    GetLastError(), "PacketSetBpf");
   1532  1.1.1.3  christos 		status = PCAP_ERROR;
   1533  1.1.1.3  christos 		goto bad;
   1534  1.1.1.3  christos 	}
   1535  1.1.1.3  christos 
   1536      1.1  christos 	PacketSetReadTimeout(pw->adapter, p->opt.timeout);
   1537      1.1  christos 
   1538      1.1  christos 	/* disable loopback capture if requested */
   1539      1.1  christos 	if (p->opt.nocapture_local)
   1540      1.1  christos 	{
   1541      1.1  christos 		if (!PacketSetLoopbackBehavior(pw->adapter, NPF_DISABLE_LOOPBACK))
   1542      1.1  christos 		{
   1543  1.1.1.3  christos 			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
   1544      1.1  christos 			    "Unable to disable the capture of loopback packets.");
   1545      1.1  christos 			goto bad;
   1546      1.1  christos 		}
   1547      1.1  christos 	}
   1548      1.1  christos 
   1549      1.1  christos #ifdef HAVE_DAG_API
   1550      1.1  christos 	if(pw->adapter->Flags & INFO_FLAG_DAG_CARD)
   1551      1.1  christos 	{
   1552      1.1  christos 		/* install dag specific handlers for read and setfilter */
   1553      1.1  christos 		p->read_op = pcap_read_win32_dag;
   1554      1.1  christos 		p->setfilter_op = pcap_setfilter_win32_dag;
   1555      1.1  christos 	}
   1556      1.1  christos 	else
   1557      1.1  christos 	{
   1558      1.1  christos #endif /* HAVE_DAG_API */
   1559      1.1  christos 		/* install traditional npf handlers for read and setfilter */
   1560      1.1  christos 		p->read_op = pcap_read_npf;
   1561      1.1  christos 		p->setfilter_op = pcap_setfilter_npf;
   1562      1.1  christos #ifdef HAVE_DAG_API
   1563      1.1  christos 	}
   1564      1.1  christos #endif /* HAVE_DAG_API */
   1565      1.1  christos 	p->setdirection_op = NULL;	/* Not implemented. */
   1566      1.1  christos 	    /* XXX - can this be implemented on some versions of Windows? */
   1567      1.1  christos 	p->inject_op = pcap_inject_npf;
   1568      1.1  christos 	p->set_datalink_op = NULL;	/* can't change data link type */
   1569      1.1  christos 	p->getnonblock_op = pcap_getnonblock_npf;
   1570      1.1  christos 	p->setnonblock_op = pcap_setnonblock_npf;
   1571      1.1  christos 	p->stats_op = pcap_stats_npf;
   1572  1.1.1.3  christos 	p->breakloop_op = pcap_breakloop_npf;
   1573      1.1  christos 	p->stats_ex_op = pcap_stats_ex_npf;
   1574      1.1  christos 	p->setbuff_op = pcap_setbuff_npf;
   1575      1.1  christos 	p->setmode_op = pcap_setmode_npf;
   1576      1.1  christos 	p->setmintocopy_op = pcap_setmintocopy_npf;
   1577      1.1  christos 	p->getevent_op = pcap_getevent_npf;
   1578      1.1  christos 	p->oid_get_request_op = pcap_oid_get_request_npf;
   1579      1.1  christos 	p->oid_set_request_op = pcap_oid_set_request_npf;
   1580      1.1  christos 	p->sendqueue_transmit_op = pcap_sendqueue_transmit_npf;
   1581      1.1  christos 	p->setuserbuffer_op = pcap_setuserbuffer_npf;
   1582      1.1  christos 	p->live_dump_op = pcap_live_dump_npf;
   1583      1.1  christos 	p->live_dump_ended_op = pcap_live_dump_ended_npf;
   1584      1.1  christos 	p->get_airpcap_handle_op = pcap_get_airpcap_handle_npf;
   1585      1.1  christos 	p->cleanup_op = pcap_cleanup_npf;
   1586      1.1  christos 
   1587      1.1  christos 	/*
   1588      1.1  christos 	 * XXX - this is only done because WinPcap supported
   1589      1.1  christos 	 * pcap_fileno() returning the hFile HANDLE from the
   1590      1.1  christos 	 * ADAPTER structure.  We make no general guarantees
   1591      1.1  christos 	 * that the caller can do anything useful with it.
   1592      1.1  christos 	 *
   1593      1.1  christos 	 * (Not that we make any general guarantee of that
   1594  1.1.1.4  christos 	 * sort on UN*X, either, anymore, given that not
   1595      1.1  christos 	 * all capture devices are regular OS network
   1596      1.1  christos 	 * interfaces.)
   1597      1.1  christos 	 */
   1598      1.1  christos 	p->handle = pw->adapter->hFile;
   1599      1.1  christos 
   1600  1.1.1.2  christos 	return (status);
   1601      1.1  christos bad:
   1602      1.1  christos 	pcap_cleanup_npf(p);
   1603      1.1  christos 	return (PCAP_ERROR);
   1604      1.1  christos }
   1605      1.1  christos 
   1606      1.1  christos /*
   1607      1.1  christos * Check if rfmon mode is supported on the pcap_t for Windows systems.
   1608      1.1  christos */
   1609      1.1  christos static int
   1610      1.1  christos pcap_can_set_rfmon_npf(pcap_t *p)
   1611      1.1  christos {
   1612      1.1  christos 	return (PacketIsMonitorModeSupported(p->opt.device) == 1);
   1613      1.1  christos }
   1614      1.1  christos 
   1615  1.1.1.3  christos /*
   1616  1.1.1.3  christos  * Get a list of time stamp types.
   1617  1.1.1.3  christos  */
   1618  1.1.1.3  christos #ifdef HAVE_PACKET_GET_TIMESTAMP_MODES
   1619  1.1.1.3  christos static int
   1620  1.1.1.3  christos get_ts_types(const char *device, pcap_t *p, char *ebuf)
   1621  1.1.1.3  christos {
   1622  1.1.1.3  christos 	char *device_copy = NULL;
   1623  1.1.1.3  christos 	ADAPTER *adapter = NULL;
   1624  1.1.1.3  christos 	ULONG num_ts_modes;
   1625  1.1.1.4  christos 	/* Npcap 1.00 driver is buggy and will write 16 bytes regardless of
   1626  1.1.1.4  christos 	 * buffer size. Using a sufficient stack buffer avoids overflow and
   1627  1.1.1.4  christos 	 * avoids a heap allocation in most (currently all) cases.
   1628  1.1.1.4  christos 	 */
   1629  1.1.1.4  christos 	ULONG ts_modes[4];
   1630  1.1.1.3  christos 	BOOL ret;
   1631  1.1.1.3  christos 	DWORD error = ERROR_SUCCESS;
   1632  1.1.1.3  christos 	ULONG *modes = NULL;
   1633  1.1.1.3  christos 	int status = 0;
   1634  1.1.1.3  christos 
   1635  1.1.1.3  christos 	do {
   1636  1.1.1.3  christos 		/*
   1637  1.1.1.3  christos 		 * First, find out how many time stamp modes we have.
   1638  1.1.1.3  christos 		 * To do that, we have to open the adapter.
   1639  1.1.1.3  christos 		 *
   1640  1.1.1.3  christos 		 * XXX - PacketOpenAdapter() takes a non-const pointer
   1641  1.1.1.3  christos 		 * as an argument, so we make a copy of the argument and
   1642  1.1.1.3  christos 		 * pass that to it.
   1643  1.1.1.3  christos 		 */
   1644  1.1.1.3  christos 		device_copy = strdup(device);
   1645  1.1.1.3  christos 		if (device_copy == NULL) {
   1646  1.1.1.4  christos 			pcapint_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, errno, "malloc");
   1647  1.1.1.3  christos 			status = -1;
   1648  1.1.1.3  christos 			break;
   1649  1.1.1.3  christos 		}
   1650  1.1.1.3  christos 
   1651  1.1.1.3  christos 		adapter = PacketOpenAdapter(device_copy);
   1652  1.1.1.3  christos 		if (adapter == NULL)
   1653  1.1.1.3  christos 		{
   1654  1.1.1.3  christos 			error = GetLastError();
   1655  1.1.1.3  christos 			/*
   1656  1.1.1.3  christos 			 * If we can't open the device now, we won't be
   1657  1.1.1.3  christos 			 * able to later, either.
   1658  1.1.1.3  christos 			 *
   1659  1.1.1.3  christos 			 * If the error is something that indicates
   1660  1.1.1.3  christos 			 * that the device doesn't exist, or that they
   1661  1.1.1.3  christos 			 * don't have permission to open the device - or
   1662  1.1.1.3  christos 			 * perhaps that they don't have permission to get
   1663  1.1.1.3  christos 			 * a list of devices, if PacketOpenAdapter() does
   1664  1.1.1.3  christos 			 * that - the user will find that out when they try
   1665  1.1.1.3  christos 			 * to activate the device; just return an empty
   1666  1.1.1.3  christos 			 * list of time stamp types.
   1667  1.1.1.3  christos 			 *
   1668  1.1.1.3  christos 			 * Treating either of those as errors will, for
   1669  1.1.1.3  christos 			 * example, cause "tcpdump -i <number>" to fail,
   1670  1.1.1.3  christos 			 * because it first tries to pass the interface
   1671  1.1.1.3  christos 			 * name to pcap_create() and pcap_activate(),
   1672  1.1.1.3  christos 			 * in order to handle OSes where interfaces can
   1673  1.1.1.3  christos 			 * have names that are just numbers (stand up
   1674  1.1.1.3  christos 			 * and say hello, Linux!), and, if pcap_activate()
   1675  1.1.1.3  christos 			 * fails with a "no such device" error, checks
   1676  1.1.1.3  christos 			 * whether the interface name is a valid number
   1677  1.1.1.3  christos 			 * and, if so, tries to use it as an index in
   1678  1.1.1.3  christos 			 * the list of interfaces.
   1679  1.1.1.3  christos 			 *
   1680  1.1.1.3  christos 			 * That means pcap_create() must succeed even
   1681  1.1.1.3  christos 			 * for interfaces that don't exist, with the
   1682  1.1.1.3  christos 			 * failure occurring at pcap_activate() time.
   1683  1.1.1.3  christos 			 */
   1684  1.1.1.3  christos 			if (error == ERROR_BAD_UNIT ||
   1685  1.1.1.3  christos 			    error == ERROR_ACCESS_DENIED) {
   1686  1.1.1.3  christos 				p->tstamp_type_count = 0;
   1687  1.1.1.3  christos 				p->tstamp_type_list = NULL;
   1688  1.1.1.3  christos 				status = 0;
   1689  1.1.1.3  christos 			} else {
   1690  1.1.1.4  christos 				pcapint_fmt_errmsg_for_win32_err(ebuf,
   1691  1.1.1.3  christos 				    PCAP_ERRBUF_SIZE, error,
   1692  1.1.1.3  christos 				    "Error opening adapter");
   1693  1.1.1.3  christos 				status = -1;
   1694  1.1.1.3  christos 			}
   1695  1.1.1.3  christos 			break;
   1696  1.1.1.3  christos 		}
   1697  1.1.1.3  christos 
   1698  1.1.1.3  christos 		/*
   1699  1.1.1.3  christos 		 * Get the total number of time stamp modes.
   1700  1.1.1.3  christos 		 *
   1701  1.1.1.3  christos 		 * The buffer for PacketGetTimestampModes() is
   1702  1.1.1.3  christos 		 * a sequence of 1 or more ULONGs.  What's
   1703  1.1.1.3  christos 		 * passed to PacketGetTimestampModes() should have
   1704  1.1.1.3  christos 		 * the total number of ULONGs in the first ULONG;
   1705  1.1.1.3  christos 		 * what's returned *from* PacketGetTimestampModes()
   1706  1.1.1.3  christos 		 * has the total number of time stamp modes in
   1707  1.1.1.3  christos 		 * the first ULONG.
   1708  1.1.1.3  christos 		 *
   1709  1.1.1.3  christos 		 * Yes, that means if there are N time stamp
   1710  1.1.1.3  christos 		 * modes, the first ULONG should be set to N+1
   1711  1.1.1.3  christos 		 * on input, and will be set to N on output.
   1712  1.1.1.3  christos 		 *
   1713  1.1.1.3  christos 		 * We first make a call to PacketGetTimestampModes()
   1714  1.1.1.3  christos 		 * with a pointer to a single ULONG set to 1; the
   1715  1.1.1.3  christos 		 * call should fail with ERROR_MORE_DATA (unless
   1716  1.1.1.3  christos 		 * there are *no* modes, but that should never
   1717  1.1.1.3  christos 		 * happen), and that ULONG should be set to the
   1718  1.1.1.3  christos 		 * number of modes.
   1719  1.1.1.3  christos 		 */
   1720  1.1.1.4  christos 		ts_modes[0] = sizeof(ts_modes) / sizeof(ULONG);
   1721  1.1.1.4  christos 		ret = PacketGetTimestampModes(adapter, ts_modes);
   1722  1.1.1.3  christos 		if (!ret) {
   1723  1.1.1.3  christos 			/*
   1724  1.1.1.3  christos 			 * OK, it failed.  Did it fail with
   1725  1.1.1.3  christos 			 * ERROR_MORE_DATA?
   1726  1.1.1.3  christos 			 */
   1727  1.1.1.3  christos 			error = GetLastError();
   1728  1.1.1.3  christos 			if (error != ERROR_MORE_DATA) {
   1729  1.1.1.3  christos 				/*
   1730  1.1.1.3  christos 				 * No, did it fail with ERROR_INVALID_FUNCTION?
   1731  1.1.1.3  christos 				 */
   1732  1.1.1.3  christos 				if (error == ERROR_INVALID_FUNCTION) {
   1733  1.1.1.3  christos 					/*
   1734  1.1.1.3  christos 					 * This is probably due to
   1735  1.1.1.3  christos 					 * the driver with which Packet.dll
   1736  1.1.1.3  christos 					 * communicates being older, or
   1737  1.1.1.3  christos 					 * being a WinPcap driver, so
   1738  1.1.1.3  christos 					 * that it doesn't support
   1739  1.1.1.3  christos 					 * BIOCGTIMESTAMPMODES.
   1740  1.1.1.3  christos 					 *
   1741  1.1.1.3  christos 					 * Tell the user to try uninstalling
   1742  1.1.1.3  christos 					 * Npcap - and WinPcap if installed -
   1743  1.1.1.3  christos 					 * and re-installing it, to flush
   1744  1.1.1.3  christos 					 * out all older drivers.
   1745  1.1.1.3  christos 					 */
   1746  1.1.1.3  christos 					snprintf(ebuf, PCAP_ERRBUF_SIZE,
   1747  1.1.1.3  christos 					    "PacketGetTimestampModes() failed with ERROR_INVALID_FUNCTION; try uninstalling Npcap, and WinPcap if installed, and re-installing it from npcap.com");
   1748  1.1.1.3  christos 					status = -1;
   1749  1.1.1.3  christos 					break;
   1750  1.1.1.3  christos 				}
   1751  1.1.1.3  christos 
   1752  1.1.1.3  christos 				/*
   1753  1.1.1.3  christos 				 * No, some other error.  Fail.
   1754  1.1.1.3  christos 				 */
   1755  1.1.1.4  christos 				pcapint_fmt_errmsg_for_win32_err(ebuf,
   1756  1.1.1.3  christos 				    PCAP_ERRBUF_SIZE, error,
   1757  1.1.1.3  christos 				    "Error calling PacketGetTimestampModes");
   1758  1.1.1.3  christos 				status = -1;
   1759  1.1.1.3  christos 				break;
   1760  1.1.1.3  christos 			}
   1761  1.1.1.4  christos 
   1762  1.1.1.4  christos 			/*
   1763  1.1.1.4  christos 			 * Yes, so we now know how many types to fetch.
   1764  1.1.1.4  christos 			 *
   1765  1.1.1.4  christos 			 * The buffer needs to have one ULONG for the
   1766  1.1.1.4  christos 			 * count and num_ts_modes ULONGs for the
   1767  1.1.1.4  christos 			 * num_ts_modes time stamp types.
   1768  1.1.1.4  christos 			 */
   1769  1.1.1.4  christos 			num_ts_modes = ts_modes[0];
   1770  1.1.1.4  christos 			modes = (ULONG *)malloc((1 + num_ts_modes) * sizeof(ULONG));
   1771  1.1.1.4  christos 			if (modes == NULL) {
   1772  1.1.1.4  christos 				/* Out of memory. */
   1773  1.1.1.4  christos 				pcapint_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, errno, "malloc");
   1774  1.1.1.4  christos 				status = -1;
   1775  1.1.1.4  christos 				break;
   1776  1.1.1.4  christos 			}
   1777  1.1.1.4  christos 			modes[0] = 1 + num_ts_modes;
   1778  1.1.1.4  christos 			if (!PacketGetTimestampModes(adapter, modes)) {
   1779  1.1.1.4  christos 				pcapint_fmt_errmsg_for_win32_err(ebuf,
   1780  1.1.1.4  christos 						PCAP_ERRBUF_SIZE, GetLastError(),
   1781  1.1.1.4  christos 						"Error calling PacketGetTimestampModes");
   1782  1.1.1.4  christos 				status = -1;
   1783  1.1.1.4  christos 				break;
   1784  1.1.1.4  christos 			}
   1785  1.1.1.4  christos 			if (modes[0] != num_ts_modes) {
   1786  1.1.1.4  christos 				snprintf(ebuf, PCAP_ERRBUF_SIZE,
   1787  1.1.1.4  christos 						"First PacketGetTimestampModes() call gives %lu modes, second call gives %lu modes",
   1788  1.1.1.4  christos 						num_ts_modes, modes[0]);
   1789  1.1.1.4  christos 				status = -1;
   1790  1.1.1.4  christos 				break;
   1791  1.1.1.4  christos 			}
   1792  1.1.1.4  christos 		}
   1793  1.1.1.4  christos 		else {
   1794  1.1.1.4  christos 			modes = ts_modes;
   1795  1.1.1.4  christos 			num_ts_modes = ts_modes[0];
   1796  1.1.1.3  christos 		}
   1797  1.1.1.3  christos 
   1798  1.1.1.3  christos 		/* If the driver reports no modes supported *and*
   1799  1.1.1.3  christos 		 * ERROR_MORE_DATA, something is seriously wrong.
   1800  1.1.1.3  christos 		 * We *could* ignore the error and continue without supporting
   1801  1.1.1.3  christos 		 * settable timestamp modes, but that would hide a bug.
   1802  1.1.1.3  christos 		 */
   1803  1.1.1.4  christos 		if (modes[0] == 0) {
   1804  1.1.1.3  christos 			snprintf(ebuf, PCAP_ERRBUF_SIZE,
   1805  1.1.1.3  christos 			    "PacketGetTimestampModes() reports 0 modes supported.");
   1806  1.1.1.3  christos 			status = -1;
   1807  1.1.1.3  christos 			break;
   1808  1.1.1.3  christos 		}
   1809  1.1.1.3  christos 
   1810  1.1.1.3  christos 		/*
   1811  1.1.1.3  christos 		 * Allocate a buffer big enough for
   1812  1.1.1.3  christos 		 * PCAP_TSTAMP_HOST (default) plus
   1813  1.1.1.3  christos 		 * the explicitly specified modes.
   1814  1.1.1.3  christos 		 */
   1815  1.1.1.3  christos 		p->tstamp_type_list = malloc((1 + num_ts_modes) * sizeof(u_int));
   1816  1.1.1.3  christos 		if (p->tstamp_type_list == NULL) {
   1817  1.1.1.4  christos 			pcapint_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, errno, "malloc");
   1818  1.1.1.3  christos 			status = -1;
   1819  1.1.1.3  christos 			break;
   1820  1.1.1.3  christos 		}
   1821  1.1.1.3  christos 		u_int num_ts_types = 0;
   1822  1.1.1.3  christos 		p->tstamp_type_list[num_ts_types] =
   1823  1.1.1.3  christos 		    PCAP_TSTAMP_HOST;
   1824  1.1.1.3  christos 		num_ts_types++;
   1825  1.1.1.3  christos 		for (ULONG i = 0; i < num_ts_modes; i++) {
   1826  1.1.1.3  christos 			switch (modes[i + 1]) {
   1827  1.1.1.3  christos 
   1828  1.1.1.3  christos 			case TIMESTAMPMODE_SINGLE_SYNCHRONIZATION:
   1829  1.1.1.3  christos 				/*
   1830  1.1.1.3  christos 				 * Better than low-res,
   1831  1.1.1.3  christos 				 * but *not* synchronized
   1832  1.1.1.3  christos 				 * with the OS clock.
   1833  1.1.1.3  christos 				 */
   1834  1.1.1.3  christos 				p->tstamp_type_list[num_ts_types] =
   1835  1.1.1.3  christos 				    PCAP_TSTAMP_HOST_HIPREC_UNSYNCED;
   1836  1.1.1.3  christos 				num_ts_types++;
   1837  1.1.1.3  christos 				break;
   1838  1.1.1.3  christos 
   1839  1.1.1.3  christos 			case TIMESTAMPMODE_QUERYSYSTEMTIME:
   1840  1.1.1.3  christos 				/*
   1841  1.1.1.3  christos 				 * Low-res, but synchronized
   1842  1.1.1.3  christos 				 * with the OS clock.
   1843  1.1.1.3  christos 				 */
   1844  1.1.1.3  christos 				p->tstamp_type_list[num_ts_types] =
   1845  1.1.1.3  christos 				    PCAP_TSTAMP_HOST_LOWPREC;
   1846  1.1.1.3  christos 				num_ts_types++;
   1847  1.1.1.3  christos 				break;
   1848  1.1.1.3  christos 
   1849  1.1.1.3  christos 			case TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE:
   1850  1.1.1.3  christos 				/*
   1851  1.1.1.3  christos 				 * High-res, and synchronized
   1852  1.1.1.3  christos 				 * with the OS clock.
   1853  1.1.1.3  christos 				 */
   1854  1.1.1.3  christos 				p->tstamp_type_list[num_ts_types] =
   1855  1.1.1.3  christos 				    PCAP_TSTAMP_HOST_HIPREC;
   1856  1.1.1.3  christos 				num_ts_types++;
   1857  1.1.1.3  christos 				break;
   1858  1.1.1.3  christos 
   1859  1.1.1.3  christos 			default:
   1860  1.1.1.3  christos 				/*
   1861  1.1.1.3  christos 				 * Unknown, so we can't
   1862  1.1.1.3  christos 				 * report it.
   1863  1.1.1.3  christos 				 */
   1864  1.1.1.3  christos 				break;
   1865  1.1.1.3  christos 			}
   1866  1.1.1.3  christos 		}
   1867  1.1.1.3  christos 		p->tstamp_type_count = num_ts_types;
   1868  1.1.1.3  christos 	} while (0);
   1869  1.1.1.3  christos 
   1870  1.1.1.3  christos 	/* Clean up temporary allocations */
   1871  1.1.1.3  christos 	if (device_copy != NULL) {
   1872  1.1.1.3  christos 		free(device_copy);
   1873  1.1.1.3  christos 	}
   1874  1.1.1.4  christos 	if (modes != NULL && modes != ts_modes) {
   1875  1.1.1.3  christos 		free(modes);
   1876  1.1.1.3  christos 	}
   1877  1.1.1.3  christos 	if (adapter != NULL) {
   1878  1.1.1.3  christos 		PacketCloseAdapter(adapter);
   1879  1.1.1.3  christos 	}
   1880  1.1.1.3  christos 
   1881  1.1.1.3  christos 	return status;
   1882  1.1.1.3  christos }
   1883  1.1.1.3  christos #else /* HAVE_PACKET_GET_TIMESTAMP_MODES */
   1884  1.1.1.3  christos static int
   1885  1.1.1.3  christos get_ts_types(const char *device _U_, pcap_t *p _U_, char *ebuf _U_)
   1886  1.1.1.3  christos {
   1887  1.1.1.3  christos 	/*
   1888  1.1.1.3  christos 	 * Nothing to fetch, so it always "succeeds".
   1889  1.1.1.3  christos 	 */
   1890  1.1.1.3  christos 	return 0;
   1891  1.1.1.3  christos }
   1892  1.1.1.3  christos #endif /* HAVE_PACKET_GET_TIMESTAMP_MODES */
   1893  1.1.1.3  christos 
   1894      1.1  christos pcap_t *
   1895  1.1.1.4  christos pcapint_create_interface(const char *device _U_, char *ebuf)
   1896      1.1  christos {
   1897      1.1  christos 	pcap_t *p;
   1898      1.1  christos 
   1899  1.1.1.3  christos 	p = PCAP_CREATE_COMMON(ebuf, struct pcap_win);
   1900      1.1  christos 	if (p == NULL)
   1901      1.1  christos 		return (NULL);
   1902      1.1  christos 
   1903      1.1  christos 	p->activate_op = pcap_activate_npf;
   1904      1.1  christos 	p->can_set_rfmon_op = pcap_can_set_rfmon_npf;
   1905  1.1.1.3  christos 
   1906  1.1.1.3  christos 	if (get_ts_types(device, p, ebuf) == -1) {
   1907  1.1.1.3  christos 		pcap_close(p);
   1908  1.1.1.3  christos 		return (NULL);
   1909  1.1.1.3  christos 	}
   1910      1.1  christos 	return (p);
   1911      1.1  christos }
   1912      1.1  christos 
   1913      1.1  christos static int
   1914      1.1  christos pcap_setfilter_npf(pcap_t *p, struct bpf_program *fp)
   1915      1.1  christos {
   1916      1.1  christos 	struct pcap_win *pw = p->priv;
   1917      1.1  christos 
   1918      1.1  christos 	if(PacketSetBpf(pw->adapter,fp)==FALSE){
   1919      1.1  christos 		/*
   1920      1.1  christos 		 * Kernel filter not installed.
   1921      1.1  christos 		 *
   1922      1.1  christos 		 * XXX - we don't know whether this failed because:
   1923      1.1  christos 		 *
   1924      1.1  christos 		 *  the kernel rejected the filter program as invalid,
   1925      1.1  christos 		 *  in which case we should fall back on userland
   1926      1.1  christos 		 *  filtering;
   1927      1.1  christos 		 *
   1928      1.1  christos 		 *  the kernel rejected the filter program as too big,
   1929      1.1  christos 		 *  in which case we should again fall back on
   1930      1.1  christos 		 *  userland filtering;
   1931      1.1  christos 		 *
   1932      1.1  christos 		 *  there was some other problem, in which case we
   1933      1.1  christos 		 *  should probably report an error.
   1934      1.1  christos 		 *
   1935      1.1  christos 		 * For NPF devices, the Win32 status will be
   1936      1.1  christos 		 * STATUS_INVALID_DEVICE_REQUEST for invalid
   1937      1.1  christos 		 * filters, but I don't know what it'd be for
   1938      1.1  christos 		 * other problems, and for some other devices
   1939      1.1  christos 		 * it might not be set at all.
   1940      1.1  christos 		 *
   1941      1.1  christos 		 * So we just fall back on userland filtering in
   1942      1.1  christos 		 * all cases.
   1943      1.1  christos 		 */
   1944      1.1  christos 
   1945      1.1  christos 		/*
   1946  1.1.1.4  christos 		 * pcapint_install_bpf_program() validates the program.
   1947      1.1  christos 		 *
   1948      1.1  christos 		 * XXX - what if we already have a filter in the kernel?
   1949      1.1  christos 		 */
   1950  1.1.1.4  christos 		if (pcapint_install_bpf_program(p, fp) < 0)
   1951      1.1  christos 			return (-1);
   1952      1.1  christos 		pw->filtering_in_kernel = 0;	/* filtering in userland */
   1953      1.1  christos 		return (0);
   1954      1.1  christos 	}
   1955      1.1  christos 
   1956      1.1  christos 	/*
   1957      1.1  christos 	 * It worked.
   1958      1.1  christos 	 */
   1959      1.1  christos 	pw->filtering_in_kernel = 1;	/* filtering in the kernel */
   1960      1.1  christos 
   1961      1.1  christos 	/*
   1962      1.1  christos 	 * Discard any previously-received packets, as they might have
   1963      1.1  christos 	 * passed whatever filter was formerly in effect, but might
   1964      1.1  christos 	 * not pass this filter (BIOCSETF discards packets buffered
   1965      1.1  christos 	 * in the kernel, so you can lose packets in any case).
   1966      1.1  christos 	 */
   1967      1.1  christos 	p->cc = 0;
   1968      1.1  christos 	return (0);
   1969      1.1  christos }
   1970      1.1  christos 
   1971      1.1  christos /*
   1972  1.1.1.3  christos  * We filter at user level, since the kernel driver doesn't process the packets
   1973      1.1  christos  */
   1974      1.1  christos static int
   1975      1.1  christos pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {
   1976      1.1  christos 
   1977      1.1  christos 	if(!fp)
   1978      1.1  christos 	{
   1979  1.1.1.4  christos 		pcapint_strlcpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf));
   1980      1.1  christos 		return (-1);
   1981      1.1  christos 	}
   1982      1.1  christos 
   1983      1.1  christos 	/* Install a user level filter */
   1984  1.1.1.4  christos 	if (pcapint_install_bpf_program(p, fp) < 0)
   1985      1.1  christos 		return (-1);
   1986      1.1  christos 
   1987      1.1  christos 	return (0);
   1988      1.1  christos }
   1989      1.1  christos 
   1990      1.1  christos static int
   1991      1.1  christos pcap_getnonblock_npf(pcap_t *p)
   1992      1.1  christos {
   1993      1.1  christos 	struct pcap_win *pw = p->priv;
   1994      1.1  christos 
   1995      1.1  christos 	/*
   1996      1.1  christos 	 * XXX - if there were a PacketGetReadTimeout() call, we
   1997      1.1  christos 	 * would use it, and return 1 if the timeout is -1
   1998      1.1  christos 	 * and 0 otherwise.
   1999      1.1  christos 	 */
   2000      1.1  christos 	return (pw->nonblock);
   2001      1.1  christos }
   2002      1.1  christos 
   2003      1.1  christos static int
   2004      1.1  christos pcap_setnonblock_npf(pcap_t *p, int nonblock)
   2005      1.1  christos {
   2006      1.1  christos 	struct pcap_win *pw = p->priv;
   2007      1.1  christos 	int newtimeout;
   2008      1.1  christos 
   2009      1.1  christos 	if (nonblock) {
   2010      1.1  christos 		/*
   2011      1.1  christos 		 * Set the packet buffer timeout to -1 for non-blocking
   2012      1.1  christos 		 * mode.
   2013      1.1  christos 		 */
   2014      1.1  christos 		newtimeout = -1;
   2015      1.1  christos 	} else {
   2016      1.1  christos 		/*
   2017      1.1  christos 		 * Restore the timeout set when the device was opened.
   2018      1.1  christos 		 * (Note that this may be -1, in which case we're not
   2019      1.1  christos 		 * really leaving non-blocking mode.  However, although
   2020      1.1  christos 		 * the timeout argument to pcap_set_timeout() and
   2021      1.1  christos 		 * pcap_open_live() is an int, you're not supposed to
   2022      1.1  christos 		 * supply a negative value, so that "shouldn't happen".)
   2023      1.1  christos 		 */
   2024      1.1  christos 		newtimeout = p->opt.timeout;
   2025      1.1  christos 	}
   2026      1.1  christos 	if (!PacketSetReadTimeout(pw->adapter, newtimeout)) {
   2027  1.1.1.4  christos 		pcapint_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
   2028  1.1.1.2  christos 		    GetLastError(), "PacketSetReadTimeout");
   2029      1.1  christos 		return (-1);
   2030      1.1  christos 	}
   2031      1.1  christos 	pw->nonblock = (newtimeout == -1);
   2032      1.1  christos 	return (0);
   2033      1.1  christos }
   2034      1.1  christos 
   2035      1.1  christos static int
   2036      1.1  christos pcap_add_if_npf(pcap_if_list_t *devlistp, char *name, bpf_u_int32 flags,
   2037      1.1  christos     const char *description, char *errbuf)
   2038      1.1  christos {
   2039      1.1  christos 	pcap_if_t *curdev;
   2040      1.1  christos 	npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
   2041      1.1  christos 	LONG if_addr_size;
   2042      1.1  christos 	int res = 0;
   2043      1.1  christos 
   2044      1.1  christos 	if_addr_size = MAX_NETWORK_ADDRESSES;
   2045      1.1  christos 
   2046      1.1  christos 	/*
   2047      1.1  christos 	 * Add an entry for this interface, with no addresses.
   2048      1.1  christos 	 */
   2049  1.1.1.4  christos 	curdev = pcapint_add_dev(devlistp, name, flags, description, errbuf);
   2050      1.1  christos 	if (curdev == NULL) {
   2051      1.1  christos 		/*
   2052      1.1  christos 		 * Failure.
   2053      1.1  christos 		 */
   2054      1.1  christos 		return (-1);
   2055      1.1  christos 	}
   2056      1.1  christos 
   2057      1.1  christos 	/*
   2058      1.1  christos 	 * Get the list of addresses for the interface.
   2059      1.1  christos 	 */
   2060      1.1  christos 	if (!PacketGetNetInfoEx((void *)name, if_addrs, &if_addr_size)) {
   2061      1.1  christos 		/*
   2062      1.1  christos 		 * Failure.
   2063      1.1  christos 		 *
   2064      1.1  christos 		 * We don't return an error, because this can happen with
   2065      1.1  christos 		 * NdisWan interfaces, and we want to supply them even
   2066      1.1  christos 		 * if we can't supply their addresses.
   2067      1.1  christos 		 *
   2068      1.1  christos 		 * We return an entry with an empty address list.
   2069      1.1  christos 		 */
   2070      1.1  christos 		return (0);
   2071      1.1  christos 	}
   2072      1.1  christos 
   2073      1.1  christos 	/*
   2074      1.1  christos 	 * Now add the addresses.
   2075      1.1  christos 	 */
   2076      1.1  christos 	while (if_addr_size-- > 0) {
   2077      1.1  christos 		/*
   2078      1.1  christos 		 * "curdev" is an entry for this interface; add an entry for
   2079      1.1  christos 		 * this address to its list of addresses.
   2080      1.1  christos 		 */
   2081  1.1.1.4  christos 		res = pcapint_add_addr_to_dev(curdev,
   2082      1.1  christos 		    (struct sockaddr *)&if_addrs[if_addr_size].IPAddress,
   2083      1.1  christos 		    sizeof (struct sockaddr_storage),
   2084      1.1  christos 		    (struct sockaddr *)&if_addrs[if_addr_size].SubnetMask,
   2085      1.1  christos 		    sizeof (struct sockaddr_storage),
   2086      1.1  christos 		    (struct sockaddr *)&if_addrs[if_addr_size].Broadcast,
   2087      1.1  christos 		    sizeof (struct sockaddr_storage),
   2088      1.1  christos 		    NULL,
   2089      1.1  christos 		    0,
   2090      1.1  christos 		    errbuf);
   2091      1.1  christos 		if (res == -1) {
   2092      1.1  christos 			/*
   2093      1.1  christos 			 * Failure.
   2094      1.1  christos 			 */
   2095      1.1  christos 			break;
   2096      1.1  christos 		}
   2097      1.1  christos 	}
   2098      1.1  christos 
   2099      1.1  christos 	return (res);
   2100      1.1  christos }
   2101      1.1  christos 
   2102      1.1  christos static int
   2103      1.1  christos get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
   2104      1.1  christos {
   2105      1.1  christos 	char *name_copy;
   2106      1.1  christos 	ADAPTER *adapter;
   2107      1.1  christos 	int status;
   2108      1.1  christos 	size_t len;
   2109      1.1  christos 	NDIS_HARDWARE_STATUS hardware_status;
   2110      1.1  christos #ifdef OID_GEN_PHYSICAL_MEDIUM
   2111      1.1  christos 	NDIS_PHYSICAL_MEDIUM phys_medium;
   2112      1.1  christos 	bpf_u_int32 gen_physical_medium_oids[] = {
   2113      1.1  christos   #ifdef OID_GEN_PHYSICAL_MEDIUM_EX
   2114      1.1  christos 		OID_GEN_PHYSICAL_MEDIUM_EX,
   2115      1.1  christos   #endif
   2116  1.1.1.3  christos 		OID_GEN_PHYSICAL_MEDIUM
   2117  1.1.1.3  christos 	};
   2118      1.1  christos #define N_GEN_PHYSICAL_MEDIUM_OIDS	(sizeof gen_physical_medium_oids / sizeof gen_physical_medium_oids[0])
   2119      1.1  christos 	size_t i;
   2120      1.1  christos #endif /* OID_GEN_PHYSICAL_MEDIUM */
   2121      1.1  christos #ifdef OID_GEN_LINK_STATE
   2122      1.1  christos 	NDIS_LINK_STATE link_state;
   2123      1.1  christos #endif
   2124      1.1  christos 	int connect_status;
   2125      1.1  christos 
   2126      1.1  christos 	if (*flags & PCAP_IF_LOOPBACK) {
   2127      1.1  christos 		/*
   2128      1.1  christos 		 * Loopback interface, so the connection status doesn't
   2129      1.1  christos 		 * apply. and it's not wireless (or wired, for that
   2130      1.1  christos 		 * matter...).  We presume it's up and running.
   2131      1.1  christos 		 */
   2132      1.1  christos 		*flags |= PCAP_IF_UP | PCAP_IF_RUNNING | PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
   2133      1.1  christos 		return (0);
   2134      1.1  christos 	}
   2135      1.1  christos 
   2136      1.1  christos 	/*
   2137      1.1  christos 	 * We need to open the adapter to get this information.
   2138      1.1  christos 	 *
   2139      1.1  christos 	 * XXX - PacketOpenAdapter() takes a non-const pointer
   2140      1.1  christos 	 * as an argument, so we make a copy of the argument and
   2141      1.1  christos 	 * pass that to it.
   2142      1.1  christos 	 */
   2143      1.1  christos 	name_copy = strdup(name);
   2144      1.1  christos 	adapter = PacketOpenAdapter(name_copy);
   2145      1.1  christos 	free(name_copy);
   2146      1.1  christos 	if (adapter == NULL) {
   2147      1.1  christos 		/*
   2148      1.1  christos 		 * Give up; if they try to open this device, it'll fail.
   2149      1.1  christos 		 */
   2150      1.1  christos 		return (0);
   2151      1.1  christos 	}
   2152      1.1  christos 
   2153      1.1  christos #ifdef HAVE_AIRPCAP_API
   2154      1.1  christos 	/*
   2155      1.1  christos 	 * Airpcap.sys do not support the below 'OID_GEN_x' values.
   2156      1.1  christos 	 * Just set these flags (and none of the '*flags' entered with).
   2157      1.1  christos 	 */
   2158      1.1  christos 	if (PacketGetAirPcapHandle(adapter)) {
   2159      1.1  christos 		/*
   2160      1.1  christos 		 * Must be "up" and "running" if the above if succeeded.
   2161      1.1  christos 		 */
   2162      1.1  christos 		*flags = PCAP_IF_UP | PCAP_IF_RUNNING;
   2163      1.1  christos 
   2164      1.1  christos 		/*
   2165      1.1  christos 		 * An airpcap device is a wireless device (duh!)
   2166      1.1  christos 		 */
   2167      1.1  christos 		*flags |= PCAP_IF_WIRELESS;
   2168      1.1  christos 
   2169      1.1  christos 		/*
   2170  1.1.1.3  christos 		 * A "network association state" makes no sense for airpcap.
   2171      1.1  christos 		 */
   2172      1.1  christos 		*flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
   2173      1.1  christos 		PacketCloseAdapter(adapter);
   2174      1.1  christos 		return (0);
   2175      1.1  christos 	}
   2176      1.1  christos #endif
   2177      1.1  christos 
   2178      1.1  christos 	/*
   2179      1.1  christos 	 * Get the hardware status, and derive "up" and "running" from
   2180      1.1  christos 	 * that.
   2181      1.1  christos 	 */
   2182      1.1  christos 	len = sizeof (hardware_status);
   2183      1.1  christos 	status = oid_get_request(adapter, OID_GEN_HARDWARE_STATUS,
   2184      1.1  christos 	    &hardware_status, &len, errbuf);
   2185      1.1  christos 	if (status == 0) {
   2186      1.1  christos 		switch (hardware_status) {
   2187      1.1  christos 
   2188      1.1  christos 		case NdisHardwareStatusReady:
   2189      1.1  christos 			/*
   2190      1.1  christos 			 * "Available and capable of sending and receiving
   2191      1.1  christos 			 * data over the wire", so up and running.
   2192      1.1  christos 			 */
   2193      1.1  christos 			*flags |= PCAP_IF_UP | PCAP_IF_RUNNING;
   2194      1.1  christos 			break;
   2195      1.1  christos 
   2196      1.1  christos 		case NdisHardwareStatusInitializing:
   2197      1.1  christos 		case NdisHardwareStatusReset:
   2198      1.1  christos 			/*
   2199      1.1  christos 			 * "Initializing" or "Resetting", so up, but
   2200      1.1  christos 			 * not running.
   2201      1.1  christos 			 */
   2202      1.1  christos 			*flags |= PCAP_IF_UP;
   2203      1.1  christos 			break;
   2204      1.1  christos 
   2205      1.1  christos 		case NdisHardwareStatusClosing:
   2206      1.1  christos 		case NdisHardwareStatusNotReady:
   2207      1.1  christos 			/*
   2208      1.1  christos 			 * "Closing" or "Not ready", so neither up nor
   2209      1.1  christos 			 * running.
   2210      1.1  christos 			 */
   2211      1.1  christos 			break;
   2212  1.1.1.3  christos 
   2213  1.1.1.3  christos 		default:
   2214  1.1.1.3  christos 			/*
   2215  1.1.1.3  christos 			 * Unknown.
   2216  1.1.1.3  christos 			 */
   2217  1.1.1.3  christos 			break;
   2218      1.1  christos 		}
   2219      1.1  christos 	} else {
   2220      1.1  christos 		/*
   2221      1.1  christos 		 * Can't get the hardware status, so assume both up and
   2222      1.1  christos 		 * running.
   2223      1.1  christos 		 */
   2224      1.1  christos 		*flags |= PCAP_IF_UP | PCAP_IF_RUNNING;
   2225      1.1  christos 	}
   2226      1.1  christos 
   2227      1.1  christos 	/*
   2228      1.1  christos 	 * Get the network type.
   2229      1.1  christos 	 */
   2230      1.1  christos #ifdef OID_GEN_PHYSICAL_MEDIUM
   2231      1.1  christos 	/*
   2232      1.1  christos 	 * Try the OIDs we have for this, in order.
   2233      1.1  christos 	 */
   2234      1.1  christos 	for (i = 0; i < N_GEN_PHYSICAL_MEDIUM_OIDS; i++) {
   2235      1.1  christos 		len = sizeof (phys_medium);
   2236      1.1  christos 		status = oid_get_request(adapter, gen_physical_medium_oids[i],
   2237      1.1  christos 		    &phys_medium, &len, errbuf);
   2238      1.1  christos 		if (status == 0) {
   2239      1.1  christos 			/*
   2240      1.1  christos 			 * Success.
   2241      1.1  christos 			 */
   2242      1.1  christos 			break;
   2243      1.1  christos 		}
   2244      1.1  christos 		/*
   2245      1.1  christos 		 * Failed.  We can't determine whether it failed
   2246      1.1  christos 		 * because that particular OID isn't supported
   2247      1.1  christos 		 * or because some other problem occurred, so we
   2248      1.1  christos 		 * just drive on and try the next OID.
   2249      1.1  christos 		 */
   2250      1.1  christos 	}
   2251      1.1  christos 	if (status == 0) {
   2252      1.1  christos 		/*
   2253      1.1  christos 		 * We got the physical medium.
   2254  1.1.1.3  christos 		 *
   2255  1.1.1.3  christos 		 * XXX - we might want to check for NdisPhysicalMediumWiMax
   2256  1.1.1.3  christos 		 * and NdisPhysicalMediumNative802_15_4 being
   2257  1.1.1.3  christos 		 * part of the enum, and check for those in the "wireless"
   2258  1.1.1.3  christos 		 * case.
   2259      1.1  christos 		 */
   2260  1.1.1.3  christos DIAG_OFF_ENUM_SWITCH
   2261      1.1  christos 		switch (phys_medium) {
   2262      1.1  christos 
   2263      1.1  christos 		case NdisPhysicalMediumWirelessLan:
   2264      1.1  christos 		case NdisPhysicalMediumWirelessWan:
   2265      1.1  christos 		case NdisPhysicalMediumNative802_11:
   2266      1.1  christos 		case NdisPhysicalMediumBluetooth:
   2267      1.1  christos 		case NdisPhysicalMediumUWB:
   2268      1.1  christos 		case NdisPhysicalMediumIrda:
   2269      1.1  christos 			/*
   2270      1.1  christos 			 * Wireless.
   2271      1.1  christos 			 */
   2272      1.1  christos 			*flags |= PCAP_IF_WIRELESS;
   2273      1.1  christos 			break;
   2274      1.1  christos 
   2275      1.1  christos 		default:
   2276      1.1  christos 			/*
   2277  1.1.1.3  christos 			 * Not wireless or unknown
   2278      1.1  christos 			 */
   2279      1.1  christos 			break;
   2280      1.1  christos 		}
   2281  1.1.1.3  christos DIAG_ON_ENUM_SWITCH
   2282      1.1  christos 	}
   2283      1.1  christos #endif
   2284      1.1  christos 
   2285      1.1  christos 	/*
   2286      1.1  christos 	 * Get the connection status.
   2287      1.1  christos 	 */
   2288      1.1  christos #ifdef OID_GEN_LINK_STATE
   2289      1.1  christos 	len = sizeof(link_state);
   2290      1.1  christos 	status = oid_get_request(adapter, OID_GEN_LINK_STATE, &link_state,
   2291      1.1  christos 	    &len, errbuf);
   2292      1.1  christos 	if (status == 0) {
   2293      1.1  christos 		/*
   2294      1.1  christos 		 * NOTE: this also gives us the receive and transmit
   2295      1.1  christos 		 * link state.
   2296      1.1  christos 		 */
   2297      1.1  christos 		switch (link_state.MediaConnectState) {
   2298      1.1  christos 
   2299      1.1  christos 		case MediaConnectStateConnected:
   2300      1.1  christos 			/*
   2301      1.1  christos 			 * It's connected.
   2302      1.1  christos 			 */
   2303      1.1  christos 			*flags |= PCAP_IF_CONNECTION_STATUS_CONNECTED;
   2304      1.1  christos 			break;
   2305      1.1  christos 
   2306      1.1  christos 		case MediaConnectStateDisconnected:
   2307      1.1  christos 			/*
   2308      1.1  christos 			 * It's disconnected.
   2309      1.1  christos 			 */
   2310      1.1  christos 			*flags |= PCAP_IF_CONNECTION_STATUS_DISCONNECTED;
   2311      1.1  christos 			break;
   2312  1.1.1.3  christos 
   2313  1.1.1.3  christos 		case MediaConnectStateUnknown:
   2314  1.1.1.3  christos 		default:
   2315  1.1.1.3  christos 			/*
   2316  1.1.1.3  christos 			 * It's unknown whether it's connected or not.
   2317  1.1.1.3  christos 			 */
   2318  1.1.1.3  christos 			break;
   2319      1.1  christos 		}
   2320      1.1  christos 	}
   2321      1.1  christos #else
   2322      1.1  christos 	/*
   2323      1.1  christos 	 * OID_GEN_LINK_STATE isn't supported because it's not in our SDK.
   2324      1.1  christos 	 */
   2325      1.1  christos 	status = -1;
   2326      1.1  christos #endif
   2327      1.1  christos 	if (status == -1) {
   2328      1.1  christos 		/*
   2329      1.1  christos 		 * OK, OID_GEN_LINK_STATE didn't work, try
   2330      1.1  christos 		 * OID_GEN_MEDIA_CONNECT_STATUS.
   2331      1.1  christos 		 */
   2332      1.1  christos 		status = oid_get_request(adapter, OID_GEN_MEDIA_CONNECT_STATUS,
   2333      1.1  christos 		    &connect_status, &len, errbuf);
   2334      1.1  christos 		if (status == 0) {
   2335      1.1  christos 			switch (connect_status) {
   2336      1.1  christos 
   2337      1.1  christos 			case NdisMediaStateConnected:
   2338      1.1  christos 				/*
   2339      1.1  christos 				 * It's connected.
   2340      1.1  christos 				 */
   2341      1.1  christos 				*flags |= PCAP_IF_CONNECTION_STATUS_CONNECTED;
   2342      1.1  christos 				break;
   2343      1.1  christos 
   2344      1.1  christos 			case NdisMediaStateDisconnected:
   2345      1.1  christos 				/*
   2346      1.1  christos 				 * It's disconnected.
   2347      1.1  christos 				 */
   2348      1.1  christos 				*flags |= PCAP_IF_CONNECTION_STATUS_DISCONNECTED;
   2349      1.1  christos 				break;
   2350      1.1  christos 			}
   2351      1.1  christos 		}
   2352      1.1  christos 	}
   2353      1.1  christos 	PacketCloseAdapter(adapter);
   2354      1.1  christos 	return (0);
   2355      1.1  christos }
   2356      1.1  christos 
   2357      1.1  christos int
   2358  1.1.1.4  christos pcapint_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
   2359      1.1  christos {
   2360      1.1  christos 	int ret = 0;
   2361      1.1  christos 	const char *desc;
   2362      1.1  christos 	char *AdaptersName;
   2363      1.1  christos 	ULONG NameLength;
   2364      1.1  christos 	char *name;
   2365      1.1  christos 
   2366      1.1  christos 	/*
   2367      1.1  christos 	 * Find out how big a buffer we need.
   2368      1.1  christos 	 *
   2369      1.1  christos 	 * This call should always return FALSE; if the error is
   2370      1.1  christos 	 * ERROR_INSUFFICIENT_BUFFER, NameLength will be set to
   2371      1.1  christos 	 * the size of the buffer we need, otherwise there's a
   2372      1.1  christos 	 * problem, and NameLength should be set to 0.
   2373      1.1  christos 	 *
   2374      1.1  christos 	 * It shouldn't require NameLength to be set, but,
   2375      1.1  christos 	 * at least as of WinPcap 4.1.3, it checks whether
   2376      1.1  christos 	 * NameLength is big enough before it checks for a
   2377      1.1  christos 	 * NULL buffer argument, so, while it'll still do
   2378      1.1  christos 	 * the right thing if NameLength is uninitialized and
   2379      1.1  christos 	 * whatever junk happens to be there is big enough
   2380      1.1  christos 	 * (because the pointer argument will be null), it's
   2381      1.1  christos 	 * still reading an uninitialized variable.
   2382      1.1  christos 	 */
   2383      1.1  christos 	NameLength = 0;
   2384      1.1  christos 	if (!PacketGetAdapterNames(NULL, &NameLength))
   2385      1.1  christos 	{
   2386      1.1  christos 		DWORD last_error = GetLastError();
   2387      1.1  christos 
   2388      1.1  christos 		if (last_error != ERROR_INSUFFICIENT_BUFFER)
   2389      1.1  christos 		{
   2390  1.1.1.4  christos 			pcapint_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
   2391  1.1.1.2  christos 			    last_error, "PacketGetAdapterNames");
   2392      1.1  christos 			return (-1);
   2393      1.1  christos 		}
   2394      1.1  christos 	}
   2395      1.1  christos 
   2396      1.1  christos 	if (NameLength <= 0)
   2397      1.1  christos 		return 0;
   2398      1.1  christos 	AdaptersName = (char*) malloc(NameLength);
   2399      1.1  christos 	if (AdaptersName == NULL)
   2400      1.1  christos 	{
   2401  1.1.1.3  christos 		snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters.");
   2402      1.1  christos 		return (-1);
   2403      1.1  christos 	}
   2404      1.1  christos 
   2405      1.1  christos 	if (!PacketGetAdapterNames(AdaptersName, &NameLength)) {
   2406  1.1.1.4  christos 		pcapint_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
   2407  1.1.1.2  christos 		    GetLastError(), "PacketGetAdapterNames");
   2408      1.1  christos 		free(AdaptersName);
   2409      1.1  christos 		return (-1);
   2410      1.1  christos 	}
   2411      1.1  christos 
   2412      1.1  christos 	/*
   2413      1.1  christos 	 * "PacketGetAdapterNames()" returned a list of
   2414      1.1  christos 	 * null-terminated ASCII interface name strings,
   2415      1.1  christos 	 * terminated by a null string, followed by a list
   2416      1.1  christos 	 * of null-terminated ASCII interface description
   2417      1.1  christos 	 * strings, terminated by a null string.
   2418      1.1  christos 	 * This means there are two ASCII nulls at the end
   2419      1.1  christos 	 * of the first list.
   2420      1.1  christos 	 *
   2421      1.1  christos 	 * Find the end of the first list; that's the
   2422      1.1  christos 	 * beginning of the second list.
   2423      1.1  christos 	 */
   2424      1.1  christos 	desc = &AdaptersName[0];
   2425      1.1  christos 	while (*desc != '\0' || *(desc + 1) != '\0')
   2426      1.1  christos 		desc++;
   2427      1.1  christos 
   2428      1.1  christos 	/*
   2429  1.1.1.3  christos 	 * Found it - "desc" points to the first of the two
   2430      1.1  christos 	 * nulls at the end of the list of names, so the
   2431      1.1  christos 	 * first byte of the list of descriptions is two bytes
   2432      1.1  christos 	 * after it.
   2433      1.1  christos 	 */
   2434      1.1  christos 	desc += 2;
   2435      1.1  christos 
   2436      1.1  christos 	/*
   2437      1.1  christos 	 * Loop over the elements in the first list.
   2438      1.1  christos 	 */
   2439      1.1  christos 	name = &AdaptersName[0];
   2440      1.1  christos 	while (*name != '\0') {
   2441      1.1  christos 		bpf_u_int32 flags = 0;
   2442  1.1.1.3  christos 
   2443  1.1.1.3  christos #ifdef HAVE_AIRPCAP_API
   2444  1.1.1.3  christos 		/*
   2445  1.1.1.3  christos 		 * Is this an AirPcap device?
   2446  1.1.1.3  christos 		 * If so, ignore it; it'll get added later, by the
   2447  1.1.1.3  christos 		 * AirPcap code.
   2448  1.1.1.3  christos 		 */
   2449  1.1.1.3  christos 		if (device_is_airpcap(name, errbuf) == 1) {
   2450  1.1.1.3  christos 			name += strlen(name) + 1;
   2451  1.1.1.3  christos 			desc += strlen(desc) + 1;
   2452  1.1.1.3  christos 			continue;
   2453  1.1.1.3  christos 		}
   2454  1.1.1.3  christos #endif
   2455  1.1.1.3  christos 
   2456      1.1  christos #ifdef HAVE_PACKET_IS_LOOPBACK_ADAPTER
   2457      1.1  christos 		/*
   2458      1.1  christos 		 * Is this a loopback interface?
   2459      1.1  christos 		 */
   2460      1.1  christos 		if (PacketIsLoopbackAdapter(name)) {
   2461      1.1  christos 			/* Yes */
   2462      1.1  christos 			flags |= PCAP_IF_LOOPBACK;
   2463      1.1  christos 		}
   2464      1.1  christos #endif
   2465      1.1  christos 		/*
   2466      1.1  christos 		 * Get additional flags.
   2467      1.1  christos 		 */
   2468      1.1  christos 		if (get_if_flags(name, &flags, errbuf) == -1) {
   2469      1.1  christos 			/*
   2470      1.1  christos 			 * Failure.
   2471      1.1  christos 			 */
   2472      1.1  christos 			ret = -1;
   2473      1.1  christos 			break;
   2474      1.1  christos 		}
   2475      1.1  christos 
   2476      1.1  christos 		/*
   2477      1.1  christos 		 * Add an entry for this interface.
   2478      1.1  christos 		 */
   2479      1.1  christos 		if (pcap_add_if_npf(devlistp, name, flags, desc,
   2480      1.1  christos 		    errbuf) == -1) {
   2481      1.1  christos 			/*
   2482      1.1  christos 			 * Failure.
   2483      1.1  christos 			 */
   2484      1.1  christos 			ret = -1;
   2485      1.1  christos 			break;
   2486      1.1  christos 		}
   2487      1.1  christos 		name += strlen(name) + 1;
   2488      1.1  christos 		desc += strlen(desc) + 1;
   2489      1.1  christos 	}
   2490      1.1  christos 
   2491      1.1  christos 	free(AdaptersName);
   2492      1.1  christos 	return (ret);
   2493      1.1  christos }
   2494      1.1  christos 
   2495      1.1  christos /*
   2496      1.1  christos  * Return the name of a network interface attached to the system, or NULL
   2497      1.1  christos  * if none can be found.  The interface must be configured up; the
   2498      1.1  christos  * lowest unit number is preferred; loopback is ignored.
   2499      1.1  christos  *
   2500      1.1  christos  * In the best of all possible worlds, this would be the same as on
   2501      1.1  christos  * UN*X, but there may be software that expects this to return a
   2502      1.1  christos  * full list of devices after the first device.
   2503      1.1  christos  */
   2504      1.1  christos #define ADAPTERSNAME_LEN	8192
   2505      1.1  christos char *
   2506      1.1  christos pcap_lookupdev(char *errbuf)
   2507      1.1  christos {
   2508      1.1  christos 	DWORD dwVersion;
   2509      1.1  christos 	DWORD dwWindowsMajorVersion;
   2510      1.1  christos 
   2511  1.1.1.3  christos 	/*
   2512  1.1.1.3  christos 	 * We disable this in "new API" mode, because 1) in WinPcap/Npcap,
   2513  1.1.1.3  christos 	 * it may return UTF-16 strings, for backwards-compatibility
   2514  1.1.1.3  christos 	 * reasons, and we're also disabling the hack to make that work,
   2515  1.1.1.3  christos 	 * for not-going-past-the-end-of-a-string reasons, and 2) we
   2516  1.1.1.3  christos 	 * want its behavior to be consistent.
   2517  1.1.1.3  christos 	 *
   2518  1.1.1.3  christos 	 * In addition, it's not thread-safe, so we've marked it as
   2519  1.1.1.3  christos 	 * deprecated.
   2520  1.1.1.3  christos 	 */
   2521  1.1.1.4  christos 	if (pcapint_new_api) {
   2522  1.1.1.3  christos 		snprintf(errbuf, PCAP_ERRBUF_SIZE,
   2523  1.1.1.3  christos 		    "pcap_lookupdev() is deprecated and is not supported in programs calling pcap_init()");
   2524  1.1.1.3  christos 		return (NULL);
   2525  1.1.1.3  christos 	}
   2526  1.1.1.3  christos 
   2527  1.1.1.3  christos /* disable MSVC's GetVersion() deprecated warning here */
   2528  1.1.1.3  christos DIAG_OFF_DEPRECATION
   2529      1.1  christos 	dwVersion = GetVersion();	/* get the OS version */
   2530  1.1.1.3  christos DIAG_ON_DEPRECATION
   2531      1.1  christos 	dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
   2532      1.1  christos 
   2533      1.1  christos 	if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
   2534      1.1  christos 		/*
   2535      1.1  christos 		 * Windows 95, 98, ME.
   2536      1.1  christos 		 */
   2537      1.1  christos 		ULONG NameLength = ADAPTERSNAME_LEN;
   2538      1.1  christos 		static char AdaptersName[ADAPTERSNAME_LEN];
   2539      1.1  christos 
   2540      1.1  christos 		if (PacketGetAdapterNames(AdaptersName,&NameLength) )
   2541      1.1  christos 			return (AdaptersName);
   2542      1.1  christos 		else
   2543      1.1  christos 			return NULL;
   2544      1.1  christos 	} else {
   2545      1.1  christos 		/*
   2546      1.1  christos 		 * Windows NT (NT 4.0 and later).
   2547      1.1  christos 		 * Convert the names to Unicode for backward compatibility.
   2548      1.1  christos 		 */
   2549      1.1  christos 		ULONG NameLength = ADAPTERSNAME_LEN;
   2550      1.1  christos 		static WCHAR AdaptersName[ADAPTERSNAME_LEN];
   2551      1.1  christos 		size_t BufferSpaceLeft;
   2552      1.1  christos 		char *tAstr;
   2553      1.1  christos 		WCHAR *Unameptr;
   2554      1.1  christos 		char *Adescptr;
   2555      1.1  christos 		size_t namelen, i;
   2556      1.1  christos 		WCHAR *TAdaptersName = (WCHAR*)malloc(ADAPTERSNAME_LEN * sizeof(WCHAR));
   2557      1.1  christos 		int NAdapts = 0;
   2558      1.1  christos 
   2559      1.1  christos 		if(TAdaptersName == NULL)
   2560      1.1  christos 		{
   2561  1.1.1.3  christos 			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
   2562      1.1  christos 			return NULL;
   2563      1.1  christos 		}
   2564      1.1  christos 
   2565      1.1  christos 		if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
   2566      1.1  christos 		{
   2567  1.1.1.4  christos 			pcapint_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
   2568  1.1.1.2  christos 			    GetLastError(), "PacketGetAdapterNames");
   2569      1.1  christos 			free(TAdaptersName);
   2570      1.1  christos 			return NULL;
   2571      1.1  christos 		}
   2572      1.1  christos 
   2573      1.1  christos 
   2574      1.1  christos 		BufferSpaceLeft = ADAPTERSNAME_LEN * sizeof(WCHAR);
   2575      1.1  christos 		tAstr = (char*)TAdaptersName;
   2576      1.1  christos 		Unameptr = AdaptersName;
   2577      1.1  christos 
   2578      1.1  christos 		/*
   2579      1.1  christos 		 * Convert the device names to Unicode into AdapterName.
   2580      1.1  christos 		 */
   2581      1.1  christos 		do {
   2582      1.1  christos 			/*
   2583      1.1  christos 			 * Length of the name, including the terminating
   2584      1.1  christos 			 * NUL.
   2585      1.1  christos 			 */
   2586      1.1  christos 			namelen = strlen(tAstr) + 1;
   2587      1.1  christos 
   2588      1.1  christos 			/*
   2589      1.1  christos 			 * Do we have room for the name in the Unicode
   2590      1.1  christos 			 * buffer?
   2591      1.1  christos 			 */
   2592      1.1  christos 			if (BufferSpaceLeft < namelen * sizeof(WCHAR)) {
   2593      1.1  christos 				/*
   2594      1.1  christos 				 * No.
   2595      1.1  christos 				 */
   2596      1.1  christos 				goto quit;
   2597      1.1  christos 			}
   2598      1.1  christos 			BufferSpaceLeft -= namelen * sizeof(WCHAR);
   2599      1.1  christos 
   2600      1.1  christos 			/*
   2601      1.1  christos 			 * Copy the name, converting ASCII to Unicode.
   2602      1.1  christos 			 * namelen includes the NUL, so we copy it as
   2603      1.1  christos 			 * well.
   2604      1.1  christos 			 */
   2605      1.1  christos 			for (i = 0; i < namelen; i++)
   2606      1.1  christos 				*Unameptr++ = *tAstr++;
   2607      1.1  christos 
   2608      1.1  christos 			/*
   2609      1.1  christos 			 * Count this adapter.
   2610      1.1  christos 			 */
   2611      1.1  christos 			NAdapts++;
   2612      1.1  christos 		} while (namelen != 1);
   2613      1.1  christos 
   2614      1.1  christos 		/*
   2615      1.1  christos 		 * Copy the descriptions, but don't convert them from
   2616      1.1  christos 		 * ASCII to Unicode.
   2617      1.1  christos 		 */
   2618      1.1  christos 		Adescptr = (char *)Unameptr;
   2619      1.1  christos 		while(NAdapts--)
   2620      1.1  christos 		{
   2621      1.1  christos 			size_t desclen;
   2622      1.1  christos 
   2623      1.1  christos 			desclen = strlen(tAstr) + 1;
   2624      1.1  christos 
   2625      1.1  christos 			/*
   2626      1.1  christos 			 * Do we have room for the name in the Unicode
   2627      1.1  christos 			 * buffer?
   2628      1.1  christos 			 */
   2629      1.1  christos 			if (BufferSpaceLeft < desclen) {
   2630      1.1  christos 				/*
   2631      1.1  christos 				 * No.
   2632      1.1  christos 				 */
   2633      1.1  christos 				goto quit;
   2634      1.1  christos 			}
   2635      1.1  christos 
   2636      1.1  christos 			/*
   2637      1.1  christos 			 * Just copy the ASCII string.
   2638      1.1  christos 			 * namelen includes the NUL, so we copy it as
   2639      1.1  christos 			 * well.
   2640      1.1  christos 			 */
   2641      1.1  christos 			memcpy(Adescptr, tAstr, desclen);
   2642      1.1  christos 			Adescptr += desclen;
   2643      1.1  christos 			tAstr += desclen;
   2644      1.1  christos 			BufferSpaceLeft -= desclen;
   2645      1.1  christos 		}
   2646      1.1  christos 
   2647      1.1  christos 	quit:
   2648      1.1  christos 		free(TAdaptersName);
   2649      1.1  christos 		return (char *)(AdaptersName);
   2650      1.1  christos 	}
   2651      1.1  christos }
   2652      1.1  christos 
   2653      1.1  christos /*
   2654      1.1  christos  * We can't use the same code that we use on UN*X, as that's doing
   2655      1.1  christos  * UN*X-specific calls.
   2656      1.1  christos  *
   2657      1.1  christos  * We don't just fetch the entire list of devices, search for the
   2658      1.1  christos  * particular device, and use its first IPv4 address, as that's too
   2659      1.1  christos  * much work to get just one device's netmask.
   2660      1.1  christos  */
   2661      1.1  christos int
   2662      1.1  christos pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
   2663      1.1  christos     char *errbuf)
   2664      1.1  christos {
   2665      1.1  christos 	/*
   2666      1.1  christos 	 * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo()
   2667      1.1  christos 	 * in order to skip non IPv4 (i.e. IPv6 addresses)
   2668      1.1  christos 	 */
   2669      1.1  christos 	npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
   2670      1.1  christos 	LONG if_addr_size = MAX_NETWORK_ADDRESSES;
   2671      1.1  christos 	struct sockaddr_in *t_addr;
   2672      1.1  christos 	LONG i;
   2673      1.1  christos 
   2674      1.1  christos 	if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) {
   2675      1.1  christos 		*netp = *maskp = 0;
   2676      1.1  christos 		return (0);
   2677      1.1  christos 	}
   2678      1.1  christos 
   2679      1.1  christos 	for(i = 0; i < if_addr_size; i++)
   2680      1.1  christos 	{
   2681      1.1  christos 		if(if_addrs[i].IPAddress.ss_family == AF_INET)
   2682      1.1  christos 		{
   2683      1.1  christos 			t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress);
   2684      1.1  christos 			*netp = t_addr->sin_addr.S_un.S_addr;
   2685      1.1  christos 			t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask);
   2686      1.1  christos 			*maskp = t_addr->sin_addr.S_un.S_addr;
   2687      1.1  christos 
   2688      1.1  christos 			*netp &= *maskp;
   2689      1.1  christos 			return (0);
   2690      1.1  christos 		}
   2691      1.1  christos 
   2692      1.1  christos 	}
   2693      1.1  christos 
   2694      1.1  christos 	*netp = *maskp = 0;
   2695      1.1  christos 	return (0);
   2696      1.1  christos }
   2697      1.1  christos 
   2698      1.1  christos static const char *pcap_lib_version_string;
   2699      1.1  christos 
   2700      1.1  christos #ifdef HAVE_VERSION_H
   2701      1.1  christos /*
   2702      1.1  christos  * libpcap being built for Windows, as part of a WinPcap/Npcap source
   2703      1.1  christos  * tree.  Include version.h from that source tree to get the WinPcap/Npcap
   2704      1.1  christos  * version.
   2705      1.1  christos  *
   2706  1.1.1.2  christos  * XXX - it'd be nice if we could somehow generate the WinPcap/Npcap version
   2707  1.1.1.2  christos  * number when building as part of WinPcap/Npcap.  (It'd be nice to do so
   2708  1.1.1.2  christos  * for the packet.dll version number as well.)
   2709      1.1  christos  */
   2710      1.1  christos #include "../../version.h"
   2711      1.1  christos 
   2712      1.1  christos static const char pcap_version_string[] =
   2713      1.1  christos 	WINPCAP_PRODUCT_NAME " version " WINPCAP_VER_STRING ", based on " PCAP_VERSION_STRING;
   2714      1.1  christos 
   2715      1.1  christos const char *
   2716      1.1  christos pcap_lib_version(void)
   2717      1.1  christos {
   2718      1.1  christos 	if (pcap_lib_version_string == NULL) {
   2719      1.1  christos 		/*
   2720      1.1  christos 		 * Generate the version string.
   2721      1.1  christos 		 */
   2722  1.1.1.3  christos 		const char *packet_version_string = PacketGetVersion();
   2723  1.1.1.2  christos 
   2724      1.1  christos 		if (strcmp(WINPCAP_VER_STRING, packet_version_string) == 0) {
   2725      1.1  christos 			/*
   2726  1.1.1.2  christos 			 * WinPcap/Npcap version string and packet.dll version
   2727  1.1.1.2  christos 			 * string are the same; just report the WinPcap/Npcap
   2728      1.1  christos 			 * version.
   2729      1.1  christos 			 */
   2730      1.1  christos 			pcap_lib_version_string = pcap_version_string;
   2731      1.1  christos 		} else {
   2732      1.1  christos 			/*
   2733  1.1.1.2  christos 			 * WinPcap/Npcap version string and packet.dll version
   2734      1.1  christos 			 * string are different; that shouldn't be the
   2735      1.1  christos 			 * case (the two libraries should come from the
   2736  1.1.1.2  christos 			 * same version of WinPcap/Npcap), so we report both
   2737      1.1  christos 			 * versions.
   2738  1.1.1.2  christos 			 */
   2739  1.1.1.2  christos 			char *full_pcap_version_string;
   2740  1.1.1.2  christos 
   2741  1.1.1.4  christos 			if (pcapint_asprintf(&full_pcap_version_string,
   2742  1.1.1.2  christos 			    WINPCAP_PRODUCT_NAME " version " WINPCAP_VER_STRING " (packet.dll version %s), based on " PCAP_VERSION_STRING,
   2743  1.1.1.2  christos 			    packet_version_string) != -1) {
   2744  1.1.1.2  christos 				/* Success */
   2745  1.1.1.2  christos 				pcap_lib_version_string = full_pcap_version_string;
   2746  1.1.1.2  christos 			}
   2747      1.1  christos 		}
   2748      1.1  christos 	}
   2749      1.1  christos 	return (pcap_lib_version_string);
   2750      1.1  christos }
   2751      1.1  christos 
   2752      1.1  christos #else /* HAVE_VERSION_H */
   2753      1.1  christos 
   2754      1.1  christos /*
   2755      1.1  christos  * libpcap being built for Windows, not as part of a WinPcap/Npcap source
   2756      1.1  christos  * tree.
   2757      1.1  christos  */
   2758      1.1  christos const char *
   2759      1.1  christos pcap_lib_version(void)
   2760      1.1  christos {
   2761      1.1  christos 	if (pcap_lib_version_string == NULL) {
   2762      1.1  christos 		/*
   2763      1.1  christos 		 * Generate the version string.  Report the packet.dll
   2764      1.1  christos 		 * version.
   2765      1.1  christos 		 */
   2766  1.1.1.2  christos 		char *full_pcap_version_string;
   2767  1.1.1.2  christos 
   2768  1.1.1.4  christos 		if (pcapint_asprintf(&full_pcap_version_string,
   2769  1.1.1.2  christos 		    PCAP_VERSION_STRING " (packet.dll version %s)",
   2770  1.1.1.2  christos 		    PacketGetVersion()) != -1) {
   2771  1.1.1.2  christos 			/* Success */
   2772  1.1.1.2  christos 			pcap_lib_version_string = full_pcap_version_string;
   2773  1.1.1.2  christos 		}
   2774      1.1  christos 	}
   2775      1.1  christos 	return (pcap_lib_version_string);
   2776      1.1  christos }
   2777      1.1  christos #endif /* HAVE_VERSION_H */
   2778