用raw socket编写一个TCP包,SYN 值为1。用抓包软件,源,目的IP地址,端口,IP头部校验和都没有错。但是TCP包的检验和就错啦!!请高手指教。
以下是检验函数以及一些相关代码。
typedef struct tcphdr
{
USHORT src_port; //16位源端口
USHORT dst_port; //16位目的端口
unsigned int seq; //32位序列号
unsigned int ack; //32位确认号
unsigned char lenres; //4位数据偏移+保留位的前4位(置0)
unsigned char flag; //2位保留位+6位标志控制比特
USHORT win; //16位,窗口大小
USHORT chksum; //16位校验和
USHORT urp; //16位紧急指针
//其它字段,选项与填充省略
}TCPHeader;//用于计算校验和,并不真正发送。
typedef struct psdhdr //定义tcp伪首部
{
unsigned long saddr; //32位源IP地址
unsigned long  daddr; //32位目的IP地址
unsigned char zeroin; //8位全0比特
unsigned char ptype; //8位服务类型(TCP类型号为6)
unsigned short tcplen; //16位TCP总长度
}PSDHeader;#define TCP_SZ sizeof(TCPHeader)
#define PSD_SZ sizeof(PSDHeader)
#define DATA_SZ 6//sizeof(th_data)
//计算校验和函数
USHORT CheckSum(USHORT *addr, int len)
{
    register int sum = 0;
    u_short answer = 0;
    register u_short *w = addr;
    register int nleft = len;     /*
     * Our algorithm is simple, using a 32 bit accumulator (sum), we add
     * sequential 16 bit words to it, and at the end, fold back all the
     * carry bits from the top 16 bits into the lower 16 bits.
     */
    while (nleft > 1)
      {
  sum += *w++;
  nleft -= 2;
      }     /* mop up an odd byte, if necessary */
    if (nleft == 1)
      {
  *(u_char *) (&answer) = *(u_char *) w;
  sum += answer;
      }
    /* add back carry outs from top 16 bits to low 16 bits */
    sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
    sum += (sum >> 16); /* add carry */
    answer = ~sum; /* truncate to 16 bits */
    return (answer);
}
void fill_package(char *send_buf)
{
 .....
 .....
TcpHd.src_port=htons(srcPort);
TcpHd.dst_port=htons(dstPort);
TcpHd.seq=htonl(0x1234);
TcpHd.ack=htonl(0x23);
TcpHd.lenres=(TCP_SZ/4<<4 | 0);//--------------数据偏移==tcp首部(没有选项字段)
TcpHd.flag=SYN;
TcpHd.win=htons(512);
TcpHd.urp=0;
TcpHd.chksum=0; psdHd.saddr=htonl(IPHd.sourceIP);
psdHd.daddr=htonl(IPHd.destIP);
psdHd.zeroin=0;
psdHd.ptype=IPPROTO_TCP;
psdHd.tcplen=htons(TCP_SZ+DATA_SZ);//--------------------TCP包总长度 //计算TCP校验和
memset(chkbuf,'\0',PACKAGE_SIZE);
memcpy(chkbuf, &psdHd, sizeof(psdHd)); 
memcpy(chkbuf+sizeof(psdHd), &TcpHd, sizeof(TcpHd)); 
memcpy(chkbuf+sizeof(psdHd)+sizeof(TcpHd),th_data,DATA_SZ);//--------------复制数据!!!!!!!!
TcpHd.chksum = CheckSum((USHORT *)chkbuf,sizeof(psdHd)+sizeof(TcpHd)+DATA_SZ); }高手指点啊!真是救命来的。两天了,没有一点头绪。