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

📄 u_capture.pas

📁 linux program to read packet data
💻 PAS
字号:
(*
 * One Way Network Sniffer (OWNS)
 * Copyright (C) 2001-2002 OWNS
 *
 * http://owns.sourceforge.net/
 * http://www.owns.st
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *)

(*
 * $Id: u_capture.pas,v 1.8 2001/10/01 20:20:37 owns Exp $
 * Main class for capturing from an ethernet interface
 *
 *
 * FCapture := TCapture.create;
 * FLibpCapSniffer := TLibpCapSniffer.create;
 * FLibpCapSniffer.AdapterIndex := 1;
 * FLibpCapSniffer.mode := Live;
 * FCapture.Sniffer := FLibpCapSniffer;
 * FCapture.startCapture;
 *
 * => Many options can be changed with filter property
 * => You can get statistics about current capture with Statistics property
 *
 * files are created in files subdirectory
 *
 * 2 threads are created in addition to main thread
 * - a thread that will capture packets (created when TSniffer.create is called)
 * - a thread that will create files (TEndConnection.Thread)
 *)


unit u_capture;
interface
uses classes,SysUtils,
     u_statistics, u_Filter,u_ConnectionsTCP,
     u_Packet, u_EthernetFrame, u_TCPPacket,
     u_Sniffer, u_Debug;

type
  ECaptureException = class(Exception);
  TEndCaptureEvent = procedure of object;

  TEndConnectionThread = class;

  TCapture = class
  private
    FSniffer         : TSniffer;
    FConnectionsTCP      : TConnectionsTCP;
    FEndConnectionThread : TEndConnectionThread;
    FSaveNonTCP       : Boolean;
    FFileStreamNonTCP : TFileStream;
    FTimeOutTCP       : Cardinal;
    FEndCapture       : TEndCaptureEvent;

    function getStatistics : TStatistics;
    function getFilter : TFilter;
    procedure OnPacket(p_packet : Pointer; p_RecvBytes: Word; p_Tick : Cardinal);
    procedure setSniffer(p_Sniffer : TSniffer);
    procedure EndSniffing;
    procedure EndConnectionThreadTerminated(Sender: TObject);
  public
    constructor Create; virtual;
    destructor destroy; override;
    procedure startCapture;
    procedure stopCapture;
    property Statistics : TStatistics read getStatistics;
    property Filter : TFilter read getFilter;
    property SaveNonTCP : boolean read FSaveNonTCP write FSaveNonTCP;
    property TimeOutTCP : Cardinal read FTimeOutTCP write FTimeOutTCP;
    property Sniffer : TSniffer read FSniffer write setSniffer;
    property OnEndCapture : TEndCaptureEvent read FEndCapture write FEndCapture;
  end;

  // this thread will call verifyTimeOut
  TEndConnectionThread = class(TThread)
  private
    FCapture : TCapture;
    FCanBeTerminated : Boolean;
  public
    constructor Create(p_Capture : TCapture); virtual;
    procedure Execute; override;
    property CanBeTerminated : Boolean read FCanBeTerminated;
  end;


implementation


// do not try to change FSniffer priority. This does not yield to good results
// keep priority to tpIdle for EndConnection too
constructor TCapture.Create;
begin
  FSaveNonTCP := false;
  FTimeOutTCP := 10000; // number of ms of inactivity after which we consider the connection as closed

  FSNiffer := nil;
  FEndCapture := nil;
end;

destructor TCapture.destroy;
begin
  if (FSniffer <> nil) then
  begin
    if FSniffer.Snooping then
      stopCapture;
  end;
  inherited;
end;

// Set the sniffer that we want to use
// see : u_ObserverSniffer, u_LibpcapSniffer, u_SehSniffer
procedure TCapture.setSniffer(p_Sniffer : TSniffer);
begin
  FSniffer := p_Sniffer;

  FSniffer.OnPacket := onPacket;
  FSniffer.OnEndSniffing := EndSniffing;
end;


// this function is called when an ethernet packet is received
procedure TCapture.OnPacket(p_packet : Pointer; p_RecvBytes: Word; p_Tick : Cardinal);
var
  l_Packet : TEthernetFrame;
  l_PacketTCP : TTCPPacket;
begin
  l_Packet := getPacket(p_packet);
  g_Statistics.packetReceived(l_packet,p_RecvBytes);
  if (l_Packet is TTCPPacket) then
  begin
    l_PacketTCP := l_Packet As TTCPPacket;
    FConnectionsTCP.addTCPPacket(l_PacketTCP,p_Tick);
  end else
  if SaveNonTCP then
    FFileStreamNonTCP.write(p_packet^,p_RecvBytes);

  l_Packet.free;
end;

// start capture
procedure TCapture.startCapture;
var
  l_ErrStr : String;
begin
  If SaveNonTCP then
    FFileStreamNonTCP := TFileStream.create('NonTCP.bin',fmCreate);
  g_Statistics.StartStatistiques;
  FConnectionsTCP := TConnectionsTCP.create;
  FConnectionsTCP.timeOut := FTimeOutTCP;


  // create thread that will free TCP connection
  FEndConnectionThread := TEndConnectionThread.create(self);
  FEndConnectionThread.OnTerminate := EndConnectionThreadTerminated;
  FEndConnectionThread.FreeOnTerminate := true;

  {$IFDEF MSWINDOWS}
  FEndConnectionThread.Priority := tpIdle;
  {$ENDIF}

  {$IFDEF LINUX}
//  FEndConnectionThread.Priority := -1;
  {$ENDIF}

  FEndConnectionThread.resume;

  if (not FSniffer.Activate(l_ErrStr)) then
  begin
    // an error occured !
    FEndCOnnectionThread.Terminate;
//    FConnectionsTCP.free;
//    if SaveNonTCP then
//      FFileStreamNonTCP.free;
    raise ECaptureException.create(l_ErrStr);
  end;
end;

// stop capture
procedure TCapture.stopCapture;
var
  l_ErrStr : String;
begin
  if (not FSniffer.Deactivate(l_ErrStr)) then
    raise ECaptureException.create(l_ErrStr);
end;

// this function is called when sniffing terminated. This can be because we
// called stopCapture or for any other reason (EOF, exception ...)
procedure TCapture.EndSniffing;
begin
  // FEndConnectionThread takes time before executing Execute Method. This is
  // because of the lower priority of this thread.
  // But we must make sure that verifyTimeOut is executed at least once
  while (FEndConnectionThread.CanBeTerminated = false) do begin end;
  FEndConnectionThread.terminate;
end;

// this function is called when EndCOnnectionThread terminates
procedure TCapture.EndConnectionThreadTerminated(Sender: TObject);
begin
  FConnectionsTCP.free;

  if SaveNonTCP then
    FFileStreamNonTCP.free;

  if assigned(FEndCapture) then FEndCapture;
end;


// Properties
////////////////////////////////////////////////////////////////////////////////

// g_Statistics is a singleton that gives many informations (number of packets received etc ...)
function TCapture.getStatistics : TStatistics;
begin
  result := g_Statistics;
end;

// g_Filter is a singleton. You can use it to filter what you want to save etc ...
function TCapture.getFilter : TFilter;
begin
  result := g_Filter;
end;


////////////////////////////////////////////////////////////////////////////////
//
// TEndConnectionThread
//
////////////////////////////////////////////////////////////////////////////////


constructor TEndConnectionThread.Create(p_Capture : TCapture);
begin
  inherited Create(True);
  FCapture := p_Capture;
  FCanBeTerminated := false;
end;

// All connections that are not being accessed since 10 seconds are considered as
// closed (and are saved on disk in "files" subdirectory if they pass the filter).
procedure TEndConnectionThread.Execute;
var
  l_VerifyOneMoreTime : Boolean;
begin
  // when terminated is set to true, we execute verifyTimeOut one more time
  l_VerifyOneMoreTime := false;
  FCanBeTerminated := True;
  while ((not Terminated) or (l_VerifyOneMoreTime)) do
  begin
    try
      FCapture.FConnectionsTCP.verifyTimeOut;
      if Terminated then
        l_VerifyOneMoreTime := not l_VerifyOneMoreTime;
    except
      on e: Exception do
      begin
        g_Debug.debug('(TEndConnectionThread)'+e.Message+' proc:'+g_CurrentProc,'TEndConnectionThread.Execute');
      end;
    end;
  end;
end;


end.

⌨️ 快捷键说明

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