WinPcap  4.1.2
Packet.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
00003  * Copyright (c) 2005 - 2010 CACE Technologies, Davis (California)
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright
00011  * notice, this list of conditions and the following disclaimer.
00012  * 2. Redistributions in binary form must reproduce the above copyright
00013  * notice, this list of conditions and the following disclaimer in the
00014  * documentation and/or other materials provided with the distribution.
00015  * 3. Neither the name of the Politecnico di Torino, CACE Technologies 
00016  * nor the names of its contributors may be used to endorse or promote 
00017  * products derived from this software without specific prior written 
00018  * permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00023  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00024  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00025  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00026  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00027  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00028  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00030  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  *
00032  */
00033 
00042 #ifndef __PACKET_INCLUDE______
00043 #define __PACKET_INCLUDE______
00044 
00045 #if !defined(NDIS30) && !defined(NDIS50)
00046 #error NDIS30 or NDIS50 should be defined
00047 #endif
00048 
00049 #ifdef _X86_
00050 #define NTKERNEL    ///< Forces the compilation of the jitter with kernel calls 
00051 #include "jitter.h"
00052 #endif
00053 
00054 #ifdef HAVE_BUGGY_TME_SUPPORT
00055 #ifndef _X86_
00056 #error TME support is available only on x86 architectures
00057 #endif // _X86_
00058 #endif //HAVE_BUGGY_TME_SUPPORT
00059 
00060 
00061 //
00062 // Needed to disable a warning due to the #pragma prefast directives,
00063 // that are ignored by the normal DDK compiler
00064 //
00065 #ifndef _PREFAST_
00066 #pragma warning(disable:4068)
00067 #endif
00068 
00069 #include "win_bpf.h"
00070 
00071 #define  MAX_REQUESTS   32 ///< Maximum number of simultaneous IOCTL requests.
00072 
00073 #define Packet_ALIGNMENT sizeof(int) ///< Alignment macro. Defines the alignment size.
00074 #define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1))  ///< Alignment macro. Rounds up to the next 
00075 
00076 
00077 #define KERNEL_EVENT_NAMESPACE L"\\BaseNamedObjects\\"
00078 
00079 
00080 // Working modes
00081 #define MODE_CAPT 0x0       ///< Capture working mode
00082 #define MODE_STAT 0x1       ///< Statistical working mode
00083 #define MODE_MON  0x2       ///< Kernel monitoring mode
00084 #define MODE_DUMP 0x10      ///< Kernel dump working mode
00085 
00086 
00087 #define IMMEDIATE 1         ///< Immediate timeout. Forces a read call to return immediately.
00088 
00089 #define NDIS_FLAGS_SKIP_LOOPBACK_W2K    0x400 ///< This is an undocumented flag for NdisSetPacketFlags() that allows to disable loopback reception.
00090 
00091 // The following definitions are used to provide compatibility 
00092 // of the dump files with the ones of libpcap
00093 #define TCPDUMP_MAGIC 0xa1b2c3d4    ///< Libpcap magic number. Used by programs like tcpdump to recognize a driver's generated dump file.
00094 #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.
00095 #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.
00096 
00097 // Loopback behaviour definitions
00098 #define NPF_DISABLE_LOOPBACK    1   ///< Tells the driver to drop the packets sent by itself. This is usefult when building applications like bridges.
00099 #define NPF_ENABLE_LOOPBACK     2   ///< Tells the driver to capture the packets sent by itself.
00100 
00106 struct packet_file_header 
00107 {
00108     UINT magic;             
00109     USHORT version_major;   
00110     USHORT version_minor;   
00111     UINT thiszone;          
00112     UINT sigfigs;           
00113     UINT snaplen;           
00114     UINT linktype;          
00115 };
00116 
00121 struct sf_pkthdr {
00122     struct timeval  ts;         
00123     UINT            caplen;     
00124 
00125 
00126     UINT            len;        
00127 };
00128 
00129 //
00130 // NT4 DDK doesn't have C_ASSERT
00131 //
00132 #ifndef C_ASSERT
00133 #define C_ASSERT(a)
00134 #endif
00135 
00143 typedef struct _PACKET_OID_DATA {
00144     ULONG Oid;                  
00145 
00146     ULONG Length;               
00147     UCHAR Data[1];              
00148 
00149 }
00150     PACKET_OID_DATA, *PPACKET_OID_DATA;
00151 
00152 C_ASSERT(sizeof(PACKET_OID_DATA) == 12);
00153 
00163 typedef struct _INTERNAL_REQUEST {
00164     LIST_ENTRY      ListElement;        
00165 //    PIRP          Irp;                ///< Irp that performed the request
00166 //  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.
00167     NDIS_EVENT      InternalRequestCompletedEvent;
00168     NDIS_REQUEST    Request;            
00169     NDIS_STATUS     RequestStatus;
00170 
00171 } INTERNAL_REQUEST, *PINTERNAL_REQUEST;
00172 
00180 typedef struct _PACKET_RESERVED {
00181     LIST_ENTRY      ListElement;        
00182     PIRP            Irp;                
00183     PMDL            pMdl;               
00184     BOOLEAN         FreeBufAfterWrite;  
00185 
00186     ULONG           Cpu;                
00187 }  PACKET_RESERVED, *PPACKET_RESERVED;
00188 
00189 #define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved)) ///< Macro to obtain a NDIS_PACKET from a PACKET_RESERVED
00190 
00196 typedef struct _DEVICE_EXTENSION {
00197     NDIS_STRING    AdapterName;         
00198     PWSTR          ExportString;        
00199 
00200 } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
00201 
00207 typedef struct __CPU_Private_Data
00208 {
00209     ULONG   P;                  
00210     ULONG   C;                  
00211     ULONG   Free;               
00212     PUCHAR  Buffer;             
00213     ULONG   Accepted;           
00214 
00215 
00216 
00217     ULONG   Received;           
00218 
00219 
00220 
00221     ULONG   Dropped;            
00222 
00223 
00224 
00225     NDIS_SPIN_LOCK BufferLock;  
00226     PMDL    TransferMdl1;       
00227     PMDL    TransferMdl2;       
00228     ULONG   NewP;               
00229 }
00230     CpuPrivateData;
00231 
00232 
00240 typedef struct _OPEN_INSTANCE
00241 {
00242     PDEVICE_EXTENSION   DeviceExtension;    
00243 
00244     NDIS_HANDLE         AdapterHandle;      
00245     UINT                Medium;             
00246 
00247     NDIS_HANDLE         PacketPool;         
00248     KSPIN_LOCK          RequestSpinLock;    
00249     LIST_ENTRY          RequestList;        
00250     LIST_ENTRY          ResetIrpList;       
00251     INTERNAL_REQUEST    Requests[MAX_REQUESTS]; 
00252     PMDL                BufferMdl;          
00253     PKEVENT             ReadEvent;          
00254     PUCHAR              bpfprogram;         
00255 
00256 
00257 
00258 
00259 #ifdef _X86_
00260     JIT_BPF_Filter      *Filter;            
00261 
00262 #endif //_X86_
00263     UINT                MinToCopy;          
00264 
00265     LARGE_INTEGER       TimeOut;            
00266 
00267                                             
00268     int                 mode;               
00269     LARGE_INTEGER       Nbytes;             
00270     LARGE_INTEGER       Npackets;           
00271     NDIS_SPIN_LOCK      CountersLock;       
00272     UINT                Nwrites;            
00273 
00274     ULONG               Multiple_Write_Counter; 
00275     NDIS_EVENT          WriteEvent;         
00276     BOOLEAN             WriteInProgress;    
00277 
00278     NDIS_SPIN_LOCK      WriteLock;          
00279     NDIS_EVENT          NdisRequestEvent;   
00280     BOOLEAN             SkipSentPackets;    
00281     NDIS_STATUS         IOStatus;           
00282     HANDLE              DumpFileHandle;     
00283     PFILE_OBJECT        DumpFileObject;     
00284     PKTHREAD            DumpThreadObject;   
00285     HANDLE              DumpThreadHandle;   
00286     NDIS_EVENT          DumpEvent;          
00287     LARGE_INTEGER       DumpOffset;         
00288     UNICODE_STRING      DumpFileName;       
00289     UINT                MaxDumpBytes;       
00290 
00291     UINT                MaxDumpPacks;       
00292 
00293 
00294     BOOLEAN             DumpLimitReached;   
00295 
00296 #ifdef HAVE_BUGGY_TME_SUPPORT
00297     MEM_TYPE            mem_ex;             
00298     TME_CORE            tme;                
00299 #endif //HAVE_BUGGY_TME_SUPPORT
00300 
00301     NDIS_SPIN_LOCK      MachineLock;        
00302     UINT                MaxFrameSize;       
00303 
00304     //
00305     // KAFFINITY is used as a bit mask for the affinity in the system. So on every supported OS is big enough for all the CPUs on the system (32 bits on x86, 64 on x64?).
00306     // We use its size to compute the max number of CPUs.
00307     //
00308     CpuPrivateData      CpuData[sizeof(KAFFINITY) * 8];     
00309     ULONG               ReaderSN;           
00310     ULONG               WriterSN;           
00311 
00312     ULONG               Size;               
00313     ULONG              AdapterHandleUsageCounter;
00314     NDIS_SPIN_LOCK     AdapterHandleLock;
00315     ULONG              AdapterBindingStatus;    
00316 
00317     NDIS_EVENT         NdisOpenCloseCompleteEvent;
00318     NDIS_EVENT         NdisWriteCompleteEvent;  
00319     NTSTATUS           OpenCloseStatus;
00320     ULONG              TransmitPendingPackets;  
00321     ULONG              NumPendingIrps;
00322     BOOLEAN            ClosePending; 
00323     NDIS_SPIN_LOCK     OpenInUseLock;
00324 }
00325 OPEN_INSTANCE, *POPEN_INSTANCE;
00326 
00327 enum ADAPTER_BINDING_STATUS
00328 {
00329     ADAPTER_UNBOUND,
00330     ADAPTER_BOUND,
00331     ADAPTER_UNBINDING,
00332 };
00333 
00341 struct PacketHeader
00342 {
00343     ULONG SN;                               
00344     struct bpf_hdr header;                  
00345 };
00346 
00347 extern ULONG        g_NCpu;
00348 extern NDIS_HANDLE  g_NdisProtocolHandle;
00349 extern struct time_conv G_Start_Time; // from openclos.c
00350 extern UINT         g_SendPacketFlags;
00351 
00352 #define TRANSMIT_PACKETS 256    ///< Maximum number of packets in the transmit packet pool. This value is an upper bound to the number
00353 
00354 
00355 
00357 #define EXIT_SUCCESS(quantity) Irp->IoStatus.Information=quantity;\
00358     Irp->IoStatus.Status = STATUS_SUCCESS;\
00359     IoCompleteRequest(Irp, IO_NO_INCREMENT);\
00360     return STATUS_SUCCESS;\
00361 
00362 
00363 #define EXIT_FAILURE(quantity) Irp->IoStatus.Information=quantity;\
00364     Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;\
00365     IoCompleteRequest(Irp, IO_NO_INCREMENT);\
00366     return STATUS_UNSUCCESSFUL;\
00367 
00368 
00373 /***************************/
00374 /*       Prototypes        */
00375 /***************************/
00376 
00393 NTSTATUS
00394 DriverEntry(
00395     IN PDRIVER_OBJECT DriverObject,
00396     IN PUNICODE_STRING RegistryPath
00397     );
00398 
00408 PWCHAR getAdaptersList(VOID);
00409 
00416 PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(VOID);
00417 
00428 BOOLEAN NPF_CreateDevice(
00429     IN OUT PDRIVER_OBJECT adriverObjectP,
00430     IN PUNICODE_STRING amacNameP
00431     );
00443 NTSTATUS
00444 NPF_Open(
00445     IN PDEVICE_OBJECT DeviceObject,
00446     IN PIRP Irp
00447     );
00448 
00458 VOID
00459 NPF_OpenAdapterComplete(
00460     IN NDIS_HANDLE  ProtocolBindingContext,
00461     IN NDIS_STATUS  Status,
00462     IN NDIS_STATUS  OpenErrorStatus
00463     );
00464 
00475 NTSTATUS
00476 NPF_Cleanup(
00477     IN PDEVICE_OBJECT DeviceObject,
00478     IN PIRP Irp
00479     );
00480 
00481 NTSTATUS
00482 NPF_Close(
00483     IN PDEVICE_OBJECT DeviceObject,
00484     IN PIRP Irp
00485     );
00486 
00487 
00488 
00497 VOID
00498 NPF_CloseAdapterComplete(
00499     IN NDIS_HANDLE  ProtocolBindingContext,
00500     IN NDIS_STATUS  Status
00501     );
00502 
00525 NDIS_STATUS
00526 NPF_tap(
00527     IN NDIS_HANDLE ProtocolBindingContext,
00528     IN NDIS_HANDLE MacReceiveContext,
00529     IN PVOID HeaderBuffer,
00530     IN UINT HeaderBufferSize,
00531     IN PVOID LookAheadBuffer,
00532     IN UINT LookaheadBufferSize,
00533     IN UINT PacketSize
00534     );
00535 
00546 VOID
00547 NPF_TransferDataComplete(
00548     IN NDIS_HANDLE ProtocolBindingContext,
00549     IN PNDIS_PACKET Packet,
00550     IN NDIS_STATUS Status,
00551     IN UINT BytesTransferred
00552     );
00553 
00560 VOID
00561 NPF_ReceiveComplete(IN NDIS_HANDLE  ProtocolBindingContext);
00562 
00586 NTSTATUS
00587 NPF_IoControl(
00588     IN PDEVICE_OBJECT DeviceObject,
00589     IN PIRP Irp
00590     );
00591 
00592 VOID
00593 
00603 NPF_RequestComplete(
00604     IN NDIS_HANDLE   ProtocolBindingContext,
00605     IN PNDIS_REQUEST pRequest,
00606     IN NDIS_STATUS   Status
00607     );
00608 
00621 NTSTATUS
00622 NPF_Write(
00623             IN PDEVICE_OBJECT DeviceObject,
00624             IN PIRP Irp
00625             );
00626 
00627 
00647 INT NPF_BufferedWrite(IN PIRP Irp, 
00648                         IN PCHAR UserBuff, 
00649                         IN ULONG UserBuffSize,
00650                         BOOLEAN sync);
00651 
00659 VOID NPF_WaitEndOfBufferedWrite(POPEN_INSTANCE Open);
00660 
00670 VOID
00671 NPF_SendComplete(
00672     IN NDIS_HANDLE   ProtocolBindingContext,
00673     IN PNDIS_PACKET  pPacket,
00674     IN NDIS_STATUS   Status
00675     );
00676 
00686 VOID
00687 NPF_ResetComplete(
00688     IN NDIS_HANDLE  ProtocolBindingContext,
00689     IN NDIS_STATUS  Status
00690     );
00691 
00695 VOID
00696 NPF_Status(
00697     IN NDIS_HANDLE   ProtocolBindingContext,
00698     IN NDIS_STATUS   Status,
00699     IN PVOID         StatusBuffer,
00700     IN UINT          StatusBufferSize
00701     );
00702 
00703 
00707 VOID
00708 NPF_StatusComplete(IN NDIS_HANDLE  ProtocolBindingContext);
00709 
00718 VOID
00719 NPF_Unload(IN PDRIVER_OBJECT DriverObject);
00720 
00721 
00740 NTSTATUS
00741 NPF_Read(
00742     IN PDEVICE_OBJECT DeviceObject,
00743     IN PIRP Irp
00744     );
00745 
00751 NTSTATUS
00752 NPF_ReadRegistry(
00753     IN  PWSTR              *MacDriverName,
00754     IN  PWSTR              *PacketDriverName,
00755     IN  PUNICODE_STRING     RegistryPath
00756     );
00757 
00764 NTSTATUS
00765 NPF_QueryRegistryRoutine(
00766     IN PWSTR     ValueName,
00767     IN ULONG     ValueType,
00768     IN PVOID     ValueData,
00769     IN ULONG     ValueLength,
00770     IN PVOID     Context,
00771     IN PVOID     EntryContext
00772     );
00773 
00779 VOID NPF_BindAdapter(
00780     OUT PNDIS_STATUS            Status,
00781     IN  NDIS_HANDLE             BindContext,
00782     IN  PNDIS_STRING            DeviceName,
00783     IN  PVOID                   SystemSpecific1,
00784     IN  PVOID                   SystemSpecific2
00785     );
00786 
00798 VOID
00799 NPF_UnbindAdapter(
00800     OUT PNDIS_STATUS        Status,
00801     IN  NDIS_HANDLE         ProtocolBindingContext,
00802     IN  NDIS_HANDLE         UnbindContext
00803     );
00804 
00805 
00813 NTSTATUS NPF_OpenDumpFile(POPEN_INSTANCE Open , PUNICODE_STRING fileName, BOOLEAN append);
00814 
00823 NTSTATUS NPF_StartDump(POPEN_INSTANCE Open);
00824 
00832 VOID NPF_DumpThread(PVOID Open);
00833 
00840 NTSTATUS NPF_SaveCurrentBuffer(POPEN_INSTANCE Open);
00841 
00854 VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject,
00855                                 PLARGE_INTEGER Offset,
00856                                 ULONG Length,
00857                                 PMDL Mdl,
00858                                 PIO_STATUS_BLOCK IoStatusBlock);
00859 
00860 
00861 
00867 NTSTATUS NPF_CloseDumpFile(POPEN_INSTANCE Open);
00868 
00869 BOOLEAN
00870 NPF_StartUsingBinding(
00871     IN POPEN_INSTANCE pOpen);
00872 
00873 VOID
00874 NPF_StopUsingBinding(
00875     IN POPEN_INSTANCE pOpen);
00876 
00877 VOID
00878 NPF_CloseBinding(
00879     IN POPEN_INSTANCE pOpen);
00880 
00881 BOOLEAN 
00882 NPF_StartUsingOpenInstance(
00883                    IN POPEN_INSTANCE pOpen);
00884 
00885 VOID
00886 NPF_StopUsingOpenInstance(
00887                    IN POPEN_INSTANCE pOpen);
00888 
00889 VOID
00890 NPF_CloseOpenInstance(
00891                    IN POPEN_INSTANCE pOpen);
00892             
00893 NTSTATUS
00894 NPF_GetDeviceMTU(
00895              IN POPEN_INSTANCE pOpen,
00896              IN PIRP    pIrp,
00897              OUT PUINT  pMtu);
00898 
00903 UINT GetBuffOccupation(POPEN_INSTANCE Open);
00904 
00916 #ifdef NDIS50
00917 NDIS_STATUS NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent);
00918 #endif
00919 
00920 //  
00921 //  Old registry based WinPcap names
00922 //
00924 //  \brief Helper function to query a value from the global WinPcap registry key
00925 //*/
00926 //VOID NPF_QueryWinpcapRegistryString(PWSTR SubKeyName,
00927 //                               WCHAR *Value,
00928 //                               UINT ValueLen, 
00929 //                               WCHAR *DefaultValue);
00930 //
00931 
00932 
00941 #endif  /*main ifndef/define*/

documentation. Copyright (c) 2002-2005 Politecnico di Torino. Copyright (c) 2005-2009 CACE Technologies. All rights reserved.