Tesiro
驱动牛犊
驱动牛犊
  • 注册日期2008-04-18
  • 最后登录2014-04-16
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望387点
  • 贡献值1点
  • 好评度3点
  • 原创分0分
  • 专家分0分
阅读:2703回复:3

UDP 包校验和计算

楼主#
更多 发布于:2012-09-24 03:57
     各位老大,今天写了一个计算校验和的程序,计算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
songbei6
驱动牛犊
驱动牛犊
  • 注册日期2012-02-09
  • 最后登录2020-09-03
  • 粉丝2
  • 关注3
  • 积分116分
  • 威望251点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于: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;
}
songbei6
驱动牛犊
驱动牛犊
  • 注册日期2012-02-09
  • 最后登录2020-09-03
  • 粉丝2
  • 关注3
  • 积分116分
  • 威望251点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2012-09-24 13:07
typedef struct _PSDHeader //定义TCP伪首部
{
    ULONG saddr; //源地址
    ULONG daddr; //目的地址
    CHAR mbz;
    CHAR ptcl; //协议类型
    USHORT tcpl; //TCP长度
}PSDHEADER,*PPSDHEADER;
Tesiro
驱动牛犊
驱动牛犊
  • 注册日期2008-04-18
  • 最后登录2014-04-16
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望387点
  • 贡献值1点
  • 好评度3点
  • 原创分0分
  • 专家分0分
地板#
发布于:2012-09-24 21:12
OK, 谢谢了
游客

返回顶部