📄 packet.h
字号:
///< See BPF_jitter() for details.
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
UINT 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.
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[32]; ///< 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
}
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.
};
#define TRANSMIT_PACKETS 256 ///< 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -