| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1707 人关注过本帖, 1 人收藏
标题:一个捕捉Ip数据包的问题 !急急急!
只看楼主 加入收藏
pjbpage
Rank: 1
等 级:新手上路
帖 子:55
专家分:0
注 册:2006-10-11
收藏(1)
 问题点数:0 回复次数:1 
一个捕捉Ip数据包的问题 !急急急!
这是一个捕捉IP数据包的程序
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,cap_ip, Grids, ExtCtrls, StdCtrls, Buttons;

type
    Tmy_data=record
    buf:array of char;
  end;
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    ComboBox1: TComboBox;
    Panel1: TPanel;
    StringGrid1: TStringGrid;
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    ComboBox2: TComboBox;
    Edit1: TEdit;
    Panel2: TPanel;
    Panel3: TPanel;
    BitBtn4: TBitBtn;
    Memo2: TMemo;
    Memo1: TMemo;
    BitBtn5: TBitBtn;
    procedure FormCreate(Sender: TObject);
    procedure cap_ip1Cap(ip, proto, sourceIP, destIP, SourcePort,
      DestPort: String; header: PChar; header_size: Integer; data: PChar;
      data_size: Integer);
    procedure StringGrid1Click(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure BitBtn2Click(Sender: TObject);
    procedure BitBtn4Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure BitBtn5Click(Sender: TObject);
  private
    { Private declarations }
  public
    function check_filter(proto, sourceIP, destIP, SourcePort,DestPort: String;data: PChar;data_size: Integer):boolean;
  end;

var
  Form1: TForm1;
  buf_list:array of Tmy_data;
  filter_str:string;
  cap_ip1:Tcap_ip;
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 StringGrid1.Cells[0,0]:='协议';
 StringGrid1.Cells[1,0]:='源地址';
 StringGrid1.Cells[2,0]:='源端口';
 StringGrid1.Cells[3,0]:='目的地址';
 StringGrid1.Cells[4,0]:='目的端口';
 StringGrid1.Cells[5,0]:='数据大小';
 StringGrid1.Cells[6,0]:='数据';
 setlength(buf_list,200);
cap_ip1:=Tcap_ip.Create(self);
cap_ip1.OnCap:=cap_ip1Cap;
 filter_str:=(edit1.Text);
end;
function TForm1.check_filter(proto, sourceIP, destIP, SourcePort,DestPort: String;data: PChar;data_size: Integer):boolean;
var
    i:integer;
    temp_str:string;
begin
 result:=true;
 filter_str:=(edit1.Text);
 if filter_str='' then
  begin
   result:=false;
   exit;
  end;
 if (filter_str='排除协议'+proto) then exit;
 if (filter_str='排除源地址'+sourceIP) then exit;
 if (filter_str='排除源端口'+SourcePort) then exit;
 if (filter_str='排除目的地址'+destIP) then exit;
 if (filter_str='排除目的端口'+DestPort) then exit;

 if (ComboBox2.text='包含') and (ComboBox1.Text<>'内容') then
   begin
     if (filter_str='包含协议'+proto) then begin result:=false;exit;end;
     if (filter_str='包含源地址'+sourceIP) then begin result:=false;exit;end;
     if (filter_str='包含源端口'+SourcePort) then begin result:=false;exit;end;
     if (filter_str='包含目的地址'+destIP) then begin result:=false;exit;end;
     if (filter_str='包含目的端口'+DestPort) then begin result:=false;exit;end;
     result:=true;exit;
   end;

 if (filter_str<>'包含内容') then
   begin
    result:=false;exit;
   end;
  setlength(buf_list[StringGrid1.RowCount-2].buf,data_size);
  copymemory(buf_list[StringGrid1.RowCount-2].buf,data,data_size);
  temp_str:='';
  for i:=0 to data_size-1 do
    temp_str:=temp_str+buf_list[StringGrid1.RowCount-2].buf[i];
    temp_str:=AnsiLowerCase(temp_str);
 result:=false;
end;
procedure TForm1.cap_ip1Cap(ip, proto, sourceIP, destIP, SourcePort,
  DestPort: String; header: PChar; header_size: Integer; data: PChar;
  data_size: Integer);
begin
 if check_filter(proto,sourceIP, destIP, SourcePort,DestPort, data,data_size) then exit;
  with StringGrid1 do
   begin
    Cells[0,StringGrid1.RowCount-1]:=proto;
    Cells[1,StringGrid1.RowCount-1]:=sourceIP;
    Cells[2,StringGrid1.RowCount-1]:=SourcePort;
    Cells[3,StringGrid1.RowCount-1]:=destIP;
    Cells[4,StringGrid1.RowCount-1]:=DestPort;
    Cells[5,StringGrid1.RowCount-1]:=inttostr(data_size);
    Cells[6,StringGrid1.RowCount-1]:=data;
   end;
   setlength(buf_list[StringGrid1.RowCount-2].buf,data_size);
   copymemory(buf_list[StringGrid1.RowCount-2].buf,data,data_size);
 if (StringGrid1.RowCount>200) then
    StringGrid1.RowCount:=2
   else
   begin
    StringGrid1.RowCount:=StringGrid1.RowCount+1;
    StringGrid1.Rows[StringGrid1.RowCount].Clear;
   end;

 stringgrid1.toprow:=StringGrid1.RowCount- StringGrid1.VisibleRowCount;
end;


procedure TForm1.BitBtn1Click(Sender: TObject);
begin
cap_ip1.StartCap;
end;

procedure TForm1.BitBtn2Click(Sender: TObject);
begin
  cap_ip1.StopCap;
end;
 procedure TForm1.StringGrid1Click(Sender: TObject);
var text_str,hex_str,all_str:string;
    i:integer;
    no: Integer;
begin
  memo1.lines.Clear;
  memo2.lines.Clear;
  text_str:='';hex_str:='';all_str:='';
  i:=0;
  while i<= high(buf_list[stringgrid1.Selection.Top-1].buf) do
   begin
     no:=ord(buf_list[stringgrid1.Selection.Top-1].buf[i]);
     hex_str:=hex_str+format('%0.2x',[no])+' ';
     if no<20 then
      begin
        text_str:=text_str+'.';
        all_str:=all_str+'.';
      end else
      begin
        text_str:=text_str+buf_list[stringgrid1.Selection.Top-1].buf[i];
        all_str:=all_str+buf_list[stringgrid1.Selection.Top-1].buf[i];
      end;

     if ((i mod 8)=7) then
      begin
       memo1.lines.add(hex_str+'  |  '+text_str);
       text_str:='';hex_str:='';
      end;
     inc(i);
   end;
 if hex_str<>'' then
   memo1.lines.add(hex_str+format('%'+inttostr(24-length(hex_str))+'s',[' '])+'  |  '+text_str);

  memo2.lines.Add(all_str);
end;

procedure TForm1.BitBtn4Click(Sender: TObject);
begin
  if MessageDlg('确认要退出吗?',mtConfirmation,[mbYes,mbNo],0)=mrYes
     then
     begin
       close;
     end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 cap_ip1.Free;
end;
procedure TForm1.BitBtn5Click(Sender: TObject);
begin
  if MessageDlg('确定要清空吗?',mtConfirmation,[mbYes,mbNo],0)=mrYes
     then
     begin
        StringGrid1.RowCount:=2;
        StringGrid1.Rows[1].Clear;
        memo1.lines.Clear;
        memo2.lines.Clear;
     end;

end;

end.
cap_ip.pas是模块函数供Unit1调用
unit cap_ip;

interface

uses
  Windows, Messages,Classes,winsock,sysutils,dialogs;
const
   WM_CapIp = WM_USER + 200;

   STATUS_FAILED        =$FFFF;        //定义异常出错代码
   MAX_PACK_LEN         =65535;        //接收的最大IP报文
   MAX_ADDR_LEN         =16;        //点分十进制地址的最大长度
   MAX_PROTO_TEXT_LEN   =16;        //子协议名称(如"TCP")最大长度
   MAX_PROTO_NUM        =12;        //子协议数量
   MAX_HOSTNAME_LAN     =255;        //最大主机名长度
   CMD_PARAM_HELP       =true;

   IOC_IN               =$80000000;
   IOC_VENDOR           =$18000000;
   IOC_out              =$40000000;
   SIO_RCVALL           =IOC_IN or IOC_VENDOR or 1;// or IOC_out;
   SIO_RCVALL_MCAST     =IOC_IN or IOC_VENDOR or 2;
   SIO_RCVALL_IGMPMCAST =IOC_IN or IOC_VENDOR or 3;
   SIO_KEEPALIVE_VALS   =IOC_IN or IOC_VENDOR or 4;
   SIO_ABSORB_RTRALERT  =IOC_IN or IOC_VENDOR or 5;
   SIO_UCAST_IF         =IOC_IN or IOC_VENDOR or 6;
   SIO_LIMIT_BROADCASTS =IOC_IN or IOC_VENDOR or 7;
   SIO_INDEX_BIND       =IOC_IN or IOC_VENDOR or 8;
   SIO_INDEX_MCASTIF    =IOC_IN or IOC_VENDOR or 9;
   SIO_INDEX_ADD_MCAST  =IOC_IN or IOC_VENDOR or 10;
   SIO_INDEX_DEL_MCAST  =IOC_IN or IOC_VENDOR or 11;


 type tcp_keepalive=record
    onoff:Longword;
    keepalivetime:Longword;
    keepaliveinterval:Longword;
   end;

// New WSAIoctl Options

//IP头
 type
  _iphdr=record
    h_lenver        :byte;        //4位首部长度+4位IP版本号
    tos             :char;        //8位服务类型TOS
    total_len       :char;        //16位总长度(字节)
    ident           :word;        //16位标识
    frag_and_flags  :word;            //3位标志位
    ttl             :byte;          //8位生存时间 TTL
    proto           :byte;          //8位协议 (TCP, UDP 或其他)
    checksum        :word;        //16位IP首部校验和
    sourceIP    :Longword;    //32位源IP地址
    destIP          :Longword;    //32位目的IP地址
   end;
  IP_HEADER=_iphdr;

 type  _tcphdr=record             //定义TCP首部
    TCP_Sport        :word;          //16位源端口
    TCP_Dport        :word;          //16位目的端口
    th_seq          :longword;    //32位序列号
    th_ack          :longword;    //32位确认号
    th_lenres       :byte;       //4位首部长度/6位保留字
    th_flag         :char;         //6位标志位
    th_win          :word;         //16位窗口大小
    th_sum          :word;              //16位校验和
    th_urp          :word;              //16位紧急数据偏移量
   end;
 TCP_HEADER=_tcphdr;
 type  _udphdr=record                 //定义UDP首部
      uh_sport          :word;        //16位源端口
      uh_dport          :word;        //16位目的端口
      uh_len            :word;             //16位长度
      uh_sum            :word;             //16位校验和
  end;
  UDP_HEADER=_udphdr;
 type _icmphdr=record                 //定义ICMP首部
    i_type          :byte;             //8位类型
    i_code          :byte;             //8位代码
    i_cksum         :word;             //16位校验和
    i_id            :word;             //识别号(一般用进程号作为识别号)
//    i_seq           :word;             //报文序列号
    timestamp       :word;             //时间戳
    end;
   ICMP_HEADER=_icmphdr;

 type _protomap=record            //定义子协议映射表
    ProtoNum    :integer;
    ProtoText   :array[0..MAX_PROTO_TEXT_LEN] of char;
  end;
  TPROTOMAP=_protomap;

type
  ESocketException   = class(Exception);
  TWSAStartup            = function (wVersionRequired: word;
                                       var WSData: TWSAData): Integer; stdcall;
  TOpenSocket            = function (af, Struct, protocol: Integer): TSocket; stdcall;
  TInet_addr             = function (cp: PChar): u_long; stdcall;
  Thtons                 = function (hostshort: u_short): u_short; stdcall;
  TConnect               = function (s: TSocket; var name: TSockAddr;
                                       namelen: Integer): Integer; stdcall;
  TWSAIoctl              = function (s: TSocket; cmd: DWORD;lpInBuffer: PCHAR;
                                 dwInBufferLen:DWORD;lpOutBuffer: PCHAR; dwOutBufferLen: DWORD;
                                 lpdwOutBytesReturned: LPDWORD;lpOverLapped: POINTER;
                                 lpOverLappedRoutine: POINTER): Integer; stdcall;
  TCloseSocket           = function (s: TSocket): Integer; stdcall;
  Tsend                  = function( s:TSOCKET; buf:pchar;Len:integer;flags:integer):Integer;stdcall;
  Trecv                  = function( s:TSOCKET; var buf;Len:integer;flags:integer):Integer;stdcall;
  TWSAAsyncSelect        =function (s: TSocket; HWindow: HWND; wMsg: u_int; lEvent: Longint): Integer; stdcall;
  TWSACleanup            =function():integer;stdcall;
  TOnCap = procedure(ip,proto,sourceIP,destIP,SourcePort,DestPort: string;
                       header:pchar;header_size:integer;data:pchar;data_size:integer) of object;
  TOnError = procedure(Error : string) of object;

  Tcap_ip = class(TComponent)
  private
    Fhand_dll   :HModule;   // Handle for mpr.dll
    FWindowHandle : HWND;
    FOnCap      :TOnCap;     //捕捉数据的事件
    FOnError    :TOnError;     //发生错误的事件
    Fsocket     :array of Tsocket;
    FActiveIP   :array of string;//存放可用的IP

    FWSAStartup            : TWSAStartup;
    FOpenSocket            : TOpenSocket;
    FInet_addr             : TInet_addr;
    Fhtons                 : Thtons;
    FConnect               : TConnect;
    FCloseSocket           : TCloseSocket;
    Fsend                  :Tsend;
    FWSAIoctl              :TWSAIoctl;
    Frecv                  :Trecv;
    FWSACleanup            :TWSACleanup;
    FWSAAsyncSelect        :TWSAAsyncSelect;

  protected
     procedure   WndProc(var MsgRec: TMessage);
     function DecodeIpPack(ip:string;buf:pchar;iBufSize:integer):integer;         //IP解包函数
//     function DecodeTcpPack(TcpBuf:pchar;iBufSize:integer):integer;     //TCP解包函数
     //function DecodeUdpPack(p:pchar;i:integer):integer;        //UDP解包函数
     //function DecodeIcmpPack(p:pchar;i:integer):integer;            //ICMP解包函数
     function  CheckProtocol(iProtocol:integer):string;            //协议检查
     procedure cap_ip(socket_no:integer);
     procedure get_ActiveIP;                                            //得当前的IP列表
     procedure set_socket_state;                                        //设置网卡状态
     function  CheckSockError(iErrorCode:integer):boolean;                  //出错处理函数
  public
    Fpause                 :boolean;//暂停
    Finitsocket            :boolean;//是否已初始化
    constructor Create(Owner : TComponent); override;
    destructor  Destroy; override;
    function    init_socket:boolean;//初始化
    procedure   StartCap;//开始捕捉
    procedure   pause;   //暂停
    procedure   StopCap;//结束捕捉
    property    Handle   : HWND       read FWindowHandle;
  published
    property    OnCap    : TOnCap     read  FOnCap write FOnCap;
    property    OnError  : TOnError   read  FOnError write FOnError;
 end;

procedure Register;

implementation
function XSocketWindowProc(ahWnd   : HWND;auMsg   : Integer;awParam : WPARAM; alParam : LPARAM): Integer; stdcall;
var
    Obj    : Tcap_ip;
    MsgRec : TMessage;
begin
    { At window creation ask windows to store a pointer to our object       }
    Obj := Tcap_ip(GetWindowLong(ahWnd, 0));

    { If the pointer is not assigned, just call the default procedure       }
    if not Assigned(Obj) then
        Result := DefWindowProc(ahWnd, auMsg, awParam, alParam)
    else begin
        { Delphi use a TMessage type to pass paramter to his own kind of    }
        { windows procedure. So we are doing the same...                    }
        MsgRec.Msg    := auMsg;
        MsgRec.wParam := awParam;
        MsgRec.lParam := alParam;
        Obj.WndProc(MsgRec);
        Result := MsgRec.Result;
    end;
end;

var
    XSocketWindowClass: TWndClass = (
        style         : 0;
        lpfnWndProc   : @XSocketWindowProc;
        cbClsExtra    : 0;
        cbWndExtra    : SizeOf(Pointer);
        hInstance     : 0;
        hIcon         : 0;
        hCursor       : 0;
        hbrBackground : 0;
        lpszMenuName  : nil;
        lpszClassName : 'TCap_ip');


function XSocketAllocateHWnd(Obj : TObject): HWND;
var
    TempClass       : TWndClass;
    ClassRegistered : Boolean;
begin
    { Check if the window class is already registered                       }
    XSocketWindowClass.hInstance := HInstance;
    ClassRegistered := GetClassInfo(HInstance,
                                    XSocketWindowClass.lpszClassName,
                                    TempClass);
    if not ClassRegistered then begin
       { Not yet registered, do it right now                                }
       Result := Windows.RegisterClass(XSocketWindowClass);
       if Result = 0 then
           Exit;
    end;

    { Now create a new window                                               }
    Result := CreateWindowEx(WS_EX_TOOLWINDOW,
                           XSocketWindowClass.lpszClassName,
                           '',        { Window name   }
                           WS_POPUP,  { Window Style  }
                           0, 0,      { X, Y          }
                           0, 0,      { Width, Height }
                           0,         { hWndParent    }
                           0,         { hMenu         }
                           HInstance, { hInstance     }
                           nil);      { CreateParam   }

    { if successfull, the ask windows to store the object reference         }
    { into the reserved byte (see RegisterClass)                            }
    if (Result <> 0) and Assigned(Obj) then
        SetWindowLong(Result, 0, Integer(Obj));
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{ Free the window handle                                                    }
procedure XSocketDeallocateHWnd(Wnd: HWND);
begin
    DestroyWindow(Wnd);
end;

//当前机的所有IP地址
procedure Tcap_ip.get_ActiveIP;
type
  TaPInAddr = Array[0..20] of PInAddr;
  PaPInAddr = ^TaPInAddr;
var
  phe: PHostEnt;
  pptr: PaPInAddr;
  Buffer: Array[0..63] of Char;
  I: Integer;
begin
  setlength(FActiveIP,20);

  GetHostName(Buffer, SizeOf(Buffer));
  phe := GetHostByName(buffer);
  if phe = nil then
   begin
    setlength(FActiveIP,0);
    if Assigned(FOnError) then FOnError('没有找到可绑定的IP!');
    exit;
   end;
  pPtr := PaPInAddr(phe^.h_addr_list);
  I := 0;
  while (pPtr^[I] <> nil) and (i<20) do
   begin
    FActiveIP[I]:=inet_ntoa(pptr^[I]^);
    Inc(I);
   end;
  setlength(FActiveIP,i);
end;

procedure Tcap_ip.set_socket_state;
var
  i,iErrorCode:integer;
  sa: tSockAddrIn;
  dwBufferLen:array[0..10]of DWORD;
  dwBufferInLen:DWORD;
  dwBytesReturned:DWORD;
begin
   if high(FActiveIP)=-1 then exit;
   setlength(Fsocket,high(FActiveIP)+1);
   for i:=0 to high(FActiveIP) do
     begin
       Fsocket[i]:= socket(AF_INET , SOCK_RAW , IPPROTO_IP);
       sa.sin_family:= AF_INET;
       sa.sin_port := htons(i);
       sa.sin_addr.S_addr:=Inet_addr(pchar(FActiveIP[i]));
       iErrorCode := bind(Fsocket[i],sa, sizeof(sa));
       CheckSockError(iErrorCode);

       dwBufferInLen := 1 ;
       dwBytesReturned:=0;
 //设置Fsocket为SIO_RCVALL接收所有的IP包
       iErrorCode:=FWSAIoctl(Fsocket[i], SIO_RCVALL,@dwBufferInLen, sizeof(dwBufferInLen),
                        @dwBufferLen, sizeof(dwBufferLen),@dwBytesReturned ,nil ,nil);

    CheckSockError(iErrorCode);
        iErrorCode:=WSAAsyncSelect(Fsocket[i],FWindowHandle,WM_CapIp+i,FD_READ or FD_CLOSE);
    CheckSockError(iErrorCode);
     end;
end;

//读IP数据
procedure Tcap_ip.cap_ip(socket_no:integer);
var
  iErrorCode:integer;
  RecvBuf:array[0..MAX_PACK_LEN] of char;
begin
     fillchar(RecvBuf,sizeof(RecvBuf),0);
     iErrorCode := frecv(Fsocket[socket_no], RecvBuf, sizeof(RecvBuf), 0);
     CheckSockError(iErrorCode);
    if not Fpause then
     begin
     iErrorCode := DecodeIpPack(FActiveIP[socket_no],RecvBuf, iErrorCode);
     CheckSockError(iErrorCode);
     end;
end;

//协议识别程序
function Tcap_ip.CheckProtocol(iProtocol:integer):string;
var
 i:integer;
begin
  result:='';
   case iProtocol of
     IPPROTO_IP   :result:='IP';
     IPPROTO_ICMP :result:='ICMP';
     IPPROTO_IGMP :result:='IGMP';
     IPPROTO_GGP  :result:='GGP';
     IPPROTO_TCP  :result:='TCP';
     IPPROTO_PUP  :result:='PUP';
     IPPROTO_UDP  :result:='UDP';
     IPPROTO_IDP  :result:='IDP';
     IPPROTO_ND   :result:='NP';
     IPPROTO_RAW  :result:='RAW';
     IPPROTO_MAX  :result:='MAX';
    else          result:='';
   end;
end;


//IP解包程序
function Tcap_ip.DecodeIpPack(ip:string;buf:pchar;iBufSize:integer):integer;
var
  SourcePort,DestPort:word;
  iProtocol, iTTL:integer;
  szProtocol :array[0..MAX_PROTO_TEXT_LEN] of char;
  szSourceIP :array[0..MAX_ADDR_LEN] of char;
  szDestIP   :array[0..MAX_ADDR_LEN] of char;

  pIpheader:IP_HEADER;
  pTcpHeader:TCP_HEADER;
  pUdpHeader:UDP_HEADER;
  pIcmpHeader:ICMP_HEADER;
  saSource, saDest:TSockAddrIn;
  iIphLen,data_size:integer;
  TcpHeaderLen:integer;
  TcpData:pchar;
begin
        result:=0;
        CopyMemory(@pIpheader,buf,sizeof(pIpheader));
//协议甄别
    iProtocol := pIpheader.proto;
    StrLCopy(szProtocol, pchar(CheckProtocol(iProtocol)),15);

//源地址
    saSource.sin_addr.s_addr := pIpheader.sourceIP;
    strlcopy(szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN);
//目的地址
    saDest.sin_addr.s_addr := pIpheader.destIP;
    strLcopy(szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN);
    iTTL := pIpheader.ttl;
//计算IP首部的长度
    iIphLen :=sizeof(pIpheader);
//根据协议类型分别调用相应的函数
    case iProtocol of
           IPPROTO_TCP    :begin
                          CopyMemory(@pTcpHeader,buf+iIphLen,sizeof(pTcpHeader));
                          SourcePort := ntohs(pTcpHeader.TCP_Sport);//源端口
                          DestPort := ntohs(pTcpHeader.TCP_Dport);  //目的端口
                          TcpData:=buf+iIphLen+sizeof(pTcpHeader);
                          data_size:=iBufSize-iIphLen-sizeof(pTcpHeader);
                         end;
       IPPROTO_UDP    :begin
                          CopyMemory(@pUdpHeader,buf+iIphLen,sizeof(pUdpHeader));
                          SourcePort := ntohs(pUdpHeader.uh_sport);//源端口
                          DestPort := ntohs(pUdpHeader.uh_dport);  //目的端口
                          TcpData:=buf+iIphLen+sizeof(pUdpHeader);
                          data_size:=iBufSize-iIphLen-sizeof(pUdpHeader);
                         end;
       IPPROTO_ICMP    :begin
                          CopyMemory(@pIcmpHeader,buf+iIphLen,sizeof(pIcmpHeader));
                          SourcePort := pIcmpHeader.i_type;//类型
                          DestPort := pIcmpHeader.i_code;  //代码
                          TcpData:=buf+iIphLen+sizeof(pIcmpHeader);
                          data_size:=iBufSize-iIphLen-sizeof(pIcmpHeader);
                         end;
       else begin
                    SourcePort :=0;
                    DestPort := 0;  //代码
                    TcpData:=buf+iIphLen;
                    data_size:=iBufSize-iIphLen;
                end;
    end;

  if Assigned(FOnCap) then
   FOnCap(ip,szProtocol,szSourceIP,szDestIP,inttostr(SourcePort),inttostr(DestPort)
          ,buf,iBufSize-data_size,TcpData,data_size);
end;

//SOCK错误处理程序
function Tcap_ip.CheckSockError(iErrorCode:integer):boolean;    //出错处理函数
begin
    if(iErrorCode=SOCKET_ERROR) then
     begin
       if Assigned(FOnError) then FOnError(inttostr(GetLastError)+SysErrorMessage(GetLastError));
       result:=true;
     end else result:=false;
end;

procedure Tcap_ip.WndProc(var MsgRec: TMessage);
begin
    with MsgRec do
     if (Msg >=WM_CapIp) and (Msg <= WM_CapIp+high(FActiveIP)) then
         cap_ip(msg-WM_CapIp)
       else
       begin
//        Result := DefWindowProc(Handle, Msg, wParam, lParam);
       end;
end;

constructor Tcap_ip.Create(Owner : TComponent);
begin
    Inherited Create(Owner);
    Fpause:=false;
    Finitsocket:=false;
    setlength(Fsocket,0);

    FWindowHandle := XSocketAllocateHWnd(Self);
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
destructor Tcap_ip.Destroy;
var i:integer;
begin
   for i:=0 to high(Fsocket) do FCloseSocket(Fsocket[i]);
   if self.Finitsocket then
     begin
       FWSACleanup;
      if Fhand_dll <> 0 then FreeLibrary(Fhand_dll);
     end;
    inherited Destroy;
end;

function  Tcap_ip.init_socket:boolean;//初始化
var
 GInitData:TWSAData;
begin
    result:=true;
    IF Finitsocket then exit;
    Fhand_dll := LoadLibrary('ws2_32.dll');
    if Fhand_dll = 0 then
      begin
        raise ESocketException.Create('Unable to register ws2_32.dll');
        result:=false;
        exit;
      end;
    @FWSAStartup  := GetProcAddress(Fhand_dll, 'WSAStartup');

    @FOpenSocket :=  GetProcAddress(Fhand_dll, 'socket');
    @FInet_addr :=   GetProcAddress(Fhand_dll, 'inet_addr');
    @Fhtons  :=      GetProcAddress(Fhand_dll, 'htons');
    @FConnect :=     GetProcAddress(Fhand_dll, 'connect');
    @FCloseSocket := GetProcAddress(Fhand_dll, 'closesocket');
    @Fsend        := GetProcAddress(Fhand_dll, 'send');
    @FWSAIoctl := GetProcAddress(Fhand_dll, 'WSAIoctl');
    @Frecv        := GetProcAddress(Fhand_dll, 'recv');
    @FWSACleanup  := GetProcAddress(Fhand_dll, 'WSACleanup');
    @FWSAAsyncSelect:=GetProcAddress(Fhand_dll, 'WSAAsyncSelect');
    if (@FWSAStartup =nil) or(@Fhtons =nil) or (@FConnect =nil) or (@Fsend =nil) or (@FWSACleanup=nil) or
       (@FOpenSocket =nil) or (@FInet_addr =nil)or (@FCloseSocket =nil) or (@recv=nil)or (@FWSAIoctl=nil)
       or (@FWSAAsyncSelect=nil) then
         begin
          raise ESocketException.Create('加载dll函数错误!');
          result:=false;
          exit;
         end;

   if FWSAStartup($201,GInitData)<>0 then
     begin
      raise ESocketException.Create('初始化SOCKET2函数失败!');
      result:=false;
      exit;
     end;
  Finitsocket:=true;
end;
procedure  Tcap_ip.StartCap;
begin
 if not Finitsocket then
    if not init_socket then exit;
   get_ActiveIP;
   set_socket_state;
end;
procedure  Tcap_ip.pause;
begin
  if Finitsocket and (high(Fsocket)>-1) then
    Fpause:=not Fpause;
end;

procedure  Tcap_ip.StopCap;
var i:integer;
begin
   for i:=0 to high(Fsocket) do FCloseSocket(Fsocket[i]);
end;

procedure Register;
begin
    RegisterComponents('Standard', [Tcap_ip]);
end;

end.
我想请高手帮我看一下当我点击BitBtn1后程序跑起来,并没有调用到
函数function Tcap_ip.DecodeIpPack(ip:string;buf:pchar;iBufSize:integer):integer;,那个函数在程序中到底有没有执行?谢谢,等着救命

[[it] 本帖最后由 pjbpage 于 2008-6-8 17:55 编辑 [/it]]
搜索更多相关主题的帖子: 数据 
2008-06-08 00:10
hackergirl
Rank: 1
等 级:新手上路
帖 子:71
专家分:0
注 册:2008-3-18
收藏
得分:0 
你用断点跟踪不就行了吗?
2008-06-08 19:19
快速回复:一个捕捉Ip数据包的问题 !急急急!
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018293 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved