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