创建报文

我想发一个TCP/IP 的原始包,但是tcp的校验和总是不对,请各位大虾帮忙
下面是我的  TCP/IP 的原始包的构造
typedef struct ip_hdr
{
    unsigned char  ip_verlen;        // IP version & length
    unsigned char  ip_tos;           // IP type of service
    unsigned short ip_totallength;   // Total length
    unsigned short ip_id;            // Unique identifier 
    unsigned short ip_offset;        // Fragment offset field
    unsigned char  ip_ttl;           // Time to live
    unsigned char  ip_protocol;      // Protocol(TCP, UDP, etc.)
    unsigned short ip_checksum;      // IP checksum
    unsigned int   ip_srcaddr;       // Source address
    unsigned int   ip_destaddr;

}IP_HDR; 


typedef struct tcp_hdr
{
     unsigned short    sport;
     unsigned short    dport;
     unsigned int             seqnum;
     unsigned int             acknum;
     unsigned char              DataOffset;
     unsigned char             Flags;
     unsigned short    Windows;
     unsigned short    Checksum;
     unsigned short    UrgPointer;

}TCP_HDR;


typedef struct ps_hdr
{
   unsigned int source_address;
   unsigned int dest_address;
   unsigned char placeholder;
   unsigned char protocol;
   unsigned short tcp_length;
 

}PS_HDR;


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); 
}

void makerawpacket()
{
    ip_hdr ipheader; 
    tcp_hdr tcp_header;
    DWORD dwFromIP = inet_addr("192.168.0.102"); 
    DWORD dwToIP = inet_addr("192.168.0.1");
    char buf[50];
    ipheader.ip_totallength = htons(50);
    ipheader.ip_offset = 0x40;            
    ipheader.ip_ttl = 128;              
    ipheader.ip_protocol = IPPROTO_TCP; 
    ipheader.ip_checksum = 0 ; 
    ipheader.ip_id=htons(1);  
    ipheader.ip_srcaddr=dwFromIP;
    ipheader.ip_destaddr=dwToIP;
    ipheader.ip_checksum=checksum((unsigned short *)&ipheader,20);

    tcp_header.sport=htons(100);
    tcp_header.dport=htons(1011);
    tcp_header.DataOffset=(5) << 4;
    tcp_header.Flags=ACK+PSH;
    tcp_header.Checksum=0;
    tcp_header.UrgPointer=0;


   PS_HDR   pseudo_header;
   pseudo_header.source_address =ipheader.ip_srcaddr ;
   pseudo_header.dest_address =ipheader.ip_destaddr ;
   pseudo_header.placeholder = 0;
   pseudo_header.protocol = IPPROTO_TCP;
   pseudo_header.tcp_length = htons(sizeof(tcp_header));

   ZeroMemory(buf, sizeof(buf));
   memcpy(buf,&pseudo_header,sizeof(pseudo_header));
   char *ptr=NULL;
   ptr=buf+sizeof(pseudo_header);
   memcpy(ptr,&tcp_header,20);
   ptr+=20;
   memcpy(ptr, "qqqqqqqqqq",10);//包中有数据“qqqqqqqqqq”
   ptr+=10; 
   //计算tcp包的校验和
   tcp_header.Checksum = checksum((unsigned short*)buf,sizeof    (pseudo_header)+30);
  
  //buf 为原始包
  ZeroMemory(buf, sizeof(buf));
  ptr = buf;
  memcpy(ptr, &ipheader, sizeof(ipheader));
  ptr += sizeof(ipheader);
  memcpy(ptr, &tcp_header, sizeof(tcp_header));
  ptr += sizeof(tcp_header);  
  memcpy(ptr, "qqqqqqqqqq",10);

}
这样产生的原始包总报tcp的校验和错误。若包中无数据,校验和是对的。
请各位大虾帮忙看一下,不胜感激!!!

你可能感兴趣的:(IP,tcp,checksum)