简体   繁体   English

TCP 序列号的简单递增并将其分配给发送 tcp header Z012570F8387D14D 中的确认号

[英]simple incrementing of TCP sequence number and assigning it to sending tcp header acknowledgement number in C

在此处输入图像描述 I am simulating TCP and now I am stuck to acknowledgement number handling.我正在模拟 TCP,现在我只能处理确认号。

tcph->seq is received sequence number and I am assigning it to tcp->ack_seq which is acknowledgement number like tcph->seq是接收到的序列号,我将它分配给 tcp->ack_seq 这是确认号,如

  tcp->ack_seq=htons(ntohs(tcph->seq)+1); 

But given the above code it seems like there is something inherently wrong, tcph->seq and tcph is in network byte order which It should be because I cast-ed it from buffer and assign to tcph pointer但是考虑到上面的代码,似乎有一些本质上的错误,tcph->seq 和 tcph 是网络字节顺序,这应该是因为我从缓冲区中转换它并分配给 tcph 指针

This is my simple thread function that reads received buffer extract tcthdr (struct tcph) and tweak values or assign values to send tcphdr (struct tcp)这是我的简单线程 function 读取接收到的缓冲区提取 tcthdr (struct tcph) 并调整值或分配值以发送 tcphdr (struct tcp)

Its simply does what it does I there is really something wrong with this.它只是做了它所做的我确实有问题。 I am keeping getting wrong acknowlegdemnet numbers (not really reflecting as to how I am incrementing sequence number and assign it to acknowledgement number).我不断收到错误的确认号(并没有真正反映我如何增加序列号并将其分配给确认号)。 Can any one please take a look at this so I finally have TCP handshake successful.任何人都可以看看这个,所以我终于有 TCP 握手成功。 Problem comes I send SYN+ACK packet and my client retransmit SYN packet and this cycle is polluting my wireshark view nothing useful just awefull loots of SYN and reponse SYN+ACK from my code问题来了,我发送 SYN+ACK 数据包,我的客户端重新传输 SYN 数据包,这个循环污染了我的 wireshark 视图没有什么有用的,只是 SYN 的大量战利品并从我的代码中响应 SYN+ACK

void * receiver(void *data)
{



    //struct sockaddr_in cliaddr = {0};
    int recvlen = -1;
    int writelen = -1;
    //socklen_t clilen = sizeof(cliaddr);

    while (!_do_exit)
    {
        //recvlen = rrecvfrom(_udp_fd, buf, sizeof(buf), 0, (struct sockaddr*)&cliaddr, &clilen);
        char buf[VPN_MAX_MTU] = {0};
        char buf_1[VPN_MAX_MTU] = {0};
        memset(buf,0,VPN_MAX_MTU);
        memset(buf_1,0,VPN_MAX_MTU);
        memset(buf,0,VPN_MAX_MTU);
        memset(buf_1,0,VPN_MAX_MTU);
        

        char *str_source=malloc(18);
        char *str_dest=malloc(18);
        memset(str_source,0,18);
        memset(str_dest,0,18);
        recvlen=read(_tun_fd,buf,VPN_MAX_MTU);
        if(recvlen>0)
        {

    //BUFFER received here        
        struct iphdr *iph=(struct iphdr *)buf;  
        struct iphdr *ip=(struct iphdr *)buf_1;
        int y=0;
        for(int b=0;b<(sizeof(struct iphdr)+sizeof(struct tcphdr));b++)
        {
            if(y==20)
            {
                y=0;
                //printf("\n");
            }
            
            //printf("%x ",buf[b]<<24);
            
            
            y++;
        
        }
    //      tcph->check=(tcp_chksum(iph,tcph));
        //iph->check = csum(iph, sizeof(*iph));
        char str_src[18]={0};
        char str_dest_t[18]={0};
           
           
        //printf("IN %s %s\n",get_ip_str_1(iph->saddr,str_src),get_ip_str_1(iph->daddr,str_dest_t));
        memcpy(&ip->daddr,&iph->saddr,sizeof(uint32_t));
        memcpy(&ip->saddr,&iph->daddr,sizeof(uint32_t));
        //printf("OUT %s %s\n",get_ip_str_1(ip->saddr,str_src),get_ip_str_1(ip->daddr,str_dest_t));
        //Create ip
        
        //DOUBLE CHECK FOR BYTE ORDER
        
        //ip->tot_len=iph->tot_len;
        populate_ip_some(iph,ip);
        ip->tos=0;
        ip->tos=iph->tos;
        ip->ihl         = 5;
        ip->version     = 4;
        ip->tot_len     = htons(sizeof(struct iphdr) + sizeof(struct tcphdr));
        ip->protocol    = 6;
        ip->check=0; 
        //DOUBLE CHECK FOR BYTE ORDER
        ip->id=htons(100);
            ip->check = htons(csum(ip, sizeof(*ip)));


        //printf("before %d \n",htons(iph->check));
        iph->check=0; 
        //printf("middle %d\n",iph->check);
        //DOUBLE CHECK FOR BYTE ORDER
            iph->check = htons(csum(iph, sizeof(*iph)));

        int i=iph->ihl*4;
        struct tcphdr *tcph=(struct tcphdr *)(buf+i);
        //printf("tcp before %x\n",htons(tcph->check));
        tcph->check=0;
        printf("TCP START\n");
        tcph->check=(tcp_chksum(iph,tcph));
            printf("TCP END\n");
        //printf("tcp after %d\n",(tcph->check));
        //printf("i == %d\n",i);
        //POSSIBLY PRINT IPH for fun
        //for(int a=0;a<recvlen;a++)
            //printf("%x\n",buf[a]);
        //GET ihl SEND --  tcp
        int j=(ip->ihl*4);
        //printf("j == %d\n",j);
        int x=0;
        
        //SEEK filling
        struct tcphdr *tcp=(struct tcphdr *)(buf_1+20);
        //populate_tcp_some(tcph,tcp);//Do LOOK AT THIS FUNCTION TO [SEE/CORRECT IT] >:)
        seq++;
        if(tcph->syn==1)
        {
               printf("WHAT THE HELL THEN WHY\n");  
               printf("syn\n");
               //populate_tcp_some(tcph,tcp);
               tcp->seq=htons(seq);

               //tcp->ack_seq=htons(ntohs(tcph->seq)+1);
               printf("seq = %d | ack_seq = %d\n",ntohs(tcph->seq),ntohs(tcp->ack_seq));
               tcp->syn=1;
               tcp->ack=1;
               tcp->res1=0;
               tcp->res1=0;
               tcp->urg=0;
               tcp->psh=0;
               tcp->fin=0;
               tcp->doff=5;
               tcp->source=htons(80);
               tcp->dest=tcph->source;
               tcp->ack_seq=htons(ntohs(tcph->seq)+1);//htons(ntohs(tcph->seq)+1);
               
    //         printf("received tcp syn = %d\n",tcph->syn);
        }
        else if(tcph->syn==0 && tcph->ack==1){
                   printf("WHAT THE HELL THEN COOL\n"); 
               printf("syn\n");
             //  populate_tcp_some(tcph,tcp);
               //tcp->seq=htons(1);
               tcp->seq=htons(seq);
               tcp->ack_seq=tcph->seq;
               tcp->syn=0;
               tcp->ack=1;
               tcp->res1=0;
               tcp->res1=0;
               tcp->urg=0;
               tcp->psh=0;
               tcp->fin=0;
               tcp->doff=5;
               tcp->source=htons(80);
                   tcp->dest=tcph->source;
               //tcp->ack_seq=tcph->seq;//htons(ntohs(tcph->seq)+1);
                   tcp->ack_seq=htons(ntohs(tcph->seq)+1);
        }
        else
        {
               populate_tcp_some(tcph,tcp);
               tcp->syn=0;
               tcp->ack=1;
               //tcp->seq=htons(1);
               tcp->seq=htons(seq);
               tcp->res1=0;
               tcp->res1=0;
               tcp->urg=0;
               tcp->psh=0;
               tcp->fin=0;
               tcp->doff=5;
               
                   tcp->source=htons(80);
                   tcp->dest=tcph->source;
               tcp->ack_seq=htons(ntohs(tcph->seq)+1);//tcp->ack_seq=tcph->seq;//htons(ntohs(tcph->seq)+1);

    //         printf("sending tcp syn = %d ack = %d\n",tcp->syn,tcp->ack);
           
        }
        
        
        
        printf("syn=%d | ack = %d | fin = %d | %d seq = %d ack_seq = %d | urg = %d  | doff = %d | psh = %d rst = %d | rst2 = %d\n",tcp->syn,tcp->ack,tcp->fin,tcp->seq,tcp->ack_seq,tcp->urg,tcp->doff,tcp->psh,tcp->res1,tcp->res2);
        //populate_tcp_some(tcph,tcp);
        tcp->dest=tcph->source;
        tcp->window=tcph->window;
        //
        //printf("%d %d SOURCE PORT \n",ntohs(tcph->source),ntohs(tcp->dest));
        
        tcp->source=htons(80);
        printf("%d %d PORTS \n",ntohs(tcp->source),ntohs(tcp->dest));
        tcp->check=0;
        //TCP CHECKSUM ABOUT TRIPPLE WOW
        tcp->check=htons(tcp_chksum(ip,tcp));
        
        //printf("tcpH = %d |  tcp = %d\n",tcph->check,htons(tcp->check));
        //IF needed make payload data
        //WRITE
        if (recvlen > 0) 
        {

            printf("\n-WOW WOW WOW received seq = %d  ack == %d",ntohs(tcph->seq),ntohs(tcp->ack_seq));

            writelen = write(_tun_fd, buf_1, sizeof(struct iphdr)+sizeof(struct tcphdr));
                    //exit(0);  
           // sleep(2);
            //debug("SR:%04d\n", recvlen);
            //debug("TW:%04d\n", writelen);
            
            if (writelen < 0) 
            {
            //debug("%s: rwrite() %s [%d]\n", _progname, strerror(errno), errno);
               //break;//NO NEED
            }
        }
        else if (recvlen < 0) 
        {
            //debug("%s: rrecvfrom() %s\n", _progname, strerror(errno));
               //break;//NO NEED
        }
        else if (recvlen == 0) 
        {
            //why
        }
    //FINALLY THEN SEND || DO WIRE SHARK 
        }
        
        // ...:)__ :) __:) ___:)___ (: __(:__ (;...  

    }

    debug("** Receiver ending.\n");
    pthread_exit(NULL);
}

Update更新

Now I am get TCP last segment not captured for my ACK+SYN packet现在我得到 TCP 最后一个段没有为我的 ACK+SYN 数据包捕获

This is received SYN这是收到的 SYN

0000   45 00 00 3c c5 18 40 00 40 06 e0 2f c0 a8 0a 14
0010   c0 a8 0a 0f bc b2 00 50 f0 32 1f de 00 00 00 00
0020   a0 02 fa f0 c6 93 00 00 02 04 05 b4 04 02 08 0a
0030   95 a6 8e 4d 00 00 00 00 01 03 03 07

This is SYN+ACK这是 SYN+ACK

0000   45 00 00 28 00 64 40 00 40 06 a4 f8 c0 a8 0a 0f
0010   c0 a8 0a 14 00 50 bc b2 86 e8 00 00 f0 32 1f df
0020   50 12 fa f0 cb 70 00 00

And this is SYN AGAIN这是 SYN AGAIN

0000   45 00 00 3c c5 19 40 00 40 06 e0 2e c0 a8 0a 14
0010   c0 a8 0a 0f bc b2 00 50 f0 32 1f de 00 00 00 00
0020   a0 02 fa f0 c2 9c 00 00 02 04 05 b4 04 02 08 0a
0030   95 a6 92 44 00 00 00 00 01 03 03 07

ANd SYN again in row of this packet I get message last segment not captured在此数据包的行中再次 SYN 我收到消息最后一个段未捕获

0000   45 00 00 28 00 64 40 00 40 06 a4 f8 c0 a8 0a 0f
0010   c0 a8 0a 14 00 50 bc b2 86 e9 00 00 f0 32 1f df
0020   50 12 fa f0 cb 6f 00 00

This is my Update 2 to this这是我的更新 2

SYN同步

0000   45 00 00 3c 9f 75 40 00 40 06 05 d3 c0 a8 0a 14
0010   c0 a8 0a 0f bc b8 00 50 55 a8 f4 2c 00 00 00 00
0020   a0 02 fa f0 83 25 00 00 02 04 05 b4 04 02 08 0a
0030   96 60 97 37 00 00 00 00 01 03 03 07

SYN + ACK同步 + 确认

0000   45 00 00 28 00 64 40 00 40 06 a4 f8 c0 a8 0a 0f
0010   c0 a8 0a 14 00 50 bc b8 00 00 00 03 55 a8 f4 2d
0020   50 12 fa f0 18 8c 00 00

And this is SYN agian retramit这是 SYN agian retramit

0000   45 00 00 3c 9f 76 40 00 40 06 05 d2 c0 a8 0a 14
0010   c0 a8 0a 0f bc b8 00 50 55 a8 f4 2c 00 00 00 00
0020   a0 02 fa f0 7f 38 00 00 02 04 05 b4 04 02 08 0a
0030   96 60 9b 24 00 00 00 00 01 03 03 07

sequence and ack numbers are 32-bit values:序列号和确认号是 32 位值:

Hence this line:因此这一行:

tcp->ack_seq=htons(ntohs(tcph->seq)+1);//htons(ntohs(tcph->seq)+1);

Is using htons/ntohs which are functions that swap the bytes of 16-bit integers.正在使用 htons/ntohs,它们是交换 16 位整数字节的函数。 You need to change it to use htonl and ntohl您需要将其更改为使用htonlntohl

That might not be your only bug.这可能不是你唯一的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM