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

📄 uip.lst

📁 移植uIP1.0到51单片机上的版本mcu_netV1.00 uIP ARP / ICMP / TCP协议的完全移植
💻 LST
📖 第 1 页 / 共 5 页
字号:
 535          void
 536          uip_listen(u16_t port)
 537          {
 538   1        for(c = 0; c < UIP_LISTENPORTS; ++c) {
 539   2          if(uip_listenports[c] == 0) {
 540   3            uip_listenports[c] = port;
 541   3            return;
 542   3          }
 543   2        }
 544   1      }
 545          /*---------------------------------------------------------------------------*/
 546          /* XXX: IP fragment reassembly: not well-tested. */
 547          
 548          #if UIP_REASSEMBLY && !UIP_CONF_IPV6
              #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
              static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
C51 COMPILER V7.06   UIP                                                                   05/02/2009 15:51:22 PAGE 10  

              static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
              static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
                                                  0x0f, 0x07, 0x03, 0x01};
              static u16_t uip_reasslen;
              static u8_t uip_reassflags;
              #define UIP_REASS_FLAG_LASTFRAG 0x01
              static u8_t uip_reasstmr;
              
              #define IP_MF   0x20
              
              static u8_t
              uip_reass(void)
              {
                u16_t offset, len;
                u16_t i;
              
                /* If ip_reasstmr is zero, no packet is present in the buffer, so we
                   write the IP header of the fragment into the reassembly
                   buffer. The timer is updated with the maximum age. */
                if(uip_reasstmr == 0) {
                  memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN);
                  uip_reasstmr = UIP_REASS_MAXAGE;
                  uip_reassflags = 0;
                  /* Clear the bitmap. */
                  memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap));
                }
              
                /* Check if the incoming fragment matches the one currently present
                   in the reasembly buffer. If so, we proceed with copying the
                   fragment into the buffer. */
                if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
                   BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
                   BUF->destipaddr[0] == FBUF->destipaddr[0] &&
                   BUF->destipaddr[1] == FBUF->destipaddr[1] &&
                   BUF->ipid[0] == FBUF->ipid[0] &&
                   BUF->ipid[1] == FBUF->ipid[1]) {
              
                  len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
                  offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
              
                  /* If the offset or the offset + fragment length overflows the
                     reassembly buffer, we discard the entire packet. */
                  if(offset > UIP_REASS_BUFSIZE ||
                     offset + len > UIP_REASS_BUFSIZE) {
                    uip_reasstmr = 0;
                    goto nullreturn;
                  }
              
                  /* Copy the fragment into the reassembly buffer, at the right
                     offset. */
                  memcpy(&uip_reassbuf[UIP_IPH_LEN + offset],
                         (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
                         len);
                    
                  /* Update the bitmap. */
                  if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
                    /* If the two endpoints are in the same byte, we only update
                       that byte. */
                           
                    uip_reassbitmap[offset / (8 * 8)] |=
                           bitmap_bits[(offset / 8 ) & 7] &
                           ~bitmap_bits[((offset + len) / 8 ) & 7];
C51 COMPILER V7.06   UIP                                                                   05/02/2009 15:51:22 PAGE 11  

                  } else {
                    /* If the two endpoints are in different bytes, we update the
                       bytes in the endpoints and fill the stuff inbetween with
                       0xff. */
                    uip_reassbitmap[offset / (8 * 8)] |=
                      bitmap_bits[(offset / 8 ) & 7];
                    for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
                      uip_reassbitmap[i] = 0xff;
                    }
                    uip_reassbitmap[(offset + len) / (8 * 8)] |=
                      ~bitmap_bits[((offset + len) / 8 ) & 7];
                  }
                  
                  /* If this fragment has the More Fragments flag set to zero, we
                     know that this is the last fragment, so we can calculate the
                     size of the entire packet. We also set the
                     IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
                     the final fragment. */
              
                  if((BUF->ipoffset[0] & IP_MF) == 0) {
                    uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
                    uip_reasslen = offset + len;
                  }
                  
                  /* Finally, we check if we have a full packet in the buffer. We do
                     this by checking if we have the last fragment and if all bits
                     in the bitmap are set. */
                  if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
                    /* Check all bytes up to and including all but the last byte in
                       the bitmap. */
                    for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
                      if(uip_reassbitmap[i] != 0xff) {
                        goto nullreturn;
                      }
                    }
                    /* Check the last byte in the bitmap. It should contain just the
                       right amount of bits. */
                    if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
                       (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
                      goto nullreturn;
                    }
              
                    /* If we have come this far, we have a full packet in the
                       buffer, so we allocate a pbuf and copy the packet into it. We
                       also reset the timer. */
                    uip_reasstmr = 0;
                    memcpy(BUF, FBUF, uip_reasslen);
              
                    /* Pretend to be a "normal" (i.e., not fragmented) IP packet
                       from now on. */
                    BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
                    BUF->len[0] = uip_reasslen >> 8;
                    BUF->len[1] = uip_reasslen & 0xff;
                    BUF->ipchksum = 0;
                    BUF->ipchksum = ~(uip_ipchksum());
              
                    return uip_reasslen;
                  }
                }
              
               nullreturn:
                return 0;
C51 COMPILER V7.06   UIP                                                                   05/02/2009 15:51:22 PAGE 12  

              }
              #endif /* UIP_REASSEMBLY */
 677          /*---------------------------------------------------------------------------*/
 678          static void
 679          uip_add_rcv_nxt(u16_t n)
 680          {
 681   1        uip_add32(uip_conn->rcv_nxt, n);
 682   1        uip_conn->rcv_nxt[0] = uip_acc32[0];
 683   1        uip_conn->rcv_nxt[1] = uip_acc32[1];
 684   1        uip_conn->rcv_nxt[2] = uip_acc32[2];
 685   1        uip_conn->rcv_nxt[3] = uip_acc32[3];
 686   1      }
 687          /*---------------------------------------------------------------------------*/
 688          void
 689          uip_process(u8_t flag)
 690          {
 691   1        //  u8_t i;
 692   1        register struct uip_conn xdata *uip_connr = uip_conn;/*gateway*/
 693   1      
 694   1      #if UIP_UDP
                if(flag == UIP_UDP_SEND_CONN) {
                  goto udp_send;
                }
              #endif /* UIP_UDP */
 699   1        
 700   1        uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
 701   1      
 702   1        /* Check if we were invoked because of a poll request for a
 703   1           particular connection. */
 704   1        if(flag == UIP_POLL_REQUEST) {
 705   2          if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
 706   2             !uip_outstanding(uip_connr)) {
 707   3              uip_flags = UIP_POLL;
 708   3              UIP_APPCALL();
 709   3              goto appsend;
 710   3          }
 711   2          goto drop;
 712   2          
 713   2          /* Check if we were invoked because of the perodic timer fireing. */
 714   2        } else if(flag == UIP_TIMER) {
 715   2      #if UIP_REASSEMBLY
                  if(uip_reasstmr != 0) {
                    --uip_reasstmr;
                  }
              #endif /* UIP_REASSEMBLY */
 720   2          /* Increase the initial sequence number. */
 721   2          if(++iss[3] == 0) {
 722   3            if(++iss[2] == 0) {
 723   4              if(++iss[1] == 0) {
 724   5                ++iss[0];
 725   5              }
 726   4            }
 727   3          }
 728   2      
 729   2          /* Reset the length variables. */
 730   2          uip_len = 0;
 731   2          uip_slen = 0;
 732   2      
 733   2          /* Check if the connection is in a state in which we simply wait
 734   2             for the connection to time out. If so, we increase the
 735   2             connection's timer and remove the connection if it times
 736   2             out. */
C51 COMPILER V7.06   UIP                                                                   05/02/2009 15:51:22 PAGE 13  

 737   2          if(uip_connr->tcpstateflags == UIP_TIME_WAIT ||
 738   2             uip_connr->tcpstateflags == UIP_FIN_WAIT_2) {
 739   3            ++(uip_connr->timer);
 740   3            if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
 741   4              uip_connr->tcpstateflags = UIP_CLOSED;
 742   4            }
 743   3          } else if(uip_connr->tcpstateflags != UIP_CLOSED) {
 744   3            /* If the connection has outstanding data, we increase the
 745   3               connection's timer and see if it has reached the RTO value
 746   3               in which case we retransmit. */
 747   3            if(uip_outstanding(uip_connr)) {
 748   4              if(uip_connr->timer-- == 0) {
 749   5                if(uip_connr->nrtx == UIP_MAXRTX ||
 750   5                   ((uip_connr->tcpstateflags == UIP_SYN_SENT ||
 751   5                     uip_connr->tcpstateflags == UIP_SYN_RCVD) &&
 752   5                    uip_connr->nrtx == UIP_MAXSYNRTX)) {
 753   6                  uip_connr->tcpstateflags = UIP_CLOSED;
 754   6      
 755   6                  /* We call UIP_APPCALL() with uip_flags set to
 756   6                     UIP_TIMEDOUT to inform the application that the
 757   6                     connection has timed out. */
 758   6                  uip_flags = UIP_TIMEDOUT;
 759   6                  UIP_APPCALL();
 760   6      
 761   6                  /* We also send a reset packet to the remote host. */
 762   6                  BUF->flags = TCP_RST | TCP_ACK;
 763   6                  goto tcp_send_nodata;
 764   6                }
 765   5      
 766   5                /* Exponential backoff. */
 767   5                uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
 768   5                                               4:
 769   5                                               uip_connr->nrtx);
 770   5                ++(uip_connr->nrtx);
 771   5                
 772   5                /* Ok, so we need to retransmit. We do this differently
 773   5                   depending on which state we are in. In ESTABLISHED, we
 774   5                   call upon the application so that it may prepare the
 775   5                   data for the retransmit. In SYN_RCVD, we resend the
 776   5                   SYNACK that we sent earlier and in LAST_ACK we have to
 777   5                   retransmit our FINACK. */
 778   5                UIP_STAT(++uip_stat.tcp.rexmit);
 779   5                switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
 780   6                case UIP_SYN_RCVD:
 781   6                  /* In the SYN_RCVD state, we should retransmit our
 782   6                     SYNACK. */
 783   6                  goto tcp_send_synack;
 784   6                  
 785   6      #if UIP_ACTIVE_OPEN
                        case UIP_SYN_SENT:
                          /* In the SYN_SENT state, we retransmit out SYN. */
                          BUF->flags = 0;
                          goto tcp_send_syn;
              #endif /* UIP_ACTIVE_OPEN */
 791   6                  
 792   6                case UIP_ESTABLISHED:
 793   6                  /* In the ESTABLISHED state, we call upon the application
 794   6                     to do the actual retransmit after which we jump into
 795   6                     the code for sending out the packet (the apprexmit
 796   6                     label). */
 797   6                  uip_flags = UIP_REXMIT;
 798   6                  UIP_APPCALL();
C51 COMPILER V7.06   UIP                                                                   05/02/2009 15:51:22 PAGE 14  

 799   6                  goto apprexmit;
 800   6                  
 801   6                case UIP_FIN_WAIT_1:
 802   6                case UIP_CLOSING:
 803   6                case UIP_LAST_ACK:
 804   6                  /* In all these states we should retransmit a FINACK. */

⌨️ 快捷键说明

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