Packet.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
00003  * Copyright (c) 2005 - 2007 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 #ifdef _X86_
00046 #define NTKERNEL    
00047 #include "jitter.h"
00048 #endif
00049 
00050 #ifdef HAVE_BUGGY_TME_SUPPORT
00051 #ifndef _X86_
00052 #error TME support is available only on x86 architectures
00053 #endif // _X86_
00054 #endif //HAVE_BUGGY_TME_SUPPORT
00055 
00056 
00057 //
00058 // Needed to disable a warning due to the #pragma prefast directives,
00059 // that are ignored by the normal DDK compiler
00060 //
00061 #ifndef _PREFAST_
00062 #pragma warning(disable:4068)
00063 #endif
00064 
00065 #include "win_bpf.h"
00066 
00067 #define  MAX_REQUESTS   32 
00068 
00069 #define Packet_ALIGNMENT sizeof(int) 
00070 #define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1))  
00071 
00072 
00073 #define KERNEL_EVENT_NAMESPACE L"\\BaseNamedObjects\\"
00074 
00075 
00076 // Working modes
00077 #define MODE_CAPT 0x0       
00078 #define MODE_STAT 0x1       
00079 #define MODE_MON  0x2       
00080 #define MODE_DUMP 0x10      
00081 
00082 
00083 #define IMMEDIATE 1         
00084 
00085 #define NDIS_FLAGS_SKIP_LOOPBACK_W2K    0x400 
00086 
00087 // The following definitions are used to provide compatibility 
00088 // of the dump files with the ones of libpcap
00089 #define TCPDUMP_MAGIC 0xa1b2c3d4    
00090 #define PCAP_VERSION_MAJOR 2        
00091 #define PCAP_VERSION_MINOR 4        
00092 
00093 // Loopback behaviour definitions
00094 #define NPF_DISABLE_LOOPBACK    1   
00095 #define NPF_ENABLE_LOOPBACK     2   
00096 
00097 
00102 struct packet_file_header 
00103 {
00104     UINT magic;             
00105     USHORT version_major;   
00106     USHORT version_minor;   
00107     UINT thiszone;          
00108     UINT sigfigs;           
00109     UINT snaplen;           
00110     UINT linktype;          
00111 };
00112 
00117 struct sf_pkthdr {
00118     struct timeval  ts;         
00119     UINT            caplen;     
00120 
00121 
00122     UINT            len;        
00123 };
00124 
00125 //
00126 // NT4 DDK doesn't have C_ASSERT
00127 //
00128 #ifndef C_ASSERT
00129 #define C_ASSERT(a)
00130 #endif
00131 
00139 typedef struct _PACKET_OID_DATA {
00140     ULONG Oid;                  
00141 
00142     ULONG Length;               
00143     UCHAR Data[1];              
00144 
00145 }
00146     PACKET_OID_DATA, *PPACKET_OID_DATA;
00147 
00148 C_ASSERT(sizeof(PACKET_OID_DATA) == 12);
00149 
00159 typedef struct _INTERNAL_REQUEST {
00160     LIST_ENTRY      ListElement;        
00161 //    PIRP          Irp;                ///< Irp that performed the request
00162 //  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.
00163     NDIS_EVENT      InternalRequestCompletedEvent;
00164     NDIS_REQUEST    Request;            
00165     NDIS_STATUS     RequestStatus;
00166 
00167 } INTERNAL_REQUEST, *PINTERNAL_REQUEST;
00168 
00176 typedef struct _PACKET_RESERVED {
00177     LIST_ENTRY      ListElement;        
00178     PIRP            Irp;                
00179     PMDL            pMdl;               
00180     BOOLEAN         FreeBufAfterWrite;  
00181 
00182     ULONG           Cpu;                
00183 }  PACKET_RESERVED, *PPACKET_RESERVED;
00184 
00185 #define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved)) 
00186 
00187 
00192 typedef struct _DEVICE_EXTENSION {
00193     NDIS_HANDLE    NdisProtocolHandle;  
00194     NDIS_STRING    AdapterName;         
00195     PWSTR          ExportString;        
00196 
00197 } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
00198 
00204 typedef struct __CPU_Private_Data
00205 {
00206     ULONG   P;                  
00207     ULONG   C;                  
00208     ULONG   Free;               
00209     PUCHAR  Buffer;             
00210     ULONG   Accepted;           
00211 
00212 
00213 
00214     ULONG   Received;           
00215 
00216 
00217 
00218     ULONG   Dropped;            
00219 
00220 
00221 
00222     NDIS_SPIN_LOCK BufferLock;  
00223     PMDL    TransferMdl1;       
00224     PMDL    TransferMdl2;       
00225     ULONG   NewP;               
00226 }
00227     CpuPrivateData;
00228 
00229 
00237 typedef struct _OPEN_INSTANCE
00238 {
00239     PDEVICE_EXTENSION   DeviceExtension;    
00240 
00241     NDIS_HANDLE         AdapterHandle;      
00242     UINT                Medium;             
00243 
00244     NDIS_HANDLE         PacketPool;         
00245     KSPIN_LOCK          RequestSpinLock;    
00246     LIST_ENTRY          RequestList;        
00247     LIST_ENTRY          ResetIrpList;       
00248     INTERNAL_REQUEST    Requests[MAX_REQUESTS]; 
00249     PMDL                BufferMdl;          
00250     PKEVENT             ReadEvent;          
00251     PUCHAR              bpfprogram;         
00252 
00253 
00254 
00255 
00256 #ifdef _X86_
00257     JIT_BPF_Filter      *Filter;            
00258 
00259 #endif //_X86_
00260     UINT                MinToCopy;          
00261 
00262     LARGE_INTEGER       TimeOut;            
00263 
00264                                             
00265     int                 mode;               
00266     LARGE_INTEGER       Nbytes;             
00267     LARGE_INTEGER       Npackets;           
00268     NDIS_SPIN_LOCK      CountersLock;       
00269     UINT                Nwrites;            
00270 
00271     ULONG               Multiple_Write_Counter; 
00272     NDIS_EVENT          WriteEvent;         
00273     BOOLEAN             WriteInProgress;    
00274 
00275     NDIS_SPIN_LOCK      WriteLock;          
00276     NDIS_EVENT          NdisRequestEvent;   
00277     BOOLEAN             SkipSentPackets;    
00278     NDIS_STATUS         IOStatus;           
00279     HANDLE              DumpFileHandle;     
00280     PFILE_OBJECT        DumpFileObject;     
00281     PKTHREAD            DumpThreadObject;   
00282     HANDLE              DumpThreadHandle;   
00283     NDIS_EVENT          DumpEvent;          
00284     LARGE_INTEGER       DumpOffset;         
00285     UNICODE_STRING      DumpFileName;       
00286     UINT                MaxDumpBytes;       
00287 
00288     UINT                MaxDumpPacks;       
00289 
00290 
00291     BOOLEAN             DumpLimitReached;   
00292 
00293 #ifdef HAVE_BUGGY_TME_SUPPORT
00294     MEM_TYPE            mem_ex;             
00295     TME_CORE            tme;                
00296 #endif //HAVE_BUGGY_TME_SUPPORT
00297 
00298     NDIS_SPIN_LOCK      MachineLock;        
00299     UINT                MaxFrameSize;       
00300 
00301     //
00302     // 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?).
00303     // We use its size to compute the max number of CPUs.
00304     //
00305     CpuPrivateData      CpuData[sizeof(KAFFINITY) * 8];     
00306     ULONG               ReaderSN;           
00307     ULONG               WriterSN;           
00308 
00309     ULONG               Size;               
00310     ULONG              AdapterHandleUsageCounter;
00311     NDIS_SPIN_LOCK     AdapterHandleLock;
00312     ULONG              AdapterBindingStatus;    
00313 
00314     NDIS_EVENT         NdisOpenCloseCompleteEvent;
00315     NDIS_EVENT         NdisWriteCompleteEvent;  
00316     NTSTATUS           OpenCloseStatus;
00317     ULONG              TransmitPendingPackets;  
00318 }
00319 OPEN_INSTANCE, *POPEN_INSTANCE;
00320 
00321 enum ADAPTER_BINDING_STATUS
00322 {
00323     ADAPTER_UNBOUND,
00324     ADAPTER_BOUND,
00325     ADAPTER_UNBINDING,
00326 };
00327 
00335 struct PacketHeader
00336 {
00337     ULONG SN;                               
00338     struct bpf_hdr header;                  
00339 };
00340 
00341 extern ULONG NCpu;
00342 
00343 
00344 #define TRANSMIT_PACKETS 256    
00345 
00346 
00347 
00349 #define EXIT_SUCCESS(quantity) Irp->IoStatus.Information=quantity;\
00350     Irp->IoStatus.Status = STATUS_SUCCESS;\
00351     IoCompleteRequest(Irp, IO_NO_INCREMENT);\
00352     return STATUS_SUCCESS;\
00353 
00355 #define EXIT_FAILURE(quantity) Irp->IoStatus.Information=quantity;\
00356     Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;\
00357     IoCompleteRequest(Irp, IO_NO_INCREMENT);\
00358     return STATUS_UNSUCCESSFUL;\
00359 
00360 
00365 /***************************/
00366 /*       Prototypes        */
00367 /***************************/
00368 
00385 NTSTATUS
00386 DriverEntry(
00387     IN PDRIVER_OBJECT DriverObject,
00388     IN PUNICODE_STRING RegistryPath
00389     );
00390 
00400 PWCHAR getAdaptersList(VOID);
00401 
00408 PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(VOID);
00409 
00421 BOOLEAN createDevice(
00422     IN OUT PDRIVER_OBJECT adriverObjectP,
00423     IN PUNICODE_STRING amacNameP,
00424     NDIS_HANDLE aProtoHandle);
00425 
00437 NTSTATUS
00438 NPF_Open(
00439     IN PDEVICE_OBJECT DeviceObject,
00440     IN PIRP Irp
00441     );
00442 
00452 VOID
00453 NPF_OpenAdapterComplete(
00454     IN NDIS_HANDLE  ProtocolBindingContext,
00455     IN NDIS_STATUS  Status,
00456     IN NDIS_STATUS  OpenErrorStatus
00457     );
00458 
00469 NTSTATUS
00470 NPF_Cleanup(
00471     IN PDEVICE_OBJECT DeviceObject,
00472     IN PIRP Irp
00473     );
00474 
00475 NTSTATUS
00476 NPF_Close(
00477     IN PDEVICE_OBJECT DeviceObject,
00478     IN PIRP Irp
00479     );
00480 
00481 
00482 
00491 VOID
00492 NPF_CloseAdapterComplete(
00493     IN NDIS_HANDLE  ProtocolBindingContext,
00494     IN NDIS_STATUS  Status
00495     );
00496 
00519 NDIS_STATUS
00520 NPF_tap(
00521     IN NDIS_HANDLE ProtocolBindingContext,
00522     IN NDIS_HANDLE MacReceiveContext,
00523     IN PVOID HeaderBuffer,
00524     IN UINT HeaderBufferSize,
00525     IN PVOID LookAheadBuffer,
00526     IN UINT LookaheadBufferSize,
00527     IN UINT PacketSize
00528     );
00529 
00540 VOID
00541 NPF_TransferDataComplete(
00542     IN NDIS_HANDLE ProtocolBindingContext,
00543     IN PNDIS_PACKET Packet,
00544     IN NDIS_STATUS Status,
00545     IN UINT BytesTransferred
00546     );
00547 
00554 VOID
00555 NPF_ReceiveComplete(IN NDIS_HANDLE  ProtocolBindingContext);
00556 
00580 NTSTATUS
00581 NPF_IoControl(
00582     IN PDEVICE_OBJECT DeviceObject,
00583     IN PIRP Irp
00584     );
00585 
00586 VOID
00587 
00597 NPF_RequestComplete(
00598     IN NDIS_HANDLE   ProtocolBindingContext,
00599     IN PNDIS_REQUEST pRequest,
00600     IN NDIS_STATUS   Status
00601     );
00602 
00615 NTSTATUS
00616 NPF_Write(
00617             IN PDEVICE_OBJECT DeviceObject,
00618             IN PIRP Irp
00619             );
00620 
00621 
00641 INT NPF_BufferedWrite(IN PIRP Irp, 
00642                         IN PCHAR UserBuff, 
00643                         IN ULONG UserBuffSize,
00644                         BOOLEAN sync);
00645 
00653 VOID NPF_WaitEndOfBufferedWrite(POPEN_INSTANCE Open);
00654 
00664 VOID
00665 NPF_SendComplete(
00666     IN NDIS_HANDLE   ProtocolBindingContext,
00667     IN PNDIS_PACKET  pPacket,
00668     IN NDIS_STATUS   Status
00669     );
00670 
00680 VOID
00681 NPF_ResetComplete(
00682     IN NDIS_HANDLE  ProtocolBindingContext,
00683     IN NDIS_STATUS  Status
00684     );
00685 
00689 VOID
00690 NPF_Status(
00691     IN NDIS_HANDLE   ProtocolBindingContext,
00692     IN NDIS_STATUS   Status,
00693     IN PVOID         StatusBuffer,
00694     IN UINT          StatusBufferSize
00695     );
00696 
00697 
00701 VOID
00702 NPF_StatusComplete(IN NDIS_HANDLE  ProtocolBindingContext);
00703 
00712 VOID
00713 NPF_Unload(IN PDRIVER_OBJECT DriverObject);
00714 
00715 
00734 NTSTATUS
00735 NPF_Read(
00736     IN PDEVICE_OBJECT DeviceObject,
00737     IN PIRP Irp
00738     );
00739 
00745 NTSTATUS
00746 NPF_ReadRegistry(
00747     IN  PWSTR              *MacDriverName,
00748     IN  PWSTR              *PacketDriverName,
00749     IN  PUNICODE_STRING     RegistryPath
00750     );
00751 
00758 NTSTATUS
00759 NPF_QueryRegistryRoutine(
00760     IN PWSTR     ValueName,
00761     IN ULONG     ValueType,
00762     IN PVOID     ValueData,
00763     IN ULONG     ValueLength,
00764     IN PVOID     Context,
00765     IN PVOID     EntryContext
00766     );
00767 
00773 VOID NPF_BindAdapter(
00774     OUT PNDIS_STATUS            Status,
00775     IN  NDIS_HANDLE             BindContext,
00776     IN  PNDIS_STRING            DeviceName,
00777     IN  PVOID                   SystemSpecific1,
00778     IN  PVOID                   SystemSpecific2
00779     );
00780 
00792 VOID
00793 NPF_UnbindAdapter(
00794     OUT PNDIS_STATUS        Status,
00795     IN  NDIS_HANDLE         ProtocolBindingContext,
00796     IN  NDIS_HANDLE         UnbindContext
00797     );
00798 
00799 
00807 NTSTATUS NPF_OpenDumpFile(POPEN_INSTANCE Open , PUNICODE_STRING fileName, BOOLEAN append);
00808 
00817 NTSTATUS NPF_StartDump(POPEN_INSTANCE Open);
00818 
00826 VOID NPF_DumpThread(PVOID Open);
00827 
00834 NTSTATUS NPF_SaveCurrentBuffer(POPEN_INSTANCE Open);
00835 
00848 VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject,
00849                                 PLARGE_INTEGER Offset,
00850                                 ULONG Length,
00851                                 PMDL Mdl,
00852                                 PIO_STATUS_BLOCK IoStatusBlock);
00853 
00854 
00855 
00861 NTSTATUS NPF_CloseDumpFile(POPEN_INSTANCE Open);
00862 
00863 VOID
00864 NPF_CloseOpenInstance(POPEN_INSTANCE pOpen);
00865 
00866 BOOLEAN
00867 NPF_StartUsingBinding(
00868     IN POPEN_INSTANCE pOpen);
00869 
00870 VOID
00871 NPF_StopUsingBinding(
00872     IN POPEN_INSTANCE pOpen);
00873 
00874 VOID
00875 NPF_CloseBinding(
00876     IN POPEN_INSTANCE pOpen);
00877 
00878 NTSTATUS
00879 NPF_GetDeviceMTU(
00880              IN POPEN_INSTANCE pOpen,
00881              IN PIRP    pIrp,
00882              OUT PUINT  pMtu);
00883 
00888 UINT GetBuffOccupation(POPEN_INSTANCE Open);
00889 
00901 #ifdef NDIS50
00902 NDIS_STATUS NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent);
00903 #endif
00904 
00905 //  
00906 //  Old registry based WinPcap names
00907 //
00909 //  \brief Helper function to query a value from the global WinPcap registry key
00910 //*/
00911 //VOID NPF_QueryWinpcapRegistryString(PWSTR SubKeyName,
00912 //                               WCHAR *Value,
00913 //                               UINT ValueLen, 
00914 //                               WCHAR *DefaultValue);
00915 //
00916 
00917 
00926 #endif  /*main ifndef/define*/

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