请高手帮看一下,计算tcp校验和是否正确。用科来查看时总提示tcp校验和错误。 int l = libnet_init_packet( (LIBNET_TCP_H+nDataLen), &pBuffer);
if(-1 == l)
        {
AfxMessageBox("init packet error.");
return l;
}

l = libnet_build_tcp((u_short)nSrcPort, (u_short)nDstPort, dwSeqguess, dwAckId,
conByte, dwWinSize, 0, pData, nDataLen, pBuffer);
l = libnet_do_checksum( pBuffer, IPPROTO_TCP, LIBNET_TCP_H);
if (l != 1)
{
AfxMessageBox("tcpÍ·µÄУÑéºÍ²»ÕýÈ·¡£");
return -1;
}
PPACKETTCP pTcp = (PPACKETTCP)pBuffer;
//重新计算tcp校验和
ip_hdr Ipheader;
tcp_hdr Tcpheader;
ps_hdr psheader;
char buf[2000]; Tcpheader.sport=nSrcPort;
Tcpheader.dport=nDstPort;
Tcpheader.DataOffset=(5) << 4;
Tcpheader.Flags=TH_ACK;//ACK+PSH;
Tcpheader.Checksum=0;
Tcpheader.UrgPointer=0; Tcpheader.Windows=dwWinSize;
Tcpheader.acknum=dwAckId;
Tcpheader.seqnum=dwSeqguess; PS_HDR   pseudo_header;
pseudo_header.source_address =dwSrcIP;
pseudo_header.dest_address =dwDstIP;
pseudo_header.placeholder = 0;
pseudo_header.protocol = IPPROTO_TCP;
pseudo_header.tcp_length = htons(20); ZeroMemory(buf, sizeof(buf));
memcpy(buf,&pseudo_header,sizeof(pseudo_header));
char *ptr=NULL;
ptr=buf+sizeof(pseudo_header);
memcpy(ptr,&Tcpheader,20);
ptr+=20;

const char* pbuf = (const char*)(pTcp+sizeof(PACKETTCP));
int nDataLen2 = 0;
nDataLen2 = strlen(pbuf);
memcpy(ptr, pbuf, nDataLen2);
//计算tcp校验和
pTcp->th_sum = 0;
pTcp->th_sum = checksum((unsigned short*)buf, (sizeof(pseudo_header)+20+nDataLen2) );
前面调用的函数的实现
unsigned short checksum(unsigned short *buffer, int size)
{
 unsigned long cksum=0;
    while (size > 1)
    {
        cksum += *buffer++;
        size  -= sizeof(USHORT);   
    }
    if (size)
    {
        cksum += *(UCHAR*)buffer;   
    }
    cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum += (cksum >>16); 
    return (unsigned short)(~cksum); 
}

解决方案 »

  1.   

    我记得TCP的校验和是伪首部+数据,而不是伪首部+TCP header + 数据
      

  2.   

    伪首部+TCP header 也不行,我试了。
    tcpip详解第2卷我看了一下目录,好像没有和计算tcp校验和有关的内容。
      

  3.   

    netinet/tcp_subr.c里面的tcp_template函数为in_cksum准备好了伪首部,如果是中文版,在707页。
    注意tcp_output不直接调用它,是connect函数最终导致它被调用,见808页的下面。然后tcp_output里面调用了in_cksum计算校验和。其实我也没做过,希望能够帮助你。
      

  4.   

    忘了写了
    tcp_output里面调用了in_cksum计算校验和,在第702页的下面
      

  5.   

    应该可以,不过libnet中有一个专门计算校验和的函数libnet_chuchsum()