📄 packet32.c
字号:
pBIOCSETDUMPLIMITS,
valbuff,
sizeof valbuff,
NULL,
0,
&BytesReturned,
NULL);
}
/*!
\brief Returns the status of the kernel dump process, i.e. tells if one of the limits defined with PacketSetDumpLimits() was reached.
\param AdapterObject Pointer to an _ADAPTER structure.
\param sync if TRUE, the function blocks until the dump is finished, otherwise it returns immediately.
\return TRUE if the dump is ended, FALSE otherwise.
PacketIsDumpEnded() informs the user about the limits that were set with a previous call to
PacketSetDumpLimits().
\warning If no calls to PacketSetDumpLimits() were performed or if the dump process has no limits
(i.e. if the arguments of the last call to PacketSetDumpLimits() were both 0), setting sync to TRUE will
block the application on this call forever.
*/
BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync)
{
DWORD BytesReturned;
int IsDumpEnded;
BOOLEAN res;
if(sync)
WaitForSingleObject(AdapterObject->ReadEvent, INFINITE);
res = DeviceIoControl(AdapterObject->hFile,
pBIOCISDUMPENDED,
NULL,
0,
&IsDumpEnded,
4,
&BytesReturned,
NULL);
if(res == FALSE) return TRUE; // If the IOCTL returns an error we consider the dump finished
return (BOOLEAN)IsDumpEnded;
}
/*!
\brief Returns the notification event associated with the read calls on an adapter.
\param AdapterObject Pointer to an _ADAPTER structure.
\return The handle of the event that the driver signals when some data is available in the kernel buffer.
The event returned by this function is signaled by the driver if:
- The adapter pointed by AdapterObject is in capture mode and an amount of data greater or equal
than the one set with the PacketSetMinToCopy() function is received from the network.
- the adapter pointed by AdapterObject is in capture mode, no data has been received from the network
but the the timeout set with the PacketSetReadTimeout() function has elapsed.
- the adapter pointed by AdapterObject is in statics mode and the the timeout set with the
PacketSetReadTimeout() function has elapsed. This means that a new statistic sample is available.
In every case, a call to PacketReceivePacket() will return immediately.
The event can be passed to standard Win32 functions (like WaitForSingleObject or WaitForMultipleObjects)
to wait until the driver's buffer contains some data. It is particularly useful in GUI applications that
need to wait concurrently on several events.
*/
HANDLE PacketGetReadEvent(LPADAPTER AdapterObject)
{
return AdapterObject->ReadEvent;
}
/*!
\brief Sets the number of times a single packet written with PacketSendPacket() will be repeated on the network.
\param AdapterObject Pointer to an _ADAPTER structure.
\param nwrites Number of copies of a packet that will be physically sent by the interface.
\return If the function succeeds, the return value is nonzero.
See PacketSendPacket() for details.
*/
BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites)
{
DWORD BytesReturned;
return DeviceIoControl(AdapterObject->hFile,pBIOCSWRITEREP,&nwrites,4,NULL,0,&BytesReturned,NULL);
}
/*!
\brief Sets the timeout after which a read on an adapter returns.
\param AdapterObject Pointer to an _ADAPTER structure.
\param timeout indicates the timeout, in milliseconds, after which a call to PacketReceivePacket() on
the adapter pointed by AdapterObject will be released, also if no packets have been captured by the driver.
Setting timeout to 0 means no timeout, i.e. PacketReceivePacket() never returns if no packet arrives.
A timeout of -1 causes PacketReceivePacket() to always return immediately.
\return If the function succeeds, the return value is nonzero.
\note This function works also if the adapter is working in statistics mode, and can be used to set the
time interval between two statistic reports.
*/
BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout)
{
DWORD BytesReturned;
int DriverTimeOut=-1;
AdapterObject->ReadTimeOut=timeout;
return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&DriverTimeOut,4,NULL,0,&BytesReturned,NULL);
}
/*!
\brief Sets the size of the kernel-level buffer associated with a capture.
\param AdapterObject Pointer to an _ADAPTER structure.
\param dim New size of the buffer, in \b kilobytes.
\return The function returns TRUE if successfully completed, FALSE if there is not enough memory to
allocate the new buffer.
When a new dimension is set, the data in the old buffer is discarded and the packets stored in it are
lost.
Note: the dimension of the kernel buffer affects heavily the performances of the capture process.
An adequate buffer in the driver is able to keep the packets while the application is busy, compensating
the delays of the application and avoiding the loss of packets during bursts or high network activity.
The buffer size is set to 0 when an instance of the driver is opened: the programmer should remember to
set it to a proper value. As an example, wpcap sets the buffer size to 1MB at the beginning of a capture.
*/
BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim)
{
DWORD BytesReturned;
return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL);
}
/*!
\brief Sets a kernel-level packet filter.
\param AdapterObject Pointer to an _ADAPTER structure.
\param fp Pointer to a filtering program that will be associated with this capture or monitoring
instance and that will be executed on every incoming packet.
\return This function returns TRUE if the filter is set successfully, FALSE if an error occurs
or if the filter program is not accepted after a safeness check by the driver. The driver performs
the check in order to avoid system crashes due to buggy or malicious filters, and it rejects non
conformat filters.
This function associates a new BPF filter to the adapter AdapterObject. The filter, pointed by fp, is a
set of bpf_insn instructions.
A filter can be automatically created by using the pcap_compile() function of wpcap. This function
converts a human readable text expression with the syntax of WinDump (see the manual of WinDump at
http://netgroup.polito.it/windump for details) into a BPF program. If your program doesn't link wpcap, but
you need to know the code of a particular filter, you can launch WinDump with the -d or -dd or -ddd
flags to obtain the pseudocode.
*/
BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp)
{
DWORD BytesReturned;
return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL);
}
/*!
\brief Returns a couple of statistic values about the current capture session.
\param AdapterObject Pointer to an _ADAPTER structure.
\param s Pointer to a user provided bpf_stat structure that will be filled by the function.
\return If the function succeeds, the return value is nonzero.
With this function, the programmer can know the value of two internal variables of the driver:
- the number of packets that have been received by the adapter AdapterObject, starting at the
time in which it was opened with PacketOpenAdapter.
- the number of packets that have been dropped by the driver. A packet is dropped when the kernel
buffer associated with the adapter is full.
*/
BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s)
{
BOOLEAN Res;
DWORD BytesReturned;
struct bpf_stat tmpstat; // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications
Res = DeviceIoControl(AdapterObject->hFile,
pBIOCGSTATS,
NULL,
0,
&tmpstat,
sizeof(struct bpf_stat),
&BytesReturned,
NULL);
// Copy only the first two values retrieved from the driver
s->bs_recv = tmpstat.bs_recv;
s->bs_drop = tmpstat.bs_drop;
return Res;
}
/*!
\brief Returns statistic values about the current capture session. Enhanced version of PacketGetStats().
\param AdapterObject Pointer to an _ADAPTER structure.
\param s Pointer to a user provided bpf_stat structure that will be filled by the function.
\return If the function succeeds, the return value is nonzero.
With this function, the programmer can retireve the sname values provided by PacketGetStats(), plus:
- the number of drops by interface (not yet supported, always 0).
- the number of packets that reached the application, i.e that were accepted by the kernel filter and
that fitted in the kernel buffer.
*/
BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s)
{
BOOLEAN Res;
DWORD BytesReturned;
struct bpf_stat tmpstat; // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications
Res = DeviceIoControl(AdapterObject->hFile,
pBIOCGSTATS,
NULL,
0,
&tmpstat,
sizeof(struct bpf_stat),
&BytesReturned,
NULL);
s->bs_recv = tmpstat.bs_recv;
s->bs_drop = tmpstat.bs_drop;
s->ps_ifdrop = tmpstat.ps_ifdrop;
s->bs_capt = tmpstat.bs_capt;
return Res;
}
/*!
\brief Performs a query/set operation on an internal variable of the network card driver.
\param AdapterObject Pointer to an _ADAPTER structure.
\param Set Determines if the operation is a set (Set=TRUE) or a query (Set=FALSE).
\param OidData A pointer to a _PACKET_OID_DATA structure that contains or receives the data.
\return If the function succeeds, the return value is nonzero.
\note not all the network adapters implement all the query/set functions. There is a set of mandatory
OID functions that is granted to be present on all the adapters, and a set of facultative functions, not
provided by all the cards (see the Microsoft DDKs to see which functions are mandatory). If you use a
facultative function, be careful to enclose it in an if statement to check the result.
*/
BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData)
{
//DWORD BytesReturned;
BOOLEAN Result = 0;
/*commented out since its broken & needs fixing*/
/*Result=DeviceIoControl(AdapterObject->hFile,(DWORD) Set ? pBIOCSETOID : pBIOCQUERYOID,
OidData,sizeof(PACKET_OID_DATA)-1+OidData->Length,OidData,
sizeof(PACKET_OID_DATA)-1+OidData->Length,&BytesReturned,NULL);*/
// output some debug info
ODSEx("PacketRequest, OID=%d ", OidData->Oid);
ODSEx("Length=%d ", OidData->Length);
ODSEx("Set=%d ", Set);
ODSEx("Res=%d\n", Result);
return Result;
}
/*!
\brief Sets a hardware filter on the incoming packets.
\param AdapterObject Pointer to an _ADAPTER structure.
\param Filter The identifier of the filter.
\return If the function succeeds, the return value is nonzero.
The filter defined with this filter is evaluated by the network card, at a level that is under the NPF
device driver. Here is a list of the most useful hardware filters (A complete list can be found in ntddndis.h):
- NDIS_PACKET_TYPE_PROMISCUOUS: sets promiscuous mode. Every incoming packet is accepted by the adapter.
- NDIS_PACKET_TYPE_DIRECTED: only packets directed to the workstation's adapter are accepted.
- NDIS_PACKET_TYPE_BROADCAST: only broadcast packets are accepted.
- NDIS_PACKET_TYPE_MULTICAST: only multicast packets belonging to groups of which this adapter is a member are accepted.
- NDIS_PACKET_TYPE_ALL_MULTICAST: every multicast packet is accepted.
- NDIS_PACKET_TYPE_ALL_LOCAL: all local packets, i.e. NDIS_PACKET_TYPE_DIRECTED + NDIS_PACKET_TYPE_BROADCAST + NDIS_PACKET_TYPE_MULTICAST
*/
BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter)
{
BOOLEAN Status;
ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
PPACKET_OID_DATA OidData;
OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
if (OidData == NULL) {
ODS("PacketSetHwFilter: GlobalAlloc Failed\n");
return FALSE;
}
OidData->Oid=OID_GEN_CURRENT_PACKET_FILTER;
OidData->Length=sizeof(ULONG);
*((PULONG)OidData->Data)=Filter;
Status=PacketRequest(AdapterObject,TRUE,OidData);
GlobalFreePtr(OidData);
return Status;
}
/*!
\brief Retrieve the list of available network adapters and their description.
\param pStr User allocated string that will be filled with the names of the adapters.
\param BufferSize Length of the buffer pointed by pStr.
\return If the function succeeds, the return value is nonzero.
Usually, this is the first function that should be used to communicate with the driver.
It returns the names of the adapters installed on the system <B>and supported by WinPcap</B>.
After the names of the adapters, pStr contains a string that describes each of them.
\b Warning:
the result of this function is obtained querying the registry, therefore the format
of the result in Windows NTx is different from the one in Windows 9x. Windows 9x uses the ASCII
encoding method to store a string, while Windows NTx uses UNICODE. After a call to PacketGetAdapterNames
in Windows 95x, pStr contains, in succession:
- a variable number of ASCII strings, each with the names of an adapter, separated by a "\0"
- a double "\0"
- a number of ASCII strings, each with the description of an adapter, separated by a "\0". The number
of descriptions is the same of the one of names. The fisrt description corresponds to the first name, and
so on.
- a double "\0".
In Windows NTx, pStr contains: the names of the adapters, in UNICODE format, separated by a single UNICODE "\0" (i.e. 2 ASCII "\0"), a double UNICODE "\0", followed by the descriptions of the adapters, in ASCII format, separated by a single ASCII "\0" . The string is terminated by a double ASCII "\0".
- a variable number of UNICODE strings, each with the names of an adapter, separated by a UNICODE "\0"
- a double UNICODE "\0"
- a number of ASCII strings, each with the description of an adapter, separated by an ASCII "\0".
- a double ASCII "\0".
*/
BOOLEAN PacketGetAdapterNames(PTSTR pStr, PULONG BufferSize)
{
HKEY LinkageKey, AdapKey;
DWORD RegKeySize = 0;
LONG Status;
ULONG Result;
PTSTR BpStr;
char *TTpStr;
char *DpStr;
char *DescBuf;
LPADAPTER adapter;
PPACKET_OID_DATA OidData;
int i = 0, k, rewind;
DWORD dim;
TCHAR AdapName[256];
ODSEx("PacketGetAdapterNames: BufferSize=%d\n",*BufferSize);
OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 512);
if (OidData == NULL) {
ODS("PacketGetAdapterNames: GlobalAlloc Failed\n");
return FALSE;
}
Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
TEXT("SYSTEM\\ControlSet001\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"),
0, KEY_READ, &AdapKey);
// Get the size to allocate for the original device names
while ((Result = RegEnumKey(AdapKey, i, AdapName, sizeof(AdapName)/2)) == ERROR_SUCCESS) {
Status = RegOpenKeyEx(AdapKey, AdapName,0, KEY_READ, &LinkageKey);
Status = RegOpenKeyExW(LinkageKey, L"Linkage",0, KEY_READ, &LinkageKey);
Status = RegQueryValueExW(LinkageKey, L"Export", NULL, NULL, NULL, &dim);
i++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -