阅读:2726回复:8
请教一个关于TCPCHECKSUM(tcp校验和)的问题,各位大侠帮帮忙了
下面的是我计算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; } |
|
沙发#
发布于:2004-05-28 14:42
呵呵,我这儿羊比较少,要保护稀有动物!:)
|
|
板凳#
发布于:2004-05-28 14:27
用户被禁言,该主题自动屏蔽! |
|
地板#
发布于:2004-05-25 11:16
youngyt:谢谢了,谢谢了,TCP的校验和现在计算时对的了,到了那边请你吃鸡腿:)不过那个驱动开发网上好像又出问题了,我得给分栏没有了,我开了新贴得,你到那去拿分好了。
但是现在又有另外一个问题:最开始我用NdisAllocateMemory分配内存驱动运行正常,当我分配更大的内存区时,系统就蓝屏!显示的错误是:page fault in nonpaged area!是不是分配过多引起的?我怎么分配更大的内存区,比如64K? 还有kangzh,谢谢你多次相助!上次我开了新贴,你没去拿分,我很是过意不去。你在哪?要不也请你吃鸡腿:) |
|
地下室#
发布于:2004-05-25 08:50
上次我那个函数就可以用,只是tcp和udp差不多,udp加了个伪头,并且需要将数据一起计算,应该tcp也有个伪头把(我手中没有书),也要将数据计算在内.
|
|
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; } 这是经过证明可以用的。 |
|
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] |
|
7楼#
发布于:2004-05-24 17:50
啊!那我先试试看看了,谢谢了
|
|
8楼#
发布于:2004-05-24 17:38
TCP校验和计算要包括数据的!
|
|
|