📄 packet32.c
字号:
/*
* Copyright (c) 1999, 2000
* Politecnico di Torino. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the Politecnico
* di Torino, and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <packet32.h>
#include <windows.h>
#include <windowsx.h>
#include <ntddndis.h>
#include <sys/timeb.h>
#ifdef __MINGW32__
#ifdef DBG
#include <assert.h>
#define _ASSERTE assert
#else
#define _ASSERTE
#endif /* DBG */
#else
#include <crtdbg.h>
#endif /* __MINGW32__ */
#ifdef __cplusplus
extern "C"
{
#endif
TCHAR szWindowTitle[] = TEXT ("PACKET.DLL");
LPADAPTER lpTheAdapter = NULL;
#if _DBG
#define ODS(_x) OutputDebugString(TEXT(_x))
#define ODSEx(_x, _y)
#else
#ifdef _DEBUG_TO_FILE
#include <stdio.h>
// Macro to print a debug string. The behavior differs depending on the debug level
#define ODS(_x) { \
FILE *f; \
f = fopen("winpcap_debug.txt", "a"); \
fprintf(f, "%s", _x); \
fclose(f); \
}
// Macro to print debug data with the printf convention. The behavior differs depending on */
#define ODSEx(_x, _y) { \
FILE *f; \
f = fopen("winpcap_debug.txt", "a"); \
fprintf(f, _x, _y); \
fclose(f); \
}
#else
#define ODS(_x)
#define ODSEx(_x, _y)
#endif
#endif
typedef DWORD(CALLBACK* OPENVXDHANDLE)(HANDLE);
BOOLEAN StartPacketDriver (LPTSTR ServiceName);
BOOLEAN StopPacketDriver (void);
BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject);
char PacketLibraryVersion[] = "3.0 alpha3";
//---------------------------------------------------------------------------
PCHAR PacketGetVersion(){
return PacketLibraryVersion;
}
//---------------------------------------------------------------------------
BOOL APIENTRY DllMain (HANDLE hModule,
DWORD dwReason,
LPVOID lpReserved)
{
BOOL Status;
ODS ("Packet32: DllEntry\n");
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
Status = StartPacketDriver (TEXT ("PACKET"));
break;
case DLL_PROCESS_DETACH:
Status = StopPacketDriver ();
break;
default:
Status = TRUE;
break;
}
return Status;
}
//---------------------------------------------------------------------------
BOOL PacketDeviceIoControl (LPADAPTER lpAdapterObject,
LPPACKET lpPacket,
ULONG ulIoctl,
BOOLEAN bSync)
{
BOOLEAN Result;
DWORD Error;
ODS ("Packet32: PacketDeviceIoControl\n");
_ASSERTE (lpAdapterObject != NULL);
_ASSERTE (lpPacket != NULL);
lpPacket->OverLapped.Offset = 0;
lpPacket->OverLapped.OffsetHigh = 0;
lpPacket->ulBytesReceived = 0;
if (!ResetEvent (lpPacket->OverLapped.hEvent))
{
lpPacket->bIoComplete = FALSE;
return FALSE;
}
Result = DeviceIoControl (lpAdapterObject->hFile,
ulIoctl,
lpPacket->Buffer,
lpPacket->Length,
lpPacket->Buffer,
lpPacket->Length,
&(lpPacket->ulBytesReceived),
&(lpPacket->OverLapped));
Error=GetLastError () ;
if (!Result && bSync)
{
if (Error == ERROR_IO_PENDING)
{
Result = GetOverlappedResult (lpAdapterObject->hFile,
&(lpPacket->OverLapped),
&(lpPacket->ulBytesReceived),
TRUE);
}
else
ODS ("Packet32: unsupported API call return error!\n");
}
lpPacket->bIoComplete = Result;
return Result;
}
//---------------------------------------------------------------------------
LPADAPTER PacketOpenAdapter (LPTSTR AdapterName)
{
LPPACKET lpSupport;
LPADAPTER nAdapter;
DWORD error;
BOOL res;
OPENVXDHANDLE OpenVxDHandle;
DWORD KernEvent;
UINT BytesReturned;
struct _timeb time;
ODSEx ("Packet32: PacketOpenAdapter, opening %s\n", AdapterName);
nAdapter = (LPADAPTER) GlobalAllocPtr (GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof (ADAPTER));
if (nAdapter == NULL)
{
error=GetLastError();
ODS ("Packet32: PacketOpenAdapter GlobalAlloc Failed\n");
ODSEx("Error=%d\n",error);
//set the error to the one on which we failed
SetLastError(error);
return NULL;
}
wsprintf (nAdapter->SymbolicLink,
TEXT ("\\\\.\\%s"),
TEXT ("NPF.VXD"));
nAdapter->hFile = CreateFile (nAdapter->SymbolicLink,
GENERIC_WRITE | GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE,
0);
if (nAdapter->hFile == INVALID_HANDLE_VALUE)
{
error=GetLastError();
ODS ("Packet32: PacketOpenAdapter Could not open adapter, 1\n");
ODSEx("Error=%d\n",error);
GlobalFreePtr (nAdapter);
//set the error to the one on which we failed
SetLastError(error);
return NULL;
}
lpSupport=PacketAllocatePacket();
PacketInitPacket(lpSupport,AdapterName,strlen(AdapterName));
if (nAdapter && (nAdapter->hFile != INVALID_HANDLE_VALUE))
{
res=PacketDeviceIoControl(nAdapter,
lpSupport,
(ULONG) IOCTL_OPEN,
TRUE);
if (res==FALSE || ((char*)lpSupport->Buffer)[0]=='\0'){
SetLastError(ERROR_FILE_NOT_FOUND);
goto err;
}
PacketFreePacket(lpSupport);
// Set the time zone
_ftime(&time);
if(DeviceIoControl(nAdapter->hFile,pBIOCSTIMEZONE,&time.timezone,2,NULL,0,&BytesReturned,NULL)==FALSE){
error=GetLastError();
ODS ("Packet32: PacketOpenAdapter Could not open adapter, 2\n");
ODSEx("Error=%d\n",error);
GlobalFreePtr (nAdapter);
//set the error to the one on which we failed
SetLastError(error);
return NULL;
}
// create the read event
nAdapter->ReadEvent=CreateEvent(NULL, TRUE, FALSE, NULL);
// obtain the pointer of OpenVxDHandle in KERNEL32.DLL.
// It is not possible to reference statically this function, because it is present only in Win9x
OpenVxDHandle = (OPENVXDHANDLE) GetProcAddress(GetModuleHandle("KERNEL32"),"OpenVxDHandle");
// map the event to kernel mode
KernEvent=(DWORD)(OpenVxDHandle)(nAdapter->ReadEvent);
// pass the event to the driver
if(DeviceIoControl(nAdapter->hFile,pBIOCEVNAME,&KernEvent,4,NULL,0,&BytesReturned,NULL)==FALSE){
error=GetLastError();
ODS("Packet32: PacketOpenAdapter Could not open adapter, 3\n");
ODSEx("Error=%d\n",error);
GlobalFreePtr (nAdapter);
//set the error to the one on which we failed
SetLastError(error);
return NULL;
}
//set the maximum lookhahead size allowable with this NIC driver
PacketSetMaxLookaheadsize(nAdapter);
//set the number of times a single write will be repeated
PacketSetNumWrites(nAdapter,1);
return nAdapter;
}
err:
error=GetLastError();
ODS ("Packet32: PacketOpenAdapter Could not open adapter, 4\n");
ODSEx("Error=%d\n",error);
//set the error to the one on which we failed
SetLastError(error);
return NULL;
}
//---------------------------------------------------------------------------
/* Function to set the working mode of the driver
mode working mode
*/
BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode)
{
int BytesReturned;
return DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL);
}
//---------------------------------------------------------------------------
/* Function to get the the read event*/
HANDLE PacketGetReadEvent(LPADAPTER AdapterObject)
{
return AdapterObject->ReadEvent;
}
//---------------------------------------------------------------------------
/* Function to set the the number of times a write will be repeated*/
BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites)
{
AdapterObject->NumWrites=nwrites;
return TRUE;
}
//---------------------------------------------------------------------------
/* This function is used to set the read timeout
timeout value of timeout(milliseconds). 0 means infinite.
*/
BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout)
{
int BytesReturned;
return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&timeout,4,NULL,0,&BytesReturned,NULL);
}
//---------------------------------------------------------------------------
/* This function allows to set the dimension of the packet buffer in the driver
parameters:
dim dimension of the buffer (kilobytes)
*/
BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim)
{
int BytesReturned;
return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL);
}
//---------------------------------------------------------------------------
/* Function to set the minimum amount of bytes that will be copied by the driver*/
BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes)
{
// not yet implemented in Windows 9x
return TRUE;
}
//---------------------------------------------------------------------------
/* Function to set a bpf filter in the driver
parameters:
fp the pointer to the beginning of the filtering program
*/
BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp)
{
int BytesReturned;
return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL);
}
//---------------------------------------------------------------------------
BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s)
{
int BytesReturned;
return DeviceIoControl(AdapterObject->hFile,pBIOCGSTATS,NULL,0,s,sizeof(struct bpf_stat),&BytesReturned,NULL);
}
//---------------------------------------------------------------------------
BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s)
{
int BytesReturned;
return DeviceIoControl(AdapterObject->hFile,pBIOCGSTATS,NULL,0,s,sizeof(struct bpf_stat),&BytesReturned,NULL);
}
//---------------------------------------------------------------------------
VOID PacketCloseAdapter (LPADAPTER lpAdapter)
{
ODS ("Packet32: PacketCloseAdapter\n");
// close the capture handle
CloseHandle (lpAdapter->hFile);
// close the read event
CloseHandle (lpAdapter->ReadEvent);
GlobalFreePtr (lpAdapter);
lpAdapter = NULL;
}
//---------------------------------------------------------------------------
LPPACKET PacketAllocatePacket (void)
{
LPPACKET lpPacket;
lpPacket = (LPPACKET) GlobalAllocPtr (
GMEM_MOVEABLE | GMEM_ZEROINIT,
sizeof (PACKET));
if (lpPacket == NULL)
{
ODS ("Packet32: PacketAllocatePacket: GlobalAlloc Failed\n");
return NULL;
}
lpPacket->OverLapped.hEvent = CreateEvent (NULL,
FALSE,
FALSE,
NULL);
if (lpPacket->OverLapped.hEvent == NULL)
{
ODS ("Packet32: PacketAllocatePacket: CreateEvent Failed\n");
GlobalFreePtr (lpPacket);
return NULL;
}
lpPacket->Buffer=NULL;
lpPacket->Length=0;
lpPacket->ulBytesReceived = 0;
lpPacket->bIoComplete = FALSE;
return lpPacket;
}
//---------------------------------------------------------------------------
VOID PacketFreePacket (LPPACKET lpPacket)
{
CloseHandle (lpPacket->OverLapped.hEvent);
GlobalFreePtr (lpPacket);
}
//---------------------------------------------------------------------------
VOID PacketInitPacket (LPPACKET lpPacket,
PVOID Buffer,
UINT Length)
{
lpPacket->Buffer = Buffer;
lpPacket->Length = Length;
}
//---------------------------------------------------------------------------
BOOLEAN PacketSendPacket (LPADAPTER AdapterObject,
LPPACKET lpPacket,
BOOLEAN Sync)
{
int i;
for(i=0;i<AdapterObject->NumWrites;i++){
if(PacketDeviceIoControl (AdapterObject,lpPacket,(ULONG) IOCTL_PROTOCOL_WRITE,Sync)==FALSE)
return FALSE;
}
return TRUE;
}
//---------------------------------------------------------------------------
// Emulated at user-level under Win9x
INT PacketSendPackets(LPADAPTER AdapterObject,
PVOID PacketBuff,
ULONG Size,
BOOLEAN Sync)
{
struct dump_bpf_hdr *winpcap_hdr;
PCHAR EndOfUserBuff = (PCHAR)PacketBuff + Size;
LPPACKET PacketToSend;
BOOLEAN res;
// Start from the first packet
winpcap_hdr = (struct dump_bpf_hdr*)PacketBuff;
if( (PCHAR)winpcap_hdr + winpcap_hdr->caplen + sizeof(struct dump_bpf_hdr) > EndOfUserBuff )
{
// Malformed buffer
return 0;
}
while( TRUE ){
if(winpcap_hdr->caplen ==0 || winpcap_hdr->caplen > 65536)
{
// Malformed header
return 0;
}
// Set up the LPPACKET structure
PacketToSend=PacketAllocatePacket();
PacketInitPacket(PacketToSend,
(PCHAR)winpcap_hdr + sizeof(struct dump_bpf_hdr),
winpcap_hdr->caplen);
// Send the packet
res = PacketSendPacket (AdapterObject, PacketToSend, TRUE);
// Free the just used LPPACKET structure
PacketFreePacket(PacketToSend);
if(res == FALSE){
// Error sending the packet
return (PCHAR)winpcap_hdr - (PCHAR)PacketBuff;
}
// Step to the next packet in the buffer
(PCHAR)winpcap_hdr += winpcap_hdr->caplen + sizeof(struct dump_bpf_hdr);
// Check if the end of the user buffer has been reached
if( (PCHAR)winpcap_hdr >= EndOfUserBuff )
{
return (PCHAR)winpcap_hdr - (PCHAR)PacketBuff;
}
}
}
//---------------------------------------------------------------------------
BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,
LPPACKET lpPacket,
BOOLEAN Sync)
{
return PacketDeviceIoControl(AdapterObject,
lpPacket,
(ULONG) IOCTL_PROTOCOL_READ,
Sync);
}
//---------------------------------------------------------------------------
BOOLEAN PacketWaitPacket (LPADAPTER AdapterObject,
LPPACKET lpPacket)
{
lpPacket->bIoComplete = GetOverlappedResult( AdapterObject->hFile,
&lpPacket->OverLapped,
&lpPacket->ulBytesReceived,
TRUE );
return lpPacket->bIoComplete;
}
//---------------------------------------------------------------------------
BOOLEAN PacketResetAdapter (LPADAPTER AdapterObject)
{
UINT BytesReturned;
DeviceIoControl (
AdapterObject->hFile,
(DWORD) IOCTL_PROTOCOL_RESET,
NULL,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -