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

BCB-DG's Blog

...

 
 
 

日志

 
 

net send  

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

  下载LOFTER 我的照片书  |

徐龙

unit NetSendPacket;

interface

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

const
  IP_HDRINCL=2;
type
  TPacket = array [0..8192] of byte;
var
  // net send 消息的网络封包头格式,按此格式填充UDP包并发送到目标机的 135 端口.对方能收到信息.需要启动windows的消息服务.
  packet_header:array[0..79] of byte =(
  $04,$00,$28,$00
  ,$10,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
  ,$00,$00,$00,$00,$f8,$91,$7b,$5a,$00,$ff,$d0,$11,$a9,$b2,$00,$c0
  ,$4f,$b6,$e6,$fc
   
  ,$ff,$ff,$ff,$ff // @40 : unique id over 16 bytes
  ,$ff,$ff,$ff,$ff
  ,$ff,$ff,$ff,$ff
  ,$ff,$ff,$ff,$ff
   
  ,$00,$00,$00,$00,$01,$00,$00,$00,$00,$00,$00,$00
  ,$00,$00,$ff,$ff,$ff,$ff
   
  ,$ff,$ff,$ff,$ff // @74 : fields length
   
  ,$00,$00);

  field_header :array [0..11]of byte =
  ($ff,$ff,$ff,$ff // @0 : field length
  ,$00,$00,$00,$00
  ,$00,$00,$00,$00); // @8 : field length


function  sd( FromIp:string;  Toip:string;ToPort:integer;FromName:string; ToName:string; msg:string ):bool  ;
   
implementation

uses  RawHeaders,WinSock;


//构造IP包时需要自已计算校验码,并填充到包.此函数负责计算校验码
function CheckSum(var Buffer;Size:integer):Word;
 type
   TwordArray=Array[0..1] of Word;
 var
   ChkSum:LongWord;
   i     :Integer;
 begin
   ChkSum:=0;
   i:=0;
   While Size>1 do
    begin
      ChkSum:=ChkSum+TwordArray(Buffer)[i];
      inc(i);
      Size:=Size-SizeOf(Word);
    end;
   if Size=1 then ChkSum:=ChkSum+Byte(TwordArray(Buffer)[i]);
   ChkSum:=(ChkSum shr 16)+(ChkSum and $FFFF);
   ChkSum:=ChkSum+(ChkSum shr 16);
   Result:=Word(ChkSum);
 end;

//发送封包函数
function  sd( FromIp:string;  Toip:string; ToPort:integer ;FromName:string; ToName:string; msg:string ):bool  ;
var
    DwFromIP:LongWord;
    DwToIP  :longWord;
  
    wsaData:TWSADATA ;
    s,ret :integer;
    addr:TSockAddr ;
    bOpt:integer;   

    packet : array [0..8192] of byte  ;
    fields_size,packet_size:integer;
    pw:pdword;
    len:longint;

    IpHdr:     TIpHdr;
    IpVersion :Word;
    IpSize:    Word;
    udpHdr:    TUdpHdr;
    udpsize:word;
    psendHdr:^TSendHdr ;
    udb_checkSum:word;
    ip_packet: array [0..4095] of byte ;
    ip_packet_size:integer;
    pb:pbyte;
 

   
  begin
  WSAStartup(makeword(2,2), wsaData);
  DwFromIP:=inet_Addr(pchar(FromIp)) ;
  DwToIP:=inet_Addr(pchar(Toip)) ;

  fillchar(addr, sizeof(addr),0);
  addr.sin_addr.s_addr := DwToIP;
  addr.sin_port := htons(ToPort);
  addr.sin_family := AF_INET;

  fillchar(packet,sizeof(packet),0);
  packet_size:=0;

  move(packet_header,packet[packet_size],sizeof(packet_header));
  inc(packet_size,sizeof(packet_header));

  len:=length(FromName)+1;
  fillchar(field_header,sizeof(field_header),0);
  field_header[0]:=len;
  field_header[8]:=len;
  move(field_header,packet[packet_size],sizeof(field_header));
  inc(packet_size,sizeof(field_header));
  StrCopy(@packet[packet_size], PAnsiChar(fromName));
  inc(packet_size,(((len - 1) shr 2) + 1) shl 2); // align to 4 bytes

  len:=length(ToName)+1;
  fillchar(field_header,sizeof(field_header),0);
  field_header[0]:=len;
  field_header[8]:=len;
  move(field_header,packet[packet_size],sizeof(field_header));
  inc(packet_size,sizeof(field_header));
  StrCopy(@packet[packet_size], PAnsiChar(ToName));
  inc(packet_size,(((len - 1) shr 2) + 1) shl 2); // align to 4 bytes
 

  len:=length(msg)+1;
  fillchar(field_header,sizeof(field_header),0);
  field_header[0]:=len;
  field_header[8]:=len;
  move(field_header,packet[packet_size],sizeof(field_header));
  inc(packet_size,sizeof(field_header));
  StrCopy(@packet[packet_size], PChar(msg));
  inc(packet_size,len);

  fields_size := packet_size - sizeof(packet_header);
  pw:=@packet[40];
  pw^:=gettickcount();
 
  pw:=@packet[74] ;
  pw^:= fields_size; 

  ip_packet_size:=sizeof(TIpHdr)+sizeof(TUdpHdr)+packet_size;
  IpVersion:=4;
  IpSize:=sizeof(TIpHdr) div sizeof(LongWord);
  IpHdr.ip_verlen:=(IpVersion shl 4) or IpSize;
  IpHdr.ip_tos:=0;
  IpHdr.ip_len:=htons(ip_packet_size);
  IpHdr.ip_id:=0;
  IpHdr.ip_off:=0;
  IpHdr.ip_ttl:=128;
  IpHdr.ip_p:=IPPROTO_UDP;
  IpHdr.ip_sum:=0;
  IpHdr.ip_src:=dwFromIP;
  IpHdr.ip_dst:=DwToIP;  

  udpsize:=sizeof(TudpHdr)+packet_size;
  udpHdr.udp_sport:=htons(135);
  udpHdr.udp_dport:=htons(135);
  udpHdr.udp_ulen:=htons(udpsize);
  udpHdr.udp_sum:=0;
 
  //以下创建套接字时,采用了IPPROTO_UDP,所以不用做checksum
  {  
  fillChar(ip_packet,sizeof(ip_packet),0);
  pb:=@ip_packet[0];
  psendHdr:= @ip_packet[0];
  psendHdr^.send_src:=IpHdr.ip_src;
  psendHdr^.send_dst:=IpHdr.ip_dst;
  psendHdr^.send_P:=IpHdr.ip_p;
  psendHdr^.send_len:= udpHdr.udp_ulen;

  inc(pb,sizeof(TSendHdr));
  move(udpHdr,pb^,sizeof(TudpHdr));
  inc(pb,sizeof(TudpHdr));
  Move(packet,pb^,packet_size);
  udpHdr.udp_sum:=CheckSum(ip_packet,sizeof(TSendHdr)+sizeof(TudpHdr)+packet_size);

  IpHdr.ip_sum:=checksum(ip_packet,ip_packet_size);
   }

  
  fillChar(ip_packet,sizeof(ip_packet),0);
  pb:=@ip_packet[0];
  Move(IpHdr,pb^,sizeof(TIpHdr));
  inc(pb,sizeof(TIpHdr));
  Move(udpHdr,pb^,sizeof(TudpHdr));
  inc(pb,sizeof(TudpHdr));  
  Move(packet,pb^,packet_size);  

 
  //创建RawSocket
   s :=socket(AF_INET,SOCK_RAW,IPPROTO_UDP);
   if (s=INVALID_SOCKET) then
    begin
      showmessage('创建Socket错误');
      exit;
    end;

  bOpt:=1;
  //设置要以 IP 包传输
  ret:=SetSockOpt(s,IPPROTO_IP,IP_HDRINCL,@bOpt,sizeof(bopt));
  if ret=SOCKET_ERROR then
    begin
      showmessage('设置Socket错误');
      exit;
    end;
  ret:=sendto(s, ip_packet, ip_packet_size, 0, TSOCKADDR(addr), sizeof(addr));
  if ret=SOCKET_ERROR then showmessage('sendto 错误');
  CloseHandle(s); 

  WSACleanup;

end;

end.

  评论这张
 
阅读(1311)| 评论(0)

历史上的今天

评论

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

页脚

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