Home | History | Annotate | Line # | Download | only in dist
pcap-npf.c revision 1.1
      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 #ifdef HAVE_CONFIG_H
     35  1.1  christos #include <config.h>
     36  1.1  christos #endif
     37  1.1  christos 
     38  1.1  christos #include <errno.h>
     39  1.1  christos #define PCAP_DONT_INCLUDE_PCAP_BPF_H
     40  1.1  christos #include <Packet32.h>
     41  1.1  christos #include <pcap-int.h>
     42  1.1  christos #include <pcap/dlt.h>
     43  1.1  christos 
     44  1.1  christos /* Old-school MinGW have these headers in a different place.
     45  1.1  christos  */
     46  1.1  christos #if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
     47  1.1  christos   #include <ddk/ntddndis.h>
     48  1.1  christos   #include <ddk/ndis.h>
     49  1.1  christos #else
     50  1.1  christos   #include <ntddndis.h>  /* MSVC/TDM-MinGW/MinGW64 */
     51  1.1  christos #endif
     52  1.1  christos 
     53  1.1  christos #ifdef HAVE_DAG_API
     54  1.1  christos   #include <dagnew.h>
     55  1.1  christos   #include <dagapi.h>
     56  1.1  christos #endif /* HAVE_DAG_API */
     57  1.1  christos 
     58  1.1  christos static int pcap_setfilter_npf(pcap_t *, struct bpf_program *);
     59  1.1  christos static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *);
     60  1.1  christos static int pcap_getnonblock_npf(pcap_t *);
     61  1.1  christos static int pcap_setnonblock_npf(pcap_t *, int);
     62  1.1  christos 
     63  1.1  christos /*dimension of the buffer in the pcap_t structure*/
     64  1.1  christos #define	WIN32_DEFAULT_USER_BUFFER_SIZE 256000
     65  1.1  christos 
     66  1.1  christos /*dimension of the buffer in the kernel driver NPF */
     67  1.1  christos #define	WIN32_DEFAULT_KERNEL_BUFFER_SIZE 1000000
     68  1.1  christos 
     69  1.1  christos /* Equivalent to ntohs(), but a lot faster under Windows */
     70  1.1  christos #define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8)
     71  1.1  christos 
     72  1.1  christos /*
     73  1.1  christos  * Private data for capturing on WinPcap devices.
     74  1.1  christos  */
     75  1.1  christos struct pcap_win {
     76  1.1  christos 	ADAPTER *adapter;		/* the packet32 ADAPTER for the device */
     77  1.1  christos 	int nonblock;
     78  1.1  christos 	int rfmon_selfstart;		/* a flag tells whether the monitor mode is set by itself */
     79  1.1  christos 	int filtering_in_kernel;	/* using kernel filter */
     80  1.1  christos 
     81  1.1  christos #ifdef HAVE_DAG_API
     82  1.1  christos 	int	dag_fcs_bits;		/* Number of checksum bits from link layer */
     83  1.1  christos #endif
     84  1.1  christos 
     85  1.1  christos #ifdef ENABLE_REMOTE
     86  1.1  christos 	int samp_npkt;			/* parameter needed for sampling, with '1 out of N' method has been requested */
     87  1.1  christos 	struct timeval samp_time;	/* parameter needed for sampling, with '1 every N ms' method has been requested */
     88  1.1  christos #endif
     89  1.1  christos };
     90  1.1  christos 
     91  1.1  christos /*
     92  1.1  christos  * Define stub versions of the monitor-mode support routines if this
     93  1.1  christos  * isn't Npcap. HAVE_NPCAP_PACKET_API is defined by Npcap but not
     94  1.1  christos  * WinPcap.
     95  1.1  christos  */
     96  1.1  christos #ifndef HAVE_NPCAP_PACKET_API
     97  1.1  christos static int
     98  1.1  christos PacketIsMonitorModeSupported(PCHAR AdapterName _U_)
     99  1.1  christos {
    100  1.1  christos 	/*
    101  1.1  christos 	 * We don't support monitor mode.
    102  1.1  christos 	 */
    103  1.1  christos 	return (0);
    104  1.1  christos }
    105  1.1  christos 
    106  1.1  christos static int
    107  1.1  christos PacketSetMonitorMode(PCHAR AdapterName _U_, int mode _U_)
    108  1.1  christos {
    109  1.1  christos 	/*
    110  1.1  christos 	 * This should never be called, as PacketIsMonitorModeSupported()
    111  1.1  christos 	 * will return 0, meaning "we don't support monitor mode, so
    112  1.1  christos 	 * don't try to turn it on or off".
    113  1.1  christos 	 */
    114  1.1  christos 	return (0);
    115  1.1  christos }
    116  1.1  christos 
    117  1.1  christos static int
    118  1.1  christos PacketGetMonitorMode(PCHAR AdapterName _U_)
    119  1.1  christos {
    120  1.1  christos 	/*
    121  1.1  christos 	 * This should fail, so that pcap_activate_npf() returns
    122  1.1  christos 	 * PCAP_ERROR_RFMON_NOTSUP if our caller requested monitor
    123  1.1  christos 	 * mode.
    124  1.1  christos 	 */
    125  1.1  christos 	return (-1);
    126  1.1  christos }
    127  1.1  christos #endif
    128  1.1  christos 
    129  1.1  christos /*
    130  1.1  christos  * Sigh.  PacketRequest() will have made a DeviceIoControl()
    131  1.1  christos  * call to the NPF driver to perform the OID request, with a
    132  1.1  christos  * BIOCQUERYOID ioctl.  The kernel code should get back one
    133  1.1  christos  * of NDIS_STATUS_INVALID_OID, NDIS_STATUS_NOT_SUPPORTED,
    134  1.1  christos  * or NDIS_STATUS_NOT_RECOGNIZED if the OID request isn't
    135  1.1  christos  * supported by the OS or the driver, but that doesn't seem
    136  1.1  christos  * to make it to the caller of PacketRequest() in a
    137  1.1  christos  * reliable fashion.
    138  1.1  christos  */
    139  1.1  christos #define NDIS_STATUS_INVALID_OID		0xc0010017
    140  1.1  christos #define NDIS_STATUS_NOT_SUPPORTED	0xc00000bb	/* STATUS_NOT_SUPPORTED */
    141  1.1  christos #define NDIS_STATUS_NOT_RECOGNIZED	0x00010001
    142  1.1  christos 
    143  1.1  christos static int
    144  1.1  christos oid_get_request(ADAPTER *adapter, bpf_u_int32 oid, void *data, size_t *lenp,
    145  1.1  christos     char *errbuf)
    146  1.1  christos {
    147  1.1  christos 	PACKET_OID_DATA *oid_data_arg;
    148  1.1  christos 
    149  1.1  christos 	/*
    150  1.1  christos 	 * Allocate a PACKET_OID_DATA structure to hand to PacketRequest().
    151  1.1  christos 	 * It should be big enough to hold "*lenp" bytes of data; it
    152  1.1  christos 	 * will actually be slightly larger, as PACKET_OID_DATA has a
    153  1.1  christos 	 * 1-byte data array at the end, standing in for the variable-length
    154  1.1  christos 	 * data that's actually there.
    155  1.1  christos 	 */
    156  1.1  christos 	oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp);
    157  1.1  christos 	if (oid_data_arg == NULL) {
    158  1.1  christos 		pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
    159  1.1  christos 		    "Couldn't allocate argument buffer for PacketRequest");
    160  1.1  christos 		return (PCAP_ERROR);
    161  1.1  christos 	}
    162  1.1  christos 
    163  1.1  christos 	/*
    164  1.1  christos 	 * No need to copy the data - we're doing a fetch.
    165  1.1  christos 	 */
    166  1.1  christos 	oid_data_arg->Oid = oid;
    167  1.1  christos 	oid_data_arg->Length = (ULONG)(*lenp);	/* XXX - check for ridiculously large value? */
    168  1.1  christos 	if (!PacketRequest(adapter, FALSE, oid_data_arg)) {
    169  1.1  christos 		char errmsgbuf[PCAP_ERRBUF_SIZE+1];
    170  1.1  christos 
    171  1.1  christos 		pcap_win32_err_to_str(GetLastError(), errmsgbuf);
    172  1.1  christos 		pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
    173  1.1  christos 		    "Error calling PacketRequest: %s", errmsgbuf);
    174  1.1  christos 		free(oid_data_arg);
    175  1.1  christos 		return (-1);
    176  1.1  christos 	}
    177  1.1  christos 
    178  1.1  christos 	/*
    179  1.1  christos 	 * Get the length actually supplied.
    180  1.1  christos 	 */
    181  1.1  christos 	*lenp = oid_data_arg->Length;
    182  1.1  christos 
    183  1.1  christos 	/*
    184  1.1  christos 	 * Copy back the data we fetched.
    185  1.1  christos 	 */
    186  1.1  christos 	memcpy(data, oid_data_arg->Data, *lenp);
    187  1.1  christos 	free(oid_data_arg);
    188  1.1  christos 	return (0);
    189  1.1  christos }
    190  1.1  christos 
    191  1.1  christos static int
    192  1.1  christos pcap_stats_npf(pcap_t *p, struct pcap_stat *ps)
    193  1.1  christos {
    194  1.1  christos 	struct pcap_win *pw = p->priv;
    195  1.1  christos 	struct bpf_stat bstats;
    196  1.1  christos 	char errbuf[PCAP_ERRBUF_SIZE+1];
    197  1.1  christos 
    198  1.1  christos 	/*
    199  1.1  christos 	 * Try to get statistics.
    200  1.1  christos 	 *
    201  1.1  christos 	 * (Please note - "struct pcap_stat" is *not* the same as
    202  1.1  christos 	 * WinPcap's "struct bpf_stat". It might currently have the
    203  1.1  christos 	 * same layout, but let's not cheat.
    204  1.1  christos 	 *
    205  1.1  christos 	 * Note also that we don't fill in ps_capt, as we might have
    206  1.1  christos 	 * been called by code compiled against an earlier version of
    207  1.1  christos 	 * WinPcap that didn't have ps_capt, in which case filling it
    208  1.1  christos 	 * in would stomp on whatever comes after the structure passed
    209  1.1  christos 	 * to us.
    210  1.1  christos 	 */
    211  1.1  christos 	if (!PacketGetStats(pw->adapter, &bstats)) {
    212  1.1  christos 		pcap_win32_err_to_str(GetLastError(), errbuf);
    213  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    214  1.1  christos 		    "PacketGetStats error: %s", errbuf);
    215  1.1  christos 		return (-1);
    216  1.1  christos 	}
    217  1.1  christos 	ps->ps_recv = bstats.bs_recv;
    218  1.1  christos 	ps->ps_drop = bstats.bs_drop;
    219  1.1  christos 
    220  1.1  christos 	/*
    221  1.1  christos 	 * XXX - PacketGetStats() doesn't fill this in, so we just
    222  1.1  christos 	 * return 0.
    223  1.1  christos 	 */
    224  1.1  christos #if 0
    225  1.1  christos 	ps->ps_ifdrop = bstats.ps_ifdrop;
    226  1.1  christos #else
    227  1.1  christos 	ps->ps_ifdrop = 0;
    228  1.1  christos #endif
    229  1.1  christos 
    230  1.1  christos 	return (0);
    231  1.1  christos }
    232  1.1  christos 
    233  1.1  christos /*
    234  1.1  christos  * Win32-only routine for getting statistics.
    235  1.1  christos  *
    236  1.1  christos  * This way is definitely safer than passing the pcap_stat * from the userland.
    237  1.1  christos  * In fact, there could happen than the user allocates a variable which is not
    238  1.1  christos  * big enough for the new structure, and the library will write in a zone
    239  1.1  christos  * which is not allocated to this variable.
    240  1.1  christos  *
    241  1.1  christos  * In this way, we're pretty sure we are writing on memory allocated to this
    242  1.1  christos  * variable.
    243  1.1  christos  *
    244  1.1  christos  * XXX - but this is the wrong way to handle statistics.  Instead, we should
    245  1.1  christos  * have an API that returns data in a form like the Options section of a
    246  1.1  christos  * pcapng Interface Statistics Block:
    247  1.1  christos  *
    248  1.1  christos  *    http://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
    249  1.1  christos  *
    250  1.1  christos  * which would let us add new statistics straightforwardly and indicate which
    251  1.1  christos  * statistics we are and are *not* providing, rather than having to provide
    252  1.1  christos  * possibly-bogus values for statistics we can't provide.
    253  1.1  christos  */
    254  1.1  christos struct pcap_stat *
    255  1.1  christos pcap_stats_ex_npf(pcap_t *p, int *pcap_stat_size)
    256  1.1  christos {
    257  1.1  christos 	struct pcap_win *pw = p->priv;
    258  1.1  christos 	struct bpf_stat bstats;
    259  1.1  christos 	char errbuf[PCAP_ERRBUF_SIZE+1];
    260  1.1  christos 
    261  1.1  christos 	*pcap_stat_size = sizeof (p->stat);
    262  1.1  christos 
    263  1.1  christos 	/*
    264  1.1  christos 	 * Try to get statistics.
    265  1.1  christos 	 *
    266  1.1  christos 	 * (Please note - "struct pcap_stat" is *not* the same as
    267  1.1  christos 	 * WinPcap's "struct bpf_stat". It might currently have the
    268  1.1  christos 	 * same layout, but let's not cheat.)
    269  1.1  christos 	 */
    270  1.1  christos 	if (!PacketGetStatsEx(pw->adapter, &bstats)) {
    271  1.1  christos 		pcap_win32_err_to_str(GetLastError(), errbuf);
    272  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    273  1.1  christos 		    "PacketGetStatsEx error: %s", errbuf);
    274  1.1  christos 		return (NULL);
    275  1.1  christos 	}
    276  1.1  christos 	p->stat.ps_recv = bstats.bs_recv;
    277  1.1  christos 	p->stat.ps_drop = bstats.bs_drop;
    278  1.1  christos 	p->stat.ps_ifdrop = bstats.ps_ifdrop;
    279  1.1  christos #ifdef ENABLE_REMOTE
    280  1.1  christos 	p->stat.ps_capt = bstats.bs_capt;
    281  1.1  christos #endif
    282  1.1  christos 	return (&p->stat);
    283  1.1  christos }
    284  1.1  christos 
    285  1.1  christos /* Set the dimension of the kernel-level capture buffer */
    286  1.1  christos static int
    287  1.1  christos pcap_setbuff_npf(pcap_t *p, int dim)
    288  1.1  christos {
    289  1.1  christos 	struct pcap_win *pw = p->priv;
    290  1.1  christos 
    291  1.1  christos 	if(PacketSetBuff(pw->adapter,dim)==FALSE)
    292  1.1  christos 	{
    293  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
    294  1.1  christos 		return (-1);
    295  1.1  christos 	}
    296  1.1  christos 	return (0);
    297  1.1  christos }
    298  1.1  christos 
    299  1.1  christos /* Set the driver working mode */
    300  1.1  christos static int
    301  1.1  christos pcap_setmode_npf(pcap_t *p, int mode)
    302  1.1  christos {
    303  1.1  christos 	struct pcap_win *pw = p->priv;
    304  1.1  christos 
    305  1.1  christos 	if(PacketSetMode(pw->adapter,mode)==FALSE)
    306  1.1  christos 	{
    307  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized");
    308  1.1  christos 		return (-1);
    309  1.1  christos 	}
    310  1.1  christos 
    311  1.1  christos 	return (0);
    312  1.1  christos }
    313  1.1  christos 
    314  1.1  christos /*set the minimum amount of data that will release a read call*/
    315  1.1  christos static int
    316  1.1  christos pcap_setmintocopy_npf(pcap_t *p, int size)
    317  1.1  christos {
    318  1.1  christos 	struct pcap_win *pw = p->priv;
    319  1.1  christos 
    320  1.1  christos 	if(PacketSetMinToCopy(pw->adapter, size)==FALSE)
    321  1.1  christos 	{
    322  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size");
    323  1.1  christos 		return (-1);
    324  1.1  christos 	}
    325  1.1  christos 	return (0);
    326  1.1  christos }
    327  1.1  christos 
    328  1.1  christos static HANDLE
    329  1.1  christos pcap_getevent_npf(pcap_t *p)
    330  1.1  christos {
    331  1.1  christos 	struct pcap_win *pw = p->priv;
    332  1.1  christos 
    333  1.1  christos 	return (PacketGetReadEvent(pw->adapter));
    334  1.1  christos }
    335  1.1  christos 
    336  1.1  christos static int
    337  1.1  christos pcap_oid_get_request_npf(pcap_t *p, bpf_u_int32 oid, void *data, size_t *lenp)
    338  1.1  christos {
    339  1.1  christos 	struct pcap_win *pw = p->priv;
    340  1.1  christos 
    341  1.1  christos 	return (oid_get_request(pw->adapter, oid, data, lenp, p->errbuf));
    342  1.1  christos }
    343  1.1  christos 
    344  1.1  christos static int
    345  1.1  christos pcap_oid_set_request_npf(pcap_t *p, bpf_u_int32 oid, const void *data,
    346  1.1  christos     size_t *lenp)
    347  1.1  christos {
    348  1.1  christos 	struct pcap_win *pw = p->priv;
    349  1.1  christos 	PACKET_OID_DATA *oid_data_arg;
    350  1.1  christos 	char errbuf[PCAP_ERRBUF_SIZE+1];
    351  1.1  christos 
    352  1.1  christos 	/*
    353  1.1  christos 	 * Allocate a PACKET_OID_DATA structure to hand to PacketRequest().
    354  1.1  christos 	 * It should be big enough to hold "*lenp" bytes of data; it
    355  1.1  christos 	 * will actually be slightly larger, as PACKET_OID_DATA has a
    356  1.1  christos 	 * 1-byte data array at the end, standing in for the variable-length
    357  1.1  christos 	 * data that's actually there.
    358  1.1  christos 	 */
    359  1.1  christos 	oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp);
    360  1.1  christos 	if (oid_data_arg == NULL) {
    361  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    362  1.1  christos 		    "Couldn't allocate argument buffer for PacketRequest");
    363  1.1  christos 		return (PCAP_ERROR);
    364  1.1  christos 	}
    365  1.1  christos 
    366  1.1  christos 	oid_data_arg->Oid = oid;
    367  1.1  christos 	oid_data_arg->Length = (ULONG)(*lenp);	/* XXX - check for ridiculously large value? */
    368  1.1  christos 	memcpy(oid_data_arg->Data, data, *lenp);
    369  1.1  christos 	if (!PacketRequest(pw->adapter, TRUE, oid_data_arg)) {
    370  1.1  christos 		pcap_win32_err_to_str(GetLastError(), errbuf);
    371  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    372  1.1  christos 		    "Error calling PacketRequest: %s", errbuf);
    373  1.1  christos 		free(oid_data_arg);
    374  1.1  christos 		return (PCAP_ERROR);
    375  1.1  christos 	}
    376  1.1  christos 
    377  1.1  christos 	/*
    378  1.1  christos 	 * Get the length actually copied.
    379  1.1  christos 	 */
    380  1.1  christos 	*lenp = oid_data_arg->Length;
    381  1.1  christos 
    382  1.1  christos 	/*
    383  1.1  christos 	 * No need to copy the data - we're doing a set.
    384  1.1  christos 	 */
    385  1.1  christos 	free(oid_data_arg);
    386  1.1  christos 	return (0);
    387  1.1  christos }
    388  1.1  christos 
    389  1.1  christos static u_int
    390  1.1  christos pcap_sendqueue_transmit_npf(pcap_t *p, pcap_send_queue *queue, int sync)
    391  1.1  christos {
    392  1.1  christos 	struct pcap_win *pw = p->priv;
    393  1.1  christos 	u_int res;
    394  1.1  christos 	char errbuf[PCAP_ERRBUF_SIZE+1];
    395  1.1  christos 
    396  1.1  christos 	if (pw->adapter==NULL) {
    397  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    398  1.1  christos 		    "Cannot transmit a queue to an offline capture or to a TurboCap port");
    399  1.1  christos 		return (0);
    400  1.1  christos 	}
    401  1.1  christos 
    402  1.1  christos 	res = PacketSendPackets(pw->adapter,
    403  1.1  christos 		queue->buffer,
    404  1.1  christos 		queue->len,
    405  1.1  christos 		(BOOLEAN)sync);
    406  1.1  christos 
    407  1.1  christos 	if(res != queue->len){
    408  1.1  christos 		pcap_win32_err_to_str(GetLastError(), errbuf);
    409  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    410  1.1  christos 		    "Error opening adapter: %s", errbuf);
    411  1.1  christos 	}
    412  1.1  christos 
    413  1.1  christos 	return (res);
    414  1.1  christos }
    415  1.1  christos 
    416  1.1  christos static int
    417  1.1  christos pcap_setuserbuffer_npf(pcap_t *p, int size)
    418  1.1  christos {
    419  1.1  christos 	unsigned char *new_buff;
    420  1.1  christos 
    421  1.1  christos 	if (size<=0) {
    422  1.1  christos 		/* Bogus parameter */
    423  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    424  1.1  christos 		    "Error: invalid size %d",size);
    425  1.1  christos 		return (-1);
    426  1.1  christos 	}
    427  1.1  christos 
    428  1.1  christos 	/* Allocate the buffer */
    429  1.1  christos 	new_buff=(unsigned char*)malloc(sizeof(char)*size);
    430  1.1  christos 
    431  1.1  christos 	if (!new_buff) {
    432  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    433  1.1  christos 		    "Error: not enough memory");
    434  1.1  christos 		return (-1);
    435  1.1  christos 	}
    436  1.1  christos 
    437  1.1  christos 	free(p->buffer);
    438  1.1  christos 
    439  1.1  christos 	p->buffer=new_buff;
    440  1.1  christos 	p->bufsize=size;
    441  1.1  christos 
    442  1.1  christos 	return (0);
    443  1.1  christos }
    444  1.1  christos 
    445  1.1  christos static int
    446  1.1  christos pcap_live_dump_npf(pcap_t *p, char *filename, int maxsize, int maxpacks)
    447  1.1  christos {
    448  1.1  christos 	struct pcap_win *pw = p->priv;
    449  1.1  christos 	BOOLEAN res;
    450  1.1  christos 
    451  1.1  christos 	/* Set the packet driver in dump mode */
    452  1.1  christos 	res = PacketSetMode(pw->adapter, PACKET_MODE_DUMP);
    453  1.1  christos 	if(res == FALSE){
    454  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    455  1.1  christos 		    "Error setting dump mode");
    456  1.1  christos 		return (-1);
    457  1.1  christos 	}
    458  1.1  christos 
    459  1.1  christos 	/* Set the name of the dump file */
    460  1.1  christos 	res = PacketSetDumpName(pw->adapter, filename, (int)strlen(filename));
    461  1.1  christos 	if(res == FALSE){
    462  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    463  1.1  christos 		    "Error setting kernel dump file name");
    464  1.1  christos 		return (-1);
    465  1.1  christos 	}
    466  1.1  christos 
    467  1.1  christos 	/* Set the limits of the dump file */
    468  1.1  christos 	res = PacketSetDumpLimits(pw->adapter, maxsize, maxpacks);
    469  1.1  christos 	if(res == FALSE) {
    470  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    471  1.1  christos 		    		"Error setting dump limit");
    472  1.1  christos 		return (-1);
    473  1.1  christos 	}
    474  1.1  christos 
    475  1.1  christos 	return (0);
    476  1.1  christos }
    477  1.1  christos 
    478  1.1  christos static int
    479  1.1  christos pcap_live_dump_ended_npf(pcap_t *p, int sync)
    480  1.1  christos {
    481  1.1  christos 	struct pcap_win *pw = p->priv;
    482  1.1  christos 
    483  1.1  christos 	return (PacketIsDumpEnded(pw->adapter, (BOOLEAN)sync));
    484  1.1  christos }
    485  1.1  christos 
    486  1.1  christos static PAirpcapHandle
    487  1.1  christos pcap_get_airpcap_handle_npf(pcap_t *p)
    488  1.1  christos {
    489  1.1  christos #ifdef HAVE_AIRPCAP_API
    490  1.1  christos 	struct pcap_win *pw = p->priv;
    491  1.1  christos 
    492  1.1  christos 	return (PacketGetAirPcapHandle(pw->adapter));
    493  1.1  christos #else
    494  1.1  christos 	return (NULL);
    495  1.1  christos #endif /* HAVE_AIRPCAP_API */
    496  1.1  christos }
    497  1.1  christos 
    498  1.1  christos static int
    499  1.1  christos pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
    500  1.1  christos {
    501  1.1  christos 	PACKET Packet;
    502  1.1  christos 	int cc;
    503  1.1  christos 	int n = 0;
    504  1.1  christos 	register u_char *bp, *ep;
    505  1.1  christos 	u_char *datap;
    506  1.1  christos 	struct pcap_win *pw = p->priv;
    507  1.1  christos 
    508  1.1  christos 	cc = p->cc;
    509  1.1  christos 	if (p->cc == 0) {
    510  1.1  christos 		/*
    511  1.1  christos 		 * Has "pcap_breakloop()" been called?
    512  1.1  christos 		 */
    513  1.1  christos 		if (p->break_loop) {
    514  1.1  christos 			/*
    515  1.1  christos 			 * Yes - clear the flag that indicates that it
    516  1.1  christos 			 * has, and return PCAP_ERROR_BREAK to indicate
    517  1.1  christos 			 * that we were told to break out of the loop.
    518  1.1  christos 			 */
    519  1.1  christos 			p->break_loop = 0;
    520  1.1  christos 			return (PCAP_ERROR_BREAK);
    521  1.1  christos 		}
    522  1.1  christos 
    523  1.1  christos 		/*
    524  1.1  christos 		 * Capture the packets.
    525  1.1  christos 		 *
    526  1.1  christos 		 * The PACKET structure had a bunch of extra stuff for
    527  1.1  christos 		 * Windows 9x/Me, but the only interesting data in it
    528  1.1  christos 		 * in the versions of Windows that we support is just
    529  1.1  christos 		 * a copy of p->buffer, a copy of p->buflen, and the
    530  1.1  christos 		 * actual number of bytes read returned from
    531  1.1  christos 		 * PacketReceivePacket(), none of which has to be
    532  1.1  christos 		 * retained from call to call, so we just keep one on
    533  1.1  christos 		 * the stack.
    534  1.1  christos 		 */
    535  1.1  christos 		PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
    536  1.1  christos 		if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
    537  1.1  christos 			pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
    538  1.1  christos 			return (PCAP_ERROR);
    539  1.1  christos 		}
    540  1.1  christos 
    541  1.1  christos 		cc = Packet.ulBytesReceived;
    542  1.1  christos 
    543  1.1  christos 		bp = p->buffer;
    544  1.1  christos 	}
    545  1.1  christos 	else
    546  1.1  christos 		bp = p->bp;
    547  1.1  christos 
    548  1.1  christos 	/*
    549  1.1  christos 	 * Loop through each packet.
    550  1.1  christos 	 */
    551  1.1  christos #define bhp ((struct bpf_hdr *)bp)
    552  1.1  christos 	ep = bp + cc;
    553  1.1  christos 	for (;;) {
    554  1.1  christos 		register int caplen, hdrlen;
    555  1.1  christos 
    556  1.1  christos 		/*
    557  1.1  christos 		 * Has "pcap_breakloop()" been called?
    558  1.1  christos 		 * If so, return immediately - if we haven't read any
    559  1.1  christos 		 * packets, clear the flag and return PCAP_ERROR_BREAK
    560  1.1  christos 		 * to indicate that we were told to break out of the loop,
    561  1.1  christos 		 * otherwise leave the flag set, so that the *next* call
    562  1.1  christos 		 * will break out of the loop without having read any
    563  1.1  christos 		 * packets, and return the number of packets we've
    564  1.1  christos 		 * processed so far.
    565  1.1  christos 		 */
    566  1.1  christos 		if (p->break_loop) {
    567  1.1  christos 			if (n == 0) {
    568  1.1  christos 				p->break_loop = 0;
    569  1.1  christos 				return (PCAP_ERROR_BREAK);
    570  1.1  christos 			} else {
    571  1.1  christos 				p->bp = bp;
    572  1.1  christos 				p->cc = (int) (ep - bp);
    573  1.1  christos 				return (n);
    574  1.1  christos 			}
    575  1.1  christos 		}
    576  1.1  christos 		if (bp >= ep)
    577  1.1  christos 			break;
    578  1.1  christos 
    579  1.1  christos 		caplen = bhp->bh_caplen;
    580  1.1  christos 		hdrlen = bhp->bh_hdrlen;
    581  1.1  christos 		datap = bp + hdrlen;
    582  1.1  christos 
    583  1.1  christos 		/*
    584  1.1  christos 		 * Short-circuit evaluation: if using BPF filter
    585  1.1  christos 		 * in kernel, no need to do it now - we already know
    586  1.1  christos 		 * the packet passed the filter.
    587  1.1  christos 		 *
    588  1.1  christos 		 * XXX - bpf_filter() should always return TRUE if
    589  1.1  christos 		 * handed a null pointer for the program, but it might
    590  1.1  christos 		 * just try to "run" the filter, so we check here.
    591  1.1  christos 		 */
    592  1.1  christos 		if (pw->filtering_in_kernel ||
    593  1.1  christos 		    p->fcode.bf_insns == NULL ||
    594  1.1  christos 		    bpf_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) {
    595  1.1  christos #ifdef ENABLE_REMOTE
    596  1.1  christos 			switch (p->rmt_samp.method) {
    597  1.1  christos 
    598  1.1  christos 			case PCAP_SAMP_1_EVERY_N:
    599  1.1  christos 				pw->samp_npkt = (pw->samp_npkt + 1) % p->rmt_samp.value;
    600  1.1  christos 
    601  1.1  christos 				/* Discard all packets that are not '1 out of N' */
    602  1.1  christos 				if (pw->samp_npkt != 0) {
    603  1.1  christos 					bp += Packet_WORDALIGN(caplen + hdrlen);
    604  1.1  christos 					continue;
    605  1.1  christos 				}
    606  1.1  christos 				break;
    607  1.1  christos 
    608  1.1  christos 			case PCAP_SAMP_FIRST_AFTER_N_MS:
    609  1.1  christos 			    {
    610  1.1  christos 				struct pcap_pkthdr *pkt_header = (struct pcap_pkthdr*) bp;
    611  1.1  christos 
    612  1.1  christos 				/*
    613  1.1  christos 				 * Check if the timestamp of the arrived
    614  1.1  christos 				 * packet is smaller than our target time.
    615  1.1  christos 				 */
    616  1.1  christos 				if (pkt_header->ts.tv_sec < pw->samp_time.tv_sec ||
    617  1.1  christos 				   (pkt_header->ts.tv_sec == pw->samp_time.tv_sec && pkt_header->ts.tv_usec < pw->samp_time.tv_usec)) {
    618  1.1  christos 					bp += Packet_WORDALIGN(caplen + hdrlen);
    619  1.1  christos 					continue;
    620  1.1  christos 				}
    621  1.1  christos 
    622  1.1  christos 				/*
    623  1.1  christos 				 * The arrived packet is suitable for being
    624  1.1  christos 				 * delivered to our caller, so let's update
    625  1.1  christos 				 * the target time.
    626  1.1  christos 				 */
    627  1.1  christos 				pw->samp_time.tv_usec = pkt_header->ts.tv_usec + p->rmt_samp.value * 1000;
    628  1.1  christos 				if (pw->samp_time.tv_usec > 1000000) {
    629  1.1  christos 					pw->samp_time.tv_sec = pkt_header->ts.tv_sec + pw->samp_time.tv_usec / 1000000;
    630  1.1  christos 					pw->samp_time.tv_usec = pw->samp_time.tv_usec % 1000000;
    631  1.1  christos 				}
    632  1.1  christos 			    }
    633  1.1  christos 			}
    634  1.1  christos #endif	/* ENABLE_REMOTE */
    635  1.1  christos 
    636  1.1  christos 			/*
    637  1.1  christos 			 * XXX A bpf_hdr matches a pcap_pkthdr.
    638  1.1  christos 			 */
    639  1.1  christos 			(*callback)(user, (struct pcap_pkthdr*)bp, datap);
    640  1.1  christos 			bp += Packet_WORDALIGN(caplen + hdrlen);
    641  1.1  christos 			if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) {
    642  1.1  christos 				p->bp = bp;
    643  1.1  christos 				p->cc = (int) (ep - bp);
    644  1.1  christos 				return (n);
    645  1.1  christos 			}
    646  1.1  christos 		} else {
    647  1.1  christos 			/*
    648  1.1  christos 			 * Skip this packet.
    649  1.1  christos 			 */
    650  1.1  christos 			bp += Packet_WORDALIGN(caplen + hdrlen);
    651  1.1  christos 		}
    652  1.1  christos 	}
    653  1.1  christos #undef bhp
    654  1.1  christos 	p->cc = 0;
    655  1.1  christos 	return (n);
    656  1.1  christos }
    657  1.1  christos 
    658  1.1  christos #ifdef HAVE_DAG_API
    659  1.1  christos static int
    660  1.1  christos pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
    661  1.1  christos {
    662  1.1  christos 	struct pcap_win *pw = p->priv;
    663  1.1  christos 	PACKET Packet;
    664  1.1  christos 	u_char *dp = NULL;
    665  1.1  christos 	int	packet_len = 0, caplen = 0;
    666  1.1  christos 	struct pcap_pkthdr	pcap_header;
    667  1.1  christos 	u_char *endofbuf;
    668  1.1  christos 	int n = 0;
    669  1.1  christos 	dag_record_t *header;
    670  1.1  christos 	unsigned erf_record_len;
    671  1.1  christos 	ULONGLONG ts;
    672  1.1  christos 	int cc;
    673  1.1  christos 	unsigned swt;
    674  1.1  christos 	unsigned dfp = pw->adapter->DagFastProcess;
    675  1.1  christos 
    676  1.1  christos 	cc = p->cc;
    677  1.1  christos 	if (cc == 0) /* Get new packets only if we have processed all the ones of the previous read */
    678  1.1  christos 	{
    679  1.1  christos 		/*
    680  1.1  christos 		 * Get new packets from the network.
    681  1.1  christos 		 *
    682  1.1  christos 		 * The PACKET structure had a bunch of extra stuff for
    683  1.1  christos 		 * Windows 9x/Me, but the only interesting data in it
    684  1.1  christos 		 * in the versions of Windows that we support is just
    685  1.1  christos 		 * a copy of p->buffer, a copy of p->buflen, and the
    686  1.1  christos 		 * actual number of bytes read returned from
    687  1.1  christos 		 * PacketReceivePacket(), none of which has to be
    688  1.1  christos 		 * retained from call to call, so we just keep one on
    689  1.1  christos 		 * the stack.
    690  1.1  christos 		 */
    691  1.1  christos 		PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
    692  1.1  christos 		if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
    693  1.1  christos 			pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
    694  1.1  christos 			return (-1);
    695  1.1  christos 		}
    696  1.1  christos 
    697  1.1  christos 		cc = Packet.ulBytesReceived;
    698  1.1  christos 		if(cc == 0)
    699  1.1  christos 			/* The timeout has expired but we no packets arrived */
    700  1.1  christos 			return (0);
    701  1.1  christos 		header = (dag_record_t*)pw->adapter->DagBuffer;
    702  1.1  christos 	}
    703  1.1  christos 	else
    704  1.1  christos 		header = (dag_record_t*)p->bp;
    705  1.1  christos 
    706  1.1  christos 	endofbuf = (char*)header + cc;
    707  1.1  christos 
    708  1.1  christos 	/*
    709  1.1  christos 	 * Cycle through the packets
    710  1.1  christos 	 */
    711  1.1  christos 	do
    712  1.1  christos 	{
    713  1.1  christos 		erf_record_len = SWAPS(header->rlen);
    714  1.1  christos 		if((char*)header + erf_record_len > endofbuf)
    715  1.1  christos 			break;
    716  1.1  christos 
    717  1.1  christos 		/* Increase the number of captured packets */
    718  1.1  christos 		p->stat.ps_recv++;
    719  1.1  christos 
    720  1.1  christos 		/* Find the beginning of the packet */
    721  1.1  christos 		dp = ((u_char *)header) + dag_record_size;
    722  1.1  christos 
    723  1.1  christos 		/* Determine actual packet len */
    724  1.1  christos 		switch(header->type)
    725  1.1  christos 		{
    726  1.1  christos 		case TYPE_ATM:
    727  1.1  christos 			packet_len = ATM_SNAPLEN;
    728  1.1  christos 			caplen = ATM_SNAPLEN;
    729  1.1  christos 			dp += 4;
    730  1.1  christos 
    731  1.1  christos 			break;
    732  1.1  christos 
    733  1.1  christos 		case TYPE_ETH:
    734  1.1  christos 			swt = SWAPS(header->wlen);
    735  1.1  christos 			packet_len = swt - (pw->dag_fcs_bits);
    736  1.1  christos 			caplen = erf_record_len - dag_record_size - 2;
    737  1.1  christos 			if (caplen > packet_len)
    738  1.1  christos 			{
    739  1.1  christos 				caplen = packet_len;
    740  1.1  christos 			}
    741  1.1  christos 			dp += 2;
    742  1.1  christos 
    743  1.1  christos 			break;
    744  1.1  christos 
    745  1.1  christos 		case TYPE_HDLC_POS:
    746  1.1  christos 			swt = SWAPS(header->wlen);
    747  1.1  christos 			packet_len = swt - (pw->dag_fcs_bits);
    748  1.1  christos 			caplen = erf_record_len - dag_record_size;
    749  1.1  christos 			if (caplen > packet_len)
    750  1.1  christos 			{
    751  1.1  christos 				caplen = packet_len;
    752  1.1  christos 			}
    753  1.1  christos 
    754  1.1  christos 			break;
    755  1.1  christos 		}
    756  1.1  christos 
    757  1.1  christos 		if(caplen > p->snapshot)
    758  1.1  christos 			caplen = p->snapshot;
    759  1.1  christos 
    760  1.1  christos 		/*
    761  1.1  christos 		 * Has "pcap_breakloop()" been called?
    762  1.1  christos 		 * If so, return immediately - if we haven't read any
    763  1.1  christos 		 * packets, clear the flag and return -2 to indicate
    764  1.1  christos 		 * that we were told to break out of the loop, otherwise
    765  1.1  christos 		 * leave the flag set, so that the *next* call will break
    766  1.1  christos 		 * out of the loop without having read any packets, and
    767  1.1  christos 		 * return the number of packets we've processed so far.
    768  1.1  christos 		 */
    769  1.1  christos 		if (p->break_loop)
    770  1.1  christos 		{
    771  1.1  christos 			if (n == 0)
    772  1.1  christos 			{
    773  1.1  christos 				p->break_loop = 0;
    774  1.1  christos 				return (-2);
    775  1.1  christos 			}
    776  1.1  christos 			else
    777  1.1  christos 			{
    778  1.1  christos 				p->bp = (char*)header;
    779  1.1  christos 				p->cc = endofbuf - (char*)header;
    780  1.1  christos 				return (n);
    781  1.1  christos 			}
    782  1.1  christos 		}
    783  1.1  christos 
    784  1.1  christos 		if(!dfp)
    785  1.1  christos 		{
    786  1.1  christos 			/* convert between timestamp formats */
    787  1.1  christos 			ts = header->ts;
    788  1.1  christos 			pcap_header.ts.tv_sec = (int)(ts >> 32);
    789  1.1  christos 			ts = (ts & 0xffffffffi64) * 1000000;
    790  1.1  christos 			ts += 0x80000000; /* rounding */
    791  1.1  christos 			pcap_header.ts.tv_usec = (int)(ts >> 32);
    792  1.1  christos 			if (pcap_header.ts.tv_usec >= 1000000) {
    793  1.1  christos 				pcap_header.ts.tv_usec -= 1000000;
    794  1.1  christos 				pcap_header.ts.tv_sec++;
    795  1.1  christos 			}
    796  1.1  christos 		}
    797  1.1  christos 
    798  1.1  christos 		/* No underlaying filtering system. We need to filter on our own */
    799  1.1  christos 		if (p->fcode.bf_insns)
    800  1.1  christos 		{
    801  1.1  christos 			if (bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0)
    802  1.1  christos 			{
    803  1.1  christos 				/* Move to next packet */
    804  1.1  christos 				header = (dag_record_t*)((char*)header + erf_record_len);
    805  1.1  christos 				continue;
    806  1.1  christos 			}
    807  1.1  christos 		}
    808  1.1  christos 
    809  1.1  christos 		/* Fill the header for the user suppplied callback function */
    810  1.1  christos 		pcap_header.caplen = caplen;
    811  1.1  christos 		pcap_header.len = packet_len;
    812  1.1  christos 
    813  1.1  christos 		/* Call the callback function */
    814  1.1  christos 		(*callback)(user, &pcap_header, dp);
    815  1.1  christos 
    816  1.1  christos 		/* Move to next packet */
    817  1.1  christos 		header = (dag_record_t*)((char*)header + erf_record_len);
    818  1.1  christos 
    819  1.1  christos 		/* Stop if the number of packets requested by user has been reached*/
    820  1.1  christos 		if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt))
    821  1.1  christos 		{
    822  1.1  christos 			p->bp = (char*)header;
    823  1.1  christos 			p->cc = endofbuf - (char*)header;
    824  1.1  christos 			return (n);
    825  1.1  christos 		}
    826  1.1  christos 	}
    827  1.1  christos 	while((u_char*)header < endofbuf);
    828  1.1  christos 
    829  1.1  christos 	return (1);
    830  1.1  christos }
    831  1.1  christos #endif /* HAVE_DAG_API */
    832  1.1  christos 
    833  1.1  christos /* Send a packet to the network */
    834  1.1  christos static int
    835  1.1  christos pcap_inject_npf(pcap_t *p, const void *buf, size_t size)
    836  1.1  christos {
    837  1.1  christos 	struct pcap_win *pw = p->priv;
    838  1.1  christos 	PACKET pkt;
    839  1.1  christos 
    840  1.1  christos 	PacketInitPacket(&pkt, (PVOID)buf, size);
    841  1.1  christos 	if(PacketSendPacket(pw->adapter,&pkt,TRUE) == FALSE) {
    842  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketSendPacket failed");
    843  1.1  christos 		return (-1);
    844  1.1  christos 	}
    845  1.1  christos 
    846  1.1  christos 	/*
    847  1.1  christos 	 * We assume it all got sent if "PacketSendPacket()" succeeded.
    848  1.1  christos 	 * "pcap_inject()" is expected to return the number of bytes
    849  1.1  christos 	 * sent.
    850  1.1  christos 	 */
    851  1.1  christos 	return ((int)size);
    852  1.1  christos }
    853  1.1  christos 
    854  1.1  christos static void
    855  1.1  christos pcap_cleanup_npf(pcap_t *p)
    856  1.1  christos {
    857  1.1  christos 	struct pcap_win *pw = p->priv;
    858  1.1  christos 
    859  1.1  christos 	if (pw->adapter != NULL) {
    860  1.1  christos 		PacketCloseAdapter(pw->adapter);
    861  1.1  christos 		pw->adapter = NULL;
    862  1.1  christos 	}
    863  1.1  christos 	if (pw->rfmon_selfstart)
    864  1.1  christos 	{
    865  1.1  christos 		PacketSetMonitorMode(p->opt.device, 0);
    866  1.1  christos 	}
    867  1.1  christos 	pcap_cleanup_live_common(p);
    868  1.1  christos }
    869  1.1  christos 
    870  1.1  christos static int
    871  1.1  christos pcap_activate_npf(pcap_t *p)
    872  1.1  christos {
    873  1.1  christos 	struct pcap_win *pw = p->priv;
    874  1.1  christos 	NetType type;
    875  1.1  christos 	int res;
    876  1.1  christos 	char errbuf[PCAP_ERRBUF_SIZE+1];
    877  1.1  christos 
    878  1.1  christos 	if (p->opt.rfmon) {
    879  1.1  christos 		/*
    880  1.1  christos 		 * Monitor mode is supported on Windows Vista and later.
    881  1.1  christos 		 */
    882  1.1  christos 		if (PacketGetMonitorMode(p->opt.device) == 1)
    883  1.1  christos 		{
    884  1.1  christos 			pw->rfmon_selfstart = 0;
    885  1.1  christos 		}
    886  1.1  christos 		else
    887  1.1  christos 		{
    888  1.1  christos 			if ((res = PacketSetMonitorMode(p->opt.device, 1)) != 1)
    889  1.1  christos 			{
    890  1.1  christos 				pw->rfmon_selfstart = 0;
    891  1.1  christos 				// Monitor mode is not supported.
    892  1.1  christos 				if (res == 0)
    893  1.1  christos 				{
    894  1.1  christos 					return PCAP_ERROR_RFMON_NOTSUP;
    895  1.1  christos 				}
    896  1.1  christos 				else
    897  1.1  christos 				{
    898  1.1  christos 					return PCAP_ERROR;
    899  1.1  christos 				}
    900  1.1  christos 			}
    901  1.1  christos 			else
    902  1.1  christos 			{
    903  1.1  christos 				pw->rfmon_selfstart = 1;
    904  1.1  christos 			}
    905  1.1  christos 		}
    906  1.1  christos 	}
    907  1.1  christos 
    908  1.1  christos 	/* Init WinSock */
    909  1.1  christos 	pcap_wsockinit();
    910  1.1  christos 
    911  1.1  christos 	pw->adapter = PacketOpenAdapter(p->opt.device);
    912  1.1  christos 
    913  1.1  christos 	if (pw->adapter == NULL)
    914  1.1  christos 	{
    915  1.1  christos 		/* Adapter detected but we are not able to open it. Return failure. */
    916  1.1  christos 		pcap_win32_err_to_str(GetLastError(), errbuf);
    917  1.1  christos 		if (pw->rfmon_selfstart)
    918  1.1  christos 		{
    919  1.1  christos 			PacketSetMonitorMode(p->opt.device, 0);
    920  1.1  christos 		}
    921  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    922  1.1  christos 		    "Error opening adapter: %s", errbuf);
    923  1.1  christos 		return (PCAP_ERROR);
    924  1.1  christos 	}
    925  1.1  christos 
    926  1.1  christos 	/*get network type*/
    927  1.1  christos 	if(PacketGetNetType (pw->adapter,&type) == FALSE)
    928  1.1  christos 	{
    929  1.1  christos 		pcap_win32_err_to_str(GetLastError(), errbuf);
    930  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    931  1.1  christos 		    "Cannot determine the network type: %s", errbuf);
    932  1.1  christos 		goto bad;
    933  1.1  christos 	}
    934  1.1  christos 
    935  1.1  christos 	/*Set the linktype*/
    936  1.1  christos 	switch (type.LinkType)
    937  1.1  christos 	{
    938  1.1  christos 	case NdisMediumWan:
    939  1.1  christos 		p->linktype = DLT_EN10MB;
    940  1.1  christos 		break;
    941  1.1  christos 
    942  1.1  christos 	case NdisMedium802_3:
    943  1.1  christos 		p->linktype = DLT_EN10MB;
    944  1.1  christos 		/*
    945  1.1  christos 		 * This is (presumably) a real Ethernet capture; give it a
    946  1.1  christos 		 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
    947  1.1  christos 		 * that an application can let you choose it, in case you're
    948  1.1  christos 		 * capturing DOCSIS traffic that a Cisco Cable Modem
    949  1.1  christos 		 * Termination System is putting out onto an Ethernet (it
    950  1.1  christos 		 * doesn't put an Ethernet header onto the wire, it puts raw
    951  1.1  christos 		 * DOCSIS frames out on the wire inside the low-level
    952  1.1  christos 		 * Ethernet framing).
    953  1.1  christos 		 */
    954  1.1  christos 		p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
    955  1.1  christos 		/*
    956  1.1  christos 		 * If that fails, just leave the list empty.
    957  1.1  christos 		 */
    958  1.1  christos 		if (p->dlt_list != NULL) {
    959  1.1  christos 			p->dlt_list[0] = DLT_EN10MB;
    960  1.1  christos 			p->dlt_list[1] = DLT_DOCSIS;
    961  1.1  christos 			p->dlt_count = 2;
    962  1.1  christos 		}
    963  1.1  christos 		break;
    964  1.1  christos 
    965  1.1  christos 	case NdisMediumFddi:
    966  1.1  christos 		p->linktype = DLT_FDDI;
    967  1.1  christos 		break;
    968  1.1  christos 
    969  1.1  christos 	case NdisMedium802_5:
    970  1.1  christos 		p->linktype = DLT_IEEE802;
    971  1.1  christos 		break;
    972  1.1  christos 
    973  1.1  christos 	case NdisMediumArcnetRaw:
    974  1.1  christos 		p->linktype = DLT_ARCNET;
    975  1.1  christos 		break;
    976  1.1  christos 
    977  1.1  christos 	case NdisMediumArcnet878_2:
    978  1.1  christos 		p->linktype = DLT_ARCNET;
    979  1.1  christos 		break;
    980  1.1  christos 
    981  1.1  christos 	case NdisMediumAtm:
    982  1.1  christos 		p->linktype = DLT_ATM_RFC1483;
    983  1.1  christos 		break;
    984  1.1  christos 
    985  1.1  christos 	case NdisMediumCHDLC:
    986  1.1  christos 		p->linktype = DLT_CHDLC;
    987  1.1  christos 		break;
    988  1.1  christos 
    989  1.1  christos 	case NdisMediumPPPSerial:
    990  1.1  christos 		p->linktype = DLT_PPP_SERIAL;
    991  1.1  christos 		break;
    992  1.1  christos 
    993  1.1  christos 	case NdisMediumNull:
    994  1.1  christos 		p->linktype = DLT_NULL;
    995  1.1  christos 		break;
    996  1.1  christos 
    997  1.1  christos 	case NdisMediumBare80211:
    998  1.1  christos 		p->linktype = DLT_IEEE802_11;
    999  1.1  christos 		break;
   1000  1.1  christos 
   1001  1.1  christos 	case NdisMediumRadio80211:
   1002  1.1  christos 		p->linktype = DLT_IEEE802_11_RADIO;
   1003  1.1  christos 		break;
   1004  1.1  christos 
   1005  1.1  christos 	case NdisMediumPpi:
   1006  1.1  christos 		p->linktype = DLT_PPI;
   1007  1.1  christos 		break;
   1008  1.1  christos 
   1009  1.1  christos 	default:
   1010  1.1  christos 		p->linktype = DLT_EN10MB;			/*an unknown adapter is assumed to be ethernet*/
   1011  1.1  christos 		break;
   1012  1.1  christos 	}
   1013  1.1  christos 
   1014  1.1  christos 	/*
   1015  1.1  christos 	 * Turn a negative snapshot value (invalid), a snapshot value of
   1016  1.1  christos 	 * 0 (unspecified), or a value bigger than the normal maximum
   1017  1.1  christos 	 * value, into the maximum allowed value.
   1018  1.1  christos 	 *
   1019  1.1  christos 	 * If some application really *needs* a bigger snapshot
   1020  1.1  christos 	 * length, we should just increase MAXIMUM_SNAPLEN.
   1021  1.1  christos 	 */
   1022  1.1  christos 	if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
   1023  1.1  christos 		p->snapshot = MAXIMUM_SNAPLEN;
   1024  1.1  christos 
   1025  1.1  christos 	/* Set promiscuous mode */
   1026  1.1  christos 	if (p->opt.promisc)
   1027  1.1  christos 	{
   1028  1.1  christos 
   1029  1.1  christos 		if (PacketSetHwFilter(pw->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
   1030  1.1  christos 		{
   1031  1.1  christos 			pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode");
   1032  1.1  christos 			goto bad;
   1033  1.1  christos 		}
   1034  1.1  christos 	}
   1035  1.1  christos 	else
   1036  1.1  christos 	{
   1037  1.1  christos 		/* NDIS_PACKET_TYPE_ALL_LOCAL selects "All packets sent by installed
   1038  1.1  christos 		 * protocols and all packets indicated by the NIC" but if no protocol
   1039  1.1  christos 		 * drivers (like TCP/IP) are installed, NDIS_PACKET_TYPE_DIRECTED,
   1040  1.1  christos 		 * NDIS_PACKET_TYPE_BROADCAST, and NDIS_PACKET_TYPE_MULTICAST are needed to
   1041  1.1  christos 		 * capture incoming frames.
   1042  1.1  christos 		 */
   1043  1.1  christos 		if (PacketSetHwFilter(pw->adapter,
   1044  1.1  christos 			NDIS_PACKET_TYPE_ALL_LOCAL |
   1045  1.1  christos 			NDIS_PACKET_TYPE_DIRECTED |
   1046  1.1  christos 			NDIS_PACKET_TYPE_BROADCAST |
   1047  1.1  christos 			NDIS_PACKET_TYPE_MULTICAST) == FALSE)
   1048  1.1  christos 		{
   1049  1.1  christos 			pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode");
   1050  1.1  christos 			goto bad;
   1051  1.1  christos 		}
   1052  1.1  christos 	}
   1053  1.1  christos 
   1054  1.1  christos 	/* Set the buffer size */
   1055  1.1  christos 	p->bufsize = WIN32_DEFAULT_USER_BUFFER_SIZE;
   1056  1.1  christos 
   1057  1.1  christos 	if(!(pw->adapter->Flags & INFO_FLAG_DAG_CARD))
   1058  1.1  christos 	{
   1059  1.1  christos 	/*
   1060  1.1  christos 	 * Traditional Adapter
   1061  1.1  christos 	 */
   1062  1.1  christos 		/*
   1063  1.1  christos 		 * If the buffer size wasn't explicitly set, default to
   1064  1.1  christos 		 * WIN32_DEFAULT_KERNEL_BUFFER_SIZE.
   1065  1.1  christos 		 */
   1066  1.1  christos 	 	if (p->opt.buffer_size == 0)
   1067  1.1  christos 	 		p->opt.buffer_size = WIN32_DEFAULT_KERNEL_BUFFER_SIZE;
   1068  1.1  christos 
   1069  1.1  christos 		if(PacketSetBuff(pw->adapter,p->opt.buffer_size)==FALSE)
   1070  1.1  christos 		{
   1071  1.1  christos 			pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
   1072  1.1  christos 			goto bad;
   1073  1.1  christos 		}
   1074  1.1  christos 
   1075  1.1  christos 		p->buffer = malloc(p->bufsize);
   1076  1.1  christos 		if (p->buffer == NULL)
   1077  1.1  christos 		{
   1078  1.1  christos 			pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
   1079  1.1  christos 			    errno, "malloc");
   1080  1.1  christos 			goto bad;
   1081  1.1  christos 		}
   1082  1.1  christos 
   1083  1.1  christos 		if (p->opt.immediate)
   1084  1.1  christos 		{
   1085  1.1  christos 			/* tell the driver to copy the buffer as soon as data arrives */
   1086  1.1  christos 			if(PacketSetMinToCopy(pw->adapter,0)==FALSE)
   1087  1.1  christos 			{
   1088  1.1  christos 				pcap_win32_err_to_str(GetLastError(), errbuf);
   1089  1.1  christos 				pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
   1090  1.1  christos 				    "Error calling PacketSetMinToCopy: %s",
   1091  1.1  christos 				    errbuf);
   1092  1.1  christos 				goto bad;
   1093  1.1  christos 			}
   1094  1.1  christos 		}
   1095  1.1  christos 		else
   1096  1.1  christos 		{
   1097  1.1  christos 			/* tell the driver to copy the buffer only if it contains at least 16K */
   1098  1.1  christos 			if(PacketSetMinToCopy(pw->adapter,16000)==FALSE)
   1099  1.1  christos 			{
   1100  1.1  christos 				pcap_win32_err_to_str(GetLastError(), errbuf);
   1101  1.1  christos 				pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
   1102  1.1  christos 				    "Error calling PacketSetMinToCopy: %s",
   1103  1.1  christos 				    errbuf);
   1104  1.1  christos 				goto bad;
   1105  1.1  christos 			}
   1106  1.1  christos 		}
   1107  1.1  christos 	} else {
   1108  1.1  christos 		/*
   1109  1.1  christos 		 * Dag Card
   1110  1.1  christos 		 */
   1111  1.1  christos #ifdef HAVE_DAG_API
   1112  1.1  christos 		/*
   1113  1.1  christos 		 * We have DAG support.
   1114  1.1  christos 		 */
   1115  1.1  christos 		LONG	status;
   1116  1.1  christos 		HKEY	dagkey;
   1117  1.1  christos 		DWORD	lptype;
   1118  1.1  christos 		DWORD	lpcbdata;
   1119  1.1  christos 		int		postype = 0;
   1120  1.1  christos 		char	keyname[512];
   1121  1.1  christos 
   1122  1.1  christos 		pcap_snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s",
   1123  1.1  christos 			"SYSTEM\\CurrentControlSet\\Services\\DAG",
   1124  1.1  christos 			strstr(_strlwr(p->opt.device), "dag"));
   1125  1.1  christos 		do
   1126  1.1  christos 		{
   1127  1.1  christos 			status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey);
   1128  1.1  christos 			if(status != ERROR_SUCCESS)
   1129  1.1  christos 				break;
   1130  1.1  christos 
   1131  1.1  christos 			status = RegQueryValueEx(dagkey,
   1132  1.1  christos 				"PosType",
   1133  1.1  christos 				NULL,
   1134  1.1  christos 				&lptype,
   1135  1.1  christos 				(char*)&postype,
   1136  1.1  christos 				&lpcbdata);
   1137  1.1  christos 
   1138  1.1  christos 			if(status != ERROR_SUCCESS)
   1139  1.1  christos 			{
   1140  1.1  christos 				postype = 0;
   1141  1.1  christos 			}
   1142  1.1  christos 
   1143  1.1  christos 			RegCloseKey(dagkey);
   1144  1.1  christos 		}
   1145  1.1  christos 		while(FALSE);
   1146  1.1  christos 
   1147  1.1  christos 
   1148  1.1  christos 		p->snapshot = PacketSetSnapLen(pw->adapter, p->snapshot);
   1149  1.1  christos 
   1150  1.1  christos 		/* Set the length of the FCS associated to any packet. This value
   1151  1.1  christos 		 * will be subtracted to the packet length */
   1152  1.1  christos 		pw->dag_fcs_bits = pw->adapter->DagFcsLen;
   1153  1.1  christos #else /* HAVE_DAG_API */
   1154  1.1  christos 		/*
   1155  1.1  christos 		 * No DAG support.
   1156  1.1  christos 		 */
   1157  1.1  christos 		goto bad;
   1158  1.1  christos #endif /* HAVE_DAG_API */
   1159  1.1  christos 	}
   1160  1.1  christos 
   1161  1.1  christos 	PacketSetReadTimeout(pw->adapter, p->opt.timeout);
   1162  1.1  christos 
   1163  1.1  christos 	/* disable loopback capture if requested */
   1164  1.1  christos 	if (p->opt.nocapture_local)
   1165  1.1  christos 	{
   1166  1.1  christos 		if (!PacketSetLoopbackBehavior(pw->adapter, NPF_DISABLE_LOOPBACK))
   1167  1.1  christos 		{
   1168  1.1  christos 			pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
   1169  1.1  christos 			    "Unable to disable the capture of loopback packets.");
   1170  1.1  christos 			goto bad;
   1171  1.1  christos 		}
   1172  1.1  christos 	}
   1173  1.1  christos 
   1174  1.1  christos #ifdef HAVE_DAG_API
   1175  1.1  christos 	if(pw->adapter->Flags & INFO_FLAG_DAG_CARD)
   1176  1.1  christos 	{
   1177  1.1  christos 		/* install dag specific handlers for read and setfilter */
   1178  1.1  christos 		p->read_op = pcap_read_win32_dag;
   1179  1.1  christos 		p->setfilter_op = pcap_setfilter_win32_dag;
   1180  1.1  christos 	}
   1181  1.1  christos 	else
   1182  1.1  christos 	{
   1183  1.1  christos #endif /* HAVE_DAG_API */
   1184  1.1  christos 		/* install traditional npf handlers for read and setfilter */
   1185  1.1  christos 		p->read_op = pcap_read_npf;
   1186  1.1  christos 		p->setfilter_op = pcap_setfilter_npf;
   1187  1.1  christos #ifdef HAVE_DAG_API
   1188  1.1  christos 	}
   1189  1.1  christos #endif /* HAVE_DAG_API */
   1190  1.1  christos 	p->setdirection_op = NULL;	/* Not implemented. */
   1191  1.1  christos 	    /* XXX - can this be implemented on some versions of Windows? */
   1192  1.1  christos 	p->inject_op = pcap_inject_npf;
   1193  1.1  christos 	p->set_datalink_op = NULL;	/* can't change data link type */
   1194  1.1  christos 	p->getnonblock_op = pcap_getnonblock_npf;
   1195  1.1  christos 	p->setnonblock_op = pcap_setnonblock_npf;
   1196  1.1  christos 	p->stats_op = pcap_stats_npf;
   1197  1.1  christos 	p->stats_ex_op = pcap_stats_ex_npf;
   1198  1.1  christos 	p->setbuff_op = pcap_setbuff_npf;
   1199  1.1  christos 	p->setmode_op = pcap_setmode_npf;
   1200  1.1  christos 	p->setmintocopy_op = pcap_setmintocopy_npf;
   1201  1.1  christos 	p->getevent_op = pcap_getevent_npf;
   1202  1.1  christos 	p->oid_get_request_op = pcap_oid_get_request_npf;
   1203  1.1  christos 	p->oid_set_request_op = pcap_oid_set_request_npf;
   1204  1.1  christos 	p->sendqueue_transmit_op = pcap_sendqueue_transmit_npf;
   1205  1.1  christos 	p->setuserbuffer_op = pcap_setuserbuffer_npf;
   1206  1.1  christos 	p->live_dump_op = pcap_live_dump_npf;
   1207  1.1  christos 	p->live_dump_ended_op = pcap_live_dump_ended_npf;
   1208  1.1  christos 	p->get_airpcap_handle_op = pcap_get_airpcap_handle_npf;
   1209  1.1  christos 	p->cleanup_op = pcap_cleanup_npf;
   1210  1.1  christos 
   1211  1.1  christos 	/*
   1212  1.1  christos 	 * XXX - this is only done because WinPcap supported
   1213  1.1  christos 	 * pcap_fileno() returning the hFile HANDLE from the
   1214  1.1  christos 	 * ADAPTER structure.  We make no general guarantees
   1215  1.1  christos 	 * that the caller can do anything useful with it.
   1216  1.1  christos 	 *
   1217  1.1  christos 	 * (Not that we make any general guarantee of that
   1218  1.1  christos 	 * sort on UN*X, either, any more, given that not
   1219  1.1  christos 	 * all capture devices are regular OS network
   1220  1.1  christos 	 * interfaces.)
   1221  1.1  christos 	 */
   1222  1.1  christos 	p->handle = pw->adapter->hFile;
   1223  1.1  christos 
   1224  1.1  christos 	return (0);
   1225  1.1  christos bad:
   1226  1.1  christos 	pcap_cleanup_npf(p);
   1227  1.1  christos 	return (PCAP_ERROR);
   1228  1.1  christos }
   1229  1.1  christos 
   1230  1.1  christos /*
   1231  1.1  christos * Check if rfmon mode is supported on the pcap_t for Windows systems.
   1232  1.1  christos */
   1233  1.1  christos static int
   1234  1.1  christos pcap_can_set_rfmon_npf(pcap_t *p)
   1235  1.1  christos {
   1236  1.1  christos 	return (PacketIsMonitorModeSupported(p->opt.device) == 1);
   1237  1.1  christos }
   1238  1.1  christos 
   1239  1.1  christos pcap_t *
   1240  1.1  christos pcap_create_interface(const char *device _U_, char *ebuf)
   1241  1.1  christos {
   1242  1.1  christos 	pcap_t *p;
   1243  1.1  christos 
   1244  1.1  christos 	p = pcap_create_common(ebuf, sizeof(struct pcap_win));
   1245  1.1  christos 	if (p == NULL)
   1246  1.1  christos 		return (NULL);
   1247  1.1  christos 
   1248  1.1  christos 	p->activate_op = pcap_activate_npf;
   1249  1.1  christos 	p->can_set_rfmon_op = pcap_can_set_rfmon_npf;
   1250  1.1  christos 	return (p);
   1251  1.1  christos }
   1252  1.1  christos 
   1253  1.1  christos static int
   1254  1.1  christos pcap_setfilter_npf(pcap_t *p, struct bpf_program *fp)
   1255  1.1  christos {
   1256  1.1  christos 	struct pcap_win *pw = p->priv;
   1257  1.1  christos 
   1258  1.1  christos 	if(PacketSetBpf(pw->adapter,fp)==FALSE){
   1259  1.1  christos 		/*
   1260  1.1  christos 		 * Kernel filter not installed.
   1261  1.1  christos 		 *
   1262  1.1  christos 		 * XXX - we don't know whether this failed because:
   1263  1.1  christos 		 *
   1264  1.1  christos 		 *  the kernel rejected the filter program as invalid,
   1265  1.1  christos 		 *  in which case we should fall back on userland
   1266  1.1  christos 		 *  filtering;
   1267  1.1  christos 		 *
   1268  1.1  christos 		 *  the kernel rejected the filter program as too big,
   1269  1.1  christos 		 *  in which case we should again fall back on
   1270  1.1  christos 		 *  userland filtering;
   1271  1.1  christos 		 *
   1272  1.1  christos 		 *  there was some other problem, in which case we
   1273  1.1  christos 		 *  should probably report an error.
   1274  1.1  christos 		 *
   1275  1.1  christos 		 * For NPF devices, the Win32 status will be
   1276  1.1  christos 		 * STATUS_INVALID_DEVICE_REQUEST for invalid
   1277  1.1  christos 		 * filters, but I don't know what it'd be for
   1278  1.1  christos 		 * other problems, and for some other devices
   1279  1.1  christos 		 * it might not be set at all.
   1280  1.1  christos 		 *
   1281  1.1  christos 		 * So we just fall back on userland filtering in
   1282  1.1  christos 		 * all cases.
   1283  1.1  christos 		 */
   1284  1.1  christos 
   1285  1.1  christos 		/*
   1286  1.1  christos 		 * install_bpf_program() validates the program.
   1287  1.1  christos 		 *
   1288  1.1  christos 		 * XXX - what if we already have a filter in the kernel?
   1289  1.1  christos 		 */
   1290  1.1  christos 		if (install_bpf_program(p, fp) < 0)
   1291  1.1  christos 			return (-1);
   1292  1.1  christos 		pw->filtering_in_kernel = 0;	/* filtering in userland */
   1293  1.1  christos 		return (0);
   1294  1.1  christos 	}
   1295  1.1  christos 
   1296  1.1  christos 	/*
   1297  1.1  christos 	 * It worked.
   1298  1.1  christos 	 */
   1299  1.1  christos 	pw->filtering_in_kernel = 1;	/* filtering in the kernel */
   1300  1.1  christos 
   1301  1.1  christos 	/*
   1302  1.1  christos 	 * Discard any previously-received packets, as they might have
   1303  1.1  christos 	 * passed whatever filter was formerly in effect, but might
   1304  1.1  christos 	 * not pass this filter (BIOCSETF discards packets buffered
   1305  1.1  christos 	 * in the kernel, so you can lose packets in any case).
   1306  1.1  christos 	 */
   1307  1.1  christos 	p->cc = 0;
   1308  1.1  christos 	return (0);
   1309  1.1  christos }
   1310  1.1  christos 
   1311  1.1  christos /*
   1312  1.1  christos  * We filter at user level, since the kernel driver does't process the packets
   1313  1.1  christos  */
   1314  1.1  christos static int
   1315  1.1  christos pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {
   1316  1.1  christos 
   1317  1.1  christos 	if(!fp)
   1318  1.1  christos 	{
   1319  1.1  christos 		strlcpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf));
   1320  1.1  christos 		return (-1);
   1321  1.1  christos 	}
   1322  1.1  christos 
   1323  1.1  christos 	/* Install a user level filter */
   1324  1.1  christos 	if (install_bpf_program(p, fp) < 0)
   1325  1.1  christos 		return (-1);
   1326  1.1  christos 
   1327  1.1  christos 	return (0);
   1328  1.1  christos }
   1329  1.1  christos 
   1330  1.1  christos static int
   1331  1.1  christos pcap_getnonblock_npf(pcap_t *p)
   1332  1.1  christos {
   1333  1.1  christos 	struct pcap_win *pw = p->priv;
   1334  1.1  christos 
   1335  1.1  christos 	/*
   1336  1.1  christos 	 * XXX - if there were a PacketGetReadTimeout() call, we
   1337  1.1  christos 	 * would use it, and return 1 if the timeout is -1
   1338  1.1  christos 	 * and 0 otherwise.
   1339  1.1  christos 	 */
   1340  1.1  christos 	return (pw->nonblock);
   1341  1.1  christos }
   1342  1.1  christos 
   1343  1.1  christos static int
   1344  1.1  christos pcap_setnonblock_npf(pcap_t *p, int nonblock)
   1345  1.1  christos {
   1346  1.1  christos 	struct pcap_win *pw = p->priv;
   1347  1.1  christos 	int newtimeout;
   1348  1.1  christos 	char win_errbuf[PCAP_ERRBUF_SIZE+1];
   1349  1.1  christos 
   1350  1.1  christos 	if (nonblock) {
   1351  1.1  christos 		/*
   1352  1.1  christos 		 * Set the packet buffer timeout to -1 for non-blocking
   1353  1.1  christos 		 * mode.
   1354  1.1  christos 		 */
   1355  1.1  christos 		newtimeout = -1;
   1356  1.1  christos 	} else {
   1357  1.1  christos 		/*
   1358  1.1  christos 		 * Restore the timeout set when the device was opened.
   1359  1.1  christos 		 * (Note that this may be -1, in which case we're not
   1360  1.1  christos 		 * really leaving non-blocking mode.  However, although
   1361  1.1  christos 		 * the timeout argument to pcap_set_timeout() and
   1362  1.1  christos 		 * pcap_open_live() is an int, you're not supposed to
   1363  1.1  christos 		 * supply a negative value, so that "shouldn't happen".)
   1364  1.1  christos 		 */
   1365  1.1  christos 		newtimeout = p->opt.timeout;
   1366  1.1  christos 	}
   1367  1.1  christos 	if (!PacketSetReadTimeout(pw->adapter, newtimeout)) {
   1368  1.1  christos 		pcap_win32_err_to_str(GetLastError(), win_errbuf);
   1369  1.1  christos 		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
   1370  1.1  christos 		    "PacketSetReadTimeout: %s", win_errbuf);
   1371  1.1  christos 		return (-1);
   1372  1.1  christos 	}
   1373  1.1  christos 	pw->nonblock = (newtimeout == -1);
   1374  1.1  christos 	return (0);
   1375  1.1  christos }
   1376  1.1  christos 
   1377  1.1  christos static int
   1378  1.1  christos pcap_add_if_npf(pcap_if_list_t *devlistp, char *name, bpf_u_int32 flags,
   1379  1.1  christos     const char *description, char *errbuf)
   1380  1.1  christos {
   1381  1.1  christos 	pcap_if_t *curdev;
   1382  1.1  christos 	npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
   1383  1.1  christos 	LONG if_addr_size;
   1384  1.1  christos 	int res = 0;
   1385  1.1  christos 
   1386  1.1  christos 	if_addr_size = MAX_NETWORK_ADDRESSES;
   1387  1.1  christos 
   1388  1.1  christos 	/*
   1389  1.1  christos 	 * Add an entry for this interface, with no addresses.
   1390  1.1  christos 	 */
   1391  1.1  christos 	curdev = add_dev(devlistp, name, flags, description, errbuf);
   1392  1.1  christos 	if (curdev == NULL) {
   1393  1.1  christos 		/*
   1394  1.1  christos 		 * Failure.
   1395  1.1  christos 		 */
   1396  1.1  christos 		return (-1);
   1397  1.1  christos 	}
   1398  1.1  christos 
   1399  1.1  christos 	/*
   1400  1.1  christos 	 * Get the list of addresses for the interface.
   1401  1.1  christos 	 */
   1402  1.1  christos 	if (!PacketGetNetInfoEx((void *)name, if_addrs, &if_addr_size)) {
   1403  1.1  christos 		/*
   1404  1.1  christos 		 * Failure.
   1405  1.1  christos 		 *
   1406  1.1  christos 		 * We don't return an error, because this can happen with
   1407  1.1  christos 		 * NdisWan interfaces, and we want to supply them even
   1408  1.1  christos 		 * if we can't supply their addresses.
   1409  1.1  christos 		 *
   1410  1.1  christos 		 * We return an entry with an empty address list.
   1411  1.1  christos 		 */
   1412  1.1  christos 		return (0);
   1413  1.1  christos 	}
   1414  1.1  christos 
   1415  1.1  christos 	/*
   1416  1.1  christos 	 * Now add the addresses.
   1417  1.1  christos 	 */
   1418  1.1  christos 	while (if_addr_size-- > 0) {
   1419  1.1  christos 		/*
   1420  1.1  christos 		 * "curdev" is an entry for this interface; add an entry for
   1421  1.1  christos 		 * this address to its list of addresses.
   1422  1.1  christos 		 */
   1423  1.1  christos 		res = add_addr_to_dev(curdev,
   1424  1.1  christos 		    (struct sockaddr *)&if_addrs[if_addr_size].IPAddress,
   1425  1.1  christos 		    sizeof (struct sockaddr_storage),
   1426  1.1  christos 		    (struct sockaddr *)&if_addrs[if_addr_size].SubnetMask,
   1427  1.1  christos 		    sizeof (struct sockaddr_storage),
   1428  1.1  christos 		    (struct sockaddr *)&if_addrs[if_addr_size].Broadcast,
   1429  1.1  christos 		    sizeof (struct sockaddr_storage),
   1430  1.1  christos 		    NULL,
   1431  1.1  christos 		    0,
   1432  1.1  christos 		    errbuf);
   1433  1.1  christos 		if (res == -1) {
   1434  1.1  christos 			/*
   1435  1.1  christos 			 * Failure.
   1436  1.1  christos 			 */
   1437  1.1  christos 			break;
   1438  1.1  christos 		}
   1439  1.1  christos 	}
   1440  1.1  christos 
   1441  1.1  christos 	return (res);
   1442  1.1  christos }
   1443  1.1  christos 
   1444  1.1  christos static int
   1445  1.1  christos get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
   1446  1.1  christos {
   1447  1.1  christos 	char *name_copy;
   1448  1.1  christos 	ADAPTER *adapter;
   1449  1.1  christos 	int status;
   1450  1.1  christos 	size_t len;
   1451  1.1  christos 	NDIS_HARDWARE_STATUS hardware_status;
   1452  1.1  christos #ifdef OID_GEN_PHYSICAL_MEDIUM
   1453  1.1  christos 	NDIS_PHYSICAL_MEDIUM phys_medium;
   1454  1.1  christos 	bpf_u_int32 gen_physical_medium_oids[] = {
   1455  1.1  christos   #ifdef OID_GEN_PHYSICAL_MEDIUM_EX
   1456  1.1  christos 		OID_GEN_PHYSICAL_MEDIUM_EX,
   1457  1.1  christos   #endif
   1458  1.1  christos   		OID_GEN_PHYSICAL_MEDIUM
   1459  1.1  christos   	};
   1460  1.1  christos #define N_GEN_PHYSICAL_MEDIUM_OIDS	(sizeof gen_physical_medium_oids / sizeof gen_physical_medium_oids[0])
   1461  1.1  christos 	size_t i;
   1462  1.1  christos #endif /* OID_GEN_PHYSICAL_MEDIUM */
   1463  1.1  christos #ifdef OID_GEN_LINK_STATE
   1464  1.1  christos 	NDIS_LINK_STATE link_state;
   1465  1.1  christos #endif
   1466  1.1  christos 	int connect_status;
   1467  1.1  christos 
   1468  1.1  christos 	if (*flags & PCAP_IF_LOOPBACK) {
   1469  1.1  christos 		/*
   1470  1.1  christos 		 * Loopback interface, so the connection status doesn't
   1471  1.1  christos 		 * apply. and it's not wireless (or wired, for that
   1472  1.1  christos 		 * matter...).  We presume it's up and running.
   1473  1.1  christos 		 */
   1474  1.1  christos 		*flags |= PCAP_IF_UP | PCAP_IF_RUNNING | PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
   1475  1.1  christos 		return (0);
   1476  1.1  christos 	}
   1477  1.1  christos 
   1478  1.1  christos 	/*
   1479  1.1  christos 	 * We need to open the adapter to get this information.
   1480  1.1  christos 	 *
   1481  1.1  christos 	 * XXX - PacketOpenAdapter() takes a non-const pointer
   1482  1.1  christos 	 * as an argument, so we make a copy of the argument and
   1483  1.1  christos 	 * pass that to it.
   1484  1.1  christos 	 */
   1485  1.1  christos 	name_copy = strdup(name);
   1486  1.1  christos 	adapter = PacketOpenAdapter(name_copy);
   1487  1.1  christos 	free(name_copy);
   1488  1.1  christos 	if (adapter == NULL) {
   1489  1.1  christos 		/*
   1490  1.1  christos 		 * Give up; if they try to open this device, it'll fail.
   1491  1.1  christos 		 */
   1492  1.1  christos 		return (0);
   1493  1.1  christos 	}
   1494  1.1  christos 
   1495  1.1  christos #ifdef HAVE_AIRPCAP_API
   1496  1.1  christos 	/*
   1497  1.1  christos 	 * Airpcap.sys do not support the below 'OID_GEN_x' values.
   1498  1.1  christos 	 * Just set these flags (and none of the '*flags' entered with).
   1499  1.1  christos 	 */
   1500  1.1  christos 	if (PacketGetAirPcapHandle(adapter)) {
   1501  1.1  christos 		/*
   1502  1.1  christos 		 * Must be "up" and "running" if the above if succeeded.
   1503  1.1  christos 		 */
   1504  1.1  christos 		*flags = PCAP_IF_UP | PCAP_IF_RUNNING;
   1505  1.1  christos 
   1506  1.1  christos 		/*
   1507  1.1  christos 		 * An airpcap device is a wireless device (duh!)
   1508  1.1  christos 		 */
   1509  1.1  christos 		*flags |= PCAP_IF_WIRELESS;
   1510  1.1  christos 
   1511  1.1  christos 		/*
   1512  1.1  christos 		 * A "network assosiation state" makes no sense for airpcap.
   1513  1.1  christos 		 */
   1514  1.1  christos 		*flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
   1515  1.1  christos 		PacketCloseAdapter(adapter);
   1516  1.1  christos 		return (0);
   1517  1.1  christos 	}
   1518  1.1  christos #endif
   1519  1.1  christos 
   1520  1.1  christos 	/*
   1521  1.1  christos 	 * Get the hardware status, and derive "up" and "running" from
   1522  1.1  christos 	 * that.
   1523  1.1  christos 	 */
   1524  1.1  christos 	len = sizeof (hardware_status);
   1525  1.1  christos 	status = oid_get_request(adapter, OID_GEN_HARDWARE_STATUS,
   1526  1.1  christos 	    &hardware_status, &len, errbuf);
   1527  1.1  christos 	if (status == 0) {
   1528  1.1  christos 		switch (hardware_status) {
   1529  1.1  christos 
   1530  1.1  christos 		case NdisHardwareStatusReady:
   1531  1.1  christos 			/*
   1532  1.1  christos 			 * "Available and capable of sending and receiving
   1533  1.1  christos 			 * data over the wire", so up and running.
   1534  1.1  christos 			 */
   1535  1.1  christos 			*flags |= PCAP_IF_UP | PCAP_IF_RUNNING;
   1536  1.1  christos 			break;
   1537  1.1  christos 
   1538  1.1  christos 		case NdisHardwareStatusInitializing:
   1539  1.1  christos 		case NdisHardwareStatusReset:
   1540  1.1  christos 			/*
   1541  1.1  christos 			 * "Initializing" or "Resetting", so up, but
   1542  1.1  christos 			 * not running.
   1543  1.1  christos 			 */
   1544  1.1  christos 			*flags |= PCAP_IF_UP;
   1545  1.1  christos 			break;
   1546  1.1  christos 
   1547  1.1  christos 		case NdisHardwareStatusClosing:
   1548  1.1  christos 		case NdisHardwareStatusNotReady:
   1549  1.1  christos 			/*
   1550  1.1  christos 			 * "Closing" or "Not ready", so neither up nor
   1551  1.1  christos 			 * running.
   1552  1.1  christos 			 */
   1553  1.1  christos 			break;
   1554  1.1  christos 		}
   1555  1.1  christos 	} else {
   1556  1.1  christos 		/*
   1557  1.1  christos 		 * Can't get the hardware status, so assume both up and
   1558  1.1  christos 		 * running.
   1559  1.1  christos 		 */
   1560  1.1  christos 		*flags |= PCAP_IF_UP | PCAP_IF_RUNNING;
   1561  1.1  christos 	}
   1562  1.1  christos 
   1563  1.1  christos 	/*
   1564  1.1  christos 	 * Get the network type.
   1565  1.1  christos 	 */
   1566  1.1  christos #ifdef OID_GEN_PHYSICAL_MEDIUM
   1567  1.1  christos 	/*
   1568  1.1  christos 	 * Try the OIDs we have for this, in order.
   1569  1.1  christos 	 */
   1570  1.1  christos 	for (i = 0; i < N_GEN_PHYSICAL_MEDIUM_OIDS; i++) {
   1571  1.1  christos 		len = sizeof (phys_medium);
   1572  1.1  christos 		status = oid_get_request(adapter, gen_physical_medium_oids[i],
   1573  1.1  christos 		    &phys_medium, &len, errbuf);
   1574  1.1  christos 		if (status == 0) {
   1575  1.1  christos 			/*
   1576  1.1  christos 			 * Success.
   1577  1.1  christos 			 */
   1578  1.1  christos 			break;
   1579  1.1  christos 		}
   1580  1.1  christos 		/*
   1581  1.1  christos 		 * Failed.  We can't determine whether it failed
   1582  1.1  christos 		 * because that particular OID isn't supported
   1583  1.1  christos 		 * or because some other problem occurred, so we
   1584  1.1  christos 		 * just drive on and try the next OID.
   1585  1.1  christos 		 */
   1586  1.1  christos 	}
   1587  1.1  christos 	if (status == 0) {
   1588  1.1  christos 		/*
   1589  1.1  christos 		 * We got the physical medium.
   1590  1.1  christos 		 */
   1591  1.1  christos 		switch (phys_medium) {
   1592  1.1  christos 
   1593  1.1  christos 		case NdisPhysicalMediumWirelessLan:
   1594  1.1  christos 		case NdisPhysicalMediumWirelessWan:
   1595  1.1  christos 		case NdisPhysicalMediumNative802_11:
   1596  1.1  christos 		case NdisPhysicalMediumBluetooth:
   1597  1.1  christos 		case NdisPhysicalMediumUWB:
   1598  1.1  christos 		case NdisPhysicalMediumIrda:
   1599  1.1  christos 			/*
   1600  1.1  christos 			 * Wireless.
   1601  1.1  christos 			 */
   1602  1.1  christos 			*flags |= PCAP_IF_WIRELESS;
   1603  1.1  christos 			break;
   1604  1.1  christos 
   1605  1.1  christos 		default:
   1606  1.1  christos 			/*
   1607  1.1  christos 			 * Not wireless.
   1608  1.1  christos 			 */
   1609  1.1  christos 			break;
   1610  1.1  christos 		}
   1611  1.1  christos 	}
   1612  1.1  christos #endif
   1613  1.1  christos 
   1614  1.1  christos 	/*
   1615  1.1  christos 	 * Get the connection status.
   1616  1.1  christos 	 */
   1617  1.1  christos #ifdef OID_GEN_LINK_STATE
   1618  1.1  christos 	len = sizeof(link_state);
   1619  1.1  christos 	status = oid_get_request(adapter, OID_GEN_LINK_STATE, &link_state,
   1620  1.1  christos 	    &len, errbuf);
   1621  1.1  christos 	if (status == 0) {
   1622  1.1  christos 		/*
   1623  1.1  christos 		 * NOTE: this also gives us the receive and transmit
   1624  1.1  christos 		 * link state.
   1625  1.1  christos 		 */
   1626  1.1  christos 		switch (link_state.MediaConnectState) {
   1627  1.1  christos 
   1628  1.1  christos 		case MediaConnectStateConnected:
   1629  1.1  christos 			/*
   1630  1.1  christos 			 * It's connected.
   1631  1.1  christos 			 */
   1632  1.1  christos 			*flags |= PCAP_IF_CONNECTION_STATUS_CONNECTED;
   1633  1.1  christos 			break;
   1634  1.1  christos 
   1635  1.1  christos 		case MediaConnectStateDisconnected:
   1636  1.1  christos 			/*
   1637  1.1  christos 			 * It's disconnected.
   1638  1.1  christos 			 */
   1639  1.1  christos 			*flags |= PCAP_IF_CONNECTION_STATUS_DISCONNECTED;
   1640  1.1  christos 			break;
   1641  1.1  christos 		}
   1642  1.1  christos 	}
   1643  1.1  christos #else
   1644  1.1  christos 	/*
   1645  1.1  christos 	 * OID_GEN_LINK_STATE isn't supported because it's not in our SDK.
   1646  1.1  christos 	 */
   1647  1.1  christos 	status = -1;
   1648  1.1  christos #endif
   1649  1.1  christos 	if (status == -1) {
   1650  1.1  christos 		/*
   1651  1.1  christos 		 * OK, OID_GEN_LINK_STATE didn't work, try
   1652  1.1  christos 		 * OID_GEN_MEDIA_CONNECT_STATUS.
   1653  1.1  christos 		 */
   1654  1.1  christos 		status = oid_get_request(adapter, OID_GEN_MEDIA_CONNECT_STATUS,
   1655  1.1  christos 		    &connect_status, &len, errbuf);
   1656  1.1  christos 		if (status == 0) {
   1657  1.1  christos 			switch (connect_status) {
   1658  1.1  christos 
   1659  1.1  christos 			case NdisMediaStateConnected:
   1660  1.1  christos 				/*
   1661  1.1  christos 				 * It's connected.
   1662  1.1  christos 				 */
   1663  1.1  christos 				*flags |= PCAP_IF_CONNECTION_STATUS_CONNECTED;
   1664  1.1  christos 				break;
   1665  1.1  christos 
   1666  1.1  christos 			case NdisMediaStateDisconnected:
   1667  1.1  christos 				/*
   1668  1.1  christos 				 * It's disconnected.
   1669  1.1  christos 				 */
   1670  1.1  christos 				*flags |= PCAP_IF_CONNECTION_STATUS_DISCONNECTED;
   1671  1.1  christos 				break;
   1672  1.1  christos 			}
   1673  1.1  christos 		}
   1674  1.1  christos 	}
   1675  1.1  christos 	PacketCloseAdapter(adapter);
   1676  1.1  christos 	return (0);
   1677  1.1  christos }
   1678  1.1  christos 
   1679  1.1  christos int
   1680  1.1  christos pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
   1681  1.1  christos {
   1682  1.1  christos 	int ret = 0;
   1683  1.1  christos 	const char *desc;
   1684  1.1  christos 	char *AdaptersName;
   1685  1.1  christos 	ULONG NameLength;
   1686  1.1  christos 	char *name;
   1687  1.1  christos 	char our_errbuf[PCAP_ERRBUF_SIZE+1];
   1688  1.1  christos 
   1689  1.1  christos 	/*
   1690  1.1  christos 	 * Find out how big a buffer we need.
   1691  1.1  christos 	 *
   1692  1.1  christos 	 * This call should always return FALSE; if the error is
   1693  1.1  christos 	 * ERROR_INSUFFICIENT_BUFFER, NameLength will be set to
   1694  1.1  christos 	 * the size of the buffer we need, otherwise there's a
   1695  1.1  christos 	 * problem, and NameLength should be set to 0.
   1696  1.1  christos 	 *
   1697  1.1  christos 	 * It shouldn't require NameLength to be set, but,
   1698  1.1  christos 	 * at least as of WinPcap 4.1.3, it checks whether
   1699  1.1  christos 	 * NameLength is big enough before it checks for a
   1700  1.1  christos 	 * NULL buffer argument, so, while it'll still do
   1701  1.1  christos 	 * the right thing if NameLength is uninitialized and
   1702  1.1  christos 	 * whatever junk happens to be there is big enough
   1703  1.1  christos 	 * (because the pointer argument will be null), it's
   1704  1.1  christos 	 * still reading an uninitialized variable.
   1705  1.1  christos 	 */
   1706  1.1  christos 	NameLength = 0;
   1707  1.1  christos 	if (!PacketGetAdapterNames(NULL, &NameLength))
   1708  1.1  christos 	{
   1709  1.1  christos 		DWORD last_error = GetLastError();
   1710  1.1  christos 
   1711  1.1  christos 		if (last_error != ERROR_INSUFFICIENT_BUFFER)
   1712  1.1  christos 		{
   1713  1.1  christos 			pcap_win32_err_to_str(last_error, our_errbuf);
   1714  1.1  christos 			pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
   1715  1.1  christos 			    "PacketGetAdapterNames: %s", our_errbuf);
   1716  1.1  christos 			return (-1);
   1717  1.1  christos 		}
   1718  1.1  christos 	}
   1719  1.1  christos 
   1720  1.1  christos 	if (NameLength <= 0)
   1721  1.1  christos 		return 0;
   1722  1.1  christos 	AdaptersName = (char*) malloc(NameLength);
   1723  1.1  christos 	if (AdaptersName == NULL)
   1724  1.1  christos 	{
   1725  1.1  christos 		pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters.");
   1726  1.1  christos 		return (-1);
   1727  1.1  christos 	}
   1728  1.1  christos 
   1729  1.1  christos 	if (!PacketGetAdapterNames(AdaptersName, &NameLength)) {
   1730  1.1  christos 		pcap_win32_err_to_str(GetLastError(), our_errbuf);
   1731  1.1  christos 		pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "PacketGetAdapterNames: %s",
   1732  1.1  christos 		    our_errbuf);
   1733  1.1  christos 		free(AdaptersName);
   1734  1.1  christos 		return (-1);
   1735  1.1  christos 	}
   1736  1.1  christos 
   1737  1.1  christos 	/*
   1738  1.1  christos 	 * "PacketGetAdapterNames()" returned a list of
   1739  1.1  christos 	 * null-terminated ASCII interface name strings,
   1740  1.1  christos 	 * terminated by a null string, followed by a list
   1741  1.1  christos 	 * of null-terminated ASCII interface description
   1742  1.1  christos 	 * strings, terminated by a null string.
   1743  1.1  christos 	 * This means there are two ASCII nulls at the end
   1744  1.1  christos 	 * of the first list.
   1745  1.1  christos 	 *
   1746  1.1  christos 	 * Find the end of the first list; that's the
   1747  1.1  christos 	 * beginning of the second list.
   1748  1.1  christos 	 */
   1749  1.1  christos 	desc = &AdaptersName[0];
   1750  1.1  christos 	while (*desc != '\0' || *(desc + 1) != '\0')
   1751  1.1  christos 		desc++;
   1752  1.1  christos 
   1753  1.1  christos 	/*
   1754  1.1  christos  	 * Found it - "desc" points to the first of the two
   1755  1.1  christos 	 * nulls at the end of the list of names, so the
   1756  1.1  christos 	 * first byte of the list of descriptions is two bytes
   1757  1.1  christos 	 * after it.
   1758  1.1  christos 	 */
   1759  1.1  christos 	desc += 2;
   1760  1.1  christos 
   1761  1.1  christos 	/*
   1762  1.1  christos 	 * Loop over the elements in the first list.
   1763  1.1  christos 	 */
   1764  1.1  christos 	name = &AdaptersName[0];
   1765  1.1  christos 	while (*name != '\0') {
   1766  1.1  christos 		bpf_u_int32 flags = 0;
   1767  1.1  christos #ifdef HAVE_PACKET_IS_LOOPBACK_ADAPTER
   1768  1.1  christos 		/*
   1769  1.1  christos 		 * Is this a loopback interface?
   1770  1.1  christos 		 */
   1771  1.1  christos 		if (PacketIsLoopbackAdapter(name)) {
   1772  1.1  christos 			/* Yes */
   1773  1.1  christos 			flags |= PCAP_IF_LOOPBACK;
   1774  1.1  christos 		}
   1775  1.1  christos #endif
   1776  1.1  christos 		/*
   1777  1.1  christos 		 * Get additional flags.
   1778  1.1  christos 		 */
   1779  1.1  christos 		if (get_if_flags(name, &flags, errbuf) == -1) {
   1780  1.1  christos 			/*
   1781  1.1  christos 			 * Failure.
   1782  1.1  christos 			 */
   1783  1.1  christos 			ret = -1;
   1784  1.1  christos 			break;
   1785  1.1  christos 		}
   1786  1.1  christos 
   1787  1.1  christos 		/*
   1788  1.1  christos 		 * Add an entry for this interface.
   1789  1.1  christos 		 */
   1790  1.1  christos 		if (pcap_add_if_npf(devlistp, name, flags, desc,
   1791  1.1  christos 		    errbuf) == -1) {
   1792  1.1  christos 			/*
   1793  1.1  christos 			 * Failure.
   1794  1.1  christos 			 */
   1795  1.1  christos 			ret = -1;
   1796  1.1  christos 			break;
   1797  1.1  christos 		}
   1798  1.1  christos 		name += strlen(name) + 1;
   1799  1.1  christos 		desc += strlen(desc) + 1;
   1800  1.1  christos 	}
   1801  1.1  christos 
   1802  1.1  christos 	free(AdaptersName);
   1803  1.1  christos 	return (ret);
   1804  1.1  christos }
   1805  1.1  christos 
   1806  1.1  christos /*
   1807  1.1  christos  * Return the name of a network interface attached to the system, or NULL
   1808  1.1  christos  * if none can be found.  The interface must be configured up; the
   1809  1.1  christos  * lowest unit number is preferred; loopback is ignored.
   1810  1.1  christos  *
   1811  1.1  christos  * In the best of all possible worlds, this would be the same as on
   1812  1.1  christos  * UN*X, but there may be software that expects this to return a
   1813  1.1  christos  * full list of devices after the first device.
   1814  1.1  christos  */
   1815  1.1  christos #define ADAPTERSNAME_LEN	8192
   1816  1.1  christos char *
   1817  1.1  christos pcap_lookupdev(char *errbuf)
   1818  1.1  christos {
   1819  1.1  christos 	DWORD dwVersion;
   1820  1.1  christos 	DWORD dwWindowsMajorVersion;
   1821  1.1  christos 	char our_errbuf[PCAP_ERRBUF_SIZE+1];
   1822  1.1  christos 
   1823  1.1  christos #pragma warning (push)
   1824  1.1  christos #pragma warning (disable: 4996) /* disable MSVC's GetVersion() deprecated warning here */
   1825  1.1  christos 	dwVersion = GetVersion();	/* get the OS version */
   1826  1.1  christos #pragma warning (pop)
   1827  1.1  christos 	dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
   1828  1.1  christos 
   1829  1.1  christos 	if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
   1830  1.1  christos 		/*
   1831  1.1  christos 		 * Windows 95, 98, ME.
   1832  1.1  christos 		 */
   1833  1.1  christos 		ULONG NameLength = ADAPTERSNAME_LEN;
   1834  1.1  christos 		static char AdaptersName[ADAPTERSNAME_LEN];
   1835  1.1  christos 
   1836  1.1  christos 		if (PacketGetAdapterNames(AdaptersName,&NameLength) )
   1837  1.1  christos 			return (AdaptersName);
   1838  1.1  christos 		else
   1839  1.1  christos 			return NULL;
   1840  1.1  christos 	} else {
   1841  1.1  christos 		/*
   1842  1.1  christos 		 * Windows NT (NT 4.0 and later).
   1843  1.1  christos 		 * Convert the names to Unicode for backward compatibility.
   1844  1.1  christos 		 */
   1845  1.1  christos 		ULONG NameLength = ADAPTERSNAME_LEN;
   1846  1.1  christos 		static WCHAR AdaptersName[ADAPTERSNAME_LEN];
   1847  1.1  christos 		size_t BufferSpaceLeft;
   1848  1.1  christos 		char *tAstr;
   1849  1.1  christos 		WCHAR *Unameptr;
   1850  1.1  christos 		char *Adescptr;
   1851  1.1  christos 		size_t namelen, i;
   1852  1.1  christos 		WCHAR *TAdaptersName = (WCHAR*)malloc(ADAPTERSNAME_LEN * sizeof(WCHAR));
   1853  1.1  christos 		int NAdapts = 0;
   1854  1.1  christos 
   1855  1.1  christos 		if(TAdaptersName == NULL)
   1856  1.1  christos 		{
   1857  1.1  christos 			(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
   1858  1.1  christos 			return NULL;
   1859  1.1  christos 		}
   1860  1.1  christos 
   1861  1.1  christos 		if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
   1862  1.1  christos 		{
   1863  1.1  christos 			pcap_win32_err_to_str(GetLastError(), our_errbuf);
   1864  1.1  christos 			(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
   1865  1.1  christos 				"PacketGetAdapterNames: %s", our_errbuf);
   1866  1.1  christos 			free(TAdaptersName);
   1867  1.1  christos 			return NULL;
   1868  1.1  christos 		}
   1869  1.1  christos 
   1870  1.1  christos 
   1871  1.1  christos 		BufferSpaceLeft = ADAPTERSNAME_LEN * sizeof(WCHAR);
   1872  1.1  christos 		tAstr = (char*)TAdaptersName;
   1873  1.1  christos 		Unameptr = AdaptersName;
   1874  1.1  christos 
   1875  1.1  christos 		/*
   1876  1.1  christos 		 * Convert the device names to Unicode into AdapterName.
   1877  1.1  christos 		 */
   1878  1.1  christos 		do {
   1879  1.1  christos 			/*
   1880  1.1  christos 			 * Length of the name, including the terminating
   1881  1.1  christos 			 * NUL.
   1882  1.1  christos 			 */
   1883  1.1  christos 			namelen = strlen(tAstr) + 1;
   1884  1.1  christos 
   1885  1.1  christos 			/*
   1886  1.1  christos 			 * Do we have room for the name in the Unicode
   1887  1.1  christos 			 * buffer?
   1888  1.1  christos 			 */
   1889  1.1  christos 			if (BufferSpaceLeft < namelen * sizeof(WCHAR)) {
   1890  1.1  christos 				/*
   1891  1.1  christos 				 * No.
   1892  1.1  christos 				 */
   1893  1.1  christos 				goto quit;
   1894  1.1  christos 			}
   1895  1.1  christos 			BufferSpaceLeft -= namelen * sizeof(WCHAR);
   1896  1.1  christos 
   1897  1.1  christos 			/*
   1898  1.1  christos 			 * Copy the name, converting ASCII to Unicode.
   1899  1.1  christos 			 * namelen includes the NUL, so we copy it as
   1900  1.1  christos 			 * well.
   1901  1.1  christos 			 */
   1902  1.1  christos 			for (i = 0; i < namelen; i++)
   1903  1.1  christos 				*Unameptr++ = *tAstr++;
   1904  1.1  christos 
   1905  1.1  christos 			/*
   1906  1.1  christos 			 * Count this adapter.
   1907  1.1  christos 			 */
   1908  1.1  christos 			NAdapts++;
   1909  1.1  christos 		} while (namelen != 1);
   1910  1.1  christos 
   1911  1.1  christos 		/*
   1912  1.1  christos 		 * Copy the descriptions, but don't convert them from
   1913  1.1  christos 		 * ASCII to Unicode.
   1914  1.1  christos 		 */
   1915  1.1  christos 		Adescptr = (char *)Unameptr;
   1916  1.1  christos 		while(NAdapts--)
   1917  1.1  christos 		{
   1918  1.1  christos 			size_t desclen;
   1919  1.1  christos 
   1920  1.1  christos 			desclen = strlen(tAstr) + 1;
   1921  1.1  christos 
   1922  1.1  christos 			/*
   1923  1.1  christos 			 * Do we have room for the name in the Unicode
   1924  1.1  christos 			 * buffer?
   1925  1.1  christos 			 */
   1926  1.1  christos 			if (BufferSpaceLeft < desclen) {
   1927  1.1  christos 				/*
   1928  1.1  christos 				 * No.
   1929  1.1  christos 				 */
   1930  1.1  christos 				goto quit;
   1931  1.1  christos 			}
   1932  1.1  christos 
   1933  1.1  christos 			/*
   1934  1.1  christos 			 * Just copy the ASCII string.
   1935  1.1  christos 			 * namelen includes the NUL, so we copy it as
   1936  1.1  christos 			 * well.
   1937  1.1  christos 			 */
   1938  1.1  christos 			memcpy(Adescptr, tAstr, desclen);
   1939  1.1  christos 			Adescptr += desclen;
   1940  1.1  christos 			tAstr += desclen;
   1941  1.1  christos 			BufferSpaceLeft -= desclen;
   1942  1.1  christos 		}
   1943  1.1  christos 
   1944  1.1  christos 	quit:
   1945  1.1  christos 		free(TAdaptersName);
   1946  1.1  christos 		return (char *)(AdaptersName);
   1947  1.1  christos 	}
   1948  1.1  christos }
   1949  1.1  christos 
   1950  1.1  christos /*
   1951  1.1  christos  * We can't use the same code that we use on UN*X, as that's doing
   1952  1.1  christos  * UN*X-specific calls.
   1953  1.1  christos  *
   1954  1.1  christos  * We don't just fetch the entire list of devices, search for the
   1955  1.1  christos  * particular device, and use its first IPv4 address, as that's too
   1956  1.1  christos  * much work to get just one device's netmask.
   1957  1.1  christos  */
   1958  1.1  christos int
   1959  1.1  christos pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
   1960  1.1  christos     char *errbuf)
   1961  1.1  christos {
   1962  1.1  christos 	/*
   1963  1.1  christos 	 * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo()
   1964  1.1  christos 	 * in order to skip non IPv4 (i.e. IPv6 addresses)
   1965  1.1  christos 	 */
   1966  1.1  christos 	npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
   1967  1.1  christos 	LONG if_addr_size = MAX_NETWORK_ADDRESSES;
   1968  1.1  christos 	struct sockaddr_in *t_addr;
   1969  1.1  christos 	LONG i;
   1970  1.1  christos 
   1971  1.1  christos 	if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) {
   1972  1.1  christos 		*netp = *maskp = 0;
   1973  1.1  christos 		return (0);
   1974  1.1  christos 	}
   1975  1.1  christos 
   1976  1.1  christos 	for(i = 0; i < if_addr_size; i++)
   1977  1.1  christos 	{
   1978  1.1  christos 		if(if_addrs[i].IPAddress.ss_family == AF_INET)
   1979  1.1  christos 		{
   1980  1.1  christos 			t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress);
   1981  1.1  christos 			*netp = t_addr->sin_addr.S_un.S_addr;
   1982  1.1  christos 			t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask);
   1983  1.1  christos 			*maskp = t_addr->sin_addr.S_un.S_addr;
   1984  1.1  christos 
   1985  1.1  christos 			*netp &= *maskp;
   1986  1.1  christos 			return (0);
   1987  1.1  christos 		}
   1988  1.1  christos 
   1989  1.1  christos 	}
   1990  1.1  christos 
   1991  1.1  christos 	*netp = *maskp = 0;
   1992  1.1  christos 	return (0);
   1993  1.1  christos }
   1994  1.1  christos 
   1995  1.1  christos static const char *pcap_lib_version_string;
   1996  1.1  christos 
   1997  1.1  christos #ifdef HAVE_VERSION_H
   1998  1.1  christos /*
   1999  1.1  christos  * libpcap being built for Windows, as part of a WinPcap/Npcap source
   2000  1.1  christos  * tree.  Include version.h from that source tree to get the WinPcap/Npcap
   2001  1.1  christos  * version.
   2002  1.1  christos  *
   2003  1.1  christos  * XXX - it'd be nice if we could somehow generate the WinPcap version number
   2004  1.1  christos  * when building WinPcap.  (It'd be nice to do so for the packet.dll version
   2005  1.1  christos  * number as well.)
   2006  1.1  christos  */
   2007  1.1  christos #include "../../version.h"
   2008  1.1  christos 
   2009  1.1  christos static const char pcap_version_string[] =
   2010  1.1  christos 	WINPCAP_PRODUCT_NAME " version " WINPCAP_VER_STRING ", based on " PCAP_VERSION_STRING;
   2011  1.1  christos static const char pcap_version_string_packet_dll_fmt[] =
   2012  1.1  christos 	WINPCAP_PRODUCT_NAME " version " WINPCAP_VER_STRING " (packet.dll version %s), based on " PCAP_VERSION_STRING;
   2013  1.1  christos 
   2014  1.1  christos const char *
   2015  1.1  christos pcap_lib_version(void)
   2016  1.1  christos {
   2017  1.1  christos 	char *packet_version_string;
   2018  1.1  christos 	size_t full_pcap_version_string_len;
   2019  1.1  christos 	char *full_pcap_version_string;
   2020  1.1  christos 
   2021  1.1  christos 	if (pcap_lib_version_string == NULL) {
   2022  1.1  christos 		/*
   2023  1.1  christos 		 * Generate the version string.
   2024  1.1  christos 		 */
   2025  1.1  christos 		packet_version_string = PacketGetVersion();
   2026  1.1  christos 		if (strcmp(WINPCAP_VER_STRING, packet_version_string) == 0) {
   2027  1.1  christos 			/*
   2028  1.1  christos 			 * WinPcap version string and packet.dll version
   2029  1.1  christos 			 * string are the same; just report the WinPcap
   2030  1.1  christos 			 * version.
   2031  1.1  christos 			 */
   2032  1.1  christos 			pcap_lib_version_string = pcap_version_string;
   2033  1.1  christos 		} else {
   2034  1.1  christos 			/*
   2035  1.1  christos 			 * WinPcap version string and packet.dll version
   2036  1.1  christos 			 * string are different; that shouldn't be the
   2037  1.1  christos 			 * case (the two libraries should come from the
   2038  1.1  christos 			 * same version of WinPcap), so we report both
   2039  1.1  christos 			 * versions.
   2040  1.1  christos 			 *
   2041  1.1  christos 			 * The -2 is for the %s in the format string,
   2042  1.1  christos 			 * which will be replaced by packet_version_string.
   2043  1.1  christos 			 */
   2044  1.1  christos 			full_pcap_version_string_len =
   2045  1.1  christos 			    (sizeof pcap_version_string_packet_dll_fmt - 2) +
   2046  1.1  christos 			    strlen(packet_version_string);
   2047  1.1  christos 			full_pcap_version_string = malloc(full_pcap_version_string_len);
   2048  1.1  christos 			if (full_pcap_version_string == NULL)
   2049  1.1  christos 				return (NULL);
   2050  1.1  christos 			pcap_snprintf(full_pcap_version_string,
   2051  1.1  christos 			    full_pcap_version_string_len,
   2052  1.1  christos 			    pcap_version_string_packet_dll_fmt,
   2053  1.1  christos 			    packet_version_string);
   2054  1.1  christos 		}
   2055  1.1  christos 		pcap_lib_version_string = full_pcap_version_string;
   2056  1.1  christos 	}
   2057  1.1  christos 	return (pcap_lib_version_string);
   2058  1.1  christos }
   2059  1.1  christos 
   2060  1.1  christos #else /* HAVE_VERSION_H */
   2061  1.1  christos 
   2062  1.1  christos /*
   2063  1.1  christos  * libpcap being built for Windows, not as part of a WinPcap/Npcap source
   2064  1.1  christos  * tree.
   2065  1.1  christos  */
   2066  1.1  christos static const char pcap_version_string_packet_dll_fmt[] =
   2067  1.1  christos 	PCAP_VERSION_STRING " (packet.dll version %s)";
   2068  1.1  christos const char *
   2069  1.1  christos pcap_lib_version(void)
   2070  1.1  christos {
   2071  1.1  christos 	char *packet_version_string;
   2072  1.1  christos 	size_t full_pcap_version_string_len;
   2073  1.1  christos 	char *full_pcap_version_string;
   2074  1.1  christos 
   2075  1.1  christos 	if (pcap_lib_version_string == NULL) {
   2076  1.1  christos 		/*
   2077  1.1  christos 		 * Generate the version string.  Report the packet.dll
   2078  1.1  christos 		 * version.
   2079  1.1  christos 		 *
   2080  1.1  christos 		 * The -2 is for the %s in the format string, which will
   2081  1.1  christos 		 * be replaced by packet_version_string.
   2082  1.1  christos 		 */
   2083  1.1  christos 		packet_version_string = PacketGetVersion();
   2084  1.1  christos 		full_pcap_version_string_len =
   2085  1.1  christos 		    (sizeof pcap_version_string_packet_dll_fmt - 2) +
   2086  1.1  christos 		    strlen(packet_version_string);
   2087  1.1  christos 		full_pcap_version_string = malloc(full_pcap_version_string_len);
   2088  1.1  christos 		if (full_pcap_version_string == NULL)
   2089  1.1  christos 			return (NULL);
   2090  1.1  christos 		pcap_snprintf(full_pcap_version_string,
   2091  1.1  christos 		    full_pcap_version_string_len,
   2092  1.1  christos 		    pcap_version_string_packet_dll_fmt,
   2093  1.1  christos 		    packet_version_string);
   2094  1.1  christos 		pcap_lib_version_string = full_pcap_version_string;
   2095  1.1  christos 	}
   2096  1.1  christos 	return (pcap_lib_version_string);
   2097  1.1  christos }
   2098  1.1  christos #endif /* HAVE_VERSION_H */
   2099