C
cyradg
Unregistered / Unconfirmed
GUEST, unregistred user!
即:计算TCP头部的Checksum值,如下:
tsd_hdr=packed record //定义TCP伪首部
saddr:ULONG; //源地址
daddr:ULONG; //目的地址
mbz:byte;
ptcl:byte; //协议类型
tcpl:USHORT; //TCP头部长度
end;
///////////////////////////////////////////
tcp_header= packed record
sport:USHORT; // 源端口号
dport:USHORT; // 目标端口号
seq_numberWORD; //32位序号
ack_numberWORD; //32位确认号
res_thl:UCHAR; //TCP头长度(4Bits;其值X4),保留值(4Bits)
flags_fo:UCHAR; //TCP 8位标志位
windowsize:USHORT; //16位窗口大小
checksum:USHORT; //16位校验和
urgent_pointer:USHORT; //16位紧急指针
// op_pad:UINT; //选项目,可选,注意,通常TCP头部长度为20,如果如此
//op_pad是不需要的
end;
////////////////////////////////////////////////////////
class function TWinPCap.checksum(bufferUSHORT;size:Integer):USHORT;
var
cksum:ULONG;
begin
cksum :=0;
while size>1 do
begin
Inc(cksum,buffer^);
Inc(buffer);
Dec(size,sizeof(USHORT));
end;
if Boolean(size) then
Inc(cksum,PByte(buffer)^);
cksum:=(cksum shr 16)+(cksum and $FFFF);
cksum:=(cksum shr 16)+cksum;
result:=USHORT(not cksum);
end;
////////////////////////////////////////////////////////////////////
procedure TMainForm.ToolButton3Click(Sender: TObject);
var
tsd:tsd_hdr;
tcp:tcp_header;
a:array [0..3] of byte;
b:array [0..300] of byte;
pByte;
begin
a[0] :=192;a[1] :=168;a[2] := 1;a[3] :=8;
CopyMemory(@tsd.saddr,@a,4);
a[0] :=220;a[1] :=194;a[2] :=57;a[3] :=88;
CopyMemory(@tsd.daddr,@a,4);
tsd.mbz :=0;
tsd.ptcl :=IPPROTO_TCP;
tsd.tcpl :=htons(sizeof(tcp_Header));
tcp.sport :=1125;
tcp.dport :=80;
tcp.seq_number :=662445656;
tcp.ack_number :=2772731560;
tcp.res_thl :=$50;
tcp.flags_fo :=$10;
tcp.windowsize :=65535;//$FF
tcp.checksum :=0;
tcp.urgent_pointer :=0;
p :=@b;
// ZeroMemory(p,sizeof(b));
CopyMemory(p,@tsd,sizeof(tsd));
Inc(p,sizeof(tsd));
CopyMemory(p,@tcp,sizeof(tcp));
tcp.checksum :=TWinPCap.checksum(PUSHORT(p),sizeof(tsd)+sizeof(tcp));
Caption :=inttohex(tcp.checksum,8);
end;
////////////////////////////////
得到的tcp.checksum是0x6735,但正确结果是0x6193,以上数据是是监视软件给的数据,照抄而已,但checksum结
果不对,哪位高手知道??
tsd_hdr=packed record //定义TCP伪首部
saddr:ULONG; //源地址
daddr:ULONG; //目的地址
mbz:byte;
ptcl:byte; //协议类型
tcpl:USHORT; //TCP头部长度
end;
///////////////////////////////////////////
tcp_header= packed record
sport:USHORT; // 源端口号
dport:USHORT; // 目标端口号
seq_numberWORD; //32位序号
ack_numberWORD; //32位确认号
res_thl:UCHAR; //TCP头长度(4Bits;其值X4),保留值(4Bits)
flags_fo:UCHAR; //TCP 8位标志位
windowsize:USHORT; //16位窗口大小
checksum:USHORT; //16位校验和
urgent_pointer:USHORT; //16位紧急指针
// op_pad:UINT; //选项目,可选,注意,通常TCP头部长度为20,如果如此
//op_pad是不需要的
end;
////////////////////////////////////////////////////////
class function TWinPCap.checksum(bufferUSHORT;size:Integer):USHORT;
var
cksum:ULONG;
begin
cksum :=0;
while size>1 do
begin
Inc(cksum,buffer^);
Inc(buffer);
Dec(size,sizeof(USHORT));
end;
if Boolean(size) then
Inc(cksum,PByte(buffer)^);
cksum:=(cksum shr 16)+(cksum and $FFFF);
cksum:=(cksum shr 16)+cksum;
result:=USHORT(not cksum);
end;
////////////////////////////////////////////////////////////////////
procedure TMainForm.ToolButton3Click(Sender: TObject);
var
tsd:tsd_hdr;
tcp:tcp_header;
a:array [0..3] of byte;
b:array [0..300] of byte;
pByte;
begin
a[0] :=192;a[1] :=168;a[2] := 1;a[3] :=8;
CopyMemory(@tsd.saddr,@a,4);
a[0] :=220;a[1] :=194;a[2] :=57;a[3] :=88;
CopyMemory(@tsd.daddr,@a,4);
tsd.mbz :=0;
tsd.ptcl :=IPPROTO_TCP;
tsd.tcpl :=htons(sizeof(tcp_Header));
tcp.sport :=1125;
tcp.dport :=80;
tcp.seq_number :=662445656;
tcp.ack_number :=2772731560;
tcp.res_thl :=$50;
tcp.flags_fo :=$10;
tcp.windowsize :=65535;//$FF
tcp.checksum :=0;
tcp.urgent_pointer :=0;
p :=@b;
// ZeroMemory(p,sizeof(b));
CopyMemory(p,@tsd,sizeof(tsd));
Inc(p,sizeof(tsd));
CopyMemory(p,@tcp,sizeof(tcp));
tcp.checksum :=TWinPCap.checksum(PUSHORT(p),sizeof(tsd)+sizeof(tcp));
Caption :=inttohex(tcp.checksum,8);
end;
////////////////////////////////
得到的tcp.checksum是0x6735,但正确结果是0x6193,以上数据是是监视软件给的数据,照抄而已,但checksum结
果不对,哪位高手知道??