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