//大家可以新建立一个工程,
//然后放上2 个memo,一个button
//然后把下面的代码贴上去就可以看了
//程序病状是可以接受其他程序的ping的回复
//但是自己的ping回复接受不到
//除了addrstr:='66.249.89.99';
//------------------------begin-------------------
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,winsock, StdCtrls;
const
icmp_echo_reply = 0;
icmp_echoreq = 8;
IP_RECORD_ROUTE = $7;
type
TForm1 = class(TForm)
Memo1: TMemo;
Memo2: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
PICMP_HDR = ^ICMP_HDR;
ICMP_HDR = packed record
PType: BYTE;
Code: BYTE;
Checksum: word;
ICMPid: word;
icmpseq: word;
data:array [0..31] of char;
end;
type
icmp_data = packed record
time: dword;
dest_ip: ulong;
end;
type
Pipoptinfo = ^Tipoptinfo;
Tipoptinfo = packed record
code: byte;
len: byte;
ptr: byte;
buf: array[0..8] of dword;
end;
type
iphdr = record //IP头结构
h_lenver: byte; //4位首部长度+4位IP版本号
tos: byte; //8位服务类型TOS
total_len: word; //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;
function recvf(addrstr: string): integer; stdcall;
function cksum(addr: PWord; len: integer): Cardinal;
var
Form1: TForm1;
implementation
{$R *.dfm}
var
hs: Thandle;
isgo:integer;
//csock: Tsocket;
function cksum(addr: PWord; len: integer): Cardinal;
var
nleft: integer;
w: PWord;
answer: cardinal;
sum: integer;
begin
nleft := len;
w := addr;
sum := 0;
while (nleft > 1) do
begin
sum := sum + w^;
Integer(w) := Integer(w) + SizeOf(Word);
nleft := nleft - 2;
end;
if(nleft = 1) then
begin
sum := sum + Word(w^);
end;
sum := sum shr 16 + sum and $ffff;
sum := sum + sum shr 16;
answer := not sum;
result := answer;
end;
function recvf(addrstr: string): integer; stdcall;
var
ms: Tsocket;
getbuf: array[0..1023] of byte;
sendbuf:array of byte;
len, flags: integer;
wd: wsadata;
h1, h2: integer;
sa_src: TSockAddr;
timeout: timeval;
csock: Tsocket;
ih1: icmp_hdr; //icmp头
idata: icmp_data;
sa_dest: sockaddr_in;
dsize: word;
seq_no: byte;
ipopt: tipoptinfo;
iph: iphdr; //ip头
rd: TFDSet;
pd:Tinaddr;
timeo:integer;
begin
addrstr:='66.249.89.99';
//addrstr:='127.0.0.1';
while 1=1 do
begin
wsastartup(2, wd);
csock := socket(af_inet, sock_raw, ipproto_icmp);
timeo:=10;
h1:= setsockopt(csock, SOL_SOCKET, SO_RCVTIMEO,
@timeout, sizeof(timeout));
if h1=SOCKET_ERROR then form1.Memo1.Lines.Add('setsockopt error')
else form1.Memo1.Lines.Add('setsockopt success');
zeromemory(@ih1,sizeof(ih1));
ih1.PType :=byte(icmp_echoreq);
ih1.Code := byte(0);
ih1.Checksum := 0;
seq_no := 0;
ih1.icmpseq := word(seq_no);
ih1.ICMPid :=word(GetCurrentProcessId);
ih1.Checksum:=0;
ih1.Checksum:=word(cksum(@ih1,sizeof(ih1)));
fillchar(ih1.data,sizeof(ih1.data),'e');
idata.time := gettickcount;
idata.dest_ip :=inet_addr(pchar(addrstr));
sa_dest.sin_family := AF_INET;
sa_dest.sin_port := htons(0);
sa_dest.sin_addr.S_addr:=inet_addr(pchar(addrstr));
setlength(sendbuf,sizeof(ih1)+32);
form1.Memo1.Lines.Add('ih1长度= '+inttostr(sizeof(ih1))+'idata的长度= '+inttostr(sizeof(idata)));
zeromemory(@sa_src,sizeof(sa_src));
len :=sizeof(sa_src);
h1:=sendto(csock,ih1,sizeof(ih1),0,sa_dest, sizeof(sa_dest));
h2 := recvfrom(csock, getbuf,sizeof(getbuf), 0, sa_src, len);
form1.Memo1.Lines.Add(inttostr(h1)+' '+ inttostr(h2));
if h2<=0 then
begin
sleep(500);
continue;
end;
//解析
dsize := sizeof(iph);
zeromemory(@ih1, dsize);
copymemory(@iph, @getbuf[0], dsize);
dsize := sizeof(ih1);
copymemory(@ih1, @getbuf[20], dsize);
form1.Memo2.Lines.Add('datalen= '+chr(getbuf[28]));
form1.Memo2.Lines.Add('datalen= '+chr(getbuf[29]));
form1.Memo2.Lines.Add('datalen= '+chr(getbuf[30]));
form1.Memo2.Lines.Add('datalen= '+chr(getbuf[31]));
form1.Memo2.Lines.Add('datalen= '+chr(getbuf[32]));
form1.Memo2.Lines.Add('datalen= '+chr(getbuf[33]));
form1.Memo2.Lines.Add('datalen= '+chr(getbuf[34]));
form1.Memo2.Lines.Add('datalen= '+chr(getbuf[35]));
form1.Memo2.Lines.Add('datalen= '+chr(getbuf[36]));
form1.Memo2.Lines.Add('datalen= '+chr(getbuf[37]));
form1.Memo2.Lines.Add('datalen= '+chr(getbuf[38]));
form1.Memo2.Lines.Add('datalen= '+chr(getbuf[39]));
form1.Memo2.Lines.Add('datalen= '+chr(getbuf[56]));
form1.Memo2.Lines.Add('datalen= '+chr(getbuf[57]));
form1.Memo2.Lines.Add('datalen= '+chr(getbuf[58]));
form1.Memo2.Lines.Add('datalen= '+chr(getbuf[59]));
form1.Memo2.Lines.Add('tos=' + inttostr(iph.tos));
form1.Memo2.Lines.Add('total_len=' + inttostr(iph.total_len));
form1.Memo2.Lines.Add(inttostr(iph.ident));
form1.Memo2.Lines.Add('frag_and_flags='+inttostr(iph.frag_and_flags));
form1.Memo2.Lines.Add('ttl='+inttostr(iph.ttl));
form1.Memo2.Lines.Add('proto='+inttostr(iph.proto));
form1.Memo2.Lines.Add('checksum='+inttostr(iph.checksum));
pd.S_addr:=iph.sourceIP;
form1.Memo2.Lines.Add('sourceip=' + inttostr(iph.sourceIP));
form1.Memo2.Lines.Add('sourceip= '+inet_ntoa(pd));
form1.Memo2.Lines.Add('destip=' + inttostr(iph.destIP));
pd.S_addr:=iph.destIP;
form1.Memo2.Lines.Add('destip= '+inet_ntoa(pd));
form1.Memo2.Lines.Add('icmp type= '+inttostr(ih1.PType));
form1.Memo2.Lines.Add('icmp code= '+inttostr(ih1.Code));
form1.Memo2.Lines.Add('icmp checksum= '+inttostr(ih1.Checksum));
form1.Memo2.Lines.Add('icmp impid= '+inttostr(ih1.ICMPid));
form1.Memo2.Lines.Add('processid= '+inttostr(GetCurrentProcessId));
form1.Memo2.Lines.Add('icmp icmpseq= '+inttostr(ih1.icmpseq));
form1.Memo2.Lines.Add('sa_src.addr='+inet_ntoa(sa_src.sin_addr));
form1.Memo2.Lines.Add('sa_src.port='+inttostr(sa_src.sin_port));
form1.Memo2.Lines.Add('sa_src.family(af_inet)='+inttostr(sa_src.sa_family));
form1.Memo2.Lines.Add('sa_src.data='+sa_src.sa_data);
form1.Memo2.Lines.Add('sa_src.zero='+sa_src.sin_zero);
form1.Memo2.Lines.Add('--------------------------------------------');
sleep(500);
//end;
wsacleanup;
closesocket(csock);
result := 1;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
ic: dword;
msg: string;
begin
ic := 2;
msg := '192.168.0.112'; //202.168.9.16
// recvf('202.168.9.16');
if hs<=0 then
begin
hs:=createthread(nil,0,@recvf,@msg,0,ic);
exit;
end;
if hs>0 then
begin
if isgo=0 then
begin
SuspendThread(hs);
isgo:=1;
exit;
end
else
begin
resumethread(hs);
isgo:=0;
exit;
end;
end;
end;
end.
//--------------------------------end----------------------