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