你需要用到winpcap. 其中包含一个packet.dll. 下面是我的源程序 packet32 is used to
link packet.dll. winpcap 是你要用的。 你需要到 http://winpcap.polito.it/下载winpacp
你可以通过call 以下function 来达到捕捉到广播包。
1: you first get NIC name
winpcap_Getadaptername(Delimiter: Char):string;
2: open NIC
function winpcap_open_adapter(nic:string;snapshotlen:integer;Promisc:boolean)
pcap;
3: read packet off the wire
function winpcap_read( p
Pcap;cnt:integer;CallBack:Tpcap_handler;User
ointer)
通过以上三个function. 你可以达到获取数据包。
[blue]unit Winpcap;
interface
uses Windows,Classes,SysUtils,QDialogs,Packet32,bpf,Ndis_def;
const
PcapBufSize = 256000; //Dimension of the buffer in TPcap
PCAP_ERRBUF_SIZE = 256; //String size of error descriptions
// [taken from interface.h]
DEFAULT_SNAPLEN = 68; //The default snapshot length.
//This value allows most printers to
//print useful information while keeping
//the amount of unwanted data down.In
//particular, it allows for an ethernet
//header, tcp/ip header, and 14 bytes of
//data (assuming no ip options).
type
TPcap_sf = record // Save file for offline reading.
rfile : HFILE;
swapped:integer;
version_major : integer;
Version_Minor : integer;
base : Pointer;
end;
PPcap_Stat = ^TPcap_stat;
Tpcap_stat = record
ps_recv, //* number of packets received */
ps_drop, //* number of packets dropped */
ps_ifdrop : LongWord; //* drops by interface not supported */
end;
TPcap_md = record
Stat : TPcap_stat;
use_bpf : integer;
TotPkts : LongWord; // Can owerflow after 79hours on ethernet
TotAccepted:LongWord; // accepted by filter/sniffer
TotDrops : LongWord; // dropped packets
TotMissed: Longword; // missed by i/f during this run
OrigMissed:LongWord; // missed by i/f before this run
end;
PPcap = ^TPcap; // THE MAIN INTERFACE HANDLE
TPcap = record // used with allmost all Pcap calls.
Adapter
adapter;
Packet
Packet; // Global Driver packet. kind of a buffer
snapshot:integer;
linktype:integer; // Type and speed of net
tzoff :integer; // timezone offset
offset :integer;
sf :Tpcap_sf; // Save file ***
md :Tpcap_md; // Diagnostics ***
//READ BUFFER
bufsize :integer;
buffer
ointer; //*u_char
bp
ointer; //*u_char
cc :integer;
//Place holder for pcap_next().
pkt
ointer; //*U_char
//Placeholder for filter code if bpf not in kernel.
fcode :Tbpf_program; // ***
// errbuf : array [0..PCAP_ERRBUF_SIZE-1] of char; //Last error message ***
end;
PPcap_PktHdr = ^Tpcap_pkthdr; // Wrapped Drivers packetHeader
TPcap_pkthdr = record
ts : TUnixTimeVal; // Time of capture
CapLen, // captured length
Len : Integer; // actual length of packet
end;
// Callback procedure
Ppcap_handler =^Tpcap_handler;
Tpcap_handler = procedure(User
ointer;const Header
pcap_pkthdr;const Data
char);
function winpcap_Getadaptername(Delimiter: Char):string;
function winpcap_open_adapter(nic:string; snapshotlen:integer; Promisc:boolean): ppcap;
function winpcap_read(p
Pcap;cnt:integer;CallBack:Tpcap_handler;User
ointer):integer;
//procedure winpcap_close(var p : ppcap);
function pcap_compile(Pcapther
pcap;fp
bpf_program;filter:string;optimize:integer;Tnetmask:Tbpf_u_int32):integer;
cdecl external 'wpcap.dll';
function pcap_setfilter(Pcapther
pcap;fp
bpf_program):integer; cdecl external 'wpcap.dll'
function pcap_lookupnet(Pdevice:string;subnet,netmask:Tbpf_u_int32;errbuf:string):integer; cdecl external 'wpcap.dll';
implementation
function winpcap_Getadaptername(Delimiter: Char):string;
var
AdapterList : Array [0..(1024*2)-1] of char; //String that contain adapter info
AdapterLength,i: LongWord;
dwVersion, dwWindowsMajorVersion: LongWord;
begin
//the data format returned by packetgetadaptername is different from win9x & NT
//so we have to check OS on which we are running
AdapterLength := 1024;//sizeof(AdapterList);
dwVersion:=Getversion();
dwWindowsMajorVersion :=(LOBYTE(LOWORD(dwVersion)));
if(PacketGetAdapterNames(Adapterlist,@AdapterLength)=0) then
begin
showMessage('Unable to retrieve the list of the adapters!');
exit;
end;
if not ((dwVersion >= $80000000) and (dwWindowsMajorVersion >= 4)) then
begin
// Windows NT
for i:=0 to adapterLength-1 do
begin
if (Pwidechar(@adapterList)
=#0)and (PwideChar(@adapterlist)[i+1]<>#0) then
PWideChar(@adapterList):= WideChar(delimiter);
//#0 is ASCII NUL
end;
Result := WideCharToString(PWideChar(@adapterList)) ;
end
else //win9x
begin
for i:=0 to adapterLength-1 do
begin
// modified
if ((adapterList=#0) and (adapterList[i+1]=#0))then
break
else
if (adapterList=' ') or (adapterList=#0) then
// adapterList:= delimiter;
end;
Result := adapterList;
end
end;
function winpcap_open_adapter(nic:string;snapshotlen:integer;Promisc:boolean) pcap;
var
P : Ppcap;
NetType : Tnet_type;
S : Pchar;
//fpbpf_program;
//pcaptherhandle:dword;
//hostip,net: Tbpf_u_int32 ;
//netmask,subnet:Tbpf_u_int32; //used for pcomplile_filter, lookup
//errbuf:string;
procedure CleanUp;
begin
if P.adapter<>nil then PacketCloseAdapter(P.adapter);
if P.buffer<>nil then FreeMem(P.buffer,PcapBufSize);
Freemem(P,SizeOf(Tpcap));
end;
begin
// CREATE PCAP OBJECT
GetMem(P,SizeOf(Tpcap));
if P=nil then
begin
MessageDlg ('Warning: unable to allocate Pcap ojbect!', mtWarning, [mbOk], 0);
result := nil;
exit;
end;
FillChar(p^,sizeof(Tpcap),0);
P.Adapter := nil;
//Create adpater object
GetMem(S,2048); // Making temporary pchar
StrPCopy(S,NIC);
p.Adapter := PacketOpenAdapter(S);
FreeMem(S,2048);
if (p.Adapter = nil) or (p.Adapter.hFile = INVALID_HANDLE_VALUE) then
begin
MessageDlg ('Error: Could not open adapter', mtError, [mbOk], 0);
cleanup;
result := nil;
exit;
end;
//// SET HARDWARE FILTER MODE
if Promisc then
begin
if(PacketSetHwFilter(p.adapter,NDIS_PACKET_TYPE_PROMISCUOUS)=FALSE) then
begin
MessageDlg ('Warning: unable to set promiscuous mode!', mtWarning, [mbOk], 0);
Cleanup;
result := nil;
exit;
end;
end
else //only packet destined to the adapter are accepted
if(PacketSetHwFilter(p.Adapter,NDIS_PACKET_TYPE_DIRECTED)=FALSE) then
begin
MessageDlg ('Warning: unable to set directed mode!', mtWarning, [mbOk], 0);
Cleanup;
result := nil;
exit;
end;
// GET NETCARD SPEED AND TYPE
if not PacketGetNetType(p.Adapter,@Nettype) then
Begin
MessageDlg ('Error: Cannot determine network type and speed!', mterror, [mbOk], 0);
Cleanup;
result := nil;
exit;
end;
Case TNDIS_MEDIUM(nettype.LinkType) of
NdisMediumWan : P.linktype := DLT_PPP_WIN32;
NdisMedium802_3 : begin
if nettype.LinkSpeed = 100000000 then
p.linktype := DLT_EN100MB
else if nettype.LinkSpeed=10000000 then
p.linktype := DLT_EN10MB
else p.linktype:=DLT_PPP_WIN32;
end;
else p.linktype := DLT_EN10MB;
end;
// Allocate room for Link header
p.bufsize := PcapBufSize;
GetMem(p.buffer,PcapBufSize);
if P.buffer = nil then
begin
MessageDlg ('Cannot allocate Link Header space!', mterror, [mbOk], 0);
cleanup;
result := nil;
exit;
end;
p.snapshot := Snapshotlen;
// Allocate Global Packet for capturing
p.packet := PacketAllocatePacket;
if p.packet = nil then
begin
MessageDlg ('Cannot allocate Global Packet Object!', mterror, [mbOk], 0);
cleanup;
result := nil;
exit;
end;
PacketInitPacket(p.Packet,p.buffer,p.bufsize);
// Sets the size of the kernel-level buffer associated with a capture.
if not PacketSetBuff(p.adapter,DEFAULT_DRIVERBUFFER) then
begin
MessageDlg ('Not enough memory to allocate Driver buffer!', mterror, [mbOk], 0);
CleanUp;
result := nil;
exit;
end;
result := p;
{
//wpcap functions. only for testing
//if pcap_lookupnet('nic',subnet,netmask,errbuf) < 0 then showmessage('netmask error');
//netmask:=$ffffff;
if PacketGetNetInfo(p.Adapter,@hostip,@net) then
begin
if pcap_compile(p,fp,'icmp',1,@net) < 0 then showmessage('filter compiling error');
if pcap_setfilter(p,fp) < 0 then showmessage('filter setting error');
end;
}
end;
function winpcap_read( pPcap;cnt:integer;CallBack:Tpcap_handler;Userointer)
: integer;
var cc : Longword;//Counter ?
n : integer;
bp,ep: pointer; //Begin and End Point ?
//bhp : Pbpf_hdr;//pointer to BPF header struct - removed by Lars Peter
hdrlen, //Length of Header
caplen: integer;//Length of captured
begin
cc := p.cc;
n := 0;
if p.cc = 0 then
begin
// *Capture the Packets*
if PacketReceivePacket(p.adapter,p.packet,TRUE)=false then
begin
MessageDlg ('Read Error: PacketRecievePacket failed!', mterror, [mbOk], 0);
result:=-1;
exit;
end;
cc := p.packet.ulBytesReceived; //number of bytes in buffer
bp := p.buffer;
end else bp := p.bp;
// Loop through each packet.
ep := ptr(longword(bp)+cc); //move end pointer to the end of packet
while (longword(bp) < longword(ep) ) do
begin
caplen := Pbpf_hdr(bp).bh_caplen; //* length of captured portion, can be diff from bh_datalen if it told to do so*/
hdrlen := Pbpf_hdr(bp).bh_hdrlen; //* length of bpf header */
//bh_hdrlen is used to retrived the actual data. it's only a header len
//bh_datalen is the orginal size of packet.
// XXX A bpf_hdr matches a pcap_pkthdr. pcap_pkthdr is generic pck head
// for all sorts of packet, bpf_hdr is actural packet head on the wire
callback(user,
Ppcap_pkthdr(bp),
ptr(longword(bp)+HdrLen)); //address data portion
LongWord(bp) := LongWord(bp) + BPF_WORDALIGN(caplen + hdrlen);
inc; //caplen + hdrlen is the total length of a packet
if (n >= cnt)and(cnt>0) then
begin
p.bp := bp;
p.cc := longword(ep)-longword(bp);
result := n;
exit;
end;
end;
p.cc := 0;
result:=n;
end;
end.[/blue]
Packet32.dll author:
webpsite: http://netgroup-serv.polito.it/windump
--------------------------------------------------------------------------------
Original Filename : Packet32.pas
Packet.dll written in C.
PacketOpenAdapter
PacketCloseAdapter
PacketResetAdapter
PacketGetAdapterNames
PacketSetBuff
PacketSetBpf
PacketSetHwFilter
PacketGetNetType
PacketGetStats
PacketAllocatePacket
PacketFreePacket
PacketSendPacket
PacketRecievePacket
PacketWaitPacket
PacketRequest
********************************************************************************
CHANGES :
20 November 2000 : TPacket Modified. No longer delivers faulty packets.
Thanks to Pol-Brieuc Lemétayer.
Email : pol-brieuc.lemetayer@eleve.emn.fr
}
unit Packet32;
interface
uses Windows, // OVERLAPPED syncronization structure
bpf; // Needs bpf structures
Const
DLL = 'packet.dll'; // Name of DLL file
DEFAULT_DRIVERBUFFER = 1000000; // Dimension of the buffer in driver
MAX_LINK_NAME_LENGTH = 64; // Adapters symbolic names maximum length
type
// Adapter with which the driver communicates
Padapter = ^Tadapter;
Tadapter = Record
hFile : LongWord;
SymbolicLink : array [0..MAX_LINK_NAME_LENGTH-1] of char;
end;
// Packet the driver uses as means of data transport.
// both snooped data and certain device controlling
Ppacket = ^Tpacket;
Tpacket = record
OverLapped :TOVERLAPPED; // Gotten From DDK -declared in windows.pas
Buffer ointer;
Next ointer; // Changed Nov.20 2000.
Length :Word;
ulBytesReceived :LongWord; // Changed Nov.20 2000. Thanks to
bIoComplete :Boolean; // Pol-Brieuc Lemétayer
end;
// [Gotten from LIBPCAP/ntddpack.h]
// Data structure to control the device driver
PPACKET_OID_DATA = ^TPACKET_OID_DATA;
TPACKET_OID_DATA = record
Oid : LongWord; // Device control code
Length: LongWord; // Length of data field
Data : Pointer; // Start of data field
end;
// [Gotten from BPF.h? - more appropiate here!]
Pnet_type = ^Tnet_type;
Tnet_type = record
LinkType,
LinkSpeed : LongWord;
end;
//type //used by PacketGetNetInfo().
host = ^hostdetail;
hostdetail = array[0..3] of uchar;
// ----------------------------------------------------------------------------
// BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout);
// ----------------------------------------------------------------------------
function PacketSetReadTimeout(AdapterObject: PAdapter; timeout: Integer): Boolean;
cdecl external DLL;
//------------------------------------------------------------------------------
//ULONG PacketGetAdapterNames(PTSTR pStr, PULONG BufferSize)
//------------------------------------------------------------------------------
Function PacketGetAdapterNames(pStrchar;BufferSizeLongWord) : LongWord;
cdecl external DLL;
{
This is the first function that must be used to communicate with the driver.
It returns the names of the adapters installed in the system through the user
allocated buffer pStr. BufferSize is the length of the buffer.
Warning: the result of this function is obtained querying directly the registry,
therefore the format of the result in Windows NT is different from the one in
Windows 95/98. This is due to the fact that Windows 95 uses the ASCII
encoding method to store a string, while Windows NT uses UNICODE. After a
call to PacketGetAdapterNames in Windows 95, pStr contains an ASCII string
with the names of the adapters separated by ASCII "/0". The string is
terminated by a double "/0". In Windows NT, pStr contains a UNICODE string
with the names of the adapters separated by a "/0" UNICODE character
(i.e. 2 ASCII "/0"), and the string ends with a double UNICODE "/0".
}
//------------------------------------------------------------------------------
// LPADAPTER PacketOpenAdapter(LPTSTR AdapterName)
//------------------------------------------------------------------------------
Function PacketOpenAdapter(AdapterNamechar) : PAdapter;cdecl external dll;
{
This function receives a string containing the name of the adapter to open and
returns the pointer to a properly initialized ADAPTER object. The names of the
adapters can be obtained calling the PacketGetAdapterNames function.
Note: as already said, the Windows 95 version of the capture driver works with
the ASCII format, the Windows NT version with UNICODE. Therefore, AdapterName
should be an ASCII string in Windows 95, and a UNICODE string in Windows NT.
This difference is not a problem if the string pointed by AdapterName was
obtained through the PacketGetAdapterNames function, because it returns the
names of the adapters in the proper format. Instead, some problems can arise
in Windows NT if the string is obtained from ANSI C functions like scanf,
because they use the ASCII format. This can be a relevant problem when porting
command-line applications from UNIX. To avoid it, we included in the Windows NT
version of PacketOpenAdapter a routine to convert strings from ASCII to UNICODE.
PacketOpenAdapter in Windows NT accepts both the ASCII and the UNICODE format.
If a ASCII string is received, it is converted to UNICODE before being passed
to the driver.
}
//------------------------------------------------------------------------------
// VOID PacketCloseAdapter(LPADAPTER lpAdapter)
//------------------------------------------------------------------------------
procedure PacketCloseAdapter(pAdapteradapter);cdecl external dll;
{
This function deallocates the ADAPTER structure lpAdapter, and closes the
adapter pointed by it.
}
//------------------------------------------------------------------------------
// LPPACKET PacketAllocatePacket(void)
//------------------------------------------------------------------------------
function PacketAllocatePacket : PPacket;cdecl external dll;
{
Allocates a PACKET structure and returns a pointer to it. The structure
returned must be properly initialized by calling the PacketInitPacket function.
Warning: The Buffer field of the PACKET structure is not set by this function.
The buffer must be allocated by the programmer, and associated to the PACKET
structure with a call to PacketInitPacket.
}
//------------------------------------------------------------------------------
// VOID PacketInitPacket(LPPACKET lpPacket, PVOID Buffer, UINT Length)
//------------------------------------------------------------------------------
Procedure PacketInitPacket(pPacketpacket;Bufferointer;Length:LongWord);cdecl
external DLL;
{
It initializes a structure PACKET. There are three input parameters:
* a pointer to the structure to initialize
* a pointer to the user-allocated buffer that will contain the packet data
* length of the buffer. This is the maximum length that will be transferred in a
single read from the driver to the application.
Note: The dimension of the buffer associated with the PACKET structure is a
parameter that can sensibly influence the performances of the capture process.
This buffer will in fact receive the packets from the packet capture driver.
The driver is able to collect data from several packets, returning it with only
one read call (see the PacketReceivePacket function). The number of packets
that the driver can transfer to the application in a single call with this
method is limited only by the dimension of the buffer associated with the
PACKET structure used to perform the reading. Therefore setting a big buffer
with PacketInitPacket can throw down the number of system calls, improving the
capture speed. Notice also that, when the application performs a
PacketReceivePacket, it is usually NOT blocked until the buffer associated with
the PACKET structure full. The driver copies the data present in its buffer,
but awakes the application without filling its buffer if it has not enough data
at the moment. In this way, also with big buffers, the application works
efficiently when the data rate on the network is low.
}
//------------------------------------------------------------------------------
// VOID PacketFreePacket(LPPACKET lpPacket)
//------------------------------------------------------------------------------
procedure PacketFreePacket( pPacketpacket);cdecl external DLL;
{
This function frees the PACKET structure pointed by lpPacket.
Warning: The Buffer field of the PACKET structure is not deallocated by this
function, and must be deallocated by the programmer.
}
//------------------------------------------------------------------------------
// BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject, LPPACKET lpPacket,
// BOOLEAN Sync)
//------------------------------------------------------------------------------
Function PacketReceivePacket(AdapterObjectadapter;pPacketPacket;
Sync:Boolean):Longbool;cdecl external DLL;
{
This function performs the capture of a set of packets. It has the following
input parameters:
* a pointer to an ADAPTER structure identifying the network adapter from which
the packets must be captured
* a pointer to a PACKET structure that will contain the packets
* a flag that indicates if the operation will be done in a synchronous or
asynchronous way. If the operation is synchronous, the function blocks the
program, returning only when the it is completed. If the operation is
asynchronous, the function doesn’t block the program, and the PacketWaitPacket
procedure must be used to verify the correct completion.
The number of packets received with this function cannot be known before the
call and can vary a lot. It depends on the number of packets actually stored in
the driver’s buffer, on the size of these packets, and on the size of the buffer
associated with the lpPacket parameter. Figure 3.1 shows the method used by the
driver in order to send the packets to the application.
[BPF_HDR]
[ DATA ]
[PADDING]
[BPF_HDR]
[ DATA ]
[PADDING]
Figure 3.1: method used to encode the packets
Packets are stored in the buffer associated with the lpPacket PACKET structure.
Each packet has a trailer consisting in a bpf_hdr structure that defines its
length and holds its timestamp. At the end of the packet there is a padding
used to word-align the data in the buffer (to increase the speed of the copies).
In order to extract the packets from the buffer the bh_datalen and bh_hdrlen of
the bpf_hdr structures should be used. An example can be seen in the sample
application provided in the developer's pack, or in the pcap_read() function in
the pcap-win32.c file (that can be found in the source distribution). Pcap
extracts correctly each incoming packet before passing it to the application,
so an application that uses it will not have to do this operation.
}
//------------------------------------------------------------------------------
// BOOLEAN PacketWaitPacket(LPADAPTER AdapterObject, LPPACKET lpPacket)
//------------------------------------------------------------------------------
function PacketWaitPacket(AdapterObjectadapter;lpPacketpacket):LongBool;
cdecl external dll;
{
This function is used to verify the completion of an I/O operation on the
packet capture driver. It is blocking if the operation has still to be
completed by the driver. The return value is TRUE if the operation was
successful, FALSE otherwise, and the SDK GetLastError function can be used in
order to retrieve the error code.
}
//------------------------------------------------------------------------------
// BOOLEAN PacketSendPacket(LPADAPTER AdapterObject, LPPACKET pPacket, BOOLEAN Sync)
//------------------------------------------------------------------------------
Function PacketSendPacket( AdapterObjectadapter;pPacketPacket;Sync:boolean)
:Longbool ;cdecl external dll;
{This function is used to send a packet to the network through the adapter
specified with the AdapterObject parameter. It has the same syntax of the
PacketReceivePacket function. This function can be used to send only a packet
at a time and the user will not have to put a bpf_hdr header before it.
}
//------------------------------------------------------------------------------
// BOOLEAN PacketResetAdapter(LPADAPTER AdapterObject)
//------------------------------------------------------------------------------
Function PacketResetAdapter( AdapterObjectadapter):Longbool; cdecl external dll;
{
It resets the adapter passed as input parameter. Returns TRUE if the operation
is performed successfully.
}
//------------------------------------------------------------------------------
// BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject, ULONG Filter)
//------------------------------------------------------------------------------
Function PacketSetHwFilter( AdapterObjectointer;Filter:Longword):Longbool;
cdecl external dll;
{
This function sets a hardware filter on the incoming packets. The constants
that define the filters are declared in the file ntddndis.h. The input
parameters are the adapter on which the filter must be defined, and the
identifier of the filter. The value returned is TRUE if the operation was
successful. Here is a list of the most useful filters:
NDIS_PACKET_TYPE_PROMISCUOUS: set the promiscuous mode. Every incoming packet is
accepted by the adapter.
NDIS_PACKET_TYPE_DIRECTED : only the packets destined to the adapter are
accepted.
NDIS_PACKET_TYPE_BROADCAST : only the broadcast packets are accepted.
NDIS_PACKET_TYPE_MULTICAST : only the multicast packets belonging to the groups
of which this adapter is a member are accepted.
NDIS_PACKET_TYPE_ALL_MULTICAST: every multicast packet is accepted
}
//------------------------------------------------------------------------------
// BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set, PPACKET_OID_DATA
// OidData)
//------------------------------------------------------------------------------
Function PacketRequest( AdapterObjectadapter;isSet:Longbool;OidData:
PPacket_oid_data ):Longbool;cdecl external DLL;
{This function is used to perform a query/set operation on the adapter pointed
by AdapterObject. The second parameter defines if the operation is a set
(set=1) or a query (set=0). The third parameter is a pointer to a
PACKET_OID_DATA structure (see the section on the data structures).
The return value is true if the function is completed without errors.
The constants that define the operations are declared in the file ntddndis.h.
More details on the argument can be found in the documentation provided with
the DDK.
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, no provided by all the
adapters (see the DDKs to see which functions are mandatory). If you use a
facultative function, please be careful and enclose it in an if statement to
check the result.
}
//------------------------------------------------------------------------------
//BOOLEAN PacketSetBuff(LPADAPTER AdapterObject, int dim)
//------------------------------------------------------------------------------
function PacketSetBuff(AdapterObject: Padapter;dim:integer) : Longbool;
cdecl external DLL;
{This function is used to set a new dimension of the driver’s circular buffer
associated with the adapter pointed by AdapterObject. dim is the new dimension
in bytes. 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 driver’s buffer affects HEAVILY the performances of
the capture process. In fact, a capture application needs to make operations on
each packet while the CPU is shared with other tasks. Therefore the application
should not be able to work at network speed during heavy traffic or bursts,
especially in presence of high CPU load due to other applications. This problem
is more noticeable on slower machines. The driver, on the other hand, runs in
kernel mode and is written explicitly to capture packets, so it is very fast
and usually does not loose packets. Therefore, an adequate buffer in the driver
to store the packets while the application is busy can compensate the slowness
of the application and can avoid the loss of packets during bursts or high
network activity. When an instance of the driver is opened the dimension of the
buffer is set to 0. The programmer must remember to set it to a proper value.
Libpcap calls this functions and sets the buffer size to 1MB. Therefore programs
written using libpcap usually do not need to cope with this problem.
}
//------------------------------------------------------------------------------
// BOOLEAN PacketSetBpf(LPADAPTER AdapterObject, struct bpf_program *fp)
//------------------------------------------------------------------------------
function PacketSetBpf( AdapterObjectadapter;fpbpf_program):Longbool;cdecl
external DLL;
{This function associates a new BPF filter with the adapter AdapterObject.
The filter, pointed by fp, is a set of instructions that the BPF
register-machine of the driver will execute on each packet. Details can be
found into the chapter on the driver, or in [McCanne and Jacobson 1993].
This function returns TRUE if the driver is set successfully, FALSE if an
error occurs or if the filter program is not accepted. The driver performs a
check on every new filter in order to avoid system crashes due to bogus or
buggy programs, and it rejects the invalid filters.
If you need to create a filter, use the pcap_compile function of libpcap.
It converts a text filter with the syntax of WinDump (see the manual of
WinDump for more details) into a BPF program. If you don't want to use libpcap,
but you need to know the code of a filter, launch WinDump with the -d or -dd
or -ddd parameters.
}
//------------------------------------------------------------------------------
// BOOLEAN PacketGetStats(LPADAPTER AdapterObject, struct bpf_stat *s)
//------------------------------------------------------------------------------
function PacketGetStats( AdapterObjectadapter;s: Pbpf_stat):Longbool;cdecl
external DLL;
{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.
* the number of packets received by the adapter but that have been dropped by
the kernel. A packet is dropped when the application is not ready to get it
and the buffer associated with the adapter is full.
The two values are copied by the driver in a bpf_stat structure (see section 3
of this manual) provided by the application. These values are very useful to
know the situation of the network and the behavior of the capture application.
They are also very useful to tune the capture stack and to choose the
dimension of the buffers. In fact:
a high value of the bs_recv variable means that there is a lot of traffic on the
network. If the application doesn’t need all the packets (for example a monitor
application may want to capture only the traffic generated by a particular
protocol, or by a single host), it is better to set a selective BPF filter,
to minimize the number of packets that the application has to process. Since
the filter works at kernel level, an appropriate filter increases the
performances of the application and decreases the load on the system. In
this way a non interesting packet does not need to be transferred from kernel
to user space, avoiding the memory copy and the context switch between kernel
and user mode.
If bs_drop is greater than zero, the application is too slow and is loosing
packets. The programmer can try, as a first solution, to set a greater buffer
in the driver with the PacketSetBuff function. A proper dimension of the buffer
often decreases dramatically the packet loss. Another solution is to speed up
the capture process associating a bigger buffer with the PACKET structure used
in the PacketReceivePacket call (see the PacketInitPacket function). This
decreases the number of system calls, improving the speed.
If the application keeps on loosing packets, probably it should be rewritten or
optimized. The driver is already very fast, and probably it is better to modify
the application than the driver, where the main optimization that can be done
is the implementation of the word-alignment.
}
//------------------------------------------------------------------------------
// BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type)
//------------------------------------------------------------------------------
Function PacketGetNetType (AdapterObjectadapter; nettypenet_Type):LongBool;
cdecl external DLL;
{Returns the type of the adapter pointed by AdapterObject in a NetType structure.
The LinkType of the type paramter can be set to one of the following values:
NdisMedium802_3: Ethernet (802.3)
NdisMedium802_5: Token Ring (802.5)
NdisMediumFddi: FDDI
NdisMediumWan: WAN
NdisMediumLocalTalk: LocalTalk
NdisMediumDix: DIX
NdisMediumArcnetRaw: ARCNET (raw)
NdisMediumArcnet878_2: ARCNET (878.2)
NdisMediumWirelessWan: Various types of NdisWirelessXxx media.
The LinkSpeed field indicates the speed of the network in Bits per second.
The return value is TRUE if the operation is performed successfully.
}
//***********add-in function , add by leo jiang from 23/mar/2003
//function PacketGetNetInfo(AdapterObjectadapter;hostip,netmask:Tbpf_u_int32):LongBool;
// cdecl external DLL;
implementation
end.