📄 u_connectionstcp.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_ConnectionsTCP.pas,v 1.6 2001/08/18 12:38:26 owns Exp $
* Contains all TCP active connections
* There are two main functions here :
* - addTCPPacket which add a TCP packet to the correct TCP Connection or
* creates a new one
* - verifyTimeout which verifies if a TCP Connection has been accessed for
* timeout seconds. Otherwise the connection is closed (files are created)
*)
unit u_ConnectionsTCP;
interface
uses SyncObjs,
u_DebugPacket,u_TCPPacket,u_IPPacket,classes,sysutils, //FileCtrl,
u_Filter, u_ConnectionTCP, u_COnnectionHTTP,u_Statistics, u_HashTable,u_Debug;
// on ne peut pas utiliser le flag FIN car on n'a que la r閏eption des trames
// -> l'閙etteur envoie FIN mais pour que ce soit fini le r閏epteur doit aussi
// envoyer FIN ce qu'il ne fait pas forc閙ent tout de suite
// two threads use FFConnections
// - the first thread add packets to TCP connections
// - the second one free TCP connections that seem not to be used anymore
// We must not free a connection for which packets are being added
// or add a packet to a connection that is being freed
// So we use a critical section to avoid such situations
type
TConnectionsTCP = class
private
FFConnections : THashTable; // all active connections
FNumConnections : LongInt;
FTimeOut : Cardinal; // number of ms after which we consider the connection closed
FLastVerifTimeOut : Cardinal; // time when the last verification took place
FLastMoment : Cardinal; // time of reception of last packet
FCriticalSection : TCriticalSection;
function getConnectionTCP(p_TCPPacket : TTCPPacket) : TConnectionTCP;
procedure verifyTimeOutForConnection(const p_TCPConnection : TObject;const p_Index : LongInt);
function isNewConnection(p_PacketTCP : TTCPPacket) : boolean;
procedure setLastMomentReception(p_LastMoment : Cardinal);
public
constructor create;
destructor destroy; override;
procedure addTCPPacket(p_TCPPacket : TTCPPacket;p_MomentReception : Cardinal);
procedure VerifyTimeOut;
property timeout : Cardinal read FTimeOut write FTimeOut;
property lastMomentReception : Cardinal write setLastMomentReception;
end;
implementation
////////////////////////////////////////////////////////////////////////////////
//
// TConnectionsTCP
//
////////////////////////////////////////////////////////////////////////////////
constructor TConnectionsTCP.create;
begin
// We create a hashtable that can contain 100000 connections. That should be
// enough
FFConnections := THashTable.create(100000);
FNumConnections := 0;
FTimeOut := 10000;//5000;
FLastMoment := 0;
FCriticalSection := TCriticalSection.create;
end;
destructor TConnectionsTCP.destroy;
begin
FFConnections.free;
FCriticalSection.free;
end;
procedure TConnectionsTCP.setLastMomentReception(p_LastMoment : Cardinal);
begin
FCriticalSection.Enter;
FLastMoment := p_LastMoment;
FCriticalSection.Leave;
end;
// called when a TCP packet has been received
// returns false if the packet has been rejected
//(when the packet is not a packet that begins a new connection or when it does not belong to
// an existing TCP connection)
procedure TConnectionsTCP.addTCPPacket(p_TCPPacket : TTCPPacket;p_MomentReception : Cardinal);
var
l_ConnectionTCP : TConnectionTCP;
begin
(*
with p_TCPPacket do
if (IPDestAddr[0] = 193) and (IPDestAddr[1] = 226) and (IPDestAddr[2] = 118) and (IPDestAddr[3] = 131) and
(TCPDestPort = 2419) then
begin
// asm
// int 3
// end;
end;
*)
FCriticalSection.Enter;
try
FLastMoment := p_MomentReception;
l_ConnectionTCP := getConnectionTCP(p_TCPPacket);
// part of a TCP connection TCP
if (l_ConnectionTCP <> nil) then
begin
l_ConnectionTCP.addTCPPacket(p_TCPPacket,p_MomentReception);
end
else
begin
// a new connection (on la prend peut-阾re en route!)
// if (p_TCPPacket.TCPFlag and TCP_FLAG_SYN <> 0) c'est qu'on la prend au d閎ut
if (isNewConnection(p_TCPPacket)) then
begin
l_ConnectionTCP := TConnectionTCP.create(FNumConnections,p_TCPPacket,p_MomentReception);
FFConnections.AddItemRandom(l_ConnectionTCP);
Inc(FNumConnections);
end; // else FDebugPacket.debugPacket(p_TCPPacket,p_MomentReception);
end;
finally
FCriticalSection.Leave;
end;
end;
// tell if p_PacketTCP can be a packet that can start a TCP connection
// we don't see if packet has the SYN flag because we are interested in a packet
// which begins with "HTTP" even if in fact it does not really begin a TCP connection
function TConnectionsTCP.isNewConnection(p_PacketTCP : TTCPPacket) : boolean;
begin
if ((g_Filter.SavePop3) and (p_PacketTCP.TCPSourcePort = 110)) then
begin
result := true;
exit;
end;
if ((g_Filter.SaveNntp) and (p_PacketTCP.TCPSourcePort = 119)) then
begin
result := true;
exit;
end;
if (g_Filter.SaveHttp) and (p_PacketTCP.TCPDataLength >= 5) then
begin
if ((p_PacketTCP.TCPData[0] = 'H') and
(p_PacketTCP.TCPData[1] = 'T') and
(p_PacketTCP.TCPData[2] = 'T') and
(p_PacketTCP.TCPData[3] = 'P')) then
begin
result := true;
exit;
end;
end;
if ((g_Filter.FilterOthers.SaveTCPStream) and
(p_PacketTCP.TCPSourcePort <> 80) and
(p_PacketTCP.TCPSourcePort <> 8080) and
(p_PacketTCP.TCPSourcePort <> 110) and
(p_PacketTCP.TCPSourcePort <> 119)) then
begin
result := true;
exit;
end;
result := false;
end;
// returns TCP connection to which this packet belongs
function TConnectionsTCP.getConnectionTCP(p_TCPPacket : TTCPPacket) : TConnectionTCP;
begin
with FFConnections do
result := Value[FindItemRandom(p_TCPPacket)];
(*
if (result <> nil) then
if((result.IPDestAddr[0] <>p_TCPPacket.IPDestAddr[0]) or
(result.IPDestAddr[1] <>p_TCPPacket.IPDestAddr[1]) or
(result.IPDestAddr[2] <>p_TCPPacket.IPDestAddr[2]) or
(result.IPDestAddr[3] <>p_TCPPacket.IPDestAddr[3]) or
(result.DestPort <> p_TCPPacket.TCPDestPort)) then
// ne passe jamais ici c'est OK
asm
int 3
end; *)
end;
// this procedure is called from a different thread
procedure TConnectionsTCP.verifyTimeOutForConnection(const p_TCPConnection : TObject;const p_Index : LongInt);
var
l_ConnectionTCP : TConnectionTCP;
begin
l_ConnectionTCP := p_TCPConnection as TConnectionTCP;
try
if FLastVerifTimeOut < l_ConnectionTCP.LastMomentReception then exit;
// il peut arriver ici qu'une exception soit d閏lench閑 car FLastVerifTimeOut < l_ConnectionTCP.LastMomentReception
// (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -