]> The Tcpdump Group git mirrors - libpcap/blob - pcap-win32.c
Get rid of declaration of non-existent routine.
[libpcap] / pcap-win32.c
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 #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__
51 int* _errno();
52 #define errno (*_errno())
53 #endif /* __MINGW32__ */
54
55 static int pcap_setfilter_win32_npf(pcap_t *, struct bpf_program *);
56 static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *);
57 static int pcap_getnonblock_win32(pcap_t *, char *);
58 static 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 */
73 struct 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 */
82 int
83 wsockinit()
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
98 static int
99 pcap_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 */
111 static int
112 pcap_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 */
123 static int
124 pcap_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*/
136 static int
137 pcap_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
147 static int
148 pcap_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
232 static int
233 pcap_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 */
393 static int
394 pcap_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
422 static void
423 pcap_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
436 static int
437 pcap_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);
691 bad:
692 pcap_cleanup_win32(p);
693 return (PCAP_ERROR);
694 }
695
696 pcap_t *
697 pcap_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
740 static int
741 pcap_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 */
766 static int
767 pcap_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
788 static int
789 pcap_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
799 static int
800 pcap_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*/
827 int
828 pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
829 {
830 return (0);
831 }