⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcap.pas

📁 Magenta Systems Internet Packet Monitoring Components are a set of Delphi components designed to cap
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{ Magenta Systems Internet Packet Monitoring Components

********************************************************************************
--------------------------------------------------------------------------------
                         Plibcap Highlevel function calls

                for Packet Capture Driver by Politecnico di Torino

     Code converted and modified from C to Pascal by Lars Peter Christiansen
--------------------------------------------------------------------------------
 TERMS AND CONDITIONS OF USE.
 some parts of this software is Copyright(C) 2000 Lars Peter Christiansen.

 The author of this software assumes no liability for damages caused under
 any circumstances whatsoever, and is under no obligation. Use of the software
 indicates acceptance of all conditions contained in this document. If you do
 not agree to these terms, you must delete this software immediately.

 You may distribute the archive in which this software is distributed, but
 under no circumstances must this archive be changed. Distributing a modified
 archive is a violation of the software license.

 If you do redistribute this software, please let me know at the email address
 given below.

 If you have any questions, requests, bug reports, etc., please contact me at
 the address given below.

Lars Peter Christiansen
Email  : lp@nzlab.dk
Website: http://www.nzlab.dk

Plibcap.c author:
old website: http://netgroup-serv.polito.it/windump
new website: http://www.winpcap.org/

Updated by Angus Robertson, Magenta Systems Ltd, England, 30th October 2005
delphi@magsys.co.uk, http://www.magsys.co.uk/delphi/
Some parts Copyright Magenta Systems Ltd

--------------------------------------------------------------------------------

                          [ user application ]
                          [       PCAP       ] <- you are here!
                          [    PacketAPI     ]
            -------------------------------------------------------
            [ Windows 95/98 |  Windows NT  |  Windows2000/XP/W2K  ]
            [  Packet.dll   |  Packet.dll  |  packet.dll          ]
            [  npf.vxd      |  npf.sys     |  npf.sys             ]
            -------------------------------------------------------
                          [    Netadapter    ]


   Original Filename : Pcap.pas

   Implemented Original Functions :
      Function pcap_open_live() : PPcap
      function pcap_read()      : integer
      function pcap_stats()     : integer
      function pcap_setbuff()   : integer
      function pcap_loop()      : integer
      function pcap_datalink    : integer

   Modified/added/removed :

    30th October 2005 - Angus Robertson, Magenta Systems Ltd
                  replaced static linkage with dynamic DLL loading
                  added new winpcap website
                  fixed Pcap_GetAdapternames not returning any names for Windows 2000 and 2003,
                    now checking WinPcap version so 3.0 and 3.1 both supported transparently
                  added Pcap_GetAdapternamesEx to return both adaptor names and friendly descriptions
                  added Pcap_GetDriverVersion (3.1), Pcap_GetPacketVersion
                  added Pcap_GetIPAddresses to get adapter IP addresses
                  added Pcap_SetMinToCopy (3.1)
                  pcap_open_live tries to set SnapLen (3.1)
                  added Pcap_GetMacAddress, useful to see if packets are being sent or received
                  tested with 3.1 final release 5th August 2005

    25-05-2005:
      Seems WinPcap 3.1 returns 8-bit adapternames in XP. issue fixed

    17-1-2002:
      Pcap_loop() : Fixed silly bug not exiting endless loop
      pcap_getwinversion(): updated to include WinXP and WinME

    28-1-2001:
      Function Pcap_GetAdapternames() : bug found&fixed [ by _blade_ ]
      Function Pcap_Read() : fixed wrong headerpos in packets. [Jody Dawkins]

     4-2-2000:
      Function Pcap_close  : now removing pcap.buffer from memory
    Older:
      function wsockinit()      : integer; // Removed. obsolete in Delphi
      function  pcap_lookupdev(): pchar;   // Modified to Delphi's advantage
      function pcap_getwinversion: Twinversion // added. Much easier OS handling
      function Pcap_getAdapternames() : String // Hand in hand with Tlist.commatext


   Wanted :
      function pcap_GetMACAddr()  : boolean;
      function pcap_open_offline  : PPcap; + offline functions

********************************************************************************
}

unit Pcap;

interface
uses windows,
     Ndis_def,
     bpf,
     sysutils,  // formatting tools. Could use FormatMessage,but is more complex
     classes,
     winsock, 
     Packet32;  // This is what we wrap

const
  PCAP_ERRBUF_SIZE = 256;              //String size of error descriptions
  PcapBufSize      = 256000;           //Dimension of the buffer in TPcap


// [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
  TWinVersion = (wv_WinS,
                 wv_Win9x,              //Added by Lars Peter Christiansen.
                 wv_WinNT,              //Eases the process of determing the
                 wv_Win2000,             //platform and do proper instructions
                 wv_WinXP,               //I.e : Char vs. WideChar issue
                 wv_Unknown );



  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_sf = record                      // Save file for offline reading.
    rfile : HFILE;
    swapped:integer;
    version_major : integer;
    Version_Minor : integer;
    base : Pointer;
  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_PktHdr = ^Tpcap_pkthdr;        // Wrapped Drivers packetHeader
  TPcap_pkthdr = record
    ts     : TUnixTimeVal;             // Time of capture
    CapLen,                            // captured length
    Len    : Integer;                  // actual length of packet
  end;

  PPcap = ^TPcap;                      // THE MAIN INTERFACE HANDLE
  TPcap = record                       // used with allmost all Pcap calls.
    Adapter:Padapter;
    Packet :PPacket;                   // 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  :Pointer; //*u_char
    bp      :Pointer; //*u_char
    cc      :integer;
    //Place holder for pcap_next().
    pkt     :Pointer; //*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;


  // Callback procedure
  Ppcap_handler =^Tpcap_handler;
  Tpcap_handler = procedure(User:pointer;const Header:Ppcap_pkthdr;const Data:pchar);

  // array of IP addresses
  IPAddrArray = array of TInAddr ;

  // a MAC address
  TMacAddr = array [0..5] of byte ;

function  pcap_open_live(Device:String;SnapLen:LongWord;Promisc:boolean;
          To_ms:integer;var errstr:String) : ppcap;
function  pcap_read(p:PPcap;cnt:integer;CallBack:Tpcap_handler;User:pointer) :integer;
function  pcap_stats    (P: pPcap;ps:PPcap_stat) : integer;
function  pcap_setbuff  (p : Ppcap;dim:integer) : integer;
procedure pcap_close    (var p : ppcap);
function  pcap_lookupdev(var ErrStr:string) : pchar;
function pcap_loop(P:Ppcap;cnt:integer;Callback:Tpcap_handler;user:pointer):integer;
function pcap_datalink(P:PPcap) : integer;
function pcap_getwinversion(var verstr:string) : Twinversion;
function Pcap_getAdapternames(Delimiter:char;var ErrStr:string):string;
function Pcap_GetAdapternamesEx (NameList, DescList: TStringList; var ErrStr:string):integer;
function Pcap_GetDriverVersion: string ;
function Pcap_GetPacketVersion: string ;
function Pcap_GetIPAddresses (AdapterName: string ; var IPArray, MaskArray,
                                BcastArray: IPAddrArray; var ErrStr:string): integer ;
function Pcap_SetMinToCopy (P: pPcap ; nbytes: integer) : integer;
function Pcap_GetMacAddress (P: pPcap; var ErrStr:string): TMacAddr ;

implementation


//------------------------------------------------------------------------------
//  pcap_t *pcap_open_live(char *device, int snaplen, int promisc,
//                         int to_ms, char *ebuf)
//------------------------------------------------------------------------------
function pcap_open_live(Device:String;SnapLen:LongWord;Promisc:boolean;
         To_ms:integer;var errstr:String) : ppcap;
  var
     P : Ppcap;
     NetType : Tnet_type;
     S : Pchar;

     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
    result :=nil;
    if NOT LoadPacketDll then
      begin
        ErrStr := 'Cannot load packet.dll';
        exit;
      end;

    // CREATE PCAP OBJECT

    GetMem(P,SizeOf(Tpcap));
    if P=nil then
      begin
        ErrStr := 'Cannot allocate pcap object';
        exit;
      end;
    FillChar(p^,sizeof(Tpcap),0);
    P.Adapter := nil;

    // CREATE ADAPTER OBJECT
    GetMem(S,2048);                       // Making temporary pchar
    StrPCopy(S,Device);
    P.Adapter := PacketOpenAdapter(S);
    FreeMem(S,2048);
    if P.Adapter = nil then
      begin
        ErrStr := 'Cannot Open Adapter "'+Device+'"';
        CleanUp;
        exit;
      end;


   // SET FILTER MODE
    if Promisc then
      begin
        if not PacketSetHWFilter(P.adapter,NDIS_PACKET_TYPE_PROMISCUOUS) then
          Begin
            ErrStr:= 'Cannot set Device Filter to Promiscuous mode';
            cleanup;
            exit;
          end;
      end else if not PacketSetHWFilter(P.adapter,NDIS_PACKET_TYPE_DIRECTED) then
          begin
            ErrStr:= 'Cannot set Device Filter to Directed mode';
            cleanup;
            exit;
          end;

    // GET NETCARD SPEED AND TYPE
    if not PacketGetNetType(P.Adapter,@Nettype) then
       Begin
         ErrStr := 'Cannot determine network type and speed';
         Cleanup;
         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
        ErrStr := 'Cannot allocate Link Header space';
        cleanup;
        exit;
      end;

    if Assigned (PacketSetSnapLen) then
        p.snapshot := PacketSetSnapLen(P.adapter, Snaplen)     // Angus - added, actually set it for 3.1 
    else
        p.snapshot := Snaplen ; 

    // Allocate Global Packet for capturing

    p.packet := PacketAllocatePacket;
    if p.packet = nil then
      begin
        ErrStr := 'Cannot allocate Global Packet Object';
        cleanup;
        exit;
      end;
    PacketInitPacket(p.Packet,p.buffer,p.bufsize);

    // Allocate Driver Buffer
    if not PacketSetBuff(p.adapter,DEFAULT_DRIVERBUFFER) then
      begin
        ErrStr := 'Not enough memory to allocate Driver buffer';
        CleanUp;
        exit;
      end;

    result := p;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -