怎么样做捕获IP数据包的小程序!

dqsaul 2003-12-21 03:33:09
怎么样做捕获IP数据包的小程序!?
有案例吗
...全文
50 点赞 收藏 5
写回复
5 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
wangii 2003-12-24
//***********************************************///
Unit ipheader;
Interface
Uses
windows, winsock;
Const
TCPFlag_URG = 0;
TCPFlag_ACK = 2;
TCPFlag_PSH = 4;
TCPFlag_RST = 8;
TCPFlag_SYN = 16;
TCPFlag_FYN = 32;
IPPROTO_IP = 0; //dummy for IP
IPPROTO_ICMP = 1; // control message protocol
IPPROTO_IGMP = 2; //internet group management protocol
IPPROTO_GGP = 3; // gateway^2 (deprecated)
IPPROTO_TCP = 6; // tcp
IPPROTO_PUP = 12; // pup
IPPROTO_UDP = 17; // user datagram protocol
IPPROTO_IDP = 22; // xns idp
IPPROTO_ND = 77; // UNOFFICIAL net disk proto
IPPROTO_RAW = 255; // raw IP packet
IPPROTO_MAX = 256;
SIO_RCVALL = $98000001;
Type
TIPPROTO = Record
itype: word;
name: String;
End;
PIP_Header = ^TIP_Header;
TIP_Header = Packed Record
ip_verlen: Byte; //4 位版本 4 位首部长度
ip_tos: Byte; //服务类型(TOS)
ip_totallength: Word; //总长度
ip_id: Word; //标记
ip_offset: Word; //
ip_ttl: Byte; //8 位生存时间
ip_protocol: Byte; //8 位协议
ip_checksum: Word; //首部校验和
ip_srcaddr: LongWord; //源ip
ip_destaddr: LongWord; //目的ip
End;
PUDP_Header = ^TUDP_Header;
TUDP_Header = Packed Record
src_portno: Word; //源端口号
dst_portno: Word; //目的端口号
udp_length: Word; //UDP 首部和UDP 数据的字节长度
udp_checksum: Word; //UDP首部和数据的校验和
End;
PTCP_Hearder = ^TTCP_Hearder;
TTCP_Hearder = Packed Record
src_portno: Word; //源端口号
dst_portno: Word; //目的端口号
Sequenceno: LongWord; //序号
Acknowledgeno: LongWord; //确认序号
DataOffset: Byte; //
flag: byte;
Windows: WORD; //窗口大小
checksum: WORD; //校验和
UrgentPointer: WORD; //紧急指针
End;
Const
IPPROTO: Array[0..8] Of TIPPROTO = (
(iType: IPPROTO_IP; name: 'IP'),
(iType: IPPROTO_ICMP; name: 'ICMP'),
(iType: IPPROTO_IGMP; name: 'IGMP'),
(iType: IPPROTO_GGP; name: 'GGP'),
(iType: IPPROTO_TCP; name: 'TCP'),
(iType: IPPROTO_PUP; name: 'PUP'),
(iType: IPPROTO_UDP; name: 'UDP'),
(iType: IPPROTO_IDP; name: 'IDP'),
(iType: IPPROTO_ND; name: 'ND'));
Implementation
End.
//***********************************************///Email: fly0128@sina.com.cn
//Create Thread
Procedure TForm1.Button3Click(Sender: TObject);
Begin
ListView1.Clear;
ListThread := TSnifferThread.Create(true);
If Length(Edit1.Text) <> 0 Then
ListThread.SrcIP := inet_addr(pchar(Edit1.text));
If Length(Edit2.Text) <> 0 Then
ListThread.DecIP := inet_addr(pchar(Edit2.text));
ListThread.PackageList := ListView1;
End;
//Destoary Thread
ListThread.FreeSocket;
Try
ListThread.Terminate;
Except
// ListThread.Destroy;
FreeAndNil(listThread);
End;
回复
wangii 2003-12-24
强烈建议你使用google。下面是我原来在网上找到的,作者是:Email: fly0128@sina.com.cn


Unit USniffer;
Interface
Uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, winsock, ComCtrls, ipheader, UThreadSniffer;
Type
TaPInAddr = Array[0..10] Of PInAddr;
PaPInAddr = ^TaPInAddr;
Type
TForm1 = Class(TForm)
Button1: TButton;
ListView1: TListView;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Edit1: TEdit;
Label1: TLabel;
Label2: TLabel;
Edit2: TEdit;
Procedure Button1Click(Sender: TObject);
Procedure Button2Click(Sender: TObject);
Procedure Button3Click(Sender: TObject);
Procedure Button4Click(Sender: TObject);
private
{ Private declarations }
ListThread: TSnifferThread;
RawSocket: TSocket;
Procedure AnalysisDataPacket;
public
{ Public declarations }
End;
Var
Form1: TForm1;
Const
MAX_CHAR = 1024 * 5;
IP_HDRINCL = 2;
SIO_RCVALL = $98000001;
Function WSAIoctl(s: Tsocket;
dwIoControlCode: dword;
lpvInBuffer: pointer;
cbInBuffer: DWORD;
lpvOUTBuffer: pointer;
cbOUTBuffer: dword;
lpcbBytesReturned: LPDWORD;
lpOverlapped: pointer;
lpCompletionROUTINE: pointer): integer; stdcall; external 'ws2_32.dll';
// 设置SOCKET的输入输出工作模式的函数,必须从动态链接库ws2_32.dll内自己导出,winsock单元
// 不包含此函数
Implementation
{$R *.dfm}
Procedure TForm1.AnalysisDataPacket;
Var
count, iRet, filterip: Integer;
buf: Array[0..MAX_CHAR] Of char;
pipheader: PIP_Header; // PIP_Header是自定义的IP头结构
buf2: pchar;
listdata: Tlistitem;
i: Integer;
str: String;
SaveFile: TextFile;
s: String;
Begin
AssignFile(SaveFile, 'c:\temp\Mon.txt');
Rewrite(SaveFile);
filterip := 0;
For count := 0 To 100 Do
Begin
iRet := recv(RawSocket, buf, sizeof(buf), 0);
If iret = -1 Then
Continue;
pipheader := PIP_Header(@buf);
{ Case filterip Of
1: ;
2: ;
3: ;
Else ;
End; //case
}
// 将获得的数据包保存在内存中
getmem(buf2, iRet);
copymemory(buf2, @buf, iRet);
s := buf2;
Try
Writeln(SaveFile, s);
Except
CloseFile(SaveFile);
End;
listdata := ListView1.Items.Add;
listdata.Caption := FormatDateTime('hh:nn:ss:zzz', now); // 获得抓包时间
listdata.Data := buf2; // 将指针指向对应数据包
// 将包进行简单解析后显示到ListView中
listdata.SubItems.Add(strpas(Inet_Ntoa(TInAddr(pipheader.ip_srcaddr))));
//来源IP
listdata.SubItems.Add(strpas(Inet_Ntoa(TInAddr(pipheader.ip_destaddr))));
For i := 0 To 8 Do
If pipheader.ip_protocol = IPPROTO[i].itype Then
str := IPPROTO[i].name;
//数据包的类型
listdata.SubItems.Add(str);
listdata.SubItems.Add(inttostr(ntohs(pipheader.ip_totallength)));
//包的长度
End; //for
CloseFile(SaveFile);
End;
Procedure TForm1.Button1Click(Sender: TObject);
Var
WSAData: TWSAData;
rcvtimeo, result: Integer;
host: Array[0..50] Of char;
hostent: Phostent;
ip: ^integer;
sa: TSockAddr;
dwBufferInLen, dwBytesReturned, dwBufferLen: DWORD;
Begin
WSAStartup(MakeWord(2, 2), WSAData);
Try
RawSocket := socket(AF_INET, SOCK_RAW, IPPROTO_IP); // 创建SOCK_RAW类型的SOCKET
If RawSocket = INVALID_SOCKET Then
Raise Exception.Create('创建Socket出错');
rcvtimeo := 5000; // 设置SOCKET的超时时间
result := setsockopt(RawSocket, SOL_SOCKET, SO_RCVTIMEO, pchar(@rcvtimeo), sizeof(rcvtimeo));
If result = SOCKET_ERROR Then
Raise Exception.Create('SetSocket出错');
gethostname(@host, sizeof(host));
hostent := gethostbyname(@host);
ip := @hostent.h_addr_list^[0]; // 获得本机IP
sa.sin_family := AF_INET;
sa.sin_port := htons(7000);
sa.sin_addr.s_addr := ip^;
result := bind(RawSocket, sa, sizeof(sa)); // 绑定SOCKET
If result = SOCKET_ERROR Then
Raise Exception.Create('bind出错');
result := WSAIoctl(RawSocket, SIO_RCVALL, @dwBufferInLen,
sizeof(dwBufferInLen), @dwBufferLen, sizeof(dwBufferLen),
@dwBytesReturned, Nil, Nil);
If result = SOCKET_ERROR Then
Raise Exception.Create('WSAIoctl出错');
AnalysisDataPacket;
Except
closesocket(RawSocket);
WSACleanup;
End; //finally
End;
Procedure TForm1.Button2Click(Sender: TObject);
Begin
closesocket(RawSocket);
WSACleanup;
End;
Procedure TForm1.Button3Click(Sender: TObject);
Begin
ListView1.Clear;
ListThread := TSnifferThread.Create(true);
If Length(Edit1.Text) <> 0 Then
ListThread.SrcIP := inet_addr(pchar(Edit1.text));
If Length(Edit2.Text) <> 0 Then
ListThread.DecIP := inet_addr(pchar(Edit2.text));
ListThread.PackageList := ListView1;
End;
Procedure TForm1.Button4Click(Sender: TObject);
Begin
ListThread.FreeSocket;
Try
ListThread.Terminate;
Except
// ListThread.Destroy;
FreeAndNil(listThread);
End;
End;
End.
回复
dqsaul 2003-12-23
有更详细一点的吗
回复
lanshing 2003-12-22
用原始套节字、NDIS、NDIS HOOK或者采用别的的开发平台(比如自由软件WINPCAP,有提供源程序)。
回复
huang_gong 2003-12-22
1、使用WINPCAP,略。

2、原始XX字:
WSAStartup等,
setsockopt(...书)
主要使用如下Function:WSAIoctl
Result := WSAIoctl(RawSocket, SIO_RCVALL, @dwBufferInLen,
sizeof(dwBufferInLen), @dwBufferLen, sizeof(dwBufferLen),
@dwBytesReturned, Nil, Nil);
If Result = SOCKET_ERROR Then
Raise Exception.Create('错了');

接收:iRet := recv(RawSocket, buf, sizeof(buf), 0);
回复
发动态
发帖子
网络通信/分布式开发
创建于2007-08-02

1566

社区成员

Delphi 网络通信/分布式开发
申请成为版主
社区公告
暂无公告