Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/SoftEtherVPN/SoftEtherVPN_Stable.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/See/Packet.h')
-rw-r--r--src/See/Packet.h954
1 files changed, 954 insertions, 0 deletions
diff --git a/src/See/Packet.h b/src/See/Packet.h
new file mode 100644
index 00000000..f75ed1d9
--- /dev/null
+++ b/src/See/Packet.h
@@ -0,0 +1,954 @@
+/*
+ * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
+ * Copyright (c) 2005 CACE Technologies, Davis (California)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Politecnico di Torino, CACE Technologies
+ * nor the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/** @ingroup NPF
+ * @{
+ */
+
+/** @defgroup NPF_include NPF structures and definitions
+ * @{
+ */
+
+#ifndef __PACKET_INCLUDE______
+#define __PACKET_INCLUDE______
+
+#ifdef __NPF_x86__
+#define NTKERNEL ///< Forces the compilation of the jitter with kernel calls
+#include "jitter.h"
+#endif
+
+
+#include "win_bpf.h"
+
+#define MAX_REQUESTS 256 ///< Maximum number of simultaneous IOCTL requests.
+
+#define Packet_ALIGNMENT sizeof(int) ///< Alignment macro. Defines the alignment size.
+#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1)) ///< Alignment macro. Rounds up to the next
+ ///< even multiple of Packet_ALIGNMENT.
+/***************************/
+/* IOCTLs */
+/***************************/
+
+/*!
+ \brief IOCTL code: set kernel buffer size.
+
+ This IOCTL is used to set a new size of the circular buffer associated with an instance of NPF.
+ When a BIOCSETBUFFERSIZE command is received, the driver frees the old buffer, allocates the new one
+ and resets all the parameters associated with the buffer in the OPEN_INSTANCE structure. The currently
+ buffered packets are lost.
+*/
+#define BIOCSETBUFFERSIZE 9592
+
+/*!
+ \brief IOCTL code: set packet filtering program.
+
+ This IOCTL sets a new packet filter in the driver. Before allocating any memory for the new filter, the
+ bpf_validate() function is called to check the correctness of the filter. If this function returns TRUE,
+ the filter is copied to the driver's memory, its address is stored in the bpfprogram field of the
+ OPEN_INSTANCE structure associated with current instance of the driver, and the filter will be applied to
+ every incoming packet. This command also empties the circular buffer used by current instance
+ to store packets. This is done to avoid the presence in the buffer of packets that do not match the filter.
+*/
+#define BIOCSETF 9030
+
+/*!
+ \brief IOCTL code: get the capture stats
+
+ This command returns to the application the number of packets received and the number of packets dropped by
+ an instance of the driver.
+*/
+#define BIOCGSTATS 9031
+
+/*!
+ \brief IOCTL code: set the read timeout
+
+ This command sets the maximum timeout after which a read is released, also if no data packets were received.
+*/
+#define BIOCSRTIMEOUT 7416
+
+/*!
+ \brief IOCTL code: set working mode
+
+ This IOCTL can be used to set the working mode of a NPF instance. The new mode, received by the driver in the
+ buffer associated with the IOCTL command, can be #MODE_CAPT for capture mode (the default), #MODE_STAT for
+ statistical mode or #MODE_DUMP for dump mode.
+*/
+#define BIOCSMODE 7412
+
+/*!
+ \brief IOCTL code: set number of physical repetions of every packet written by the app
+
+ Sets the number of times a single write call must be repeated. This command sets the OPEN_INSTANCE::Nwrites
+ member, and is used to implement the 'multiple write' feature of the driver.
+*/
+#define BIOCSWRITEREP 7413
+
+/*!
+ \brief IOCTL code: set minimum amount of data in the kernel buffer that unlocks a read call
+
+ This command sets the OPEN_INSTANCE::MinToCopy member.
+*/
+#define BIOCSMINTOCOPY 7414
+
+/*!
+ \brief IOCTL code: set an OID value
+
+ This IOCTL is used to perform an OID set operation on the NIC driver.
+*/
+#define BIOCSETOID 2147483648
+
+/*!
+ \brief IOCTL code: get an OID value
+
+ This IOCTL is used to perform an OID get operation on the NIC driver.
+*/
+#define BIOCQUERYOID 2147483652
+#define BIOCISETLOBBEH 7410
+/*!
+ \brief IOCTL code: set the name of a the file used by kernel dump mode
+
+ This command opens a file whose name is contained in the IOCTL buffer and associates it with current NPf instance.
+ The dump thread uses it to copy the content of the circular buffer to file.
+ If a file was already opened, the driver closes it before opening the new one.
+*/
+#define BIOCSETDUMPFILENAME 9029
+
+/*!
+ \brief IOCTL code: get the name of the event that the driver signals when some data is present in the buffer
+
+ Command used by the application to retrieve the name of the global event associated with a NPF instance.
+ The event is signaled by the driver when the kernel buffer contains enough data for a transfer.
+*/
+#define BIOCGEVNAME 7415
+
+/*!
+ \brief IOCTL code: Send a buffer containing multiple packets to the network, ignoring the timestamps.
+
+ Command used to send a buffer of packets in a single system call. Every packet in the buffer is preceded by
+ a sf_pkthdr structure. The timestamps of the packets are ignored, i.e. the packets are sent as fast as
+ possible. The NPF_BufferedWrite() function is invoked to send the packets.
+*/
+#define BIOCSENDPACKETSNOSYNC 9032
+
+/*!
+ \brief IOCTL code: Send a buffer containing multiple packets to the network, considering the timestamps.
+
+ Command used to send a buffer of packets in a single system call. Every packet in the buffer is preceded by
+ a sf_pkthdr structure. The timestamps of the packets are used to synchronize the write, i.e. the packets
+ are sent to the network respecting the intervals specified in the sf_pkthdr structure assiciated with each
+ packet. NPF_BufferedWrite() function is invoked to send the packets.
+*/
+#define BIOCSENDPACKETSSYNC 9033
+
+/*!
+ \brief IOCTL code: Set the dump file limits.
+
+ This IOCTL sets the limits (maximum size and maximum number of packets) of the dump file created when the
+ driver works in dump mode.
+*/
+#define BIOCSETDUMPLIMITS 9034
+
+/*!
+ \brief IOCTL code: Get the status of the kernel dump process.
+
+ This command returns TRUE if the kernel dump is ended, i.e if one of the limits set with BIOCSETDUMPLIMITS
+ (amount of bytes or number of packets) has been reached.
+*/
+#define BIOCISDUMPENDED 7411
+
+// Working modes
+#define MODE_CAPT 0x0 ///< Capture working mode
+#define MODE_STAT 0x1 ///< Statistical working mode
+#define MODE_MON 0x2 ///< Kernel monitoring mode
+#define MODE_DUMP 0x10 ///< Kernel dump working mode
+
+
+#define IMMEDIATE 1 ///< Immediate timeout. Forces a read call to return immediately.
+
+
+// The following definitions are used to provide compatibility
+// of the dump files with the ones of libpcap
+#define TCPDUMP_MAGIC 0xa1b2c3d4 ///< Libpcap magic number. Used by programs like tcpdump to recognize a driver's generated dump file.
+#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.
+#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.
+
+/*!
+ \brief Header of a libpcap dump file.
+
+ Used when a driver instance is set in dump mode to create a libpcap-compatible file.
+*/
+struct packet_file_header
+{
+ UINT magic; ///< Libpcap magic number
+ USHORT version_major; ///< Libpcap major version
+ USHORT version_minor; ///< Libpcap minor version
+ UINT thiszone; ///< Gmt to local correction
+ UINT sigfigs; ///< Accuracy of timestamps
+ UINT snaplen; ///< Length of the max saved portion of each packet
+ UINT linktype; ///< Data link type (DLT_*). See win_bpf.h for details.
+};
+
+/*!
+ \brief Header associated to a packet in the driver's buffer when the driver is in dump mode.
+ Similar to the bpf_hdr structure, but simpler.
+*/
+struct sf_pkthdr {
+ struct timeval ts; ///< time stamp
+ UINT caplen; ///< Length of captured portion. The captured portion can be different from
+ ///< the original packet, because it is possible (with a proper filter) to
+ ///< instruct the driver to capture only a portion of the packets.
+ UINT len; ///< Length of the original packet (off wire).
+};
+
+/*!
+ \brief Stores an OID request.
+
+ This structure is used by the driver to perform OID query or set operations on the underlying NIC driver.
+ The OID operations be performed usually only by network drivers, but NPF exports this mechanism to user-level
+ applications through an IOCTL interface. The driver uses this structure to wrap a NDIS_REQUEST structure.
+ This allows to handle correctly the callback structure of NdisRequest(), handling multiple requests and
+ maintaining information about the IRPs to complete.
+*/
+typedef struct _INTERNAL_REQUEST {
+ LIST_ENTRY ListElement; ///< Used to handle lists of requests.
+ PIRP Irp; ///< Irp that performed the request
+ 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.
+ NDIS_REQUEST Request; ///< The structure with the actual request, that will be passed to NdisRequest().
+} INTERNAL_REQUEST, *PINTERNAL_REQUEST;
+
+/*!
+ \brief Contains a NDIS packet.
+
+ The driver uses this structure to wrap a NDIS_PACKET structure.
+ This allows to handle correctly the callback structure of NdisTransferData(), handling multiple requests and
+ maintaining information about the IRPs to complete.
+*/
+typedef struct _PACKET_RESERVED {
+ LIST_ENTRY ListElement; ///< Used to handle lists of packets.
+ PIRP Irp; ///< Irp that performed the request
+ PMDL pMdl; ///< MDL mapping the buffer of the packet.
+ BOOLEAN FreeBufAfterWrite; ///< True if the memory buffer associated with the packet must be freed
+ ///< after a call to NdisSend().
+ ULONG Cpu; ///< The CPU on which the packet was pulled out of the linked list of free packets
+} PACKET_RESERVED, *PPACKET_RESERVED;
+
+#define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved)) ///< Macro to obtain a NDIS_PACKET from a PACKET_RESERVED
+
+/*!
+ \brief Port device extension.
+
+ Structure containing some data relative to every adapter on which NPF is bound.
+*/
+typedef struct _DEVICE_EXTENSION {
+ NDIS_HANDLE NdisProtocolHandle; ///< NDIS handle of NPF.
+ NDIS_STRING AdapterName; ///< Name of the adapter.
+ PWSTR ExportString; ///< Name of the exported device, i.e. name that the applications will use
+ ///< to open this adapter through WinPcap.
+} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
+
+/*!
+ \brief Kernel buffer of each CPU.
+
+ Structure containing the kernel buffer (and other CPU related fields) used to capture packets.
+*/
+typedef struct __CPU_Private_Data
+{
+ ULONG P; ///< Zero-based index of the producer in the buffer. It indicates the first free byte to be written.
+ ULONG C; ///< Zero-based index of the consumer in the buffer. It indicates the first free byte to be read.
+ ULONG Free; ///< Number of the free bytes in the buffer
+ PUCHAR Buffer; ///< Pointer to the kernel buffer used to capture packets.
+ ULONG Accepted; ///< Number of packet that current capture instance acepted, from its opening. A packet
+ ///< is accepted if it passes the filter and fits in the buffer. Accepted packets are the
+ ///< ones that reach the application.
+ ///< This number is related to the particular CPU this structure is referring to.
+ ULONG Received; ///< Number of packets received by current instance from its opening, i.e. number of
+ ///< packet received by the network adapter since the beginning of the
+ ///< capture/monitoring/dump session.
+ ///< This number is related to the particular CPU this structure is referring to.
+ ULONG Dropped; ///< Number of packet that current instance had to drop, from its opening. A packet
+ ///< is dropped if there is no more space to store it in the circular buffer that the
+ ///< driver associates to current instance.
+ ///< This number is related to the particular CPU this structure is referring to.
+ ULONG Processing; ///< Flag. If set to 1, it indicates that the tap is processing a packet on the CPU this structure is referring to.
+ PMDL TransferMdl1; ///< MDL used to map the portion of the buffer that will contain an incoming packet.
+ PMDL TransferMdl2; ///< Second MDL used to map the portion of the buffer that will contain an incoming packet.
+ ULONG NewP; ///< Used by NdisTransferData() (when we call NdisTransferData, p index must be updated only in the TransferDataComplete.
+}
+ CpuPrivateData;
+
+
+/*!
+ \brief Contains the state of a running instance of the NPF driver.
+
+ This is the most important structure of NPF: it is used by almost all the functions of the driver. An
+ _OPEN_INSTANCE structure is associated with every user-level session, allowing concurrent access
+ to the driver.
+*/
+typedef struct _OPEN_INSTANCE
+{
+ PDEVICE_EXTENSION DeviceExtension; ///< Pointer to the _DEVICE_EXTENSION structure of the device on which
+ ///< the instance is bound.
+ NDIS_HANDLE AdapterHandle; ///< NDIS idetifier of the adapter used by this instance.
+ UINT Medium; ///< Type of physical medium the underlying NDIS driver uses. See the
+ ///< documentation of NdisOpenAdapter in the MS DDK for details.
+ NDIS_HANDLE PacketPool; ///< Pool of NDIS_PACKET structures used to transfer the packets from and to the NIC driver.
+ PIRP OpenCloseIrp; ///< Pointer used to store the open/close IRP requests and provide them to the
+ ///< callbacks of NDIS.
+ KSPIN_LOCK RequestSpinLock; ///< SpinLock used to synchronize the OID requests.
+ LIST_ENTRY RequestList; ///< List of pending OID requests.
+ LIST_ENTRY ResetIrpList; ///< List of pending adapter reset requests.
+ INTERNAL_REQUEST Requests[MAX_REQUESTS]; ///< Array of structures that wrap every single OID request.
+ PMDL BufferMdl; ///< Pointer to a Memory descriptor list (MDL) that maps the circular buffer's memory.
+ PKEVENT ReadEvent; ///< Pointer to the event on which the read calls on this instance must wait.
+ HANDLE ReadEventHandle; ///< Handle of the event on which the read calls on this instance must wait.
+ UNICODE_STRING ReadEventName; ///< Name of the event on which the read calls on this instance must wait.
+ ///< The event is created with a name, so it can be used at user level to know when it
+ ///< is possible to access the driver without being blocked. This fiels stores the name
+ ///< that and is used by the BIOCGEVNAME IOCTL call.
+ PUCHAR bpfprogram; ///< Pointer to the filtering pseudo-code associated with current instance of the driver.
+ ///< This code is used only in particular situations (for example when the packet received
+ ///< from the NIC driver is stored in two non-consecutive buffers. In normal situations
+ ///< the filtering routine created by the JIT compiler and pointed by the next field
+ ///< is used. See \ref NPF for details on the filtering process.
+#ifdef __NPF_x86__
+ JIT_BPF_Filter *Filter; ///< Pointer to the native filtering function created by the jitter.
+ ///< See BPF_jitter() for details.
+#endif
+ UINT MinToCopy; ///< Minimum amount of data in the circular buffer that unlocks a read. Set with the
+ ///< BIOCSMINTOCOPY IOCTL.
+ LARGE_INTEGER TimeOut; ///< Timeout after which a read is released, also if the amount of data in the buffer is
+ ///< less than MinToCopy. Set with the BIOCSRTIMEOUT IOCTL.
+
+ int mode; ///< Working mode of the driver. See PacketSetMode() for details.
+ LARGE_INTEGER Nbytes; ///< Amount of bytes accepted by the filter when this instance is in statistical mode.
+ LARGE_INTEGER Npackets; ///< Number of packets accepted by the filter when this instance is in statistical mode.
+ NDIS_SPIN_LOCK CountersLock; ///< SpinLock that protects the statistical mode counters.
+ UINT Nwrites; ///< Number of times a single write must be physically repeated. See \ref NPF for an
+ ///< explanation
+ ULONG Multiple_Write_Counter; ///< Counts the number of times a single write has already physically repeated.
+ NDIS_EVENT WriteEvent; ///< Event used to synchronize the multiple write process.
+ BOOLEAN WriteInProgress; ///< True if a write is currently in progress. NPF currently allows a single wite on
+ ///< the same open instance.
+ NDIS_SPIN_LOCK WriteLock; ///< SpinLock that protects the WriteInProgress variable.
+ NDIS_EVENT IOEvent; ///< Event used to synchronize I/O requests with the callback structure of NDIS.
+ NDIS_STATUS IOStatus; ///< Maintains the status of and OID request call, that will be passed to the application.
+ BOOLEAN Bound; ///< Specifies if NPF is still bound to the adapter used by this instance. Bound can be
+ ///< FALSE if a Plug and Play adapter has been removed or disabled by the user.
+ HANDLE DumpFileHandle; ///< Handle of the file used in dump mode.
+ PFILE_OBJECT DumpFileObject; ///< Pointer to the object of the file used in dump mode.
+ PKTHREAD DumpThreadObject; ///< Pointer to the object of the thread used in dump mode.
+ HANDLE DumpThreadHandle; ///< Handle of the thread created by dump mode to asynchronously move the buffer to disk.
+ NDIS_EVENT DumpEvent; ///< Event used to synchronize the dump thread with the tap when the instance is in dump mode.
+ LARGE_INTEGER DumpOffset; ///< Current offset in the dump file.
+ UNICODE_STRING DumpFileName; ///< String containing the name of the dump file.
+ UINT MaxDumpBytes; ///< Maximum dimension in bytes of the dump file. If the dump file reaches this size it
+ ///< will be closed. A value of 0 means unlimited size.
+ UINT MaxDumpPacks; ///< Maximum number of packets that will be saved in the dump file. If this number of
+ ///< packets is reached the dump will be closed. A value of 0 means unlimited number of
+ ///< packets.
+ BOOLEAN DumpLimitReached; ///< TRUE if the maximum dimension of the dump file (MaxDumpBytes or MaxDumpPacks) is
+ ///< reached.
+ MEM_TYPE mem_ex; ///< Memory used by the TME virtual co-processor
+ TME_CORE tme; ///< Data structure containing the virtualization of the TME co-processor
+ NDIS_SPIN_LOCK MachineLock; ///< SpinLock that protects the mem_ex buffer
+ UINT MaxFrameSize; ///< Maximum frame size that the underlying MAC acceptes. Used to perform a check on the
+ ///< size of the frames sent with NPF_Write() or NPF_BufferedWrite().
+ CpuPrivateData CpuData[1024]; ///< Pool of kernel buffer structures, one for each CPU.
+ ULONG ReaderSN; ///< Sequence number of the next packet to be read from the pool of kernel buffers.
+ ULONG WriterSN; ///< Sequence number of the next packet to be written in the pool of kernel buffers.
+ ///< These two sequence numbers are unique for each capture instance.
+ ULONG Size; ///< Size of each kernel buffer contained in the CpuData field.
+ ULONG SkipProcessing; ///< Flag. When set to 1, the tap discards each packet. It is set to 1 by the IOCTLs that modify
+ ///< some "sensible" fields of the Open structure (e.g. they reallocate the pool of kernel buffers,
+ ///< or change the filter program
+ BOOLEAN SkipSentPackets;
+
+}
+OPEN_INSTANCE, *POPEN_INSTANCE;
+
+/*!
+ \brief Structure prepended to each packet in the kernel buffer pool.
+
+ Each packet in one of the kernel buffers is prepended by this header. It encapsulates the bpf_header,
+ which will be passed to user level programs, as well as the sequence number of the packet, set by the producer (the tap function),
+ and used by the consumer (the read function) to "reorder" the packets contained in the various kernel buffers.
+*/
+struct PacketHeader
+{
+ ULONG SN; ///< Sequence number of the packet.
+ struct bpf_hdr header; ///< bpf header, created by the tap, and copied unmodified to user level programs.
+};
+
+extern UINT g_SendPacketFlags;
+#define NDIS_FLAGS_SKIP_LOOPBACK_W2K 0x400 ///< This is an undocumented flag for NdisSetPacketFlags() that allows to disable loopback reception.
+
+#define TRANSMIT_PACKETS 2048 ///< Maximum number of packets in the transmit packet pool. This value is an upper bound to the number
+ ///< of packets that can be transmitted at the same time or with a single call to NdisSendPackets.
+
+
+/// Macro used in the I/O routines to return the control to user-mode with a success status.
+#define EXIT_SUCCESS(quantity) Irp->IoStatus.Information=quantity;\
+ Irp->IoStatus.Status = STATUS_SUCCESS;\
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);\
+ return STATUS_SUCCESS;\
+
+/// Macro used in the I/O routines to return the control to user-mode with a failure status.
+#define EXIT_FAILURE(quantity) Irp->IoStatus.Information=quantity;\
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;\
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);\
+ return STATUS_UNSUCCESSFUL;\
+
+/**
+ * @}
+ */
+
+
+/***************************/
+/* Prototypes */
+/***************************/
+
+/** @defgroup NPF_code NPF functions
+ * @{
+ */
+
+
+/*!
+ \brief The initialization routine of the driver.
+ \param DriverObject The driver object of NPF created by the system.
+ \param RegistryPath The registry path containing the keys related to the driver.
+ \return A string containing a list of network adapters.
+
+ DriverEntry is a mandatory function in a device driver. Like the main() of a user level program, it is called
+ by the system when the driver is loaded in memory and started. Its purpose is to initialize the driver,
+ performing all the allocations and the setup. In particular, DriverEntry registers all the driver's I/O
+ callbacks, creates the devices, defines NPF as a protocol inside NDIS.
+*/
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ );
+
+/*!
+ \brief Returns the list of the MACs available on the system.
+ \return A string containing a list of network adapters.
+
+ The list of adapters is retrieved from the
+ SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318} registry key.
+ NPF tries to create its bindings from this list. In this way it is possible to be loaded
+ and unloaded dynamically without passing from the control panel.
+*/
+PWCHAR getAdaptersList(VOID);
+
+/*!
+ \brief Returns the MACs that bind to TCP/IP.
+ \return Pointer to the registry key containing the list of adapters on which TCP/IP is bound.
+
+ If getAdaptersList() fails, NPF tries to obtain the TCP/IP bindings through this function.
+*/
+PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(VOID);
+
+/*!
+ \brief Creates a device for a given MAC.
+ \param adriverObjectP The driver object that will be associated with the device, i.e. the one of NPF.
+ \param amacNameP The name of the network interface that the device will point.
+ \param aProtoHandle NDIS protocol handle of NPF.
+ \return If the function succeeds, the return value is nonzero.
+
+ NPF creates a device for every valid network adapter. The new device points to the NPF driver, but contains
+ information about the original device. In this way, when the user opens the new device, NPF will be able to
+ determine the correct adapter to use.
+*/
+BOOLEAN createDevice(
+ IN OUT PDRIVER_OBJECT adriverObjectP,
+ IN PUNICODE_STRING amacNameP,
+ NDIS_HANDLE aProtoHandle);
+
+/*!
+ \brief Opens a new instance of the driver.
+ \param DeviceObject Pointer to the device object utilized by the user.
+ \param Irp Pointer to the IRP containing the user request.
+ \return The status of the operation. See ntstatus.h in the DDK.
+
+ This function is called by the OS when a new instance of the driver is opened, i.e. when a user application
+ performs a CreateFile on a device created by NPF. NPF_Open allocates and initializes variables, objects
+ and buffers needed by the new instance, fills the OPEN_INSTANCE structure associated with it and opens the
+ adapter with a call to NdisOpenAdapter.
+*/
+NTSTATUS
+NPF_Open(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ );
+
+/*!
+ \brief Ends the opening of an adapter.
+ \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
+ \param Status Status of the opening operation performed by NDIS.
+ \param OpenErrorStatus not used by NPF.
+
+ Callback function associated with the NdisOpenAdapter() NDIS function. It is invoked by NDIS when the NIC
+ driver has finished an open operation that was previously started by NPF_Open().
+*/
+VOID
+NPF_OpenAdapterComplete(
+ IN NDIS_HANDLE ProtocolBindingContext,
+ IN NDIS_STATUS Status,
+ IN NDIS_STATUS OpenErrorStatus
+ );
+
+/*!
+ \brief Closes an instance of the driver.
+ \param DeviceObject Pointer to the device object utilized by the user.
+ \param Irp Pointer to the IRP containing the user request.
+ \return The status of the operation. See ntstatus.h in the DDK.
+
+ This function is called when a running instance of the driver is closed by the user with a CloseHandle().
+ It stops the capture/monitoring/dump process, deallocates the memory and the objects associated with the
+ instance and closing the files. The network adapter is then closed with a call to NdisCloseAdapter.
+*/
+NTSTATUS
+NPF_Close(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ );
+
+/*!
+ \brief Ends the closing of an adapter.
+ \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
+ \param Status Status of the close operation performed by NDIS.
+
+ Callback function associated with the NdisCloseAdapter() NDIS function. It is invoked by NDIS when the NIC
+ driver has finished a close operation that was previously started by NPF_Close().
+*/
+VOID
+NPF_CloseAdapterComplete(
+ IN NDIS_HANDLE ProtocolBindingContext,
+ IN NDIS_STATUS Status
+ );
+
+/*!
+ \brief Callback invoked by NDIS when a packet arrives from the network.
+ \param ProtocolBindingContext Context of the function. Points to a OPEN_INSTANCE structure that identifies
+ the NPF instance to which the packets are destined.
+ \param MacReceiveContext Handle that identifies the underlying NIC driver that generated the request.
+ This value must be used when the packet is transferred from the NIC driver with NdisTransferData().
+ \param HeaderBuffer Pointer to the buffer in the NIC driver memory that contains the header of the packet.
+ \param HeaderBufferSize Size in bytes of the header.
+ \param LookAheadBuffer Pointer to the buffer in the NIC driver's memory that contains the incoming packet's
+ data <b>available to NPF</b>. This value does not necessarily coincide with the actual size of the packet,
+ since only a portion can be available at this time. The remaining portion can be obtained with the
+ NdisTransferData() NDIS function.
+ \param LookaheadBufferSize Size in bytes of the lookahead buffer.
+ \param PacketSize Total size of the incoming packet, excluded the header.
+ \return The status of the operation. See ntstatus.h in the DDK.
+
+ NPF_tap() is called by the underlying NIC for every incoming packet. It is the most important and one of
+ the most complex functions of NPF: it executes the filter, runs the statistical engine (if the instance is in
+ statistical mode), gathers the timestamp, moves the packet in the buffer. NPF_tap() is the only function,
+ along with the filtering ones, that is executed for every incoming packet, therefore it is carefully
+ optimized.
+*/
+NDIS_STATUS
+NPF_tap(
+ IN NDIS_HANDLE ProtocolBindingContext,
+ IN NDIS_HANDLE MacReceiveContext,
+ IN PVOID HeaderBuffer,
+ IN UINT HeaderBufferSize,
+ IN PVOID LookAheadBuffer,
+ IN UINT LookaheadBufferSize,
+ IN UINT PacketSize
+ );
+
+/*!
+ \brief Ends the transfer of a packet.
+ \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
+ \param Packet Pointer to the NDIS_PACKET structure that received the packet data.
+ \param Status Status of the transfer operation.
+ \param BytesTransferred Amount of bytes transferred.
+
+ Callback function associated with the NdisTransferData() NDIS function. It is invoked by NDIS when the NIC
+ driver has finished the transfer of a packet from the NIC driver memory to the NPF circular buffer.
+*/
+VOID
+NPF_TransferDataComplete(
+ IN NDIS_HANDLE ProtocolBindingContext,
+ IN PNDIS_PACKET Packet,
+ IN NDIS_STATUS Status,
+ IN UINT BytesTransferred
+ );
+
+/*!
+ \brief Callback function that signals the end of a packet reception.
+ \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
+
+ does nothing in NPF
+*/
+VOID
+NPF_ReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext);
+
+/*!
+ \brief Handles the IOCTL calls.
+ \param DeviceObject Pointer to the device object utilized by the user.
+ \param Irp Pointer to the IRP containing the user request.
+ \return The status of the operation. See ntstatus.h in the DDK.
+
+ Once the packet capture driver is opened it can be configured from user-level applications with IOCTL commands
+ using the DeviceIoControl() system call. NPF_IoControl receives and serves all the IOCTL calls directed to NPF.
+ The following commands are recognized:
+ - #BIOCSETBUFFERSIZE
+ - #BIOCSETF
+ - #BIOCGSTATS
+ - #BIOCSRTIMEOUT
+ - #BIOCSMODE
+ - #BIOCSWRITEREP
+ - #BIOCSMINTOCOPY
+ - #BIOCSETOID
+ - #BIOCQUERYOID
+ - #BIOCSETDUMPFILENAME
+ - #BIOCGEVNAME
+ - #BIOCSENDPACKETSSYNC
+ - #BIOCSENDPACKETSNOSYNC
+*/
+NTSTATUS
+NPF_IoControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ );
+
+VOID
+
+/*!
+ \brief Ends an OID request.
+ \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
+ \param pRequest Pointer to the completed OID request.
+ \param Status Status of the operation.
+
+ Callback function associated with the NdisRequest() NDIS function. It is invoked by NDIS when the NIC
+ driver has finished an OID request operation that was previously started by NPF_IoControl().
+*/
+NPF_RequestComplete(
+ IN NDIS_HANDLE ProtocolBindingContext,
+ IN PNDIS_REQUEST pRequest,
+ IN NDIS_STATUS Status
+ );
+
+/*!
+ \brief Writes a raw packet to the network.
+ \param DeviceObject Pointer to the device object on which the user wrote the packet.
+ \param Irp Pointer to the IRP containing the user request.
+ \return The status of the operation. See ntstatus.h in the DDK.
+
+ This function is called by the OS in consequence of user WriteFile() call, with the data of the packet that must
+ be sent on the net. The data is contained in the buffer associated with Irp, NPF_Write takes it and
+ delivers it to the NIC driver via the NdisSend() function. The Nwrites field of the OPEN_INSTANCE structure
+ associated with Irp indicates the number of copies of the packet that will be sent: more than one copy of the
+ packet can be sent for performance reasons.
+*/
+NTSTATUS
+NPF_Write(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ );
+
+
+/*!
+ \brief Writes a buffer of raw packets to the network.
+ \param Irp Pointer to the IRP containing the user request.
+ \param UserBuff Pointer to the buffer containing the packets to send.
+ \param UserBuffSize Size of the buffer with the packets.
+ \return The amount of bytes actually sent. If the return value is smaller than the Size parameter, an
+ error occurred during the send. The error can be caused by an adapter problem or by an
+ inconsistent/bogus user buffer.
+
+ This function is called by the OS in consequence of a BIOCSENDPACKETSNOSYNC or a BIOCSENDPACKETSSYNC IOCTL.
+ The buffer received as input parameter contains an arbitrary number of packets, each of which preceded by a
+ sf_pkthdr structure. NPF_BufferedWrite() scans the buffer and sends every packet via the NdisSend() function.
+ When Sync is set to TRUE, the packets are synchronized with the KeQueryPerformanceCounter() function.
+ This requires a remarkable amount of CPU, but allows to respect the timestamps associated with packets with a precision
+ of some microseconds (depending on the precision of the performance counter of the machine).
+ If Sync is false, the timestamps are ignored and the packets are sent as fat as possible.
+*/
+
+INT NPF_BufferedWrite(IN PIRP Irp,
+ IN PCHAR UserBuff,
+ IN ULONG UserBuffSize,
+ BOOLEAN sync);
+
+/*!
+ \brief Waits the completion of all the sends performed by NPF_BufferedWrite.
+
+ \param Open Pointer to open context structure
+
+ Used by NPF_BufferedWrite to wait the completion of all the sends before returning the control to the user.
+*/
+VOID NPF_WaitEndOfBufferedWrite(POPEN_INSTANCE Open);
+
+/*!
+ \brief Ends a send operation.
+ \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
+ \param pRequest Pointer to the NDIS PACKET structure used by NPF_Write() to send the packet.
+ \param Status Status of the operation.
+
+ Callback function associated with the NdisSend() NDIS function. It is invoked by NDIS when the NIC
+ driver has finished an OID request operation that was previously started by NPF_Write().
+*/
+VOID
+NPF_SendComplete(
+ IN NDIS_HANDLE ProtocolBindingContext,
+ IN PNDIS_PACKET pPacket,
+ IN NDIS_STATUS Status
+ );
+
+/*!
+ \brief Ends a reset of the adapter.
+ \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
+ \param Status Status of the operation.
+
+ Callback function associated with the NdisReset() NDIS function. It is invoked by NDIS when the NIC
+ driver has finished an OID request operation that was previously started by NPF_IoControl(), in an IOCTL_PROTOCOL_RESET
+ command.
+*/
+VOID
+NPF_ResetComplete(
+ IN NDIS_HANDLE ProtocolBindingContext,
+ IN NDIS_STATUS Status
+ );
+
+/*!
+ \brief Callback for NDIS StatusHandler. Not used by NPF
+*/
+VOID
+NPF_Status(
+ IN NDIS_HANDLE ProtocolBindingContext,
+ IN NDIS_STATUS Status,
+ IN PVOID StatusBuffer,
+ IN UINT StatusBufferSize
+ );
+
+
+/*!
+ \brief Callback for NDIS StatusCompleteHandler. Not used by NPF
+*/
+VOID
+NPF_StatusComplete(IN NDIS_HANDLE ProtocolBindingContext);
+
+/*!
+ \brief Function called by the OS when NPF is unloaded.
+ \param DriverObject The driver object of NPF created by the system.
+
+ This is the last function executed when the driver is unloaded from the system. It frees global resources,
+ delete the devices and deregisters the protocol. The driver can be unloaded by the user stopping the NPF
+ service (from control panel or with a console 'net stop npf').
+*/
+VOID
+NPF_Unload(IN PDRIVER_OBJECT DriverObject);
+
+
+/*!
+ \brief Function that serves the user's reads.
+ \param DeviceObject Pointer to the device used by the user.
+ \param Irp Pointer to the IRP containing the user request.
+ \return The status of the operation. See ntstatus.h in the DDK.
+
+ This function is called by the OS in consequence of user ReadFile() call. It moves the data present in the
+ kernel buffer to the user buffer associated with Irp.
+ First of all, NPF_Read checks the amount of data in kernel buffer associated with current NPF instance.
+ - If the instance is in capture mode and the buffer contains more than OPEN_INSTANCE::MinToCopy bytes,
+ NPF_Read moves the data in the user buffer and returns immediatly. In this way, the read performed by the
+ user is not blocking.
+ - If the buffer contains less than MinToCopy bytes, the application's request isn't
+ satisfied immediately, but it's blocked until at least MinToCopy bytes arrive from the net
+ or the timeout on this read expires. The timeout is kept in the OPEN_INSTANCE::TimeOut field.
+ - If the instance is in statistical mode or in dump mode, the application's request is blocked until the
+ timeout kept in OPEN_INSTANCE::TimeOut expires.
+*/
+NTSTATUS
+NPF_Read(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ );
+
+/*!
+ \brief Reads the registry keys associated woth NPF if the driver is manually installed via the control panel.
+
+ Normally not used in recent versions of NPF.
+*/
+NTSTATUS
+NPF_ReadRegistry(
+ IN PWSTR *MacDriverName,
+ IN PWSTR *PacketDriverName,
+ IN PUNICODE_STRING RegistryPath
+ );
+
+/*!
+ \brief Function used by NPF_ReadRegistry() to quesry the registry keys associated woth NPF if the driver
+ is manually installed via the control panel.
+
+ Normally not used in recent versions of NPF.
+*/
+NTSTATUS
+NPF_QueryRegistryRoutine(
+ IN PWSTR ValueName,
+ IN ULONG ValueType,
+ IN PVOID ValueData,
+ IN ULONG ValueLength,
+ IN PVOID Context,
+ IN PVOID EntryContext
+ );
+
+/*!
+ \brief Callback for NDIS BindAdapterHandler. Not used by NPF.
+
+ Function called by NDIS when a new adapter is installed on the machine With Plug and Play.
+*/
+VOID NPF_BindAdapter(
+ OUT PNDIS_STATUS Status,
+ IN NDIS_HANDLE BindContext,
+ IN PNDIS_STRING DeviceName,
+ IN PVOID SystemSpecific1,
+ IN PVOID SystemSpecific2
+ );
+
+/*!
+ \brief Callback for NDIS UnbindAdapterHandler.
+ \param Status out variable filled by NPF_UnbindAdapter with the status of the unbind operation.
+ \param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with current instance.
+ \param UnbindContext Specifies a handle, supplied by NDIS, that NPF can use to complete the opration.
+
+ Function called by NDIS when a new adapter is removed from the machine without shutting it down.
+ NPF_UnbindAdapter closes the adapter calling NdisCloseAdapter() and frees the memory and the structures
+ associated with it. It also releases the waiting user-level app and closes the dump thread if the instance
+ is in dump mode.
+*/
+VOID
+NPF_UnbindAdapter(
+ OUT PNDIS_STATUS Status,
+ IN NDIS_HANDLE ProtocolBindingContext,
+ IN NDIS_HANDLE UnbindContext
+ );
+
+
+/*!
+ \brief Creates the file that will receive the packets when the driver is in dump mode.
+ \param Open The NPF instance that opens the file.
+ \param fileName Pointer to a UNICODE string containing the name of the file.
+ \param append Boolean value that specifies if the data must be appended to the file.
+ \return The status of the operation. See ntstatus.h in the DDK.
+*/
+NTSTATUS NPF_OpenDumpFile(POPEN_INSTANCE Open , PUNICODE_STRING fileName, BOOLEAN append);
+
+/*!
+ \brief Starts dump to file.
+ \param Open The NPF instance that opens the file.
+ \return The status of the operation. See ntstatus.h in the DDK.
+
+ This function performs two operations. First, it writes the libpcap header at the beginning of the file.
+ Second, it starts the thread that asynchronously dumps the network data to the file.
+*/
+NTSTATUS NPF_StartDump(POPEN_INSTANCE Open);
+
+/*!
+ \brief The dump thread.
+ \param Open The NPF instance that creates the thread.
+
+ This function moves the content of the NPF kernel buffer to file. It runs in the user context, so at lower
+ priority than the TAP.
+*/
+VOID NPF_DumpThread(PVOID Open);
+
+/*!
+ \brief Saves the content of the packet buffer to the file associated with current instance.
+ \param Open The NPF instance that creates the thread.
+
+ Used by NPF_DumpThread() and NPF_CloseDumpFile().
+*/
+NTSTATUS NPF_SaveCurrentBuffer(POPEN_INSTANCE Open);
+
+/*!
+ \brief Writes a block of packets on the dump file.
+ \param FileObject The file object that will receive the packets.
+ \param Offset The offset in the file where the packets will be put.
+ \param Length The amount of bytes to write.
+ \param Mdl MDL mapping the memory buffer that will be written to disk.
+ \param IoStatusBlock Used by the function to return the status of the operation.
+ \return The status of the operation. See ntstatus.h in the DDK.
+
+ NPF_WriteDumpFile addresses directly the file system, creating a custom IRP and using it to send a portion
+ of the NPF circular buffer to disk. This function is used by NPF_DumpThread().
+*/
+VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject,
+ PLARGE_INTEGER Offset,
+ ULONG Length,
+ PMDL Mdl,
+ PIO_STATUS_BLOCK IoStatusBlock);
+
+
+
+/*!
+ \brief Closes the dump file associated with an instance of the driver.
+ \param Open The NPF instance that closes the file.
+ \return The status of the operation. See ntstatus.h in the DDK.
+*/
+NTSTATUS NPF_CloseDumpFile(POPEN_INSTANCE Open);
+
+/*!
+ \brief Returns the amount of bytes present in the packet buffer.
+ \param Open The NPF instance that closes the file.
+*/
+UINT GetBuffOccupation(POPEN_INSTANCE Open);
+
+/*!
+ \brief Called by NDIS to notify us of a PNP event. The most significant one for us is power state change.
+
+ \param ProtocolBindingContext Pointer to open context structure. This is NULL for global reconfig
+ events.
+ \param pNetPnPEvent Pointer to the PnP event
+
+ If there is a power state change, the driver is forced to resynchronize the global timer.
+ This hopefully avoids the synchronization issues caused by hibernation or standby.
+ This function is excluded from the NT4 driver, where PnP is not supported
+*/
+#ifdef NDIS50
+NDIS_STATUS NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent);
+#endif
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /*main ifndef/define*/