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