精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● Delphi>>Delphi 网络编程>>发送ICMP数据包?

主题:发送ICMP数据包?
发信人: 1981327()
整理人: teleme(2003-06-03 17:53:23), 站内信件
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,winsock, StdCtrls;

type
  TForm1 = class(TForm)
    ping: TButton;
    Memo1: TMemo;
    procedure pingClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }

    function checksum(len:integer;buf:pchar):word;
    procedure pingc;
  end;
  ip_packet=record
   len_ver:byte;
   tos:byte;
   service_type:byte;
   totlelen:word;
   flag_and_flags:word;
   ttl:byte;
   proto:byte;
   checksum:word;
   sourceIP:dword;
   desIP:dword;
   end;
   ICMP_PACKET=record
   i_type:byte;
   i_code:byte;
   checksum:word;
   i_id:word;
   i_seq:word;
   end;

   PICMP_PACKET=^ICMP_PACKET ;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.pingClick(Sender: TObject);
begin
  pingc;
end;
procedure tform1.pingc;
var wsa:Wsadata;
sock_id:Tsocket;
timeout,sendsum,from,recvsum:integer;
icmp:ICMP_PACKET;
addrto,fromaddr:sockaddr_in;
buf:array[1..500] of char;
picmp:PICMP_PACKET;
buffer:array[1..1000] of char;
//p:pointer;
begin
   timeout:=1000;
   icmp.i_type:=8;
   icmp.i_code:=0;
   icmp.i_id:=123;
   icmp.i_seq:=1;
   icmp.checksum:=0;

   addrto.sin_family:=af_inet;
  // addrto.sin_port:=htons(7);
   addrto.sin_addr.S_addr:=inet_addr('127.0.0.1');
   wsastartup($0201,wsa);
   sock_id:=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
    setsockopt(sock_id,SOL_SOCKET,SO_RCVTIMEO,pchar(timeout),sizeof(timeout));
    setsockopt(sock_id,SOL_SOCKET,SO_SNDTIMEO,pchar(timeout),sizeof(timeout));
     fillchar(buf,500,0);
     //p:=@buf;

     PICMP:=@buf;
     PICMP^.i_type:=icmp.i_type;
     PICMP^.i_code:=icmp.i_code;
     PICMP^.i_id:=icmp.i_id;
     PICMP^.i_seq:=icmp.i_seq;
     PICMP^.checksum:=icmp.checksum;
     PICMP^.checksum:=checksum(500,@buf);
    // memo1.Lines.Add(inttostr(buf[4]));
      sendsum:=sendto(sock_id,buf,500,0,addrto,sizeof(addrto)) ;
    if sendsum<>SOCKET_ERROR then
      memo1.Lines.Add('success send '+inttostr(sendsum))
      else  memo1.Lines.Add('send error');
     recvsum:=recvfrom(sock_id,buffer,1000,0,fromaddr,from);
      if recvsum<>SOCKET_ERROR then
      memo1.Lines.Add('recv success '+inttostr(recvsum))
      else  memo1.Lines.Add('recv error'+inttostr(WSAGetLastError()));

     closesocket(sock_id);
end;
function tform1.checksum(len:integer;buf:pchar):word ;
var i:integer;  sum:Dword; check:word ;
begin
sum:=0;i:=len;
while i>1 do
  begin
      buf:=buf+2;
      sum:=(pword(buf))^+sum;
      i:=i-2;
  end;
  if i=1 then  sum:=(pbyte(buf))^+sum;
  sum:=(sum shr 16)+(sum and $ffff) ;
  sum:=sum+(sum shr 16);
  sum:= not sum ;
    check:=word(sum);
  result:=check;

end;
end.

[关闭][返回]