Home | History | Annotate | Download | only in libpcap
      1 /*
      2  * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
      3  * Copyright (c) 2005 - 2008 CACE Technologies, Davis (California)
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  *
     10  * 1. Redistributions of source code must retain the above copyright
     11  * notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  * notice, this list of conditions and the following disclaimer in the
     14  * documentation and/or other materials provided with the distribution.
     15  * 3. Neither the name of the Politecnico di Torino, CACE Technologies
     16  * nor the names of its contributors may be used to endorse or promote
     17  * products derived from this software without specific prior written
     18  * permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  *
     32  */
     33 
     34 #ifndef lint
     35 static const char rcsid[] _U_ =
     36     "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.42 2008-05-21 22:15:25 gianluca Exp $ (LBL)";
     37 #endif
     38 
     39 #include <pcap-int.h>
     40 #include <Packet32.h>
     41 #ifdef __MINGW32__
     42 #ifdef __MINGW64__
     43 #include <ntddndis.h>
     44 #else  /*__MINGW64__*/
     45 #include <ddk/ntddndis.h>
     46 #include <ddk/ndis.h>
     47 #endif /*__MINGW64__*/
     48 #else /*__MINGW32__*/
     49 #include <ntddndis.h>
     50 #endif /*__MINGW32__*/
     51 #ifdef HAVE_DAG_API
     52 #include <dagnew.h>
     53 #include <dagapi.h>
     54 #endif /* HAVE_DAG_API */
     55 #ifdef __MINGW32__
     56 int* _errno();
     57 #define errno (*_errno())
     58 #endif /* __MINGW32__ */
     59 
     60 static int pcap_setfilter_win32_npf(pcap_t *, struct bpf_program *);
     61 static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *);
     62 static int pcap_getnonblock_win32(pcap_t *, char *);
     63 static int pcap_setnonblock_win32(pcap_t *, int, char *);
     64 
     65 /*dimension of the buffer in the pcap_t structure*/
     66 #define	WIN32_DEFAULT_USER_BUFFER_SIZE 256000
     67 
     68 /*dimension of the buffer in the kernel driver NPF */
     69 #define	WIN32_DEFAULT_KERNEL_BUFFER_SIZE 1000000
     70 
     71 /* Equivalent to ntohs(), but a lot faster under Windows */
     72 #define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8)
     73 
     74 /*
     75  * Private data for capturing on WinPcap devices.
     76  */
     77 struct pcap_win {
     78 	int nonblock;
     79 
     80 #ifdef HAVE_DAG_API
     81 	int	dag_fcs_bits;	/* Number of checksum bits from link layer */
     82 #endif
     83 };
     84 
     85 /*
     86  * Header that the WinPcap driver associates to the packets.
     87  * Once was in bpf.h
     88  */
     89 struct bpf_hdr {
     90 	struct timeval	bh_tstamp;	/* time stamp */
     91 	bpf_u_int32	bh_caplen;	/* length of captured portion */
     92 	bpf_u_int32	bh_datalen;	/* original length of packet */
     93 	u_short		bh_hdrlen;	/* length of bpf header (this struct
     94 					   plus alignment padding) */
     95 };
     96 
     97 CRITICAL_SECTION g_PcapCompileCriticalSection;
     98 
     99 BOOL WINAPI DllMain(
    100   HANDLE hinstDLL,
    101   DWORD dwReason,
    102   LPVOID lpvReserved
    103 )
    104 {
    105 	if (dwReason == DLL_PROCESS_ATTACH)
    106 	{
    107 		InitializeCriticalSection(&g_PcapCompileCriticalSection);
    108 	}
    109 
    110 	return TRUE;
    111 }
    112 
    113 /* Start winsock */
    114 int
    115 wsockinit()
    116 {
    117 	WORD wVersionRequested;
    118 	WSADATA wsaData;
    119 	int err;
    120 	wVersionRequested = MAKEWORD( 1, 1);
    121 	err = WSAStartup( wVersionRequested, &wsaData );
    122 	if ( err != 0 )
    123 	{
    124 		return -1;
    125 	}
    126 	return 0;
    127 }
    128 
    129 
    130 static int
    131 pcap_stats_win32(pcap_t *p, struct pcap_stat *ps)
    132 {
    133 
    134 	if(PacketGetStats(p->adapter, (struct bpf_stat*)ps) != TRUE){
    135 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "PacketGetStats error: %s", pcap_win32strerror());
    136 		return -1;
    137 	}
    138 
    139 	return 0;
    140 }
    141 
    142 /* Set the dimension of the kernel-level capture buffer */
    143 static int
    144 pcap_setbuff_win32(pcap_t *p, int dim)
    145 {
    146 	if(PacketSetBuff(p->adapter,dim)==FALSE)
    147 	{
    148 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
    149 		return -1;
    150 	}
    151 	return 0;
    152 }
    153 
    154 /* Set the driver working mode */
    155 static int
    156 pcap_setmode_win32(pcap_t *p, int mode)
    157 {
    158 	if(PacketSetMode(p->adapter,mode)==FALSE)
    159 	{
    160 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized");
    161 		return -1;
    162 	}
    163 
    164 	return 0;
    165 }
    166 
    167 /*set the minimum amount of data that will release a read call*/
    168 static int
    169 pcap_setmintocopy_win32(pcap_t *p, int size)
    170 {
    171 	if(PacketSetMinToCopy(p->adapter, size)==FALSE)
    172 	{
    173 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size");
    174 		return -1;
    175 	}
    176 	return 0;
    177 }
    178 
    179 /*return the Adapter for a pcap_t*/
    180 static Adapter *
    181 pcap_getadapter_win32(pcap_t *p)
    182 {
    183 	return p->adapter;
    184 }
    185 
    186 static int
    187 pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
    188 {
    189 	int cc;
    190 	int n = 0;
    191 	register u_char *bp, *ep;
    192 
    193 	cc = p->cc;
    194 	if (p->cc == 0) {
    195 		/*
    196 		 * Has "pcap_breakloop()" been called?
    197 		 */
    198 		if (p->break_loop) {
    199 			/*
    200 			 * Yes - clear the flag that indicates that it
    201 			 * has, and return -2 to indicate that we were
    202 			 * told to break out of the loop.
    203 			 */
    204 			p->break_loop = 0;
    205 			return (-2);
    206 		}
    207 
    208 	    /* capture the packets */
    209 		if(PacketReceivePacket(p->adapter,p->Packet,TRUE)==FALSE){
    210 			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
    211 			return (-1);
    212 		}
    213 
    214 		cc = p->Packet->ulBytesReceived;
    215 
    216 		bp = p->Packet->Buffer;
    217 	}
    218 	else
    219 		bp = p->bp;
    220 
    221 	/*
    222 	 * Loop through each packet.
    223 	 */
    224 #define bhp ((struct bpf_hdr *)bp)
    225 	ep = bp + cc;
    226 	while (1) {
    227 		register int caplen, hdrlen;
    228 
    229 		/*
    230 		 * Has "pcap_breakloop()" been called?
    231 		 * If so, return immediately - if we haven't read any
    232 		 * packets, clear the flag and return -2 to indicate
    233 		 * that we were told to break out of the loop, otherwise
    234 		 * leave the flag set, so that the *next* call will break
    235 		 * out of the loop without having read any packets, and
    236 		 * return the number of packets we've processed so far.
    237 		 */
    238 		if (p->break_loop) {
    239 			if (n == 0) {
    240 				p->break_loop = 0;
    241 				return (-2);
    242 			} else {
    243 				p->bp = bp;
    244 				p->cc = ep - bp;
    245 				return (n);
    246 			}
    247 		}
    248 		if (bp >= ep)
    249 			break;
    250 
    251 		caplen = bhp->bh_caplen;
    252 		hdrlen = bhp->bh_hdrlen;
    253 
    254 		/*
    255 		 * XXX A bpf_hdr matches a pcap_pkthdr.
    256 		 */
    257 		(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
    258 		bp += Packet_WORDALIGN(caplen + hdrlen);
    259 		if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) {
    260 			p->bp = bp;
    261 			p->cc = ep - bp;
    262 			return (n);
    263 		}
    264 	}
    265 #undef bhp
    266 	p->cc = 0;
    267 	return (n);
    268 }
    269 
    270 #ifdef HAVE_DAG_API
    271 static int
    272 pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
    273 {
    274 	struct pcap_win *pw = p->priv;
    275 	u_char *dp = NULL;
    276 	int	packet_len = 0, caplen = 0;
    277 	struct pcap_pkthdr	pcap_header;
    278 	u_char *endofbuf;
    279 	int n = 0;
    280 	dag_record_t *header;
    281 	unsigned erf_record_len;
    282 	ULONGLONG ts;
    283 	int cc;
    284 	unsigned swt;
    285 	unsigned dfp = p->adapter->DagFastProcess;
    286 
    287 	cc = p->cc;
    288 	if (cc == 0) /* Get new packets only if we have processed all the ones of the previous read */
    289 	{
    290 	    /* Get new packets from the network */
    291 		if(PacketReceivePacket(p->adapter, p->Packet, TRUE)==FALSE){
    292 			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
    293 			return (-1);
    294 		}
    295 
    296 		cc = p->Packet->ulBytesReceived;
    297 		if(cc == 0)
    298 			/* The timeout has expired but we no packets arrived */
    299 			return 0;
    300 		header = (dag_record_t*)p->adapter->DagBuffer;
    301 	}
    302 	else
    303 		header = (dag_record_t*)p->bp;
    304 
    305 	endofbuf = (char*)header + cc;
    306 
    307 	/*
    308 	 * Cycle through the packets
    309 	 */
    310 	do
    311 	{
    312 		erf_record_len = SWAPS(header->rlen);
    313 		if((char*)header + erf_record_len > endofbuf)
    314 			break;
    315 
    316 		/* Increase the number of captured packets */
    317 		pw->stat.ps_recv++;
    318 
    319 		/* Find the beginning of the packet */
    320 		dp = ((u_char *)header) + dag_record_size;
    321 
    322 		/* Determine actual packet len */
    323 		switch(header->type)
    324 		{
    325 		case TYPE_ATM:
    326 			packet_len = ATM_SNAPLEN;
    327 			caplen = ATM_SNAPLEN;
    328 			dp += 4;
    329 
    330 			break;
    331 
    332 		case TYPE_ETH:
    333 			swt = SWAPS(header->wlen);
    334 			packet_len = swt - (pw->dag_fcs_bits);
    335 			caplen = erf_record_len - dag_record_size - 2;
    336 			if (caplen > packet_len)
    337 			{
    338 				caplen = packet_len;
    339 			}
    340 			dp += 2;
    341 
    342 			break;
    343 
    344 		case TYPE_HDLC_POS:
    345 			swt = SWAPS(header->wlen);
    346 			packet_len = swt - (pw->dag_fcs_bits);
    347 			caplen = erf_record_len - dag_record_size;
    348 			if (caplen > packet_len)
    349 			{
    350 				caplen = packet_len;
    351 			}
    352 
    353 			break;
    354 		}
    355 
    356 		if(caplen > p->snapshot)
    357 			caplen = p->snapshot;
    358 
    359 		/*
    360 		 * Has "pcap_breakloop()" been called?
    361 		 * If so, return immediately - if we haven't read any
    362 		 * packets, clear the flag and return -2 to indicate
    363 		 * that we were told to break out of the loop, otherwise
    364 		 * leave the flag set, so that the *next* call will break
    365 		 * out of the loop without having read any packets, and
    366 		 * return the number of packets we've processed so far.
    367 		 */
    368 		if (p->break_loop)
    369 		{
    370 			if (n == 0)
    371 			{
    372 				p->break_loop = 0;
    373 				return (-2);
    374 			}
    375 			else
    376 			{
    377 				p->bp = (char*)header;
    378 				p->cc = endofbuf - (char*)header;
    379 				return (n);
    380 			}
    381 		}
    382 
    383 		if(!dfp)
    384 		{
    385 			/* convert between timestamp formats */
    386 			ts = header->ts;
    387 			pcap_header.ts.tv_sec = (int)(ts >> 32);
    388 			ts = (ts & 0xffffffffi64) * 1000000;
    389 			ts += 0x80000000; /* rounding */
    390 			pcap_header.ts.tv_usec = (int)(ts >> 32);
    391 			if (pcap_header.ts.tv_usec >= 1000000) {
    392 				pcap_header.ts.tv_usec -= 1000000;
    393 				pcap_header.ts.tv_sec++;
    394 			}
    395 		}
    396 
    397 		/* No underlaying filtering system. We need to filter on our own */
    398 		if (p->fcode.bf_insns)
    399 		{
    400 			if (bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0)
    401 			{
    402 				/* Move to next packet */
    403 				header = (dag_record_t*)((char*)header + erf_record_len);
    404 				continue;
    405 			}
    406 		}
    407 
    408 		/* Fill the header for the user suppplied callback function */
    409 		pcap_header.caplen = caplen;
    410 		pcap_header.len = packet_len;
    411 
    412 		/* Call the callback function */
    413 		(*callback)(user, &pcap_header, dp);
    414 
    415 		/* Move to next packet */
    416 		header = (dag_record_t*)((char*)header + erf_record_len);
    417 
    418 		/* Stop if the number of packets requested by user has been reached*/
    419 		if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt))
    420 		{
    421 			p->bp = (char*)header;
    422 			p->cc = endofbuf - (char*)header;
    423 			return (n);
    424 		}
    425 	}
    426 	while((u_char*)header < endofbuf);
    427 
    428   return 1;
    429 }
    430 #endif /* HAVE_DAG_API */
    431 
    432 /* Send a packet to the network */
    433 static int
    434 pcap_inject_win32(pcap_t *p, const void *buf, size_t size){
    435 	LPPACKET PacketToSend;
    436 
    437 	PacketToSend=PacketAllocatePacket();
    438 
    439 	if (PacketToSend == NULL)
    440 	{
    441 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketAllocatePacket failed");
    442 		return -1;
    443 	}
    444 
    445 	PacketInitPacket(PacketToSend,(PVOID)buf,size);
    446 	if(PacketSendPacket(p->adapter,PacketToSend,TRUE) == FALSE){
    447 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketSendPacket failed");
    448 		PacketFreePacket(PacketToSend);
    449 		return -1;
    450 	}
    451 
    452 	PacketFreePacket(PacketToSend);
    453 
    454 	/*
    455 	 * We assume it all got sent if "PacketSendPacket()" succeeded.
    456 	 * "pcap_inject()" is expected to return the number of bytes
    457 	 * sent.
    458 	 */
    459 	return size;
    460 }
    461 
    462 static void
    463 pcap_cleanup_win32(pcap_t *p)
    464 {
    465 	if (p->adapter != NULL) {
    466 		PacketCloseAdapter(p->adapter);
    467 		p->adapter = NULL;
    468 	}
    469 	if (p->Packet) {
    470 		PacketFreePacket(p->Packet);
    471 		p->Packet = NULL;
    472 	}
    473 	pcap_cleanup_live_common(p);
    474 }
    475 
    476 static int
    477 pcap_activate_win32(pcap_t *p)
    478 {
    479 	struct pcap_win *pw = p->priv;
    480 	NetType type;
    481 
    482 	if (p->opt.rfmon) {
    483 		/*
    484 		 * No monitor mode on Windows.  It could be done on
    485 		 * Vista with drivers that support the native 802.11
    486 		 * mechanism and monitor mode.
    487 		 */
    488 		return (PCAP_ERROR_RFMON_NOTSUP);
    489 	}
    490 
    491 	/* Init WinSock */
    492 	wsockinit();
    493 
    494 	p->adapter = PacketOpenAdapter(p->opt.source);
    495 
    496 	if (p->adapter == NULL)
    497 	{
    498 		/* Adapter detected but we are not able to open it. Return failure. */
    499 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror());
    500 		return PCAP_ERROR;
    501 	}
    502 
    503 	/*get network type*/
    504 	if(PacketGetNetType (p->adapter,&type) == FALSE)
    505 	{
    506 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror());
    507 		goto bad;
    508 	}
    509 
    510 	/*Set the linktype*/
    511 	switch (type.LinkType)
    512 	{
    513 	case NdisMediumWan:
    514 		p->linktype = DLT_EN10MB;
    515 		break;
    516 
    517 	case NdisMedium802_3:
    518 		p->linktype = DLT_EN10MB;
    519 		/*
    520 		 * This is (presumably) a real Ethernet capture; give it a
    521 		 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
    522 		 * that an application can let you choose it, in case you're
    523 		 * capturing DOCSIS traffic that a Cisco Cable Modem
    524 		 * Termination System is putting out onto an Ethernet (it
    525 		 * doesn't put an Ethernet header onto the wire, it puts raw
    526 		 * DOCSIS frames out on the wire inside the low-level
    527 		 * Ethernet framing).
    528 		 */
    529 		p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
    530 		/*
    531 		 * If that fails, just leave the list empty.
    532 		 */
    533 		if (p->dlt_list != NULL) {
    534 			p->dlt_list[0] = DLT_EN10MB;
    535 			p->dlt_list[1] = DLT_DOCSIS;
    536 			p->dlt_count = 2;
    537 		}
    538 		break;
    539 
    540 	case NdisMediumFddi:
    541 		p->linktype = DLT_FDDI;
    542 		break;
    543 
    544 	case NdisMedium802_5:
    545 		p->linktype = DLT_IEEE802;
    546 		break;
    547 
    548 	case NdisMediumArcnetRaw:
    549 		p->linktype = DLT_ARCNET;
    550 		break;
    551 
    552 	case NdisMediumArcnet878_2:
    553 		p->linktype = DLT_ARCNET;
    554 		break;
    555 
    556 	case NdisMediumAtm:
    557 		p->linktype = DLT_ATM_RFC1483;
    558 		break;
    559 
    560 	case NdisMediumCHDLC:
    561 		p->linktype = DLT_CHDLC;
    562 		break;
    563 
    564 	case NdisMediumPPPSerial:
    565 		p->linktype = DLT_PPP_SERIAL;
    566 		break;
    567 
    568 	case NdisMediumNull:
    569 		p->linktype = DLT_NULL;
    570 		break;
    571 
    572 	case NdisMediumBare80211:
    573 		p->linktype = DLT_IEEE802_11;
    574 		break;
    575 
    576 	case NdisMediumRadio80211:
    577 		p->linktype = DLT_IEEE802_11_RADIO;
    578 		break;
    579 
    580 	case NdisMediumPpi:
    581 		p->linktype = DLT_PPI;
    582 		break;
    583 
    584 	default:
    585 		p->linktype = DLT_EN10MB;			/*an unknown adapter is assumed to be ethernet*/
    586 		break;
    587 	}
    588 
    589 	/* Set promiscuous mode */
    590 	if (p->opt.promisc)
    591 	{
    592 
    593 		if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
    594 		{
    595 			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode");
    596 			goto bad;
    597 		}
    598 	}
    599 	else
    600 	{
    601 		if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL) == FALSE)
    602 		{
    603 			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode");
    604 			goto bad;
    605 		}
    606 	}
    607 
    608 	/* Set the buffer size */
    609 	p->bufsize = WIN32_DEFAULT_USER_BUFFER_SIZE;
    610 
    611 	/* allocate Packet structure used during the capture */
    612 	if((p->Packet = PacketAllocatePacket())==NULL)
    613 	{
    614 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure");
    615 		goto bad;
    616 	}
    617 
    618 	if(!(p->adapter->Flags & INFO_FLAG_DAG_CARD))
    619 	{
    620 	/*
    621 	 * Traditional Adapter
    622 	 */
    623 		/*
    624 		 * If the buffer size wasn't explicitly set, default to
    625 		 * WIN32_DEFAULT_USER_BUFFER_SIZE.
    626 		 */
    627 	 	if (p->opt.buffer_size == 0)
    628 	 		p->opt.buffer_size = WIN32_DEFAULT_KERNEL_BUFFER_SIZE;
    629 
    630 		if(PacketSetBuff(p->adapter,p->opt.buffer_size)==FALSE)
    631 		{
    632 			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
    633 			goto bad;
    634 		}
    635 
    636 		p->buffer = (u_char *)malloc(p->bufsize);
    637 		if (p->buffer == NULL)
    638 		{
    639 			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
    640 			goto bad;
    641 		}
    642 
    643 		PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);
    644 
    645 		if (p-opt.immediate)
    646 		{
    647 			/* tell the driver to copy the buffer as soon as data arrives */
    648 			if(PacketSetMinToCopy(p->adapter,0)==FALSE)
    649 			{
    650 				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s", pcap_win32strerror());
    651 				goto bad;
    652 			}
    653 		}
    654 		else
    655 		{
    656 			/* tell the driver to copy the buffer only if it contains at least 16K */
    657 			if(PacketSetMinToCopy(p->adapter,16000)==FALSE)
    658 			{
    659 				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s", pcap_win32strerror());
    660 				goto bad;
    661 			}
    662 		}
    663 	}
    664 	else
    665 #ifdef HAVE_DAG_API
    666 	{
    667 	/*
    668 	 * Dag Card
    669 	 */
    670 		LONG	status;
    671 		HKEY	dagkey;
    672 		DWORD	lptype;
    673 		DWORD	lpcbdata;
    674 		int		postype = 0;
    675 		char	keyname[512];
    676 
    677 		snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s",
    678 			"SYSTEM\\CurrentControlSet\\Services\\DAG",
    679 			strstr(_strlwr(p->opt.source), "dag"));
    680 		do
    681 		{
    682 			status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey);
    683 			if(status != ERROR_SUCCESS)
    684 				break;
    685 
    686 			status = RegQueryValueEx(dagkey,
    687 				"PosType",
    688 				NULL,
    689 				&lptype,
    690 				(char*)&postype,
    691 				&lpcbdata);
    692 
    693 			if(status != ERROR_SUCCESS)
    694 			{
    695 				postype = 0;
    696 			}
    697 
    698 			RegCloseKey(dagkey);
    699 		}
    700 		while(FALSE);
    701 
    702 
    703 		p->snapshot = PacketSetSnapLen(p->adapter, snaplen);
    704 
    705 		/* Set the length of the FCS associated to any packet. This value
    706 		 * will be subtracted to the packet length */
    707 		pw->dag_fcs_bits = p->adapter->DagFcsLen;
    708 	}
    709 #else
    710 	goto bad;
    711 #endif /* HAVE_DAG_API */
    712 
    713 	PacketSetReadTimeout(p->adapter, p->opt.timeout);
    714 
    715 #ifdef HAVE_DAG_API
    716 	if(p->adapter->Flags & INFO_FLAG_DAG_CARD)
    717 	{
    718 		/* install dag specific handlers for read and setfilter */
    719 		p->read_op = pcap_read_win32_dag;
    720 		p->setfilter_op = pcap_setfilter_win32_dag;
    721 	}
    722 	else
    723 	{
    724 #endif /* HAVE_DAG_API */
    725 		/* install traditional npf handlers for read and setfilter */
    726 		p->read_op = pcap_read_win32_npf;
    727 		p->setfilter_op = pcap_setfilter_win32_npf;
    728 #ifdef HAVE_DAG_API
    729 	}
    730 #endif /* HAVE_DAG_API */
    731 	p->setdirection_op = NULL;	/* Not implemented. */
    732 	    /* XXX - can this be implemented on some versions of Windows? */
    733 	p->inject_op = pcap_inject_win32;
    734 	p->set_datalink_op = NULL;	/* can't change data link type */
    735 	p->getnonblock_op = pcap_getnonblock_win32;
    736 	p->setnonblock_op = pcap_setnonblock_win32;
    737 	p->stats_op = pcap_stats_win32;
    738 	p->setbuff_op = pcap_setbuff_win32;
    739 	p->setmode_op = pcap_setmode_win32;
    740 	p->setmintocopy_op = pcap_setmintocopy_win32;
    741 	p->getadapter_op = pcap_getadapter_win32;
    742 	p->cleanup_op = pcap_cleanup_win32;
    743 
    744 	return (0);
    745 bad:
    746 	pcap_cleanup_win32(p);
    747 	return (PCAP_ERROR);
    748 }
    749 
    750 pcap_t *
    751 pcap_create_interface(const char *device, char *ebuf)
    752 {
    753 	pcap_t *p;
    754 
    755 	if (strlen(device) == 1)
    756 	{
    757 		/*
    758 		 * It's probably a unicode string
    759 		 * Convert to ascii and pass it to pcap_create_common
    760 		 *
    761 		 * This wonderful hack is needed because pcap_lookupdev still returns
    762 		 * unicode strings, and it's used by windump when no device is specified
    763 		 * in the command line
    764 		 */
    765 		size_t length;
    766 		char* deviceAscii;
    767 
    768 		length = wcslen((wchar_t*)device);
    769 
    770 		deviceAscii = (char*)malloc(length + 1);
    771 
    772 		if (deviceAscii == NULL)
    773 		{
    774 			snprintf(ebuf, PCAP_ERRBUF_SIZE, "Malloc failed");
    775 			return NULL;
    776 		}
    777 
    778 		snprintf(deviceAscii, length + 1, "%ws", (wchar_t*)device);
    779 		p = pcap_create_common(deviceAscii, ebuf, sizeof (struct pcap_win));
    780 		free(deviceAscii);
    781 	}
    782 	else
    783 	{
    784 		p = pcap_create_common(device, ebuf, sizeof (struct pcap_win));
    785 	}
    786 
    787 	if (p == NULL)
    788 		return (NULL);
    789 
    790 	p->activate_op = pcap_activate_win32;
    791 	return (p);
    792 }
    793 
    794 static int
    795 pcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp)
    796 {
    797 	if(PacketSetBpf(p->adapter,fp)==FALSE){
    798 		/*
    799 		 * Kernel filter not installed.
    800 		 * XXX - fall back on userland filtering, as is done
    801 		 * on other platforms?
    802 		 */
    803 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Driver error: cannot set bpf filter: %s", pcap_win32strerror());
    804 		return (-1);
    805 	}
    806 
    807 	/*
    808 	 * Discard any previously-received packets, as they might have
    809 	 * passed whatever filter was formerly in effect, but might
    810 	 * not pass this filter (BIOCSETF discards packets buffered
    811 	 * in the kernel, so you can lose packets in any case).
    812 	 */
    813 	p->cc = 0;
    814 	return (0);
    815 }
    816 
    817 /*
    818  * We filter at user level, since the kernel driver does't process the packets
    819  */
    820 static int
    821 pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {
    822 
    823 	if(!fp)
    824 	{
    825 		strncpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf));
    826 		return -1;
    827 	}
    828 
    829 	/* Install a user level filter */
    830 	if (install_bpf_program(p, fp) < 0)
    831 	{
    832 		snprintf(p->errbuf, sizeof(p->errbuf),
    833 			"setfilter, unable to install the filter: %s", pcap_strerror(errno));
    834 		return -1;
    835 	}
    836 
    837 	return (0);
    838 }
    839 
    840 static int
    841 pcap_getnonblock_win32(pcap_t *p, char *errbuf)
    842 {
    843 	struct pcap_win *pw = p->priv;
    844 
    845 	/*
    846 	 * XXX - if there were a PacketGetReadTimeout() call, we
    847 	 * would use it, and return 1 if the timeout is -1
    848 	 * and 0 otherwise.
    849 	 */
    850 	return (pw->nonblock);
    851 }
    852 
    853 static int
    854 pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
    855 {
    856 	struct pcap_win *pw = p->priv;
    857 	int newtimeout;
    858 
    859 	if (nonblock) {
    860 		/*
    861 		 * Set the read timeout to -1 for non-blocking mode.
    862 		 */
    863 		newtimeout = -1;
    864 	} else {
    865 		/*
    866 		 * Restore the timeout set when the device was opened.
    867 		 * (Note that this may be -1, in which case we're not
    868 		 * really leaving non-blocking mode.)
    869 		 */
    870 		newtimeout = p->opt.timeout;
    871 	}
    872 	if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
    873 		snprintf(errbuf, PCAP_ERRBUF_SIZE,
    874 		    "PacketSetReadTimeout: %s", pcap_win32strerror());
    875 		return (-1);
    876 	}
    877 	pw->nonblock = (newtimeout == -1);
    878 	return (0);
    879 }
    880 
    881 /*platform-dependent routine to add devices other than NDIS interfaces*/
    882 int
    883 pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
    884 {
    885 	return (0);
    886 }
    887