CHECKSUM检验和的问题(出1000分)(200分)

X

xiyf

Unregistered / Unconfirmed
GUEST, unregistred user!
我要发一个数据包(tcp),谁能提供我一个例子程序,我发出去的包,检验和老是有问题。
急呀。。。。。
我查到网上所有的检验和的算法(包括大富温已有的方法),可还是有问题,所以我想,
是不是我发包的方法有问题了。请大侠贴完整代码。
如果1000分不够,我可以出2000分呀。。。。。。。(只要能解决我的问题)
 
以下代码绝对没有问题,我测试过,用很多抓包软件看包的校验和都没有任何问题,
如果出问题那是你的程序其他部分有逻辑问题
function checksum(buffer:pword;size:integer):word; //校验和函数
var
cksum:Longword;
buf:pword;
begin
cksum:=0;
buf:=buffer;

while size>1 do
begin
cksum:=cksum+buf^;
inc(buf);
dec(size,sizeof(word));
end;

if size=1 then
inc(cksum,Pbyte(buf)^);

cksum:=(cksum shr 16)+(cksum and $FFFF);
cksum:=(cksum shr 16)+cksum;
result:=word(not cksum);

end;

 
我以前就看过你这个方法了,非常感谢!
但好象还是不行了,是不是tcp的检验和,还要定义一个伪首部,才能计算呀,我现在就是
搞不清楚什么时候调用这个方法呀。
如果是直接给IP包头赋好值,然后直接把IP包头的BUF传进去,是肯定错的。
不知道如何传参数进去呀。

 
IPman中的C代码,参考一下吧:
WORD CheckSum(WORD *addr,WORD len)
{
DWORD lSum;
WORD wOddByte;
WORD wAnswer;

lSum=0l;

while(len>1) {
lSum+= *addr++;
len-=2;
}

if(len==1) {
wOddByte=0;
*((unsigned char*)&wOddByte)=*(unsigned char*)addr;
lSum+=wOddByte;
}

lSum=(lSum>>16)+(lSum&0xffff);
lSum+=(lSum>>16);
wAnswer=(unsigned int)~lSum;

return wAnswer;
}

...

WORD SendTCPPacket(HANDLE hVxD,
struct EtherAddr *psourether,
struct EtherAddr *pdestether,
struct IPAddr *psourip,
struct IPAddr *pdestip,
WORD sourport,
WORD destport,
WORD flag,
DWORD seqno,
DWORD ackno,
char *pbuf,
WORD len)
{
char Buffer[BUFFER_SIZE];
char HelpBuffer[BUFFER_SIZE];
char *pdata;
struct EtherPacketHead *pEtherHead;
struct IPPacketHead *pIPHead;
struct TCPPacketHead *pTCPHead,*pHelpTCPHead;
struct PseudoHead *pPseudoHead;
static WORD id=0;
WORD wlen;

id++;
memset(Buffer,0,BUFFER_SIZE);
pEtherHead=(struct EtherPacketHead *)Buffer;
pIPHead=(struct IPPacketHead *)(Buffer+ETHER_HEAD_LEN);
pTCPHead=(struct TCPPacketHead *)(Buffer+ETHER_HEAD_LEN+IP_HEAD_BYTE_LEN);
pPseudoHead=(struct PseudoHead *)HelpBuffer;
pHelpTCPHead=(struct TCPPacketHead *)(HelpBuffer+PSEUDO_HEAD_LEN);
pdata=(char *)(Buffer+ETHER_HEAD_LEN+IP_HEAD_BYTE_LEN+TCP_HEAD_BYTE_LEN);
/* Set ether head */
memcpy((void *)&pEtherHead->SourEther,(void *)psourether,6);
memcpy((void *)&pEtherHead->DestEther,(void *)pdestether,6);
pEtherHead->ServType=swaps(ETHER_PROTO_IP);
/* Set IP head */
memcpy((void *)&pIPHead->SourIP,(void *)psourip,4);
memcpy((void *)&pIPHead->DestIP,(void *)pdestip,4);
pIPHead->VerHLen=(IP_VER<<4)|IP_HEAD_LEN;
pIPHead->Type=IP_SERV_TYPE;
wlen=len+TCP_HEAD_BYTE_LEN+IP_HEAD_BYTE_LEN;
pIPHead->TtlLen=swaps(wlen);
pIPHead->Id=swaps(id);
pIPHead->FlgOff=0;
pIPHead->TTL=69;
pIPHead->Proto=IP_PROTO_TCP;
pIPHead->ChkSum=0;
pIPHead->ChkSum=CheckSum((WORD *)pIPHead,IP_HEAD_BYTE_LEN);
/* Set TCP head */
pTCPHead->SourPort=swaps(sourport);
pTCPHead->DestPort=swaps(destport);
pTCPHead->SeqNo=swapl(seqno);
pTCPHead->AckNo=swapl(ackno);
pTCPHead->HLen=TCP_HEAD_LEN<<4;
pTCPHead->Flag=flag;
pTCPHead->WndSize=swaps(8192);
pTCPHead->ChkSum=0;
pTCPHead->UrgPtr=0;
/* Set TCP data */
memcpy((void *)pdata,(void *)pbuf,len);
/* Calculate TCP checksum */
memcpy((void *)&pPseudoHead->SourIP,(void *)psourip,4);
memcpy((void *)&pPseudoHead->DestIP,(void *)pdestip,4);
pPseudoHead->Pad=0;
pPseudoHead->Proto=IP_PROTO_TCP;
wlen=len+TCP_HEAD_BYTE_LEN;
pPseudoHead->Len=swaps(wlen);
memcpy((void *)pHelpTCPHead,(void *)pTCPHead,wlen);
wlen=len+TCP_HEAD_BYTE_LEN+PSEUDO_HEAD_LEN;
pTCPHead->ChkSum=CheckSum((WORD *)HelpBuffer,wlen);
wlen=len+TCP_HEAD_BYTE_LEN+IP_HEAD_BYTE_LEN+ETHER_HEAD_LEN;
if(SendPacket(hVxD,Buffer,wlen)==SYSERR) {
fprintf(stderr,"Can not send TCP packet./n");
return SYSERR;
}
return OK;
}
 
c的代码我也有呀,我需要DELPHI的代码,
我现在急死了,我发出去的包都检验和都不对呀!
现在我加200分,总分已经达到1200分了。
 
要定义一个伪头,包括对方的IP,本方的IP,还有TCP头,一起计算校验和,
我的算法没有问题,我做的程序通过了抓包软件的测试,所以我说是你的
程序的其他部分有问题
 
呵呵,对了,你要这类的程序干吗?好象一般项目里都用不上呀
 
我要做旁路信息过滤系统。
 
终于解决了。
 
恭喜!!!
 
顶部