jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2726回复:8

请教一个关于TCPCHECKSUM(tcp校验和)的问题,各位大侠帮帮忙了

楼主#
更多 发布于:2004-05-24 15:47
下面的是我计算TCP校验和的程序段,但是发现老是出错,这里面确实有问题,但我不知道怎么解决,还请各位帮帮忙了
USHORT TcpCheckSum(PIPHeader buffer,UINT TcPpacketsize)
{
//buffer是IP包头指针,TcPpacketsize是TCP包的结构中没有长度字段,故需要自己计算,我是用整个包的长度-MAC头-IP头,不知道对否?
unsigned short size;//TCP包头长,参与计算的只有TCP包头和伪头,不包括数据,但是由于有的TCP包是有可选字段,而有些包又没有,我不知道该怎么计算这个包头长度
unsigned char tempchar;
unsigned long cksum = 0;
unsigned short * TempAddr;
unsigned short * TempAddr1;
int i = 0;
//加伪首
TempAddr = (unsigned short *)(&(buffer->src_addr));
for(i=0;i<4;i++)
{
cksum += *TempAddr;
TempAddr++;
}
cksum += 0x0600; //类型
cksum += TcPpacketsize;//加上TCP包的长度

//校验和位置清0
*(TempAddr + 8) = 0;
         size=sizeof(TCPHeader);//暂且所有的都作为没有可选字段的来处理
TempAddr1 = TempAddr;
while (size > 1)
{
cksum += *TempAddr++;
size -= sizeof(unsigned short);
}
if (size)
{
cksum += *(unsigned char*)TempAddr;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (unsigned short)(~cksum)&0xffff;
}
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-05-28 14:42
呵呵,我这儿羊比较少,要保护稀有动物!:)
baoyibao99
禁止发言
禁止发言
  • 注册日期2003-05-07
  • 最后登录2016-04-11
  • 粉丝0
  • 关注0
  • 积分894分
  • 威望8415点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-05-28 14:27
用户被禁言,该主题自动屏蔽!
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-05-25 11:16
youngyt:谢谢了,谢谢了,TCP的校验和现在计算时对的了,到了那边请你吃鸡腿:)不过那个驱动开发网上好像又出问题了,我得给分栏没有了,我开了新贴得,你到那去拿分好了。
但是现在又有另外一个问题:最开始我用NdisAllocateMemory分配内存驱动运行正常,当我分配更大的内存区时,系统就蓝屏!显示的错误是:page fault in nonpaged area!是不是分配过多引起的?我怎么分配更大的内存区,比如64K?
还有kangzh,谢谢你多次相助!上次我开了新贴,你没去拿分,我很是过意不去。你在哪?要不也请你吃鸡腿:)
kangzh
驱动小牛
驱动小牛
  • 注册日期2004-03-09
  • 最后登录2012-08-06
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望22点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-05-25 08:50
上次我那个函数就可以用,只是tcp和udp差不多,udp加了个伪头,并且需要将数据一起计算,应该tcp也有个伪头把(我手中没有书),也要将数据计算在内.
youngyt
驱动牛犊
驱动牛犊
  • 注册日期2003-11-23
  • 最后登录2006-12-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-05-24 19:36
/*-----
 * routines:
 * 计算TCP 或者UDP的检验和
 * Arguments:
 *  pBuf :指向IP数据包的首部
 *  size :IP数据包长度
 *----*/
unsigned short GetUdpOrTcpCheckSum(PUCHAR pIPBuf, int size)
{
char *pCheckIP;
PCHECKHEADER pCheckHeader;//指向伪头

unsigned char *p;//指向TCP or UDP数据头部
unsigned char *p1;//指向目的端口号

NDIS_STATUS Status;

IPHEADER* pTempIP;
PTCPHEADER pTCPHeader;

USHORT IPHeaderLen ;
USHORT TCPHeaderLen;
USHORT nCheckSum = 0;

pTempIP=(IPHEADER*)pIPBuf;

p=(UCHAR*)pTempIP+(UCHAR)((pTempIP->iVersion_iHeaderLength)&0x0f)*4;
p1=(UCHAR*)pTempIP+(UCHAR)((pTempIP->iVersion_iHeaderLength)&0x0f)*4+2;

TCPHeaderLen=(*(p1+10)>>4)*4;
IPHeaderLen = (UCHAR)((pTempIP->iVersion_iHeaderLength)&0x0f)*4;

pTCPHeader = (PTCPHEADER)((UCHAR*)pTempIP+IPHeaderLen);
Status = NdisAllocateMemoryWithTag(&pCheckIP,BUFFER_SIZE,CHECK);
if (Status != NDIS_STATUS_SUCCESS ){
DBGPRINT((\"ndisallocatememory failed\\n\"));
return 0 ;
}
if (pCheckIP == NULL){
DBGPRINT((\"pCheckIP == NULL\\n\"));
return 0 ;
}
NdisZeroMemory(pCheckIP,1700);

pCheckHeader = (PCHECKHEADER)pCheckIP;
pCheckHeader->nSourceIP = pTempIP->iSourceIP;
pCheckHeader->nDestinateIP = pTempIP->iDestinateIP;
pCheckHeader->nReserved = 0;
pCheckHeader->nProtocolType =pTempIP->szProtocol;
pCheckHeader->nLength = ntohs((USHORT)(size-20));
pTCPHeader->nCheckSum  = 0;
NdisMoveMemory(pCheckIP+12,(UCHAR*)pTempIP+IPHeaderLen,size-IPHeaderLen);

nCheckSum = GetChecksum((USHORT*)(pCheckIP),size-20+12);
ExFreePool(pCheckIP);
return nCheckSum;
}


这是经过证明可以用的。
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-05-24 18:29
我改了一下,但是还是不对
USHORT TcpCheckSum(PIPHeader buffer,UINT TcPpacketsize)
{
//buffer是IP包头指针,TcPpacketsize是TCP包的结构中没有长度字段,故需要自己计算,我是用整个包的长度-MAC头-IP头,不知道对否?
unsigned short size;
unsigned char tempchar;
unsigned long cksum = 0;
unsigned short * TempAddr;
int i = 0;
//加伪首
TempAddr = (unsigned short *)(&(buffer->src_addr));
for(i=0;i<4;i++)
{
cksum += *TempAddr;
TempAddr++;
}
cksum += 0x0600; //类型
cksum += TcPpacketsize;//加上TCP包的长度

//校验和位置清0
*(TempAddr + 8) = 0;
size=sizeof(TCPHeader);//暂且所有的都作为没有可选字段的来处理
while (size > 1)
{
cksum += *TempAddr++;
size -= sizeof(unsigned short);
}
if (size)
{
cksum += *(unsigned char*)TempAddr;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (unsigned short)(~cksum)&0xffff;
}
是不是TCP包长度的计算错误?但应该是包的总长度-MAC头-IP头
这有什么不对吗?还是程序其他地方的错误?

[编辑 -  5/24/04 by  jackieky]
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-05-24 17:50
啊!那我先试试看看了,谢谢了
flyhobo
驱动小牛
驱动小牛
  • 注册日期2004-03-05
  • 最后登录2005-05-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-05-24 17:38
TCP校验和计算要包括数据的!
好好过日子
游客

返回顶部