阅读:2833回复:3
UDP 包校验和计算
各位老大,今天写了一个计算校验和的程序,计算IP头与UDP包的,IP的没有什么问题,但是UDP的校验和总是计算出错,以下是我使用调试器调试的数据,算法应该没有问题(IP与UDP使用相同),后来我直接对以下数据使用计算器进行手工的计算(计算时已经将包中的校验和作为0处理),得到的结果也与数据中包的校验和不一样(结果为9B71),请教是什么问题:(
1: kd> dt Udp Local var @ 0x8b0b92d4 Type _UDP_HEADER* 0x88111d82 +0x000 Source : 0x2ed8 +0x002 Target : 0xeb14 +0x004 Length : 0x2900 +0x006 Checksum : 0x92e6 1: kd> db 0x88111d82 L29 88111d82 d8 2e 14 eb 00 29 e6 92-79 78 00 00 00 01 00 00 .....)..yx...... 88111d92 00 00 00 00 0f 57 49 4e-2d 4d 4d 38 4e 43 55 52 .....WIN-MM8NCUR 88111da2 54 39 4d 43 00 00 ff 00-01 T9MC..... 1: kd> dt IPv4 Local var @ 0x8b0b92d8 Type _IPV4_HEADER* 0x88111d6e +0x000 Field1 : 0x45 'E' +0x001 TOS : 0 '' +0x002 Length : 0x3d00 +0x004 Fragment : 0x200 +0x006 Field2 : 0 +0x008 TTL : 0x1 '' +0x009 Protocol : 0x11 '' +0x00a Checksum : 0x56d3 +0x00c Source : 0x5d5bfea9 +0x010 Target : 0xfc0000e0 1: kd> db 0x88111d6e 88111d6e 45 00 00 3d 00 02 00 00-01 11 d3 56 a9 fe 5b 5d E..=.......V..[] 88111d7e e0 00 00 fc d8 2e 14 eb-00 29 e6 92 79 78 00 00 .........)..yx.. 88111d8e 00 01 00 00 00 00 00 00-0f 57 49 4e 2d 4d 4d 38 .........WIN-MM8 88111d9e 4e 43 55 52 54 39 4d 43-00 00 ff 00 01 00 00 00 NCURT9MC........ 88111dae 00 00 0b 00 0d 04 4d 64-6c 20 00 00 00 00 20 00 ......Mdl .... . 88111dbe 1c 00 00 00 00 00 80 f4-07 88 00 f0 07 88 21 00 ..............!. 88111dce 00 00 80 04 00 00 7f f0-05 00 00 00 00 00 00 00 ................ 88111dde 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 另外,检验和的算法,我参照http://blog.csdn.net/sahusoft/article/details/4584774 |
|
沙发#
发布于:2012-09-24 13:06
可以参考一下我的代码:
//校验 USHORT checksum(USHORT* buff, INT size) { ULONG cksum = 0; while(size>1) { cksum += *buff++; size -= sizeof(USHORT); } // 是奇数 if(size) { cksum += *(UCHAR*)buff; } // 将位的chsum高位和低位相加,然后取反 cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >> 16); return (USHORT)(~cksum); } //修改数包窗口大小,以及清除标志位 void ModifyPacketWndSize(PVOID pPacketContent,INT iPacketSize) { //定义数据包tcp/ip结构指针 int nLeavingLen; PETHeader pEtherHdr=NULL; PIPHeader pIpHdr=NULL; PTCPHeader pTcpHdr=NULL; PUDPHeader pUdpHdr=NULL; CHAR *pData=NULL; //基本判断 if (pPacketContent==NULL) { return FALSE; } //获得以太帧头,过滤协议,过滤ip协议,放行其他协议 nLeavingLen=iPacketSize; if(nLeavingLen < sizeof(ETHeader)) { return NDIS_STATUS_SUCCESS; } nLeavingLen -= sizeof(ETHeader); pEtherHdr = (PETHeader)pPacketContent; if(pEtherHdr->type != 0x8) // 如果不是IP协议,则不处理 return; //获得ip头 pIpHdr = (PIPHeader)(pEtherHdr + 1); // 验证剩余数据长度,防止发生内核非法访问 if(nLeavingLen < sizeof(IPHeader)) return; nLeavingLen -= sizeof(IPHeader); // 检查版本信息,我们仅处理IPv4 if(((pIpHdr->iphVerLen >> 4) & 0x0f) == 6) { return; } // 如果是TCP封包,修改窗口大小 if(pIpHdr->ipProtocol == 6) { //TCP伪数据包头指针 PSDHEADER *pPsdHeader=NULL; //数据包校验缓存大小 INT iTcpCheckoutBufSize; NDIS_PHYSICAL_ADDRESS phyaddr = {-1}; NDIS_STATUS Status; //修改窗口大小 pTcpHdr = (PTCPHeader)(pIpHdr + 1); pTcpHdr->windows=200; KdPrint(("改变窗口大小!\n")); //pTcpHdr->flags=0; //Tcp数据校验 iTcpCheckoutBufSize=sizeof(PSDHEADER)+nLeavingLen; Status=NdisAllocateMemory(&pPsdHeader,iTcpCheckoutBufSize,0,phyaddr); if (Status==NDIS_STATUS_SUCCESS) { NdisZeroMemory(pPsdHeader,iTcpCheckoutBufSize); //填充伪TCP头 pPsdHeader->daddr=pIpHdr->ipSource; pPsdHeader->saddr=pIpHdr->ipDestination; pPsdHeader->mbz=0; pPsdHeader->ptcl=0x06; pPsdHeader->tcpl=htons(nLeavingLen); ////计算TCP校验和 pTcpHdr->checksum=0; NdisMoveMemory((PCHAR)pPsdHeader+sizeof(PSDHEADER),pTcpHdr,nLeavingLen); pTcpHdr->checksum=checksum((PUSHORT)pPsdHeader,iTcpCheckoutBufSize); NdisFreeMemory(pPsdHeader,iTcpCheckoutBufSize,0); } } return; } |
|
板凳#
发布于:2012-09-24 13:07
typedef struct _PSDHeader //定义TCP伪首部
{ ULONG saddr; //源地址 ULONG daddr; //目的地址 CHAR mbz; CHAR ptcl; //协议类型 USHORT tcpl; //TCP长度 }PSDHEADER,*PPSDHEADER; |
|
地板#
发布于:2012-09-24 21:12
OK, 谢谢了
|
|