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

📄 u_connectionnntp.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_ConnectionNntp.pas,v 1.4 2002/11/02 14:05:37 owns Exp $
 * Represents an Nntp connection
 * An Nntp connection is composed from several messages
 * You can naviguate through the messages with nextMessage
 *
 * TConnectionNntp is easy to use :
 * - create(p_Data,p_Size,p_NumConnection,p_IPSourceAddr, p_SourcePort, p_IPDestAddr, p_DestPort, p_Damaged);
 * - saveMessages
 * - free
 *)
unit u_ConnectionNntp;
interface
uses sysutils,classes,
     u_IPPacket, u_Statistics,u_Filter,u_Mimetypes,u_FileStreamCapture;


// cf RFC0977

type
  TConnectionNntp  = class
  private
    FData            : PChar;        // data (TCP stream) for this connection
    FSize            : Integer;      // size of FData
    FPosition        : Integer;
    FIPSource        : IP_ADDR;
    FSourcePort      : Word;
    FIPDest          : IP_ADDR;
    FDestPort        : Word;
    FNumConnection   : LongInt;
    FDamaged         : Boolean;

    FResponseTextBody       : PChar;
    FResponseTextBodyLength : Integer;
    FResponse        : String;
    FStatusCode      : Integer;
    FHeadBody        : PChar;
    FHead            : PChar;
    FBody            : PChar;
    FHeadBodyLength  : Integer;
    FHeadLength      : Integer;
    FBodyLength      : Integer;
    function readLine : String;
    function getStatusCode(p_Line : String) : Integer;
    procedure readResponseTextBody;
    function nextResponse : String;
  public
    constructor create(p_Data : PChar; p_Size : LongInt;p_NumConnection : LongInt;
                       p_IPSourceAddr : PIP_ADDR; p_SourcePort : Word;
                       p_IPDestAddr : PIP_ADDR; p_DestPort : Word; p_Damaged : Boolean);
    procedure saveMessages;
    function firstMessage : boolean;
    function nextMessage : boolean;
    property IPSource : IP_ADDR read FIPSource;
    property SourcePort : Word read FSourcePort;
    property IPDest : IP_ADDR read FIPDest;
    property DestPort : Word read FDestPort;

    property Head : PChar read FHead;
    property Body : PChar read FBody;
    property HeadBody : Pchar read FHeadBody;
    property HeadLength : Integer read FHeadLength;
    property BodyLength : Integer read FBodyLength;
    property HeadBodyLength : Integer read FHeadBodyLength;
  end;

implementation


// read a line
function TConnectionNntp.readLine : String;
begin
  result := '';
  while (FData[FPosition] <> #13) do
  begin
    result := result + FData[FPosition];
    Inc(FPosition);
    if (FPosition = FSize) then exit;
  end;
  Inc(FPosition,2); // for #13 #10 (CRLF)
end;

// return the status code of the "status response line"
// returns 0 (this code does not exist for NNTP) if p_Line is not a "status response line"
function TConnectionNntp.getStatusCode(p_Line : String) : Integer;
var
  l_StatusCodeString : String;
begin
  if (Length(p_Line) >= 3) then
  begin
    l_StatusCodeString := p_Line[1]+p_Line[2]+p_Line[3];
    result := StrToIntDef(l_StatusCodeString,0);
  end else
    result := 0;
end;

// read "text" from a "text response"
// remark : if the text contained a period as the first character of the text
//   line in the original, that first period is doubled.
//   So we should replace a '..' by a  '.' but we don't do that for now
procedure TConnectionNntp.readResponseTextBody;
var
  l_PositionTextBody : Integer; // position du d閎ut du body
  l_Line             : String;
  l_PositionLine     : Integer;
begin
  FResponseTextBody := @(FData[FPosition]);
  FResponseTextBodyLength := 0;
  l_PositionTextBody := FPosition;
  while (FPosition < FSize) do
  begin
    l_PositionLine := FPosition;
    l_Line := readLine;
    if (l_Line = '.') then
    begin
      FResponseTextBodyLength := l_PositionLine-l_PositionTextBody; // on n'a pas besoin du '.'
      exit;
    end;
  end;
end;

// return the next response
// response which are interesting are those which begin with 220, 221 and 222
function TConnectionNntp.nextResponse : String;
var
  l_Line : String;
begin
  FResponse := ''; // texte de la r閜onse
  FStatusCode := 0; FResponseTextBody := nil; FResponseTextBodyLength := 0;
  while (FPosition < FSize) do
  begin
    l_Line := readLine;
    FStatusCode := getStatusCode(l_Line);
    if (FStatusCode <> 0) then
    begin
      FResponse := l_Line;
      result := FResponse;
      readResponseTextBody;
      exit;
    end;
  end;
  result := '';
end;


// go to the first message
// return false if there is no messages
function TConnectionNntp.firstMessage : boolean;
begin
  FPosition := 0;
  result := nextMessage;
end;

// go to the next message
// the message is in FHeadBody or separated in two in FHead and FBody
// returns false if there is no more message
function TConnectionNntp.nextMessage : boolean;
begin
  FHeadBody := nil; FHeadBodyLength := 0;
  FHead := nil; FHeadLength := 0;
  FBody := nil; FBodyLength := 0;
  nextResponse;
  while (FResponse <> '') do
  begin
    if (FStatusCode = 220) then
    begin
      FHeadBody := FResponseTextBody;
      FHeadBodyLength := FResponseTextBodyLength;
      result := true;
      exit;
    end;
    if (FStatusCode = 221) then
    begin
      FHead := FResponseTextBody;
      FHeadLength := FResponseTextBodyLength;
    end;
    if (FStatusCode = 222) then
    begin
      FBody := FResponseTextBody;
      FBodyLength := FResponseTextBodyLength;
    end;
    if (FHead <> nil) and (Fbody <> nil) then
    begin
      result := true;
      exit;
    end;
    nextResponse;
  end;
  // pour 関iter que l'un seulement des deux soit <> nil
  FHead := nil; FHeadLength := 0;
  FBody := nil; FBodyLength := 0;
  result := false;
end;

// save all the messages
procedure TConnectionNntp.saveMessages;
var
  l_NumMessage : Integer;
  l_UniqueId   : String;
  l_FileStream : TFileStreamCapture;
  l_FilePath   : String;
  l_HasMessage : Boolean;
  l_MimeType   : TMimeType;
begin
  try
  l_HasMessage := firstMessage; l_NumMessage := 0;
  l_MimeType := TMimeType.create('internal/rfc822-news');
  while (l_HasMessage) do
  begin
    l_UniqueId := IntToStr(FNumConnection)+'-'+IntToStr(l_NumMessage);
    if FDamaged then l_UniqueId := l_UniqueId + ' DAMAGED ';
    l_FilePath := g_Filter.getFilePath(
                l_UniqueId,
                l_MimeType,
                @(IPSource[0]),SourcePort,
                @(IPDest[0]),DestPort);

    l_FileStream := TFileStreamCapture.create(l_FilePath);
    if (HeadBody <> nil) then
    begin
       l_FileStream.write(HeadBody^,HeadBodyLength);
    end
    else
    begin
       l_FileStream.write(Head^,HeadLength);
       l_FileStream.write(Body^,BodyLength);
    end;
    l_FileStream.free;

    Inc(l_NumMessage);

    l_HasMessage := nextMessage;
  end;
  l_MimeType.free;
  except

  end;
end;

constructor TConnectionNntp.create(p_Data : PChar; p_Size : LongInt;p_NumConnection : LongInt;
                                p_IPSourceAddr : PIP_ADDR; p_SourcePort : Word;
                                p_IPDestAddr : PIP_ADDR; p_DestPort : Word; p_Damaged : Boolean);
var
  i : Integer;
begin
  FDestPort := p_DestPort;
  FSourcePort := p_SourcePort;
  for i := 0 to 3 do
  begin
    FIPDest[i] := p_IPDestAddr[i];
    FIPSource[i] := p_IPSourceAddr[i];
  end;
  FData := p_Data;
  FSize := p_Size;
  FNumConnection := p_NumConnection;
  FDamaged := p_Damaged;
end;


end.

⌨️ 快捷键说明

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