注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

BCB-DG's Blog

...

 
 
 

日志

 
 

raw socket  

2009-09-21 16:26:36|  分类: Delphi |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

xboshi8

TsnatchThread = class(TThread)
private
    addrLen: Integer;
    addrLocal: TSockAddrin;
    buf: array[0..BUFLEN - 1] of char;
    FdwNotifyWnd: Cardinal;
    FisDispICMP: Boolean;
    FisDispIGMP: Boolean;
    FisDispTCP: Boolean;
    FisDispUDP: Boolean;
    FlistenIP: string;
    FlistenPort: Word;
    hCloseEvent: Cardinal;
    hSocket: Cardinal;
    packCount: Integer;
    str: string;
public
    constructor Create;
    destructor Destroy; override;
    function createListen: Integer;
    procedure execute; override;
    procedure handlePack(pbuf: PChar; DataLen: integer);
    procedure run;
    procedure stop;
published
    property dwNotifyWnd: Cardinal read FdwNotifyWnd write FdwNotifyWnd;
    property isDispICMP: Boolean read FisDispICMP write FisDispICMP;
    property isDispIGMP: Boolean read FisDispIGMP write FisDispIGMP;
    property isDispTCP: Boolean read FisDispTCP write FisDispTCP;
    property isDispUDP: Boolean read FisDispUDP write FisDispUDP;
    property listenIP: string read FlistenIP write FlistenIP;
    property listenPort: Word read FlistenPort write FlistenPort;
end;
constructor TsnatchThread.Create;
begin
inherited Create(true);
hCloseEvent := CreateEvent(nil, true, false, '');
end;

destructor TsnatchThread.Destroy;
begin
closehandle(hCloseEvent);
inherited Destroy;
end;

function TsnatchThread.createListen: Integer;
var
flag: Integer;
begin
result := -1;
hSocket := socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if hSocket = INVALID_SOCKET then
begin
    str := 'socket create error!';
    sendmessage(FdwNotifyWnd, WM_STRINFO, integer(str), 0);
    exit;
end;

flag := 1;
if setsockopt(hSocket, IPPROTO_IP, IP_HDRINCL, @flag, sizeof(flag)) = SOCKET_ERROR then
begin // 设置 ip头包含 选项
    str := 'setsockopt IP_HDRINCL error';
    sendmessage(FdwNotifyWnd, WM_STRINFO, integer(str), 0);
    exit;
end;

flag := 5000;
if setsockopt(hSocket, SOL_SOCKET, SO_RCVTIMEO, @flag, sizeof(flag)) = SOCKET_ERROR then
begin // 设置接收超时
    str := 'setsockopt SO_RCVTIMEO error';
    sendmessage(FdwNotifyWnd, WM_STRINFO, integer(str), 0);
    exit;
end;

addrLocal.sin_family := AF_INET;
if FlistenIp = '' then addrLocal.sin_addr.S_addr := INADDR_ANY
else addrLocal.sin_addr.S_addr := inet_addr(pchar(FlistenIp));
addrLocal.sin_port := ntohs(FlistenPort);
addrLen := sizeof(addrLocal);

if bind(hSocket, @addrLocal, addrLen) = SOCKET_ERROR then
begin // 绑定到本地网卡上
    str := 'bind error';
    sendmessage(FdwNotifyWnd, WM_STRINFO, integer(str), 0);
    exit;
end;

flag := 1;
if ioctlsocket(hSocket, SIO_RCVALL, cardinal(flag)) = SOCKET_ERROR then
begin // 设置为混杂模式
    str := 'ioctlsocket SIO_RCVALL error'; // 接受所有的数据
    sendmessage(FdwNotifyWnd, WM_STRINFO, integer(str), 0);
    exit;
end;

result := 1;
end;

procedure TsnatchThread.execute;
var
recvLen: Integer;
begin
FreeOnTerminate := true;
while not Terminated do
try
    //str := '监听数据包......';
    //SendMessage(FdwNotifyWnd, WM_STRINFO, integer(str), 0);
    if WaitForSingleObject(hCloseEvent, 0) = WAIT_OBJECT_0 then break;
    recvLen := recvfrom(hSocket, buf, BUFLEN, 0, @addrLocal, @addrLen);//效果与recv相同
    //recvLen := recv(hSocket, buf, BUFLEN, 0);
    if recvLen > 0 then
    begin
      inc(packCount);
      PostMessage(FdwNotifyWnd, WM_PACKCOUNT, packCount, 0);
      handlePack(@buf[0], recvLen);
    end;
except
end;
end;

procedure TsnatchThread.handlePack(pbuf: PChar; DataLen: integer);
var
lpipHead: pipHead;
lpudpHead: pudpHead;
lptcpHead: ptcpHead;
lpicmpHead: picmpHead;
srciplen: Integer;
dstiplen: Integer;
packType: string;
packLen: string;
srcIP: string;
dstIP: string;
srcPORT: string;
dstPORT: string;
begin
lpipHead := pipHead(pbuf);
srcIP := inet_ntoa(TInAddr(lpipHead^.srcAddr));
srciplen := length(srcIP);
dstIP := inet_ntoa(TInAddr(lpipHead^.dstAddr));
dstiplen := length(dstIP);
srcIP := ' srcIP:=' + srcIP + stringofchar(#32, 16 - srciplen);
dstIP := ' dstIP:=' + dstIP + stringofchar(#32, 16 - dstiplen);
case lpipHead^.protocol of
    IPPROTO_ICMP:
      begin
        if not isDispICMP then exit;
        packType := 'ICMP:';
        lpicmpHead := picmpHead(pbuf + sizeof(lpipHead^));
        str := packType + packLen + srcIP + dstIP + ' type:='
          + inttostr(lpicmpHead^._type) + ' code:=' + inttostr(lpicmpHead^._code);
      end;
    IPPROTO_IGMP:
      begin
        if not isDispIGMP then exit;
        packType := 'IGMP:';
      end;
    IPPROTO_TCP:
      begin
        if not isDispTCP then exit;
        packType := 'TCP:';
        lptcpHead := ptcpHead(pbuf + sizeof(lpipHead^));
        srcPORT := ' srcPort:' + Format('%-5d', [ntohs(lptcpHead^.srcPort)]);
        dstPORT := ' dstPort:' + Format('%-5d', [ntohs(lptcpHead^.dstPort)]);
        packLen := ' len:=' + Format('%-5d', [ntohs(lpipHead^.totalLen)]);
        str := packType + packLen + srcIP + srcPORT + dstIP + dstPORT;
      end;
    IPPROTO_UDP:
      begin
        if not isDispUDP then exit;
        packType := 'UDP:';
        lpudpHead := pudpHead(pbuf + sizeof(lpipHead^));
        srcPORT := ' srcPort:' + Format('%-5d', [ntohs(lpudpHead^.srcPort)]);
        dstPORT := ' dstPort:' + Format('%-5d', [ntohs(lpudpHead^.dstPort)]);
        packLen := ' len:=' + Format('%-5d', [ntohs(lpipHead^.totalLen)]);
        str := packType + packLen + srcIP + srcPORT + dstIP + dstPORT;
      end;
else
    packType := '未知包:';
end;
SendMessage(FdwNotifyWnd, WM_STRINFO, integer(str), 0);
end;

procedure TsnatchThread.run;
begin
while suspended do resume;
end;

procedure TsnatchThread.stop;
begin
SetEvent(hCloseEvent);
end;

  评论这张
 
阅读(1089)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017