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