passthru 2010-11-12

最近用passthru简单改了改,对tcp和udp的数据包做了个简单加密。贴个计算校验和的代码

//计算校验和
USHORT checksum(USHORT *buffer,int size)
{
    unsigned long cksum=0;
    while(size>1)
    {
       cksum+=*buffer++;
       size-=sizeof(USHORT);
    }
    if(size)
    {
       cksum+=*(UCHAR *)buffer;
    }
    //将32位数转换成16
    while (cksum>>16)
    {
       cksum=(cksum>>16)+(cksum & 0xffff);
    }
    return (USHORT) (~cksum);
}
ULONG ntohl(IN ULONG data)
{
_asm
{
    mov ecx, data
    mov eax,ecx
    mov edx,ecx
    shl eax,10h
    and edx,0FF00h
    or eax,edx
    mov edx,ecx
    shr edx,10h
    and ecx,0FF0000h
    or edx,ecx
    shl eax,8
    shr edx,8
    or eax,edx
}
}
USHORT ntohs(USHORT data)
{
USHORT sRet;
_asm
{
    mov cx,data
    mov ah,cl
    mov al,ch
    mov sRet,ax
}
return sRet;
}
//-------------------------------------------------------------------------
// PacketCheckSum
// 计算数据包的校验和
// 参数:packet-待处理数据(将封装好的数据包的指针)
//-------------------------------------------------------------------------
void PacketCheckSum(PUCHAR packet)
{
    Dlc_Header *pdlc_header=NULL; //以太头指针
    Ip_Header *pip_header=NULL; //IP头指针
    USHORT attachsize=0; //传输层协议头以及附加数据的总长度
    pdlc_header=(Dlc_Header *)packet;//判断ethertype,如果不是IP包则不予处理
    if(pdlc_header->ethertype!=0x0008) //不是IP协议直接返回
    {
       return;
    }
    pip_header=(Ip_Header *)(packet+14);
    //TCP包
    if(0x06==pip_header->proto)
    {
       Tcp_Header *ptcp_header=NULL; //TCP头指针
       Tcp_Psd_Header *ptcp_psd_header=NULL;
       ptcp_header=(Tcp_Header *)(packet+14+((pip_header->ver_len)&15)*4);
       attachsize=ntohs(pip_header->total_len)-(((pip_header->ver_len)&15)*4);
       ptcp_psd_header=(Tcp_Psd_Header *)ExAllocatePoolWithTag(NonPagedPool,attachsize+sizeof(Tcp_Psd_Header),'x70');
       if(!ptcp_psd_header) 
       {
        DbgPrint("计算校验和失败,内存不足 \n");
        return;
       }
       RtlZeroMemory(ptcp_psd_header,attachsize+sizeof(Tcp_Psd_Header));   //填充伪TCP头0
       ptcp_psd_header->destip=pip_header->destIP;
       ptcp_psd_header->sourceip=pip_header->sourceIP;
       ptcp_psd_header->mbz=0;
       ptcp_psd_header->ptcl=0x06;
       ptcp_psd_header->tcpl=ntohs(attachsize);   //计算TCP校验和
       ptcp_header->chksum=0;
       RtlCopyMemory((unsigned char *)ptcp_psd_header+sizeof(Tcp_Psd_Header),(unsigned char *)ptcp_header,attachsize);
       ptcp_header->chksum=checksum((unsigned short *)ptcp_psd_header,
        attachsize+sizeof(Tcp_Psd_Header));
       //计算ip头的校验和
       pip_header->checksum=0;
       pip_header->checksum=checksum((unsigned short *)pip_header,20);
       //计算完成释放内存
       ExFreePool(ptcp_psd_header);
       return;
    }
    //UDP包
    if(0x11==pip_header->proto)
    {
       Udp_Header *pudp_header=NULL; //UDP头指针 
       Udp_Psd_Header *pudp_psd_header=NULL;
       pudp_header=(Udp_Header *)(packet+14+((pip_header->ver_len)&15)*4); 
       attachsize=ntohs(pip_header->total_len)-(((pip_header->ver_len)&15)*4);
       pudp_psd_header=(Udp_Psd_Header *)ExAllocatePoolWithTag(NonPagedPool,attachsize+sizeof(Udp_Psd_Header),'x70');
       if(!pudp_psd_header)
       {
        DbgPrint("计算校验和失败,内存不足 \n");
        return;
       }
       RtlZeroMemory(pudp_psd_header,attachsize+sizeof(Udp_Psd_Header));   //填充伪UDP头0
       pudp_psd_header->destip=pip_header->destIP;
       pudp_psd_header->sourceip=pip_header->sourceIP;
       pudp_psd_header->mbz=0;
       pudp_psd_header->ptcl=0x11;
       pudp_psd_header->udpl=ntohs(attachsize);
       //计算UDP校验和
       pudp_header->chksum=0;
       RtlCopyMemory((unsigned char *)pudp_psd_header+sizeof(Udp_Psd_Header),(unsigned char *)pudp_header,attachsize);
       pudp_header->chksum=checksum((unsigned short *)pudp_psd_header,attachsize+sizeof(Udp_Psd_Header));
       //计算ip头的校验和
       pip_header->checksum=0;
       pip_header->checksum=checksum((unsigned short *)pip_header,20); 
       //计算完成释放内存
       ExFreePool(pudp_psd_header);
       return;
    }
    return;
}

你可能感兴趣的:(passthru 2010-11-12)