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