1 /*
2  * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
3  * Copyright (c) 2005 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 /** @ingroup NPF
35  *  @{
36  */
37 
38 /** @defgroup NPF_include NPF structures and definitions
39  *  @{
40  */
41 
42 #ifndef __PACKET_INCLUDE______
43 #define __PACKET_INCLUDE______
44 
45 #ifdef __NPF_x86__
46 #define NTKERNEL	///< Forces the compilation of the jitter with kernel calls
47 #include "jitter.h"
48 #endif
49 
50 
51 #include "win_bpf.h"
52 
53 #define  MAX_REQUESTS   256 ///< Maximum number of simultaneous IOCTL requests.
54 
55 #define Packet_ALIGNMENT sizeof(int) ///< Alignment macro. Defines the alignment size.
56 #define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1))	///< Alignment macro. Rounds up to the next
57 																				///< even multiple of Packet_ALIGNMENT.
58 /***************************/
59 /*         IOCTLs          */
60 /***************************/
61 
62 /*!
63   \brief IOCTL code: set kernel buffer size.
64 
65   This IOCTL is used to set a new size of the circular buffer associated with an instance of NPF.
66   When a BIOCSETBUFFERSIZE command is received, the driver frees the old buffer, allocates the new one
67   and resets all the parameters associated with the buffer in the OPEN_INSTANCE structure. The currently
68   buffered packets are lost.
69 */
70 #define	 BIOCSETBUFFERSIZE 9592
71 
72 /*!
73   \brief IOCTL code: set packet filtering program.
74 
75   This IOCTL sets a new packet filter in the driver. Before allocating any memory for the new filter, the
76   bpf_validate() function is called to check the correctness of the filter. If this function returns TRUE,
77   the filter is copied to the driver's memory, its address is stored in the bpfprogram field of the
78   OPEN_INSTANCE structure associated with current instance of the driver, and the filter will be applied to
79   every incoming packet. This command also empties the circular buffer used by current instance
80   to store packets. This is done to avoid the presence in the buffer of packets that do not match the filter.
81 */
82 #define	 BIOCSETF 9030
83 
84 /*!
85   \brief IOCTL code: get the capture stats
86 
87   This command returns to the application the number of packets received and the number of packets dropped by
88   an instance of the driver.
89 */
90 #define  BIOCGSTATS 9031
91 
92 /*!
93   \brief IOCTL code: set the read timeout
94 
95   This command sets the maximum timeout after which a read is released, also if no data packets were received.
96 */
97 #define	 BIOCSRTIMEOUT 7416
98 
99 /*!
100   \brief IOCTL code: set working mode
101 
102   This IOCTL can be used to set the working mode of a NPF instance. The new mode, received by the driver in the
103   buffer associated with the IOCTL command, can be #MODE_CAPT for capture mode (the default), #MODE_STAT for
104   statistical mode or #MODE_DUMP for dump mode.
105 */
106 #define	 BIOCSMODE 7412
107 
108 /*!
109   \brief IOCTL code: set number of physical repetions of every packet written by the app
110 
111   Sets the number of times a single write call must be repeated. This command sets the OPEN_INSTANCE::Nwrites
112   member, and is used to implement the 'multiple write' feature of the driver.
113 */
114 #define	 BIOCSWRITEREP 7413
115 
116 /*!
117   \brief IOCTL code: set minimum amount of data in the kernel buffer that unlocks a read call
118 
119   This command sets the OPEN_INSTANCE::MinToCopy member.
120 */
121 #define	 BIOCSMINTOCOPY 7414
122 
123 /*!
124   \brief IOCTL code: set an OID value
125 
126   This IOCTL is used to perform an OID set operation on the NIC driver.
127 */
128 #define	 BIOCSETOID 2147483648
129 
130 /*!
131   \brief IOCTL code: get an OID value
132 
133   This IOCTL is used to perform an OID get operation on the NIC driver.
134 */
135 #define	 BIOCQUERYOID 2147483652
136 #define  BIOCISETLOBBEH 7410
137 /*!
138   \brief IOCTL code: set the name of a the file used by kernel dump mode
139 
140   This command opens a file whose name is contained in the IOCTL buffer and associates it with current NPf instance.
141   The dump thread uses it to copy the content of the circular buffer to file.
142   If a file was already opened, the driver closes it before opening the new one.
143 */
144 #define  BIOCSETDUMPFILENAME 9029
145 
146 /*!
147   \brief IOCTL code: get the name of the event that the driver signals when some data is present in the buffer
148 
149   Command used by the application to retrieve the name of the global event associated with a NPF instance.
150   The event is signaled by the driver when the kernel buffer contains enough data for a transfer.
151 */
152 #define  BIOCGEVNAME 7415
153 
154 /*!
155   \brief IOCTL code: Send a buffer containing multiple packets to the network, ignoring the timestamps.
156 
157   Command used to send a buffer of packets in a single system call. Every packet in the buffer is preceded by
158   a sf_pkthdr structure. The timestamps of the packets are ignored, i.e. the packets are sent as fast as
159   possible. The NPF_BufferedWrite() function is invoked to send the packets.
160 */
161 #define  BIOCSENDPACKETSNOSYNC 9032
162 
163 /*!
164   \brief IOCTL code: Send a buffer containing multiple packets to the network, considering the timestamps.
165 
166   Command used to send a buffer of packets in a single system call. Every packet in the buffer is preceded by
167   a sf_pkthdr structure. The timestamps of the packets are used to synchronize the write, i.e. the packets
168   are sent to the network respecting the intervals specified in the sf_pkthdr structure associated with each
169   packet. NPF_BufferedWrite() function is invoked to send the packets.
170 */
171 #define  BIOCSENDPACKETSSYNC 9033
172 
173 /*!
174   \brief IOCTL code: Set the dump file limits.
175 
176   This IOCTL sets the limits (maximum size and maximum number of packets) of the dump file created when the
177   driver works in dump mode.
178 */
179 #define  BIOCSETDUMPLIMITS 9034
180 
181 /*!
182   \brief IOCTL code: Get the status of the kernel dump process.
183 
184   This command returns TRUE if the kernel dump is ended, i.e if one of the limits set with BIOCSETDUMPLIMITS
185   (amount of bytes or number of packets) has been reached.
186 */
187 #define BIOCISDUMPENDED 7411
188 
189 // Working modes
190 #define MODE_CAPT 0x0		///< Capture working mode
191 #define MODE_STAT 0x1		///< Statistical working mode
192 #define MODE_MON  0x2		///< Kernel monitoring mode
193 #define MODE_DUMP 0x10		///< Kernel dump working mode
194 
195 
196 #define IMMEDIATE 1			///< Immediate timeout. Forces a read call to return immediately.
197 
198 
199 // The following definitions are used to provide compatibility
200 // of the dump files with the ones of libpcap
201 #define TCPDUMP_MAGIC 0xa1b2c3d4	///< Libpcap magic number. Used by programs like tcpdump to recognize a driver's generated dump file.
202 #define PCAP_VERSION_MAJOR 2		///< Major libpcap version of the dump file. Used by programs like tcpdump to recognize a driver's generated dump file.
203 #define PCAP_VERSION_MINOR 4		///< Minor libpcap version of the dump file. Used by programs like tcpdump to recognize a driver's generated dump file.
204 
205 /*!
206   \brief Header of a libpcap dump file.
207 
208   Used when a driver instance is set in dump mode to create a libpcap-compatible file.
209 */
210 struct packet_file_header
211 {
212 	UINT magic;				///< Libpcap magic number
213 	USHORT version_major;	///< Libpcap major version
214 	USHORT version_minor;	///< Libpcap minor version
215 	UINT thiszone;			///< Gmt to local correction
216 	UINT sigfigs;			///< Accuracy of timestamps
217 	UINT snaplen;			///< Length of the max saved portion of each packet
218 	UINT linktype;			///< Data link type (DLT_*). See win_bpf.h for details.
219 };
220 
221 /*!
222   \brief Header associated to a packet in the driver's buffer when the driver is in dump mode.
223   Similar to the bpf_hdr structure, but simpler.
224 */
225 struct sf_pkthdr {
226     struct timeval	ts;			///< time stamp
227     UINT			caplen;		///< Length of captured portion. The captured portion can be different from
228 								///< the original packet, because it is possible (with a proper filter) to
229 								///< instruct the driver to capture only a portion of the packets.
230     UINT			len;		///< Length of the original packet (off wire).
231 };
232 
233 /*!
234   \brief Stores an OID request.
235 
236   This structure is used by the driver to perform OID query or set operations on the underlying NIC driver.
237   The OID operations be performed usually only by network drivers, but NPF exports this mechanism to user-level
238   applications through an IOCTL interface. The driver uses this structure to wrap a NDIS_REQUEST structure.
239   This allows to handle correctly the callback structure of NdisRequest(), handling multiple requests and
240   maintaining information about the IRPs to complete.
241 */
242 typedef struct _INTERNAL_REQUEST {
243     LIST_ENTRY		ListElement;		///< Used to handle lists of requests.
244     PIRP			Irp;				///< Irp that performed the request
245 	BOOLEAN			Internal;			///< True if the request is for internal use of npf.sys. False if the request is performed by the user through an IOCTL.
246     NDIS_REQUEST	Request;			///< The structure with the actual request, that will be passed to NdisRequest().
247 } INTERNAL_REQUEST, *PINTERNAL_REQUEST;
248 
249 /*!
250   \brief Contains a NDIS packet.
251 
252   The driver uses this structure to wrap a NDIS_PACKET  structure.
253   This allows to handle correctly the callback structure of NdisTransferData(), handling multiple requests and
254   maintaining information about the IRPs to complete.
255 */
256 typedef struct _PACKET_RESERVED {
257     LIST_ENTRY		ListElement;		///< Used to handle lists of packets.
258     PIRP			Irp;				///< Irp that performed the request
259     PMDL			pMdl;				///< MDL mapping the buffer of the packet.
260 	BOOLEAN			FreeBufAfterWrite;	///< True if the memory buffer associated with the packet must be freed
261 										///< after a call to NdisSend().
262 	ULONG			Cpu;				///< The CPU on which the packet was pulled out of the linked list of free packets
263 }  PACKET_RESERVED, *PPACKET_RESERVED;
264 
265 #define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved)) ///< Macro to obtain a NDIS_PACKET from a PACKET_RESERVED
266 
267 /*!
268   \brief Port device extension.
269 
270   Structure containing some data relative to every adapter on which NPF is bound.
271 */
272 typedef struct _DEVICE_EXTENSION {
273     NDIS_HANDLE    NdisProtocolHandle;	///< NDIS handle of NPF.
274     NDIS_STRING    AdapterName;			///< Name of the adapter.
275 	PWSTR		   ExportString;		///< Name of the exported device, i.e. name that the applications will use
276 										///< to open this adapter through WinPcap.
277 } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
278 
279 /*!
280   \brief Kernel buffer of each CPU.
281 
282   Structure containing the kernel buffer (and other CPU related fields) used to capture packets.
283 */
284 typedef struct __CPU_Private_Data
285 {
286 	ULONG	P;					///< Zero-based index of the producer in the buffer. It indicates the first free byte to be written.
287 	ULONG	C;					///< Zero-based index of the consumer in the buffer. It indicates the first free byte to be read.
288 	ULONG	Free;				///< Number of the free bytes in the buffer
289 	PUCHAR	Buffer;				///< Pointer to the kernel buffer used to capture packets.
290 	ULONG	Accepted;			///< Number of packet that current capture instance accepted, from its opening. A packet
291 								///< is accepted if it passes the filter and fits in the buffer. Accepted packets are the
292 								///< ones that reach the application.
293 								///< This number is related to the particular CPU this structure is referring to.
294 	ULONG	Received;			///< Number of packets received by current instance from its opening, i.e. number of
295 								///< packet received by the network adapter since the beginning of the
296 								///< capture/monitoring/dump session.
297 								///< This number is related to the particular CPU this structure is referring to.
298 	ULONG	Dropped;			///< Number of packet that current instance had to drop, from its opening. A packet
299 								///< is dropped if there is no more space to store it in the circular buffer that the
300 								///< driver associates to current instance.
301 								///< This number is related to the particular CPU this structure is referring to.
302 	ULONG	Processing;			///< Flag. If set to 1, it indicates that the tap is processing a packet on the CPU this structure is referring to.
303 	PMDL    TransferMdl1;		///< MDL used to map the portion of the buffer that will contain an incoming packet.
304 	PMDL    TransferMdl2;		///< Second MDL used to map the portion of the buffer that will contain an incoming packet.
305 	ULONG	NewP;				///< Used by NdisTransferData() (when we call NdisTransferData, p index must be updated only in the TransferDataComplete.
306 }
307 	CpuPrivateData;
308 
309 
310 /*!
311   \brief Contains the state of a running instance of the NPF driver.
312 
313   This is the most important structure of NPF: it is used by almost all the functions of the driver. An
314   _OPEN_INSTANCE structure is associated with every user-level session, allowing concurrent access
315   to the driver.
316 */
317 typedef struct _OPEN_INSTANCE
318 {
319 	PDEVICE_EXTENSION   DeviceExtension;	///< Pointer to the _DEVICE_EXTENSION structure of the device on which
320 											///< the instance is bound.
321 	NDIS_HANDLE         AdapterHandle;		///< NDIS Identifier of the adapter used by this instance.
322 	UINT				Medium;				///< Type of physical medium the underlying NDIS driver uses. See the
323 											///< documentation of NdisOpenAdapter in the MS DDK for details.
324 	NDIS_HANDLE         PacketPool;			///< Pool of NDIS_PACKET structures used to transfer the packets from and to the NIC driver.
325 	PIRP                OpenCloseIrp;		///< Pointer used to store the open/close IRP requests and provide them to the
326 											///< callbacks of NDIS.
327 	KSPIN_LOCK			RequestSpinLock;	///< SpinLock used to synchronize the OID requests.
328 	LIST_ENTRY          RequestList;		///< List of pending OID requests.
329 	LIST_ENTRY          ResetIrpList;		///< List of pending adapter reset requests.
330     INTERNAL_REQUEST    Requests[MAX_REQUESTS]; ///< Array of structures that wrap every single OID request.
331 	PMDL				BufferMdl;			///< Pointer to a Memory descriptor list (MDL) that maps the circular buffer's memory.
332 	PKEVENT				ReadEvent;			///< Pointer to the event on which the read calls on this instance must wait.
333 	HANDLE				ReadEventHandle;	///< Handle of the event on which the read calls on this instance must wait.
334 	UNICODE_STRING		ReadEventName;		///< Name of the event on which the read calls on this instance must wait.
335 											///< The event is created with a name, so it can be used at user level to know when it
336 											///< is possible to access the driver without being blocked. This field stores the name
337 											///< that and is used by the BIOCGEVNAME IOCTL call.
338 	PUCHAR				bpfprogram;			///< Pointer to the filtering pseudo-code associated with current instance of the driver.
339 											///< This code is used only in particular situations (for example when the packet received
340 											///< from the NIC driver is stored in two non-consecutive buffers. In normal situations
341 											///< the filtering routine created by the JIT compiler and pointed by the next field
342 											///< is used. See \ref NPF for details on the filtering process.
343 #ifdef __NPF_x86__
344 	JIT_BPF_Filter		*Filter;			///< Pointer to the native filtering function created by the jitter.
345 											///< See BPF_jitter() for details.
346 #endif
347 	UINT				MinToCopy;			///< Minimum amount of data in the circular buffer that unlocks a read. Set with the
348 											///< BIOCSMINTOCOPY IOCTL.
349 	LARGE_INTEGER		TimeOut;			///< Timeout after which a read is released, also if the amount of data in the buffer is
350 											///< less than MinToCopy. Set with the BIOCSRTIMEOUT IOCTL.
351 
352 	int					mode;				///< Working mode of the driver. See PacketSetMode() for details.
353 	LARGE_INTEGER		Nbytes;				///< Amount of bytes accepted by the filter when this instance is in statistical mode.
354 	LARGE_INTEGER		Npackets;			///< Number of packets accepted by the filter when this instance is in statistical mode.
355 	NDIS_SPIN_LOCK		CountersLock;		///< SpinLock that protects the statistical mode counters.
356 	UINT				Nwrites;			///< Number of times a single write must be physically repeated. See \ref NPF for an
357 											///< explanation
358 	ULONG				Multiple_Write_Counter;	///< Counts the number of times a single write has already physically repeated.
359 	NDIS_EVENT			WriteEvent;			///< Event used to synchronize the multiple write process.
360 	BOOLEAN				WriteInProgress;	///< True if a write is currently in progress. NPF currently allows a single wite on
361 											///< the same open instance.
362 	NDIS_SPIN_LOCK		WriteLock;			///< SpinLock that protects the WriteInProgress variable.
363 	NDIS_EVENT			IOEvent;			///< Event used to synchronize I/O requests with the callback structure of NDIS.
364 	NDIS_STATUS			IOStatus;			///< Maintains the status of and OID request call, that will be passed to the application.
365 	BOOLEAN				Bound;				///< Specifies if NPF is still bound to the adapter used by this instance. Bound can be
366 											///< FALSE if a Plug and Play adapter has been removed or disabled by the user.
367 	HANDLE				DumpFileHandle;		///< Handle of the file used in dump mode.
368 	PFILE_OBJECT		DumpFileObject;		///< Pointer to the object of the file used in dump mode.
369 	PKTHREAD			DumpThreadObject;	///< Pointer to the object of the thread used in dump mode.
370 	HANDLE				DumpThreadHandle;	///< Handle of the thread created by dump mode to asynchronously move the buffer to disk.
371 	NDIS_EVENT			DumpEvent;			///< Event used to synchronize the dump thread with the tap when the instance is in dump mode.
372 	LARGE_INTEGER		DumpOffset;			///< Current offset in the dump file.
373 	UNICODE_STRING      DumpFileName;		///< String containing the name of the dump file.
374 	UINT				MaxDumpBytes;		///< Maximum dimension in bytes of the dump file. If the dump file reaches this size it
375 											///< will be closed. A value of 0 means unlimited size.
376 	UINT				MaxDumpPacks;		///< Maximum number of packets that will be saved in the dump file. If this number of
377 											///< packets is reached the dump will be closed. A value of 0 means unlimited number of
378 											///< packets.
379 	BOOLEAN				DumpLimitReached;	///< TRUE if the maximum dimension of the dump file (MaxDumpBytes or MaxDumpPacks) is
380 											///< reached.
381 	MEM_TYPE			mem_ex;				///< Memory used by the TME virtual co-processor
382 	TME_CORE			tme;				///< Data structure containing the virtualization of the TME co-processor
383 	NDIS_SPIN_LOCK		MachineLock;		///< SpinLock that protects the mem_ex buffer
384 	UINT				MaxFrameSize;		///< Maximum frame size that the underlying MAC accepts. Used to perform a check on the
385 											///< size of the frames sent with NPF_Write() or NPF_BufferedWrite().
386 	CpuPrivateData		CpuData[1024];		///< Pool of kernel buffer structures, one for each CPU.
387 	ULONG				ReaderSN;			///< Sequence number of the next packet to be read from the pool of kernel buffers.
388 	ULONG				WriterSN;			///< Sequence number of the next packet to be written in the pool of kernel buffers.
389 											///< These two sequence numbers are unique for each capture instance.
390 	ULONG				Size;				///< Size of each kernel buffer contained in the CpuData field.
391 	ULONG				SkipProcessing;		///< Flag. When set to 1, the tap discards each packet. It is set to 1 by the IOCTLs that modify
392 											///< some "sensible" fields of the Open structure (e.g. they reallocate the pool of kernel buffers,
393 											///< or change the filter program
394 	BOOLEAN				SkipSentPackets;
395 
396 }
397 OPEN_INSTANCE, *POPEN_INSTANCE;
398 
399 /*!
400   \brief Structure prepended to each packet in the kernel buffer pool.
401 
402   Each packet in one of the kernel buffers is prepended by this header. It encapsulates the bpf_header,
403   which will be passed to user level programs, as well as the sequence number of the packet, set by the producer (the tap function),
404   and used by the consumer (the read function) to "reorder" the packets contained in the various kernel buffers.
405 */
406 struct PacketHeader
407 {
408 	ULONG SN;								///< Sequence number of the packet.
409 	struct bpf_hdr header;					///< bpf header, created by the tap, and copied unmodified to user level programs.
410 };
411 
412 extern UINT			g_SendPacketFlags;
413 #define NDIS_FLAGS_SKIP_LOOPBACK_W2K    0x400 ///< This is an undocumented flag for NdisSetPacketFlags() that allows to disable loopback reception.
414 
415 #define TRANSMIT_PACKETS 2048	///< Maximum number of packets in the transmit packet pool. This value is an upper bound to the number
416 								///< of packets that can be transmitted at the same time or with a single call to NdisSendPackets.
417 
418 
419 /// Macro used in the I/O routines to return the control to user-mode with a success status.
420 #define EXIT_SUCCESS(quantity) Irp->IoStatus.Information=quantity;\
421 	Irp->IoStatus.Status = STATUS_SUCCESS;\
422 	IoCompleteRequest(Irp, IO_NO_INCREMENT);\
423 	return STATUS_SUCCESS;\
424 
425 /// Macro used in the I/O routines to return the control to user-mode with a failure status.
426 #define EXIT_FAILURE(quantity) Irp->IoStatus.Information=quantity;\
427 	Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;\
428 	IoCompleteRequest(Irp, IO_NO_INCREMENT);\
429 	return STATUS_UNSUCCESSFUL;\
430 
431 /**
432  *  @}
433  */
434 
435 
436 /***************************/
437 /*       Prototypes        */
438 /***************************/
439 
440 /** @defgroup NPF_code NPF functions
441  *  @{
442  */
443 
444 
445 /*!
446   \brief The initialization routine of the driver.
447   \param DriverObject The driver object of NPF created by the system.
448   \param RegistryPath The registry path containing the keys related to the driver.
449   \return A string containing a list of network adapters.
450 
451   DriverEntry is a mandatory function in a device driver. Like the main() of a user level program, it is called
452   by the system when the driver is loaded in memory and started. Its purpose is to initialize the driver,
453   performing all the allocations and the setup. In particular, DriverEntry registers all the driver's I/O
454   callbacks, creates the devices, defines NPF as a protocol inside NDIS.
455 */
456 NTSTATUS
457 DriverEntry(
458     IN PDRIVER_OBJECT DriverObject,
459     IN PUNICODE_STRING RegistryPath
460     );
461 
462 /*!
463   \brief Returns the list of the MACs available on the system.
464   \return A string containing a list of network adapters.
465 
466   The list of adapters is retrieved from the
467   SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318} registry key.
468   NPF tries to create its bindings from this list. In this way it is possible to be loaded
469   and unloaded dynamically without passing from the control panel.
470 */
471 PWCHAR getAdaptersList(VOID);
472 
473 /*!
474   \brief Returns the MACs that bind to TCP/IP.
475   \return Pointer to the registry key containing the list of adapters on which TCP/IP is bound.
476 
477   If getAdaptersList() fails, NPF tries to obtain the TCP/IP bindings through this function.
478 */
479 PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(VOID);
480 
481 /*!
482   \brief Creates a device for a given MAC.
483   \param adriverObjectP The driver object that will be associated with the device, i.e. the one of NPF.
484   \param amacNameP The name of the network interface that the device will point.
485   \param aProtoHandle NDIS protocol handle of NPF.
486   \return If the function succeeds, the return value is nonzero.
487 
488   NPF creates a device for every valid network adapter. The new device points to the NPF driver, but contains
489   information about the original device. In this way, when the user opens the new device, NPF will be able to
490   determine the correct adapter to use.
491 */
492 BOOLEAN createDevice(
493 	IN OUT PDRIVER_OBJECT adriverObjectP,
494 	IN PUNICODE_STRING amacNameP,
495 	NDIS_HANDLE aProtoHandle);
496 
497 /*!
498   \brief Opens a new instance of the driver.
499   \param DeviceObject Pointer to the device object utilized by the user.
500   \param Irp Pointer to the IRP containing the user request.
501   \return The status of the operation. See ntstatus.h in the DDK.
502 
503   This function is called by the OS when a new instance of the driver is opened, i.e. when a user application
504   performs a CreateFile on a device created by NPF. NPF_Open allocates and initializes variables, objects
505   and buffers needed by the new instance, fills the OPEN_INSTANCE structure associated with it and opens the
506   adapter with a call to NdisOpenAdapter.
507 */
508 NTSTATUS
509 NPF_Open(
510     IN PDEVICE_OBJECT DeviceObject,
511     IN PIRP Irp
512     );
513 
514 /*!
515   \brief Ends the opening of an adapter.
516   \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
517   \param Status Status of the opening operation performed by NDIS.
518   \param OpenErrorStatus not used by NPF.
519 
520   Callback function associated with the NdisOpenAdapter() NDIS function. It is invoked by NDIS when the NIC
521   driver has finished an open operation that was previously started by NPF_Open().
522 */
523 VOID
524 NPF_OpenAdapterComplete(
525     IN NDIS_HANDLE  ProtocolBindingContext,
526     IN NDIS_STATUS  Status,
527     IN NDIS_STATUS  OpenErrorStatus
528     );
529 
530 /*!
531   \brief Closes an instance of the driver.
532   \param DeviceObject Pointer to the device object utilized by the user.
533   \param Irp Pointer to the IRP containing the user request.
534   \return The status of the operation. See ntstatus.h in the DDK.
535 
536   This function is called when a running instance of the driver is closed by the user with a CloseHandle().
537   It stops the capture/monitoring/dump process, deallocates the memory and the objects associated with the
538   instance and closing the files. The network adapter is then closed with a call to NdisCloseAdapter.
539 */
540 NTSTATUS
541 NPF_Close(
542     IN PDEVICE_OBJECT DeviceObject,
543     IN PIRP Irp
544     );
545 
546 /*!
547   \brief Ends the closing of an adapter.
548   \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
549   \param Status Status of the close operation performed by NDIS.
550 
551   Callback function associated with the NdisCloseAdapter() NDIS function. It is invoked by NDIS when the NIC
552   driver has finished a close operation that was previously started by NPF_Close().
553 */
554 VOID
555 NPF_CloseAdapterComplete(
556     IN NDIS_HANDLE  ProtocolBindingContext,
557     IN NDIS_STATUS  Status
558     );
559 
560 /*!
561   \brief Callback invoked by NDIS when a packet arrives from the network.
562   \param ProtocolBindingContext Context of the function. Points to a OPEN_INSTANCE structure that identifies
563    the NPF instance to which the packets are destined.
564   \param MacReceiveContext Handle that identifies the underlying NIC driver that generated the request.
565    This value must be used when the packet is transferred from the NIC driver with NdisTransferData().
566   \param HeaderBuffer Pointer to the buffer in the NIC driver memory that contains the header of the packet.
567   \param HeaderBufferSize Size in bytes of the header.
568   \param LookAheadBuffer Pointer to the buffer in the NIC driver's memory that contains the incoming packet's
569    data <b>available to NPF</b>. This value does not necessarily coincide with the actual size of the packet,
570    since only a portion can be available at this time. The remaining portion can be obtained with the
571    NdisTransferData() NDIS function.
572   \param LookaheadBufferSize Size in bytes of the lookahead buffer.
573   \param PacketSize Total size of the incoming packet, excluded the header.
574   \return The status of the operation. See ntstatus.h in the DDK.
575 
576   NPF_tap() is called by the underlying NIC for every incoming packet. It is the most important and one of
577   the most complex functions of NPF: it executes the filter, runs the statistical engine (if the instance is in
578   statistical mode), gathers the timestamp, moves the packet in the buffer. NPF_tap() is the only function,
579   along with the filtering ones, that is executed for every incoming packet, therefore it is carefully
580   optimized.
581 */
582 NDIS_STATUS
583 NPF_tap(
584     IN NDIS_HANDLE ProtocolBindingContext,
585     IN NDIS_HANDLE MacReceiveContext,
586     IN PVOID HeaderBuffer,
587     IN UINT HeaderBufferSize,
588     IN PVOID LookAheadBuffer,
589     IN UINT LookaheadBufferSize,
590     IN UINT PacketSize
591     );
592 
593 /*!
594   \brief Ends the transfer of a packet.
595   \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
596   \param Packet Pointer to the NDIS_PACKET structure that received the packet data.
597   \param Status Status of the transfer operation.
598   \param BytesTransferred Amount of bytes transferred.
599 
600   Callback function associated with the NdisTransferData() NDIS function. It is invoked by NDIS when the NIC
601   driver has finished the transfer of a packet from the NIC driver memory to the NPF circular buffer.
602 */
603 VOID
604 NPF_TransferDataComplete(
605     IN NDIS_HANDLE ProtocolBindingContext,
606     IN PNDIS_PACKET Packet,
607     IN NDIS_STATUS Status,
608     IN UINT BytesTransferred
609     );
610 
611 /*!
612   \brief Callback function that signals the end of a packet reception.
613   \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
614 
615   does nothing in NPF
616 */
617 VOID
618 NPF_ReceiveComplete(IN NDIS_HANDLE  ProtocolBindingContext);
619 
620 /*!
621   \brief Handles the IOCTL calls.
622   \param DeviceObject Pointer to the device object utilized by the user.
623   \param Irp Pointer to the IRP containing the user request.
624   \return The status of the operation. See ntstatus.h in the DDK.
625 
626   Once the packet capture driver is opened it can be configured from user-level applications with IOCTL commands
627   using the DeviceIoControl() system call. NPF_IoControl receives and serves all the IOCTL calls directed to NPF.
628   The following commands are recognized:
629   - #BIOCSETBUFFERSIZE
630   - #BIOCSETF
631   - #BIOCGSTATS
632   - #BIOCSRTIMEOUT
633   - #BIOCSMODE
634   - #BIOCSWRITEREP
635   - #BIOCSMINTOCOPY
636   - #BIOCSETOID
637   - #BIOCQUERYOID
638   - #BIOCSETDUMPFILENAME
639   - #BIOCGEVNAME
640   -	#BIOCSENDPACKETSSYNC
641   -	#BIOCSENDPACKETSNOSYNC
642 */
643 NTSTATUS
644 NPF_IoControl(
645     IN PDEVICE_OBJECT DeviceObject,
646     IN PIRP Irp
647     );
648 
649 VOID
650 
651 /*!
652   \brief Ends an OID request.
653   \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
654   \param pRequest Pointer to the completed OID request.
655   \param Status Status of the operation.
656 
657   Callback function associated with the NdisRequest() NDIS function. It is invoked by NDIS when the NIC
658   driver has finished an OID request operation that was previously started by NPF_IoControl().
659 */
660 NPF_RequestComplete(
661     IN NDIS_HANDLE   ProtocolBindingContext,
662     IN PNDIS_REQUEST pRequest,
663     IN NDIS_STATUS   Status
664     );
665 
666 /*!
667   \brief Writes a raw packet to the network.
668   \param DeviceObject Pointer to the device object on which the user wrote the packet.
669   \param Irp Pointer to the IRP containing the user request.
670   \return The status of the operation. See ntstatus.h in the DDK.
671 
672   This function is called by the OS in consequence of user WriteFile() call, with the data of the packet that must
673   be sent on the net. The data is contained in the buffer associated with Irp, NPF_Write takes it and
674   delivers it to the NIC driver via the NdisSend() function. The Nwrites field of the OPEN_INSTANCE structure
675   associated with Irp indicates the number of copies of the packet that will be sent: more than one copy of the
676   packet can be sent for performance reasons.
677 */
678 NTSTATUS
679 NPF_Write(
680 			IN PDEVICE_OBJECT DeviceObject,
681 			IN PIRP Irp
682 			);
683 
684 
685 /*!
686   \brief Writes a buffer of raw packets to the network.
687   \param Irp Pointer to the IRP containing the user request.
688   \param UserBuff Pointer to the buffer containing the packets to send.
689   \param UserBuffSize Size of the buffer with the packets.
690   \return The amount of bytes actually sent. If the return value is smaller than the Size parameter, an
691           error occurred during the send. The error can be caused by an adapter problem or by an
692 		  inconsistent/bogus user buffer.
693 
694   This function is called by the OS in consequence of a BIOCSENDPACKETSNOSYNC or a BIOCSENDPACKETSSYNC IOCTL.
695   The buffer received as input parameter contains an arbitrary number of packets, each of which preceded by a
696   sf_pkthdr structure. NPF_BufferedWrite() scans the buffer and sends every packet via the NdisSend() function.
697   When Sync is set to TRUE, the packets are synchronized with the KeQueryPerformanceCounter() function.
698   This requires a remarkable amount of CPU, but allows to respect the timestamps associated with packets with a precision
699   of some microseconds (depending on the precision of the performance counter of the machine).
700   If Sync is false, the timestamps are ignored and the packets are sent as fat as possible.
701 */
702 
703 INT NPF_BufferedWrite(IN PIRP Irp,
704 						IN PCHAR UserBuff,
705 						IN ULONG UserBuffSize,
706 						BOOLEAN sync);
707 
708 /*!
709   \brief Waits the completion of all the sends performed by NPF_BufferedWrite.
710 
711   \param Open Pointer to open context structure
712 
713   Used by NPF_BufferedWrite to wait the completion of all the sends before returning the control to the user.
714 */
715 VOID NPF_WaitEndOfBufferedWrite(POPEN_INSTANCE Open);
716 
717 /*!
718   \brief Ends a send operation.
719   \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
720   \param pRequest Pointer to the NDIS PACKET structure used by NPF_Write() to send the packet.
721   \param Status Status of the operation.
722 
723   Callback function associated with the NdisSend() NDIS function. It is invoked by NDIS when the NIC
724   driver has finished an OID request operation that was previously started by NPF_Write().
725 */
726 VOID
727 NPF_SendComplete(
728     IN NDIS_HANDLE   ProtocolBindingContext,
729     IN PNDIS_PACKET  pPacket,
730     IN NDIS_STATUS   Status
731     );
732 
733 /*!
734   \brief Ends a reset of the adapter.
735   \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
736   \param Status Status of the operation.
737 
738   Callback function associated with the NdisReset() NDIS function. It is invoked by NDIS when the NIC
739   driver has finished an OID request operation that was previously started by NPF_IoControl(), in an IOCTL_PROTOCOL_RESET
740   command.
741 */
742 VOID
743 NPF_ResetComplete(
744     IN NDIS_HANDLE  ProtocolBindingContext,
745     IN NDIS_STATUS  Status
746     );
747 
748 /*!
749   \brief Callback for NDIS StatusHandler. Not used by NPF
750 */
751 VOID
752 NPF_Status(
753     IN NDIS_HANDLE   ProtocolBindingContext,
754     IN NDIS_STATUS   Status,
755     IN PVOID         StatusBuffer,
756     IN UINT          StatusBufferSize
757     );
758 
759 
760 /*!
761   \brief Callback for NDIS StatusCompleteHandler. Not used by NPF
762 */
763 VOID
764 NPF_StatusComplete(IN NDIS_HANDLE  ProtocolBindingContext);
765 
766 /*!
767   \brief Function called by the OS when NPF is unloaded.
768   \param DriverObject The driver object of NPF created by the system.
769 
770   This is the last function executed when the driver is unloaded from the system. It frees global resources,
771   delete the devices and deregisters the protocol. The driver can be unloaded by the user stopping the NPF
772   service (from control panel or with a console 'net stop npf').
773 */
774 VOID
775 NPF_Unload(IN PDRIVER_OBJECT DriverObject);
776 
777 
778 /*!
779   \brief Function that serves the user's reads.
780   \param DeviceObject Pointer to the device used by the user.
781   \param Irp Pointer to the IRP containing the user request.
782   \return The status of the operation. See ntstatus.h in the DDK.
783 
784   This function is called by the OS in consequence of user ReadFile() call. It moves the data present in the
785   kernel buffer to the user buffer associated with Irp.
786   First of all, NPF_Read checks the amount of data in kernel buffer associated with current NPF instance.
787   - If the instance is in capture mode and the buffer contains more than OPEN_INSTANCE::MinToCopy bytes,
788   NPF_Read moves the data in the user buffer and returns immediatly. In this way, the read performed by the
789   user is not blocking.
790   - If the buffer contains less than MinToCopy bytes, the application's request isn't
791   satisfied immediately, but it's blocked until at least MinToCopy bytes arrive from the net
792   or the timeout on this read expires. The timeout is kept in the OPEN_INSTANCE::TimeOut field.
793   - If the instance is in statistical mode or in dump mode, the application's request is blocked until the
794   timeout kept in OPEN_INSTANCE::TimeOut expires.
795 */
796 NTSTATUS
797 NPF_Read(
798     IN PDEVICE_OBJECT DeviceObject,
799     IN PIRP Irp
800     );
801 
802 /*!
803   \brief Reads the registry keys associated woth NPF if the driver is manually installed via the control panel.
804 
805   Normally not used in recent versions of NPF.
806 */
807 NTSTATUS
808 NPF_ReadRegistry(
809     IN  PWSTR              *MacDriverName,
810     IN  PWSTR              *PacketDriverName,
811     IN  PUNICODE_STRING     RegistryPath
812     );
813 
814 /*!
815   \brief Function used by NPF_ReadRegistry() to query the registry keys associated woth NPF if the driver
816   is manually installed via the control panel.
817 
818   Normally not used in recent versions of NPF.
819 */
820 NTSTATUS
821 NPF_QueryRegistryRoutine(
822     IN PWSTR     ValueName,
823     IN ULONG     ValueType,
824     IN PVOID     ValueData,
825     IN ULONG     ValueLength,
826     IN PVOID     Context,
827     IN PVOID     EntryContext
828     );
829 
830 /*!
831   \brief Callback for NDIS BindAdapterHandler. Not used by NPF.
832 
833   Function called by NDIS when a new adapter is installed on the machine With Plug and Play.
834 */
835 VOID NPF_BindAdapter(
836     OUT PNDIS_STATUS            Status,
837     IN  NDIS_HANDLE             BindContext,
838     IN  PNDIS_STRING            DeviceName,
839     IN  PVOID                   SystemSpecific1,
840     IN  PVOID                   SystemSpecific2
841     );
842 
843 /*!
844   \brief Callback for NDIS UnbindAdapterHandler.
845   \param Status out variable filled by NPF_UnbindAdapter with the status of the unbind operation.
846   \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with current instance.
847   \param UnbindContext Specifies a handle, supplied by NDIS, that NPF can use to complete the operation.
848 
849   Function called by NDIS when a new adapter is removed from the machine without shutting it down.
850   NPF_UnbindAdapter closes the adapter calling NdisCloseAdapter() and frees the memory and the structures
851   associated with it. It also releases the waiting user-level app and closes the dump thread if the instance
852   is in dump mode.
853 */
854 VOID
855 NPF_UnbindAdapter(
856     OUT PNDIS_STATUS        Status,
857     IN  NDIS_HANDLE         ProtocolBindingContext,
858     IN  NDIS_HANDLE         UnbindContext
859     );
860 
861 
862 /*!
863   \brief Creates the file that will receive the packets when the driver is in dump mode.
864   \param Open The NPF instance that opens the file.
865   \param fileName Pointer to a UNICODE string containing the name of the file.
866   \param append Boolean value that specifies if the data must be appended to the file.
867   \return The status of the operation. See ntstatus.h in the DDK.
868 */
869 NTSTATUS NPF_OpenDumpFile(POPEN_INSTANCE Open , PUNICODE_STRING fileName, BOOLEAN append);
870 
871 /*!
872   \brief Starts dump to file.
873   \param Open The NPF instance that opens the file.
874   \return The status of the operation. See ntstatus.h in the DDK.
875 
876   This function performs two operations. First, it writes the libpcap header at the beginning of the file.
877   Second, it starts the thread that asynchronously dumps the network data to the file.
878 */
879 NTSTATUS NPF_StartDump(POPEN_INSTANCE Open);
880 
881 /*!
882   \brief The dump thread.
883   \param Open The NPF instance that creates the thread.
884 
885   This function moves the content of the NPF kernel buffer to file. It runs in the user context, so at lower
886   priority than the TAP.
887 */
888 VOID NPF_DumpThread(PVOID Open);
889 
890 /*!
891   \brief Saves the content of the packet buffer to the file associated with current instance.
892   \param Open The NPF instance that creates the thread.
893 
894   Used by NPF_DumpThread() and NPF_CloseDumpFile().
895 */
896 NTSTATUS NPF_SaveCurrentBuffer(POPEN_INSTANCE Open);
897 
898 /*!
899   \brief Writes a block of packets on the dump file.
900   \param FileObject The file object that will receive the packets.
901   \param Offset The offset in the file where the packets will be put.
902   \param Length The amount of bytes to write.
903   \param Mdl MDL mapping the memory buffer that will be written to disk.
904   \param IoStatusBlock Used by the function to return the status of the operation.
905   \return The status of the operation. See ntstatus.h in the DDK.
906 
907   NPF_WriteDumpFile addresses directly the file system, creating a custom IRP and using it to send a portion
908   of the NPF circular buffer to disk. This function is used by NPF_DumpThread().
909 */
910 VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject,
911 			                    PLARGE_INTEGER Offset,
912 								ULONG Length,
913 								PMDL Mdl,
914 								PIO_STATUS_BLOCK IoStatusBlock);
915 
916 
917 
918 /*!
919   \brief Closes the dump file associated with an instance of the driver.
920   \param Open The NPF instance that closes the file.
921   \return The status of the operation. See ntstatus.h in the DDK.
922 */
923 NTSTATUS NPF_CloseDumpFile(POPEN_INSTANCE Open);
924 
925 /*!
926   \brief Returns the amount of bytes present in the packet buffer.
927   \param Open The NPF instance that closes the file.
928 */
929 UINT GetBuffOccupation(POPEN_INSTANCE Open);
930 
931 /*!
932   \brief Called by NDIS to notify us of a PNP event. The most significant one for us is power state change.
933 
934   \param ProtocolBindingContext Pointer to open context structure. This is NULL for global reconfig
935   events.
936   \param pNetPnPEvent Pointer to the PnP event
937 
938   If there is a power state change, the driver is forced to resynchronize the global timer.
939   This hopefully avoids the synchronization issues caused by hibernation or standby.
940   This function is excluded from the NT4 driver, where PnP is not supported
941 */
942 #ifdef NDIS50
943 NDIS_STATUS NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent);
944 #endif
945 
946 /**
947  *  @}
948  */
949 
950 /**
951  *  @}
952  */
953 
954 #endif  /*main ifndef/define*/
955