⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uip.lst

📁 运行环境是keil。这是一个实现嵌入式TCP/IP的程序
💻 LST
📖 第 1 页 / 共 4 页
字号:
 501   4              ++BUF->ackno[0];
 502   4            }
 503   3          }
 504   2        }
 505   1       
 506   1        /* Swap port numbers. */
 507   1        tmpport = BUF->srcport;
 508   1        BUF->srcport = BUF->destport;
 509   1        BUF->destport = tmpport;
 510   1        
 511   1        /* Swap IP addresses. */
 512   1        tmpport = BUF->destipaddr[0];
 513   1        BUF->destipaddr[0] = BUF->srcipaddr[0];
 514   1        BUF->srcipaddr[0] = tmpport;
 515   1        tmpport = BUF->destipaddr[1];
 516   1        BUF->destipaddr[1] = BUF->srcipaddr[1];
 517   1        BUF->srcipaddr[1] = tmpport;
 518   1      
 519   1        /* And send out the RST packet! */
 520   1        goto tcp_send_noconn;
 521   1      
 522   1        /* This label will be jumped to if we matched the incoming packet
 523   1           with a connection in LISTEN. In that case, we should create a new
 524   1           connection and send a SYNACK in return. */
 525   1       found_listen:
 526   1        /* First we check if there are any connections avaliable. Unused
 527   1           connections are kept in the same table as used connections, but
 528   1           unused ones have the tcpstate set to CLOSED. */
 529   1        for(c = 0; c < UIP_CONNS; ++c) {
 530   2          if(uip_conns[c].tcpstateflags == CLOSED) 
 531   2            goto found_unused_connection;
 532   2        }
 533   1        for(c = 0; c < UIP_CONNS; ++c) {
 534   2          if(uip_conns[c].tcpstateflags == TIME_WAIT) 
 535   2            goto found_unused_connection;
 536   2        }
 537   1        /* All connections are used already, we drop packet and hope that
 538   1           the remote end will retransmit the packet at a time when we have
 539   1           more spare connections. */
 540   1        UIP_STAT(++uip_stat.tcp.syndrop);
 541   1        UIP_LOG("tcp: found no unused connections.");
 542   1        goto drop;
 543   1      
 544   1        /* This label will be jumped to if we have found an unused
 545   1           connection that we can use. */
 546   1       found_unused_connection:
 547   1        uip_conn = &uip_conns[c];
 548   1      
 549   1        /* Fill in the necessary fields for the new connection. */
 550   1        uip_conn->timer = UIP_RTO;
C51 COMPILER V7.06   UIP                                                                   04/05/2006 12:13:01 PAGE 10  

 551   1        uip_conn->nrtx = 0;
 552   1        uip_conn->lport = BUF->destport;
 553   1        uip_conn->rport = BUF->srcport;
 554   1        uip_conn->ripaddr[0] = BUF->srcipaddr[0];
 555   1        uip_conn->ripaddr[1] = BUF->srcipaddr[1];
 556   1        uip_conn->tcpstateflags = SYN_RCVD | UIP_OUTSTANDING;
 557   1      
 558   1        uip_conn->snd_nxt[0] = uip_conn->ack_nxt[0] = iss[0];
 559   1        uip_conn->snd_nxt[1] = uip_conn->ack_nxt[1] = iss[1];
 560   1        uip_conn->snd_nxt[2] = uip_conn->ack_nxt[2] = iss[2];
 561   1        uip_conn->snd_nxt[3] = uip_conn->ack_nxt[3] = iss[3];
 562   1        uip_add_ack_nxt(1);
 563   1      
 564   1        /* rcv_nxt should be the seqno from the incoming packet + 1. */
 565   1        uip_conn->rcv_nxt[3] = BUF->seqno[3];
 566   1        uip_conn->rcv_nxt[2] = BUF->seqno[2];
 567   1        uip_conn->rcv_nxt[1] = BUF->seqno[1];
 568   1        uip_conn->rcv_nxt[0] = BUF->seqno[0];
 569   1        uip_add_rcv_nxt(1);
 570   1      
 571   1      
 572   1        /* Parse the TCP MSS option, if present. */
 573   1        if((BUF->tcpoffset & 0xf0) > 0x50) {
 574   2          for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
 575   3            opt = uip_buf[40 + UIP_LLH_LEN + c];
 576   3            if(opt == 0x00) {
 577   4              /* End of options. */   
 578   4              break;
 579   4            } else if(opt == 0x01) {
 580   4              ++c;
 581   4              /* NOP option. */
 582   4            } else if(opt == 0x02 &&
 583   3                      uip_buf[40 + UIP_LLH_LEN + c + 1] == 0x04) {
 584   4              /* An MSS option with the right option length. */       
 585   4              tmpport = (uip_buf[40 + UIP_LLH_LEN + c + 2] << 8) |
 586   4                uip_buf[40 + UIP_LLH_LEN + c + 3];
 587   4              uip_conn->mss = tmpport > UIP_TCP_MSS? UIP_TCP_MSS: tmpport;
 588   4              
 589   4              /* And we are done processing options. */
 590   4              break;
 591   4            } else {
 592   4              /* All other options have a length field, so that we easily
 593   4                 can skip past them. */
 594   4              c += uip_buf[40 + UIP_LLH_LEN + c + 1];
 595   4            }      
 596   3          }
 597   2        }
 598   1        
 599   1        /* Our response will be a SYNACK. */
 600   1      #if UIP_ACTIVE_OPEN
               tcp_send_synack:
                BUF->flags = TCP_ACK;    
                
               tcp_send_syn:
                BUF->flags |= TCP_SYN;    
              #else /* UIP_ACTIVE_OPEN */
 607   1       tcp_send_synack:
 608   1        BUF->flags = TCP_SYN | TCP_ACK;    
 609   1      #endif /* UIP_ACTIVE_OPEN */
 610   1        
 611   1        /* We send out the TCP Maximum Segment Size option with our
 612   1           SYNACK. */
C51 COMPILER V7.06   UIP                                                                   04/05/2006 12:13:01 PAGE 11  

 613   1        BUF->optdata[0] = 2;
 614   1        BUF->optdata[1] = 4;
 615   1        BUF->optdata[2] = (UIP_TCP_MSS) / 256;
 616   1        BUF->optdata[3] = (UIP_TCP_MSS) & 255;
 617   1        uip_len = 44;
 618   1        BUF->tcpoffset = 6 << 4;
 619   1        goto tcp_send;
 620   1      
 621   1        /* This label will be jumped to if we found an active connection. */
 622   1       found:
 623   1        uip_flags = 0;
 624   1      
 625   1        /* We do a very naive form of TCP reset processing; we just accept
 626   1           any RST and kill our connection. We should in fact check if the
 627   1           sequence number of this reset is wihtin our advertised window
 628   1           before we accept the reset. */
 629   1        if(BUF->flags & TCP_RST) {
 630   2          uip_conn->tcpstateflags = CLOSED;
 631   2          UIP_LOG("tcp: got reset, aborting connection.");
 632   2          uip_flags = UIP_ABORT;
 633   2          UIP_APPCALL();
 634   2          goto drop;
 635   2        }
 636   1        /* All segments that are come thus far should have the ACK flag set,
 637   1           otherwise we drop the packet. */
 638   1        if(!(BUF->flags & TCP_ACK)) {
 639   2          UIP_STAT(++uip_stat.tcp.drop);
 640   2          UIP_STAT(++uip_stat.tcp.ackerr);
 641   2          UIP_LOG("tcp: dropped non-ack segment.");
 642   2          goto drop;
 643   2        }
 644   1            
 645   1        /* Calculated the length of the data, if the application has sent
 646   1           any data to us. */
 647   1        c = (BUF->tcpoffset >> 4) << 2;
 648   1        /* uip_len will contain the length of the actual TCP data. This is
 649   1           calculated by subtracing the length of the TCP header (in
 650   1           c) and the length of the IP header (20 bytes). */
 651   1        uip_len = uip_len - c - 20;
 652   1      
 653   1        /* First, check if the sequence number of the incoming packet is
 654   1           what we're expecting next. If not, we send out an ACK with the
 655   1           correct numbers in. */
 656   1        if(uip_len > 0 &&
 657   1           (BUF->seqno[0] != uip_conn->rcv_nxt[0] ||
 658   1            BUF->seqno[1] != uip_conn->rcv_nxt[1] ||
 659   1            BUF->seqno[2] != uip_conn->rcv_nxt[2] ||
 660   1            BUF->seqno[3] != uip_conn->rcv_nxt[3])) {
 661   2          goto tcp_send_ack;
 662   2        }
 663   1      
 664   1        /* Next, check if the incoming segment acknowledges any outstanding
 665   1           data. If so, we also reset the retransmission timer. */
 666   1        if(BUF->ackno[0] == uip_conn->ack_nxt[0] &&
 667   1           BUF->ackno[1] == uip_conn->ack_nxt[1] &&
 668   1           BUF->ackno[2] == uip_conn->ack_nxt[2] &&
 669   1           BUF->ackno[3] == uip_conn->ack_nxt[3]) {
 670   2          uip_conn->snd_nxt[0] = uip_conn->ack_nxt[0];
 671   2          uip_conn->snd_nxt[1] = uip_conn->ack_nxt[1];
 672   2          uip_conn->snd_nxt[2] = uip_conn->ack_nxt[2];
 673   2          uip_conn->snd_nxt[3] = uip_conn->ack_nxt[3];
 674   2          if(uip_conn->tcpstateflags & UIP_OUTSTANDING) {
C51 COMPILER V7.06   UIP                                                                   04/05/2006 12:13:01 PAGE 12  

 675   3            uip_flags = UIP_ACKDATA;
 676   3            uip_conn->tcpstateflags &= ~UIP_OUTSTANDING;
 677   3            uip_conn->timer = UIP_RTO;
 678   3          }
 679   2        }
 680   1      
 681   1        /* Do different things depending on in what state the connection is. */
 682   1        switch(uip_conn->tcpstateflags & TS_MASK) {
 683   2          /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
 684   2              implemented, since we force the application to close when the
 685   2              peer sends a FIN (hence the application goes directly from
 686   2              ESTABLISHED to LAST_ACK). */
 687   2        case SYN_RCVD:
 688   2          /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
 689   2             we are waiting for an ACK that acknowledges the data we sent
 690   2             out the last time. Therefore, we want to have the UIP_ACKDATA
 691   2             flag set. If so, we enter the ESTABLISHED state. */
 692   2          if(uip_flags & UIP_ACKDATA) {
 693   3            uip_conn->tcpstateflags = ESTABLISHED;
 694   3            uip_flags = UIP_CONNECTED;
 695   3            uip_len = 0;
 696   3            UIP_APPCALL();
 697   3            goto appsend;
 698   3          }
 699   2          goto drop;
 700   2      #if UIP_ACTIVE_OPEN
                case SYN_SENT:
                  /* In SYN_SENT, we wait for a SYNACK that is sent in response to
                     our SYN. The rcv_nxt is set to sequence number in the SYNACK
                     plus one, and we send an ACK. We move into the ESTABLISHED
                     state. */
                  if((uip_flags & UIP_ACKDATA) &&
                     BUF->flags == (TCP_SYN | TCP_ACK)) {
              
                    /* Parse the TCP MSS option, if present. */
                    if((BUF->tcpoffset & 0xf0) > 0x50) {
                      for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
                        opt = uip_buf[40 + UIP_LLH_LEN + c];
                        if(opt == 0x00) {
                          /* End of options. */       
                          break;
                        } else if(opt == 0x01) {
                          ++c;
                          /* NOP option. */
                        } else if(opt == 0x02 &&
                                  uip_buf[40 + UIP_LLH_LEN + c + 1] == 0x04) {
                          /* An MSS option with the right option length. */
                          tmpport = (uip_buf[40 + UIP_LLH_LEN + c + 2] << 8) |
                            uip_buf[40 + UIP_LLH_LEN + c + 3];
                          uip_conn->mss = tmpport > UIP_TCP_MSS? UIP_TCP_MSS: tmpport;
              
                          /* And we are done processing options. */
                          break;
                        } else {
                          /* All other options have a length field, so that we easily
                             can skip past them. */
                          c += uip_buf[40 + UIP_LLH_LEN + c + 1];
                        }      
                      }
                    }  
              
                    uip_conn->tcpstateflags = ESTABLISHED;      
C51 COMPILER V7.06   UIP                                                                   04/05/2006 12:13:01 PAGE 13  

                    uip_conn->rcv_nxt[0] = BUF->seqno[0];
                    uip_conn->rcv_nxt[1] = BUF->seqno[1];
                    uip_conn->rcv_nxt[2] = BUF->seqno[2];
                    uip_conn->rcv_nxt[3] = BUF->seqno[3];
                    uip_add_rcv_nxt(1);
                    uip_flags = UIP_CONNECTED | UIP_NEWDATA;
                    uip_len = 0;
                    UIP_APPCALL();
                    goto appsend;
                  }
                  goto drop;
              #endif /* UIP_ACTIVE_OPEN */
 749   2          
 750   2        case ESTABLISHED:
 751   2          /* In the ESTABLISHED state, we call upon the application to feed
 752   2          data into the uip_buf. If the UIP_ACKDATA flag is set, the
 753   2          application should put new data into the buffer, otherwise we are
 754   2          retransmitting an old segment, and the application should put that
 755   2          data into the buffer.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -