add winpcap 4.0.2 from url http://www.winpcap.org/
[natblaster.git] / winpcap / packetNtx / driver / Packet.h
blobeb6b519242cf649c53066565d1b9021716d8ac94
1 /*
2 * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
3 * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
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.
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.
34 /** @addtogroup NPF
35 * @{
38 /** @defgroup NPF_include NPF structures and definitions
39 * @{
42 #ifndef __PACKET_INCLUDE______
43 #define __PACKET_INCLUDE______
45 #ifdef _X86_
46 #define NTKERNEL ///< Forces the compilation of the jitter with kernel calls
47 #include "jitter.h"
48 #endif
50 #ifdef HAVE_BUGGY_TME_SUPPORT
51 #ifndef _X86_
52 #error TME support is available only on x86 architectures
53 #endif // _X86_
54 #endif //HAVE_BUGGY_TME_SUPPORT
58 // Needed to disable a warning due to the #pragma prefast directives,
59 // that are ignored by the normal DDK compiler
61 #ifndef _PREFAST_
62 #pragma warning(disable:4068)
63 #endif
65 #include "win_bpf.h"
67 #define MAX_REQUESTS 32 ///< Maximum number of simultaneous IOCTL requests.
69 #define Packet_ALIGNMENT sizeof(int) ///< Alignment macro. Defines the alignment size.
70 #define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1)) ///< Alignment macro. Rounds up to the next
71 ///< even multiple of Packet_ALIGNMENT.
73 #define KERNEL_EVENT_NAMESPACE L"\\BaseNamedObjects\\"
75 /***************************/
76 /* IOCTLs */
77 /***************************/
79 /*!
80 \brief IOCTL code: set kernel buffer size.
82 This IOCTL is used to set a new size of the circular buffer associated with an instance of NPF.
83 When a BIOCSETBUFFERSIZE command is received, the driver frees the old buffer, allocates the new one
84 and resets all the parameters associated with the buffer in the OPEN_INSTANCE structure. The currently
85 buffered packets are lost.
87 #define BIOCSETBUFFERSIZE 9592
89 /*!
90 \brief IOCTL code: set packet filtering program.
92 This IOCTL sets a new packet filter in the driver. Before allocating any memory for the new filter, the
93 bpf_validate() function is called to check the correctness of the filter. If this function returns TRUE,
94 the filter is copied to the driver's memory, its address is stored in the bpfprogram field of the
95 OPEN_INSTANCE structure associated with current instance of the driver, and the filter will be applied to
96 every incoming packet. This command also empties the circular buffer used by current instance
97 to store packets. This is done to avoid the presence in the buffer of packets that do not match the filter.
99 #define BIOCSETF 9030
102 \brief IOCTL code: get the capture stats
104 This command returns to the application the number of packets received and the number of packets dropped by
105 an instance of the driver.
107 #define BIOCGSTATS 9031
110 \brief IOCTL code: set the read timeout
112 This command sets the maximum timeout after which a read is released, also if no data packets were received.
114 #define BIOCSRTIMEOUT 7416
117 \brief IOCTL code: set working mode
119 This IOCTL can be used to set the working mode of a NPF instance. The new mode, received by the driver in the
120 buffer associated with the IOCTL command, can be #MODE_CAPT for capture mode (the default), #MODE_STAT for
121 statistical mode or #MODE_DUMP for dump mode.
123 #define BIOCSMODE 7412
126 \brief IOCTL code: set number of physical repetions of every packet written by the app
128 Sets the number of times a single write call must be repeated. This command sets the OPEN_INSTANCE::Nwrites
129 member, and is used to implement the 'multiple write' feature of the driver.
131 #define BIOCSWRITEREP 7413
134 \brief IOCTL code: set minimum amount of data in the kernel buffer that unlocks a read call
136 This command sets the OPEN_INSTANCE::MinToCopy member.
138 #define BIOCSMINTOCOPY 7414
141 \brief IOCTL code: set an OID value
143 This IOCTL is used to perform an OID set operation on the NIC driver.
145 #define BIOCSETOID 2147483648
148 \brief IOCTL code: get an OID value
150 This IOCTL is used to perform an OID get operation on the NIC driver.
152 #define BIOCQUERYOID 2147483652
155 \brief IOCTL code: set the name of a the file used by kernel dump mode
157 This command opens a file whose name is contained in the IOCTL buffer and associates it with current NPf instance.
158 The dump thread uses it to copy the content of the circular buffer to file.
159 If a file was already opened, the driver closes it before opening the new one.
161 #define BIOCSETDUMPFILENAME 9029
164 \brief IOCTL code: get the name of the event that the driver signals when some data is present in the buffer
166 Command used by the application to retrieve the name of the global event associated with a NPF instance.
167 The event is signaled by the driver when the kernel buffer contains enough data for a transfer.
169 #define BIOCGEVNAME 7415
172 \brief IOCTL code: Send a buffer containing multiple packets to the network, ignoring the timestamps.
174 Command used to send a buffer of packets in a single system call. Every packet in the buffer is preceded by
175 a sf_pkthdr structure. The timestamps of the packets are ignored, i.e. the packets are sent as fast as
176 possible. The NPF_BufferedWrite() function is invoked to send the packets.
178 #define BIOCSENDPACKETSNOSYNC 9032
181 \brief IOCTL code: Send a buffer containing multiple packets to the network, considering the timestamps.
183 Command used to send a buffer of packets in a single system call. Every packet in the buffer is preceded by
184 a sf_pkthdr structure. The timestamps of the packets are used to synchronize the write, i.e. the packets
185 are sent to the network respecting the intervals specified in the sf_pkthdr structure assiciated with each
186 packet. NPF_BufferedWrite() function is invoked to send the packets.
188 #define BIOCSENDPACKETSSYNC 9033
191 \brief IOCTL code: Set the dump file limits.
193 This IOCTL sets the limits (maximum size and maximum number of packets) of the dump file created when the
194 driver works in dump mode.
196 #define BIOCSETDUMPLIMITS 9034
199 \brief IOCTL code: Get the status of the kernel dump process.
201 This command returns TRUE if the kernel dump is ended, i.e if one of the limits set with BIOCSETDUMPLIMITS
202 (amount of bytes or number of packets) has been reached.
204 #define BIOCISDUMPENDED 7411
207 \brief IOCTL code: set the loopback behavior.
209 This IOCTL sets the loopback behavior of the driver with packets sent by itself: capture or drop.
211 #define BIOCISETLOBBEH 7410
214 \brief This IOCTL passes the read event HANDLE allocated by the user (packet.dll) to kernel level
216 Parameter: HANDLE
217 Parameter size: sizeof(HANDLE). If the caller is 32 bit, the parameter size is 4 bytes, even if sizeof(HANDLE) at kernel level
218 is 8 bytes. That's why in this IOCTL code handler we detect a 32bit calling process and do the necessary thunking.
220 TODO GV:I will go to hell for this ugly IOCTL definition. We should use CTL_CODE!!
222 #define BIOCSETEVENTHANDLE 7920
224 // Working modes
225 #define MODE_CAPT 0x0 ///< Capture working mode
226 #define MODE_STAT 0x1 ///< Statistical working mode
227 #define MODE_MON 0x2 ///< Kernel monitoring mode
228 #define MODE_DUMP 0x10 ///< Kernel dump working mode
231 #define IMMEDIATE 1 ///< Immediate timeout. Forces a read call to return immediately.
233 #define NDIS_FLAGS_SKIP_LOOPBACK_W2K 0x400 ///< This is an undocumented flag for NdisSetPacketFlags() that allows to disable loopback reception.
235 // The following definitions are used to provide compatibility
236 // of the dump files with the ones of libpcap
237 #define TCPDUMP_MAGIC 0xa1b2c3d4 ///< Libpcap magic number. Used by programs like tcpdump to recognize a driver's generated dump file.
238 #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.
239 #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.
241 // Loopback behaviour definitions
242 #define NPF_DISABLE_LOOPBACK 1 ///< Tells the driver to drop the packets sent by itself. This is usefult when building applications like bridges.
243 #define NPF_ENABLE_LOOPBACK 2 ///< Tells the driver to capture the packets sent by itself.
246 \brief Header of a libpcap dump file.
248 Used when a driver instance is set in dump mode to create a libpcap-compatible file.
250 struct packet_file_header
252 UINT magic; ///< Libpcap magic number
253 USHORT version_major; ///< Libpcap major version
254 USHORT version_minor; ///< Libpcap minor version
255 UINT thiszone; ///< Gmt to local correction
256 UINT sigfigs; ///< Accuracy of timestamps
257 UINT snaplen; ///< Length of the max saved portion of each packet
258 UINT linktype; ///< Data link type (DLT_*). See win_bpf.h for details.
262 \brief Header associated to a packet in the driver's buffer when the driver is in dump mode.
263 Similar to the bpf_hdr structure, but simpler.
265 struct sf_pkthdr {
266 struct timeval ts; ///< time stamp
267 UINT caplen; ///< Length of captured portion. The captured portion can be different from
268 ///< the original packet, because it is possible (with a proper filter) to
269 ///< instruct the driver to capture only a portion of the packets.
270 UINT len; ///< Length of the original packet (off wire).
274 \brief Stores an OID request.
276 This structure is used by the driver to perform OID query or set operations on the underlying NIC driver.
277 The OID operations be performed usually only by network drivers, but NPF exports this mechanism to user-level
278 applications through an IOCTL interface. The driver uses this structure to wrap a NDIS_REQUEST structure.
279 This allows to handle correctly the callback structure of NdisRequest(), handling multiple requests and
280 maintaining information about the IRPs to complete.
282 typedef struct _INTERNAL_REQUEST {
283 LIST_ENTRY ListElement; ///< Used to handle lists of requests.
284 // PIRP Irp; ///< Irp that performed the request
285 // 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.
286 NDIS_EVENT InternalRequestCompletedEvent;
287 NDIS_REQUEST Request; ///< The structure with the actual request, that will be passed to NdisRequest().
288 NDIS_STATUS RequestStatus;
290 } INTERNAL_REQUEST, *PINTERNAL_REQUEST;
293 \brief Contains a NDIS packet.
295 The driver uses this structure to wrap a NDIS_PACKET structure.
296 This allows to handle correctly the callback structure of NdisTransferData(), handling multiple requests and
297 maintaining information about the IRPs to complete.
299 typedef struct _PACKET_RESERVED {
300 LIST_ENTRY ListElement; ///< Used to handle lists of packets.
301 PIRP Irp; ///< Irp that performed the request
302 PMDL pMdl; ///< MDL mapping the buffer of the packet.
303 BOOLEAN FreeBufAfterWrite; ///< True if the memory buffer associated with the packet must be freed
304 ///< after a call to NdisSend().
305 ULONG Cpu; ///< The CPU on which the packet was pulled out of the linked list of free packets
306 } PACKET_RESERVED, *PPACKET_RESERVED;
308 #define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved)) ///< Macro to obtain a NDIS_PACKET from a PACKET_RESERVED
311 \brief Port device extension.
313 Structure containing some data relative to every adapter on which NPF is bound.
315 typedef struct _DEVICE_EXTENSION {
316 NDIS_HANDLE NdisProtocolHandle; ///< NDIS handle of NPF.
317 NDIS_STRING AdapterName; ///< Name of the adapter.
318 PWSTR ExportString; ///< Name of the exported device, i.e. name that the applications will use
319 ///< to open this adapter through WinPcap.
320 } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
323 \brief Kernel buffer of each CPU.
325 Structure containing the kernel buffer (and other CPU related fields) used to capture packets.
327 typedef struct __CPU_Private_Data
329 ULONG P; ///< Zero-based index of the producer in the buffer. It indicates the first free byte to be written.
330 ULONG C; ///< Zero-based index of the consumer in the buffer. It indicates the first free byte to be read.
331 ULONG Free; ///< Number of the free bytes in the buffer
332 PUCHAR Buffer; ///< Pointer to the kernel buffer used to capture packets.
333 ULONG Accepted; ///< Number of packet that current capture instance acepted, from its opening. A packet
334 ///< is accepted if it passes the filter and fits in the buffer. Accepted packets are the
335 ///< ones that reach the application.
336 ///< This number is related to the particular CPU this structure is referring to.
337 ULONG Received; ///< Number of packets received by current instance from its opening, i.e. number of
338 ///< packet received by the network adapter since the beginning of the
339 ///< capture/monitoring/dump session.
340 ///< This number is related to the particular CPU this structure is referring to.
341 ULONG Dropped; ///< Number of packet that current instance had to drop, from its opening. A packet
342 ///< is dropped if there is no more space to store it in the circular buffer that the
343 ///< driver associates to current instance.
344 ///< This number is related to the particular CPU this structure is referring to.
345 NDIS_SPIN_LOCK BufferLock; ///< It protects the buffer associated with this CPU.
346 PMDL TransferMdl1; ///< MDL used to map the portion of the buffer that will contain an incoming packet.
347 PMDL TransferMdl2; ///< Second MDL used to map the portion of the buffer that will contain an incoming packet.
348 ULONG NewP; ///< Used by NdisTransferData() (when we call NdisTransferData, p index must be updated only in the TransferDataComplete.
350 CpuPrivateData;
354 \brief Contains the state of a running instance of the NPF driver.
356 This is the most important structure of NPF: it is used by almost all the functions of the driver. An
357 _OPEN_INSTANCE structure is associated with every user-level session, allowing concurrent access
358 to the driver.
360 typedef struct _OPEN_INSTANCE
362 PDEVICE_EXTENSION DeviceExtension; ///< Pointer to the _DEVICE_EXTENSION structure of the device on which
363 ///< the instance is bound.
364 NDIS_HANDLE AdapterHandle; ///< NDIS idetifier of the adapter used by this instance.
365 UINT Medium; ///< Type of physical medium the underlying NDIS driver uses. See the
366 ///< documentation of NdisOpenAdapter in the MS DDK for details.
367 NDIS_HANDLE PacketPool; ///< Pool of NDIS_PACKET structures used to transfer the packets from and to the NIC driver.
368 KSPIN_LOCK RequestSpinLock; ///< SpinLock used to synchronize the OID requests.
369 LIST_ENTRY RequestList; ///< List of pending OID requests.
370 LIST_ENTRY ResetIrpList; ///< List of pending adapter reset requests.
371 INTERNAL_REQUEST Requests[MAX_REQUESTS]; ///< Array of structures that wrap every single OID request.
372 PMDL BufferMdl; ///< Pointer to a Memory descriptor list (MDL) that maps the circular buffer's memory.
373 PKEVENT ReadEvent; ///< Pointer to the event on which the read calls on this instance must wait.
374 PUCHAR bpfprogram; ///< Pointer to the filtering pseudo-code associated with current instance of the driver.
375 ///< This code is used only in particular situations (for example when the packet received
376 ///< from the NIC driver is stored in two non-consecutive buffers. In normal situations
377 ///< the filtering routine created by the JIT compiler and pointed by the next field
378 ///< is used. See \ref NPF for details on the filtering process.
379 #ifdef _X86_
380 JIT_BPF_Filter *Filter; ///< Pointer to the native filtering function created by the jitter.
381 ///< See BPF_jitter() for details.
382 #endif //_X86_
383 UINT MinToCopy; ///< Minimum amount of data in the circular buffer that unlocks a read. Set with the
384 ///< BIOCSMINTOCOPY IOCTL.
385 LARGE_INTEGER TimeOut; ///< Timeout after which a read is released, also if the amount of data in the buffer is
386 ///< less than MinToCopy. Set with the BIOCSRTIMEOUT IOCTL.
388 int mode; ///< Working mode of the driver. See PacketSetMode() for details.
389 LARGE_INTEGER Nbytes; ///< Amount of bytes accepted by the filter when this instance is in statistical mode.
390 LARGE_INTEGER Npackets; ///< Number of packets accepted by the filter when this instance is in statistical mode.
391 NDIS_SPIN_LOCK CountersLock; ///< SpinLock that protects the statistical mode counters.
392 UINT Nwrites; ///< Number of times a single write must be physically repeated. See \ref NPF for an
393 ///< explanation
394 ULONG Multiple_Write_Counter; ///< Counts the number of times a single write has already physically repeated.
395 NDIS_EVENT WriteEvent; ///< Event used to synchronize the multiple write process.
396 BOOLEAN WriteInProgress; ///< True if a write is currently in progress. NPF currently allows a single wite on
397 ///< the same open instance.
398 NDIS_SPIN_LOCK WriteLock; ///< SpinLock that protects the WriteInProgress variable.
399 NDIS_EVENT NdisRequestEvent; ///< Event used to synchronize I/O requests with the callback structure of NDIS.
400 BOOLEAN SkipSentPackets; ///< True if this instance should not capture back the packets that it transmits.
401 NDIS_STATUS IOStatus; ///< Maintains the status of and OID request call, that will be passed to the application.
402 HANDLE DumpFileHandle; ///< Handle of the file used in dump mode.
403 PFILE_OBJECT DumpFileObject; ///< Pointer to the object of the file used in dump mode.
404 PKTHREAD DumpThreadObject; ///< Pointer to the object of the thread used in dump mode.
405 HANDLE DumpThreadHandle; ///< Handle of the thread created by dump mode to asynchronously move the buffer to disk.
406 NDIS_EVENT DumpEvent; ///< Event used to synchronize the dump thread with the tap when the instance is in dump mode.
407 LARGE_INTEGER DumpOffset; ///< Current offset in the dump file.
408 UNICODE_STRING DumpFileName; ///< String containing the name of the dump file.
409 UINT MaxDumpBytes; ///< Maximum dimension in bytes of the dump file. If the dump file reaches this size it
410 ///< will be closed. A value of 0 means unlimited size.
411 UINT MaxDumpPacks; ///< Maximum number of packets that will be saved in the dump file. If this number of
412 ///< packets is reached the dump will be closed. A value of 0 means unlimited number of
413 ///< packets.
414 BOOLEAN DumpLimitReached; ///< TRUE if the maximum dimension of the dump file (MaxDumpBytes or MaxDumpPacks) is
415 ///< reached.
416 MEM_TYPE mem_ex; ///< Memory used by the TME virtual co-processor
417 TME_CORE tme; ///< Data structure containing the virtualization of the TME co-processor
418 NDIS_SPIN_LOCK MachineLock; ///< SpinLock that protects the BPF filter and the TME engine, if in use.
419 UINT MaxFrameSize; ///< Maximum frame size that the underlying MAC acceptes. Used to perform a check on the
420 ///< size of the frames sent with NPF_Write() or NPF_BufferedWrite().
421 CpuPrivateData CpuData[32]; ///< Pool of kernel buffer structures, one for each CPU.
422 ULONG ReaderSN; ///< Sequence number of the next packet to be read from the pool of kernel buffers.
423 ULONG WriterSN; ///< Sequence number of the next packet to be written in the pool of kernel buffers.
424 ///< These two sequence numbers are unique for each capture instance.
425 ULONG Size; ///< Size of each kernel buffer contained in the CpuData field.
426 ULONG AdapterHandleUsageCounter;
427 NDIS_SPIN_LOCK AdapterHandleLock;
428 ULONG AdapterBindingStatus; ///< Specifies if NPF is still bound to the adapter used by this instance, it's unbinding or it's not bound.
430 NDIS_EVENT NdisOpenCloseCompleteEvent;
431 NDIS_EVENT NdisWriteCompleteEvent; ///< Event that is signalled when all the packets have been successfully sent by NdisSend (and corresponfing sendComplete has been called)
432 NTSTATUS OpenCloseStatus;
433 ULONG TransmitPendingPackets; ///< Specifies the number of packets that are pending to be transmitted, i.e. have been submitted to NdisSendXXX but the SendComplete has not been called yet.
435 OPEN_INSTANCE, *POPEN_INSTANCE;
437 enum ADAPTER_BINDING_STATUS
439 ADAPTER_UNBOUND,
440 ADAPTER_BOUND,
441 ADAPTER_UNBINDING,
445 \brief Structure prepended to each packet in the kernel buffer pool.
447 Each packet in one of the kernel buffers is prepended by this header. It encapsulates the bpf_header,
448 which will be passed to user level programs, as well as the sequence number of the packet, set by the producer (the tap function),
449 and used by the consumer (the read function) to "reorder" the packets contained in the various kernel buffers.
451 struct PacketHeader
453 ULONG SN; ///< Sequence number of the packet.
454 struct bpf_hdr header; ///< bpf header, created by the tap, and copied unmodified to user level programs.
457 extern ULONG NCpu;
460 #define TRANSMIT_PACKETS 256 ///< Maximum number of packets in the transmit packet pool. This value is an upper bound to the number
461 ///< of packets that can be transmitted at the same time or with a single call to NdisSendPackets.
464 /// Macro used in the I/O routines to return the control to user-mode with a success status.
465 #define EXIT_SUCCESS(quantity) Irp->IoStatus.Information=quantity;\
466 Irp->IoStatus.Status = STATUS_SUCCESS;\
467 IoCompleteRequest(Irp, IO_NO_INCREMENT);\
468 return STATUS_SUCCESS;\
470 /// Macro used in the I/O routines to return the control to user-mode with a failure status.
471 #define EXIT_FAILURE(quantity) Irp->IoStatus.Information=quantity;\
472 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;\
473 IoCompleteRequest(Irp, IO_NO_INCREMENT);\
474 return STATUS_UNSUCCESSFUL;\
477 * @}
481 /***************************/
482 /* Prototypes */
483 /***************************/
485 /** @defgroup NPF_code NPF functions
486 * @{
491 \brief The initialization routine of the driver.
492 \param DriverObject The driver object of NPF created by the system.
493 \param RegistryPath The registry path containing the keys related to the driver.
494 \return A string containing a list of network adapters.
496 DriverEntry is a mandatory function in a device driver. Like the main() of a user level program, it is called
497 by the system when the driver is loaded in memory and started. Its purpose is to initialize the driver,
498 performing all the allocations and the setup. In particular, DriverEntry registers all the driver's I/O
499 callbacks, creates the devices, defines NPF as a protocol inside NDIS.
501 NTSTATUS
502 DriverEntry(
503 IN PDRIVER_OBJECT DriverObject,
504 IN PUNICODE_STRING RegistryPath
508 \brief Returns the list of the MACs available on the system.
509 \return A string containing a list of network adapters.
511 The list of adapters is retrieved from the
512 SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318} registry key.
513 NPF tries to create its bindings from this list. In this way it is possible to be loaded
514 and unloaded dynamically without passing from the control panel.
516 PWCHAR getAdaptersList(VOID);
519 \brief Returns the MACs that bind to TCP/IP.
520 \return Pointer to the registry key containing the list of adapters on which TCP/IP is bound.
522 If getAdaptersList() fails, NPF tries to obtain the TCP/IP bindings through this function.
524 PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(VOID);
527 \brief Creates a device for a given MAC.
528 \param adriverObjectP The driver object that will be associated with the device, i.e. the one of NPF.
529 \param amacNameP The name of the network interface that the device will point.
530 \param aProtoHandle NDIS protocol handle of NPF.
531 \return If the function succeeds, the return value is nonzero.
533 NPF creates a device for every valid network adapter. The new device points to the NPF driver, but contains
534 information about the original device. In this way, when the user opens the new device, NPF will be able to
535 determine the correct adapter to use.
537 BOOLEAN createDevice(
538 IN OUT PDRIVER_OBJECT adriverObjectP,
539 IN PUNICODE_STRING amacNameP,
540 NDIS_HANDLE aProtoHandle);
543 \brief Opens a new instance of the driver.
544 \param DeviceObject Pointer to the device object utilized by the user.
545 \param Irp Pointer to the IRP containing the user request.
546 \return The status of the operation. See ntstatus.h in the DDK.
548 This function is called by the OS when a new instance of the driver is opened, i.e. when a user application
549 performs a CreateFile on a device created by NPF. NPF_Open allocates and initializes variables, objects
550 and buffers needed by the new instance, fills the OPEN_INSTANCE structure associated with it and opens the
551 adapter with a call to NdisOpenAdapter.
553 NTSTATUS
554 NPF_Open(
555 IN PDEVICE_OBJECT DeviceObject,
556 IN PIRP Irp
560 \brief Ends the opening of an adapter.
561 \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
562 \param Status Status of the opening operation performed by NDIS.
563 \param OpenErrorStatus not used by NPF.
565 Callback function associated with the NdisOpenAdapter() NDIS function. It is invoked by NDIS when the NIC
566 driver has finished an open operation that was previously started by NPF_Open().
568 VOID
569 NPF_OpenAdapterComplete(
570 IN NDIS_HANDLE ProtocolBindingContext,
571 IN NDIS_STATUS Status,
572 IN NDIS_STATUS OpenErrorStatus
576 \brief Closes an instance of the driver.
577 \param DeviceObject Pointer to the device object utilized by the user.
578 \param Irp Pointer to the IRP containing the user request.
579 \return The status of the operation. See ntstatus.h in the DDK.
581 This function is called when a running instance of the driver is closed by the user with a CloseHandle().
582 It stops the capture/monitoring/dump process, deallocates the memory and the objects associated with the
583 instance and closing the files. The network adapter is then closed with a call to NdisCloseAdapter.
585 NTSTATUS
586 NPF_Cleanup(
587 IN PDEVICE_OBJECT DeviceObject,
588 IN PIRP Irp
591 NTSTATUS
592 NPF_Close(
593 IN PDEVICE_OBJECT DeviceObject,
594 IN PIRP Irp
600 \brief Ends the closing of an adapter.
601 \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
602 \param Status Status of the close operation performed by NDIS.
604 Callback function associated with the NdisCloseAdapter() NDIS function. It is invoked by NDIS when the NIC
605 driver has finished a close operation that was previously started by NPF_Close().
607 VOID
608 NPF_CloseAdapterComplete(
609 IN NDIS_HANDLE ProtocolBindingContext,
610 IN NDIS_STATUS Status
614 \brief Callback invoked by NDIS when a packet arrives from the network.
615 \param ProtocolBindingContext Context of the function. Points to a OPEN_INSTANCE structure that identifies
616 the NPF instance to which the packets are destined.
617 \param MacReceiveContext Handle that identifies the underlying NIC driver that generated the request.
618 This value must be used when the packet is transferred from the NIC driver with NdisTransferData().
619 \param HeaderBuffer Pointer to the buffer in the NIC driver memory that contains the header of the packet.
620 \param HeaderBufferSize Size in bytes of the header.
621 \param LookAheadBuffer Pointer to the buffer in the NIC driver's memory that contains the incoming packet's
622 data <b>available to NPF</b>. This value does not necessarily coincide with the actual size of the packet,
623 since only a portion can be available at this time. The remaining portion can be obtained with the
624 NdisTransferData() NDIS function.
625 \param LookaheadBufferSize Size in bytes of the lookahead buffer.
626 \param PacketSize Total size of the incoming packet, excluded the header.
627 \return The status of the operation. See ntstatus.h in the DDK.
629 NPF_tap() is called by the underlying NIC for every incoming packet. It is the most important and one of
630 the most complex functions of NPF: it executes the filter, runs the statistical engine (if the instance is in
631 statistical mode), gathers the timestamp, moves the packet in the buffer. NPF_tap() is the only function,
632 along with the filtering ones, that is executed for every incoming packet, therefore it is carefully
633 optimized.
635 NDIS_STATUS
636 NPF_tap(
637 IN NDIS_HANDLE ProtocolBindingContext,
638 IN NDIS_HANDLE MacReceiveContext,
639 IN PVOID HeaderBuffer,
640 IN UINT HeaderBufferSize,
641 IN PVOID LookAheadBuffer,
642 IN UINT LookaheadBufferSize,
643 IN UINT PacketSize
647 \brief Ends the transfer of a packet.
648 \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
649 \param Packet Pointer to the NDIS_PACKET structure that received the packet data.
650 \param Status Status of the transfer operation.
651 \param BytesTransferred Amount of bytes transferred.
653 Callback function associated with the NdisTransferData() NDIS function. It is invoked by NDIS when the NIC
654 driver has finished the transfer of a packet from the NIC driver memory to the NPF circular buffer.
656 VOID
657 NPF_TransferDataComplete(
658 IN NDIS_HANDLE ProtocolBindingContext,
659 IN PNDIS_PACKET Packet,
660 IN NDIS_STATUS Status,
661 IN UINT BytesTransferred
665 \brief Callback function that signals the end of a packet reception.
666 \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
668 does nothing in NPF
670 VOID
671 NPF_ReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext);
674 \brief Handles the IOCTL calls.
675 \param DeviceObject Pointer to the device object utilized by the user.
676 \param Irp Pointer to the IRP containing the user request.
677 \return The status of the operation. See ntstatus.h in the DDK.
679 Once the packet capture driver is opened it can be configured from user-level applications with IOCTL commands
680 using the DeviceIoControl() system call. NPF_IoControl receives and serves all the IOCTL calls directed to NPF.
681 The following commands are recognized:
682 - #BIOCSETBUFFERSIZE
683 - #BIOCSETF
684 - #BIOCGSTATS
685 - #BIOCSRTIMEOUT
686 - #BIOCSMODE
687 - #BIOCSWRITEREP
688 - #BIOCSMINTOCOPY
689 - #BIOCSETOID
690 - #BIOCQUERYOID
691 - #BIOCSETDUMPFILENAME
692 - #BIOCGEVNAME
693 - #BIOCSENDPACKETSSYNC
694 - #BIOCSENDPACKETSNOSYNC
696 NTSTATUS
697 NPF_IoControl(
698 IN PDEVICE_OBJECT DeviceObject,
699 IN PIRP Irp
702 VOID
705 \brief Ends an OID request.
706 \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
707 \param pRequest Pointer to the completed OID request.
708 \param Status Status of the operation.
710 Callback function associated with the NdisRequest() NDIS function. It is invoked by NDIS when the NIC
711 driver has finished an OID request operation that was previously started by NPF_IoControl().
713 NPF_RequestComplete(
714 IN NDIS_HANDLE ProtocolBindingContext,
715 IN PNDIS_REQUEST pRequest,
716 IN NDIS_STATUS Status
720 \brief Writes a raw packet to the network.
721 \param DeviceObject Pointer to the device object on which the user wrote the packet.
722 \param Irp Pointer to the IRP containing the user request.
723 \return The status of the operation. See ntstatus.h in the DDK.
725 This function is called by the OS in consequence of user WriteFile() call, with the data of the packet that must
726 be sent on the net. The data is contained in the buffer associated with Irp, NPF_Write takes it and
727 delivers it to the NIC driver via the NdisSend() function. The Nwrites field of the OPEN_INSTANCE structure
728 associated with Irp indicates the number of copies of the packet that will be sent: more than one copy of the
729 packet can be sent for performance reasons.
731 NTSTATUS
732 NPF_Write(
733 IN PDEVICE_OBJECT DeviceObject,
734 IN PIRP Irp
739 \brief Writes a buffer of raw packets to the network.
740 \param Irp Pointer to the IRP containing the user request.
741 \param UserBuff Pointer to the buffer containing the packets to send.
742 \param UserBuffSize Size of the buffer with the packets.
743 \param sync If set to TRUE, the packets are transmitted respecting their timestamps.
744 \return The amount of bytes actually sent. If the return value is smaller than the Size parameter, an
745 error occurred during the send. The error can be caused by an adapter problem or by an
746 inconsistent/bogus user buffer.
748 This function is called by the OS in consequence of a BIOCSENDPACKETSNOSYNC or a BIOCSENDPACKETSSYNC IOCTL.
749 The buffer received as input parameter contains an arbitrary number of packets, each of which preceded by a
750 sf_pkthdr structure. NPF_BufferedWrite() scans the buffer and sends every packet via the NdisSend() function.
751 When Sync is set to TRUE, the packets are synchronized with the KeQueryPerformanceCounter() function.
752 This requires a remarkable amount of CPU, but allows to respect the timestamps associated with packets with a precision
753 of some microseconds (depending on the precision of the performance counter of the machine).
754 If Sync is false, the timestamps are ignored and the packets are sent as fat as possible.
757 INT NPF_BufferedWrite(IN PIRP Irp,
758 IN PCHAR UserBuff,
759 IN ULONG UserBuffSize,
760 BOOLEAN sync);
763 \brief Waits the completion of all the sends performed by NPF_BufferedWrite.
765 \param Open Pointer to open context structure
767 Used by NPF_BufferedWrite to wait the completion of all the sends before returning the control to the user.
769 VOID NPF_WaitEndOfBufferedWrite(POPEN_INSTANCE Open);
772 \brief Ends a send operation.
773 \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
774 \param pPacket Pointer to the NDIS PACKET structure used by NPF_Write() to send the packet.
775 \param Status Status of the operation.
777 Callback function associated with the NdisSend() NDIS function. It is invoked by NDIS when the NIC
778 driver has finished an OID request operation that was previously started by NPF_Write().
780 VOID
781 NPF_SendComplete(
782 IN NDIS_HANDLE ProtocolBindingContext,
783 IN PNDIS_PACKET pPacket,
784 IN NDIS_STATUS Status
788 \brief Ends a reset of the adapter.
789 \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
790 \param Status Status of the operation.
792 Callback function associated with the NdisReset() NDIS function. It is invoked by NDIS when the NIC
793 driver has finished an OID request operation that was previously started by NPF_IoControl(), in an IOCTL_PROTOCOL_RESET
794 command.
796 VOID
797 NPF_ResetComplete(
798 IN NDIS_HANDLE ProtocolBindingContext,
799 IN NDIS_STATUS Status
803 \brief Callback for NDIS StatusHandler. Not used by NPF
805 VOID
806 NPF_Status(
807 IN NDIS_HANDLE ProtocolBindingContext,
808 IN NDIS_STATUS Status,
809 IN PVOID StatusBuffer,
810 IN UINT StatusBufferSize
815 \brief Callback for NDIS StatusCompleteHandler. Not used by NPF
817 VOID
818 NPF_StatusComplete(IN NDIS_HANDLE ProtocolBindingContext);
821 \brief Function called by the OS when NPF is unloaded.
822 \param DriverObject The driver object of NPF created by the system.
824 This is the last function executed when the driver is unloaded from the system. It frees global resources,
825 delete the devices and deregisters the protocol. The driver can be unloaded by the user stopping the NPF
826 service (from control panel or with a console 'net stop npf').
828 VOID
829 NPF_Unload(IN PDRIVER_OBJECT DriverObject);
833 \brief Function that serves the user's reads.
834 \param DeviceObject Pointer to the device used by the user.
835 \param Irp Pointer to the IRP containing the user request.
836 \return The status of the operation. See ntstatus.h in the DDK.
838 This function is called by the OS in consequence of user ReadFile() call. It moves the data present in the
839 kernel buffer to the user buffer associated with Irp.
840 First of all, NPF_Read checks the amount of data in kernel buffer associated with current NPF instance.
841 - If the instance is in capture mode and the buffer contains more than OPEN_INSTANCE::MinToCopy bytes,
842 NPF_Read moves the data in the user buffer and returns immediatly. In this way, the read performed by the
843 user is not blocking.
844 - If the buffer contains less than MinToCopy bytes, the application's request isn't
845 satisfied immediately, but it's blocked until at least MinToCopy bytes arrive from the net
846 or the timeout on this read expires. The timeout is kept in the OPEN_INSTANCE::TimeOut field.
847 - If the instance is in statistical mode or in dump mode, the application's request is blocked until the
848 timeout kept in OPEN_INSTANCE::TimeOut expires.
850 NTSTATUS
851 NPF_Read(
852 IN PDEVICE_OBJECT DeviceObject,
853 IN PIRP Irp
857 \brief Reads the registry keys associated woth NPF if the driver is manually installed via the control panel.
859 Normally not used in recent versions of NPF.
861 NTSTATUS
862 NPF_ReadRegistry(
863 IN PWSTR *MacDriverName,
864 IN PWSTR *PacketDriverName,
865 IN PUNICODE_STRING RegistryPath
869 \brief Function used by NPF_ReadRegistry() to quesry the registry keys associated woth NPF if the driver
870 is manually installed via the control panel.
872 Normally not used in recent versions of NPF.
874 NTSTATUS
875 NPF_QueryRegistryRoutine(
876 IN PWSTR ValueName,
877 IN ULONG ValueType,
878 IN PVOID ValueData,
879 IN ULONG ValueLength,
880 IN PVOID Context,
881 IN PVOID EntryContext
885 \brief Callback for NDIS BindAdapterHandler. Not used by NPF.
887 Function called by NDIS when a new adapter is installed on the machine With Plug and Play.
889 VOID NPF_BindAdapter(
890 OUT PNDIS_STATUS Status,
891 IN NDIS_HANDLE BindContext,
892 IN PNDIS_STRING DeviceName,
893 IN PVOID SystemSpecific1,
894 IN PVOID SystemSpecific2
898 \brief Callback for NDIS UnbindAdapterHandler.
899 \param Status out variable filled by NPF_UnbindAdapter with the status of the unbind operation.
900 \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with current instance.
901 \param UnbindContext Specifies a handle, supplied by NDIS, that NPF can use to complete the opration.
903 Function called by NDIS when a new adapter is removed from the machine without shutting it down.
904 NPF_UnbindAdapter closes the adapter calling NdisCloseAdapter() and frees the memory and the structures
905 associated with it. It also releases the waiting user-level app and closes the dump thread if the instance
906 is in dump mode.
908 VOID
909 NPF_UnbindAdapter(
910 OUT PNDIS_STATUS Status,
911 IN NDIS_HANDLE ProtocolBindingContext,
912 IN NDIS_HANDLE UnbindContext
917 \brief Creates the file that will receive the packets when the driver is in dump mode.
918 \param Open The NPF instance that opens the file.
919 \param fileName Pointer to a UNICODE string containing the name of the file.
920 \param append Boolean value that specifies if the data must be appended to the file.
921 \return The status of the operation. See ntstatus.h in the DDK.
923 NTSTATUS NPF_OpenDumpFile(POPEN_INSTANCE Open , PUNICODE_STRING fileName, BOOLEAN append);
926 \brief Starts dump to file.
927 \param Open The NPF instance that opens the file.
928 \return The status of the operation. See ntstatus.h in the DDK.
930 This function performs two operations. First, it writes the libpcap header at the beginning of the file.
931 Second, it starts the thread that asynchronously dumps the network data to the file.
933 NTSTATUS NPF_StartDump(POPEN_INSTANCE Open);
936 \brief The dump thread.
937 \param Open The NPF instance that creates the thread.
939 This function moves the content of the NPF kernel buffer to file. It runs in the user context, so at lower
940 priority than the TAP.
942 VOID NPF_DumpThread(PVOID Open);
945 \brief Saves the content of the packet buffer to the file associated with current instance.
946 \param Open The NPF instance that creates the thread.
948 Used by NPF_DumpThread() and NPF_CloseDumpFile().
950 NTSTATUS NPF_SaveCurrentBuffer(POPEN_INSTANCE Open);
953 \brief Writes a block of packets on the dump file.
954 \param FileObject The file object that will receive the packets.
955 \param Offset The offset in the file where the packets will be put.
956 \param Length The amount of bytes to write.
957 \param Mdl MDL mapping the memory buffer that will be written to disk.
958 \param IoStatusBlock Used by the function to return the status of the operation.
959 \return The status of the operation. See ntstatus.h in the DDK.
961 NPF_WriteDumpFile addresses directly the file system, creating a custom IRP and using it to send a portion
962 of the NPF circular buffer to disk. This function is used by NPF_DumpThread().
964 VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject,
965 PLARGE_INTEGER Offset,
966 ULONG Length,
967 PMDL Mdl,
968 PIO_STATUS_BLOCK IoStatusBlock);
973 \brief Closes the dump file associated with an instance of the driver.
974 \param Open The NPF instance that closes the file.
975 \return The status of the operation. See ntstatus.h in the DDK.
977 NTSTATUS NPF_CloseDumpFile(POPEN_INSTANCE Open);
979 VOID
980 NPF_CloseOpenInstance(POPEN_INSTANCE pOpen);
982 BOOLEAN
983 NPF_StartUsingBinding(
984 IN POPEN_INSTANCE pOpen);
986 VOID
987 NPF_StopUsingBinding(
988 IN POPEN_INSTANCE pOpen);
990 VOID
991 NPF_CloseBinding(
992 IN POPEN_INSTANCE pOpen);
994 NTSTATUS
995 NPF_GetDeviceMTU(
996 IN POPEN_INSTANCE pOpen,
997 IN PIRP pIrp,
998 OUT PUINT pMtu);
1001 \brief Returns the amount of bytes present in the packet buffer.
1002 \param Open The NPF instance that closes the file.
1004 UINT GetBuffOccupation(POPEN_INSTANCE Open);
1007 \brief Called by NDIS to notify us of a PNP event. The most significant one for us is power state change.
1009 \param ProtocolBindingContext Pointer to open context structure. This is NULL for global reconfig
1010 events.
1011 \param pNetPnPEvent Pointer to the PnP event
1013 If there is a power state change, the driver is forced to resynchronize the global timer.
1014 This hopefully avoids the synchronization issues caused by hibernation or standby.
1015 This function is excluded from the NT4 driver, where PnP is not supported
1017 #ifdef NDIS50
1018 NDIS_STATUS NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent);
1019 #endif
1022 // Old registry based WinPcap names
1024 ///*!
1025 // \brief Helper function to query a value from the global WinPcap registry key
1026 //*/
1027 //VOID NPF_QueryWinpcapRegistryString(PWSTR SubKeyName,
1028 // WCHAR *Value,
1029 // UINT ValueLen,
1030 // WCHAR *DefaultValue);
1035 * @}
1039 * @}
1042 #endif /*main ifndef/define*/