uip.c

Go to the documentation of this file.
00001 
00012 /*
00013  * Copyright (c) 2001-2003, Adam Dunkels.
00014  * All rights reserved. 
00015  *
00016  * Redistribution and use in source and binary forms, with or without 
00017  * modification, are permitted provided that the following conditions 
00018  * are met: 
00019  * 1. Redistributions of source code must retain the above copyright 
00020  *    notice, this list of conditions and the following disclaimer. 
00021  * 2. Redistributions in binary form must reproduce the above copyright 
00022  *    notice, this list of conditions and the following disclaimer in the 
00023  *    documentation and/or other materials provided with the distribution. 
00024  * 3. The name of the author may not be used to endorse or promote
00025  *    products derived from this software without specific prior
00026  *    written permission.  
00027  *
00028  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
00029  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00030  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00031  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00032  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00033  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00034  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00035  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00036  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00037  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00038  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
00039  *
00040  * This file is part of the uIP TCP/IP stack.
00041  *
00042  * $Id: uip.c,v 1.62.2.10 2003/10/07 13:23:01 adam Exp $
00043  *
00044  */
00045 
00046 /*
00047 This is a small implementation of the IP and TCP protocols (as well as
00048 some basic ICMP stuff). The implementation couples the IP, TCP and the
00049 application layers very tightly. To keep the size of the compiled code
00050 down, this code also features heavy usage of the goto statement.
00051 
00052 The principle is that we have a small buffer, called the uip_buf, in
00053 which the device driver puts an incoming packet. The TCP/IP stack
00054 parses the headers in the packet, and calls upon the application. If
00055 the remote host has sent data to the application, this data is present
00056 in the uip_buf and the application read the data from there. It is up
00057 to the application to put this data into a byte stream if needed. The
00058 application will not be fed with data that is out of sequence.
00059 
00060 If the application whishes to send data to the peer, it should put its
00061 data into the uip_buf, 40 bytes from the start of the buffer. The
00062 TCP/IP stack will calculate the checksums, and fill in the necessary
00063 header fields and finally send the packet back to the peer.
00064 */
00065 
00066 #include "uip.h"
00067 #include "uipopt.h"
00068 #include "uip_arch.h"
00069 
00070 /*-----------------------------------------------------------------------------------*/
00071 /* Variable definitions. */
00072 
00073 
00074 /* The IP address of this host. If it is defined to be fixed (by setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set here. Otherwise, the address */
00075 #if UIP_FIXEDADDR > 0
00076 const u16_t uip_hostaddr[2] =
00077   {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
00078    HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
00079 const u16_t uip_arp_draddr[2] =
00080   {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
00081    HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
00082 const u16_t uip_arp_netmask[2] =
00083   {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
00084    HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
00085 #else
00086 u16_t uip_hostaddr[2];       
00087 u16_t uip_arp_draddr[2], uip_arp_netmask[2];
00088 #endif /* UIP_FIXEDADDR */
00089 
00090 u8_t uip_buf[UIP_BUFSIZE+2];   /* The packet buffer that contains
00091                                 incoming packets. */
00092 volatile u8_t *uip_appdata;  /* The uip_appdata pointer points to
00093                                 application data. */
00094 volatile u8_t *uip_sappdata;  /* The uip_appdata pointer points to the
00095                                  application data which is to be sent. */
00096 #if UIP_URGDATA > 0
00097 volatile u8_t *uip_urgdata;  /* The uip_urgdata pointer points to
00098                                 urgent data (out-of-band data), if
00099                                 present. */
00100 volatile u8_t uip_urglen, uip_surglen;
00101 #endif /* UIP_URGDATA > 0 */
00102 
00103 volatile u16_t uip_len, uip_slen;
00104                              /* The uip_len is either 8 or 16 bits,
00105                                 depending on the maximum packet
00106                                 size. */
00107 
00108 volatile u8_t uip_flags;     /* The uip_flags variable is used for
00109                                 communication between the TCP/IP stack
00110                                 and the application program. */
00111 struct uip_conn *uip_conn;   /* uip_conn always points to the current
00112                                 connection. */
00113 
00114 struct uip_conn uip_conns[UIP_CONNS];
00115                              /* The uip_conns array holds all TCP
00116                                 connections. */
00117 u16_t uip_listenports[UIP_LISTENPORTS];
00118                              /* The uip_listenports list all currently
00119                                 listning ports. */
00120 #if UIP_UDP
00121 struct uip_udp_conn *uip_udp_conn;
00122 struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
00123 #endif /* UIP_UDP */
00124 
00125 
00126 static u16_t ipid;           /* Ths ipid variable is an increasing
00127                                 number that is used for the IP ID
00128                                 field. */
00129 
00130 static u8_t iss[4];          /* The iss variable is used for the TCP
00131                                 initial sequence number. */
00132 
00133 #if UIP_ACTIVE_OPEN
00134 static u16_t lastport;       /* Keeps track of the last port used for
00135                                 a new connection. */
00136 #endif /* UIP_ACTIVE_OPEN */
00137 
00138 /* Temporary variables. */
00139 volatile u8_t uip_acc32[4];
00140 static u8_t c, opt;
00141 static u16_t tmp16;
00142 
00143 /* Structures and definitions. */
00144 #define TCP_FIN 0x01
00145 #define TCP_SYN 0x02
00146 #define TCP_RST 0x04
00147 #define TCP_PSH 0x08
00148 #define TCP_ACK 0x10
00149 #define TCP_URG 0x20
00150 #define TCP_CTL 0x3f
00151 
00152 #define ICMP_ECHO_REPLY 0
00153 #define ICMP_ECHO       8     
00154 
00155 /* Macros. */
00156 #define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
00157 #define FBUF ((uip_tcpip_hdr *)&uip_reassbuf[0])
00158 #define ICMPBUF ((uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
00159 #define UDPBUF ((uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
00160 
00161 #if UIP_STATISTICS == 1
00162 struct uip_stats uip_stat;
00163 #define UIP_STAT(s) s
00164 #else
00165 #define UIP_STAT(s)
00166 #endif /* UIP_STATISTICS == 1 */
00167 
00168 #if UIP_LOGGING == 1
00169 #define uip_log(str) TxStrk_P(str);
00170 
00171 #define UIP_LOG(m) uip_log(m)
00172 #else
00173 #define UIP_LOG(m)
00174 #endif /* UIP_LOGGING == 1 */
00175 
00176 /*-----------------------------------------------------------------------------------*/
00177 void
00178 uip_init(void)
00179 {
00180   for(c = 0; c < UIP_LISTENPORTS; ++c) {
00181     uip_listenports[c] = 0;
00182   }
00183   for(c = 0; c < UIP_CONNS; ++c) {
00184     uip_conns[c].tcpstateflags = CLOSED;
00185   }
00186 #if UIP_ACTIVE_OPEN
00187   lastport = 1024;
00188 #endif /* UIP_ACTIVE_OPEN */
00189 
00190 #if UIP_UDP
00191   for(c = 0; c < UIP_UDP_CONNS; ++c) {
00192     uip_udp_conns[c].lport = 0;
00193   }
00194 #endif /* UIP_UDP */
00195   
00196 
00197   /* IPv4 initialization. */
00198 #if UIP_FIXEDADDR == 0
00199   uip_hostaddr[0] = uip_hostaddr[1] = 0;
00200 #endif /* UIP_FIXEDADDR */
00201 
00202 }
00203 /*-----------------------------------------------------------------------------------*/
00204 #if UIP_ACTIVE_OPEN
00205 struct uip_conn *
00206 uip_connect(u16_t *ripaddr, u16_t rport)
00207 {
00208   register struct uip_conn *conn, *cconn;
00209   
00210   /* Find an unused local port. */
00211  again:
00212   ++lastport;
00213 
00214   if(lastport >= 32000) {
00215     lastport = 4096;
00216   }
00217 
00218   /* Check if this port is already in use, and if so try to find
00219      another one. */
00220   for(c = 0; c < UIP_CONNS; ++c) {
00221     conn = &uip_conns[c];
00222     if(conn->tcpstateflags != CLOSED &&
00223        conn->lport == htons(lastport)) {
00224       goto again;
00225     }
00226   }
00227 
00228 
00229   conn = 0;
00230   for(c = 0; c < UIP_CONNS; ++c) {
00231     cconn = &uip_conns[c]; 
00232     if(cconn->tcpstateflags == CLOSED) {
00233       conn = cconn;
00234       break;
00235     }
00236     if(cconn->tcpstateflags == TIME_WAIT) {
00237       if(conn == 0 ||
00238          cconn->timer > uip_conn->timer) {
00239         conn = cconn;
00240       }
00241     }
00242   }
00243 
00244   if(conn == 0) {
00245     return 0;
00246   }
00247   
00248   conn->tcpstateflags = SYN_SENT;
00249 
00250   conn->snd_nxt[0] = iss[0];
00251   conn->snd_nxt[1] = iss[1];
00252   conn->snd_nxt[2] = iss[2];
00253   conn->snd_nxt[3] = iss[3];
00254 
00255   conn->initialmss = conn->mss = UIP_TCP_MSS;
00256   
00257   conn->len = 1;   /* TCP length of the SYN is one. */
00258   conn->nrtx = 0;
00259   conn->timer = 1; /* Send the SYN next time around. */
00260   conn->rto = UIP_RTO;
00261   conn->sa = 0;
00262   conn->sv = 16;
00263   conn->lport = htons(lastport);
00264   conn->rport = rport;
00265   conn->ripaddr[0] = ripaddr[0];
00266   conn->ripaddr[1] = ripaddr[1];
00267   
00268   return conn;
00269 }
00270 #endif /* UIP_ACTIVE_OPEN */
00271 /*-----------------------------------------------------------------------------------*/
00272 #if UIP_UDP
00273 struct uip_udp_conn *
00274 uip_udp_new(u16_t *ripaddr, u16_t rport)
00275 {
00276   register struct uip_udp_conn *conn;
00277   
00278   /* Find an unused local port. */
00279  again:
00280   ++lastport;
00281 
00282   if(lastport >= 32000) {
00283     lastport = 4096;
00284   }
00285   
00286   for(c = 0; c < UIP_UDP_CONNS; ++c) {
00287     if(uip_udp_conns[c].lport == lastport) {
00288       goto again;
00289     }
00290   }
00291 
00292 
00293   conn = 0;
00294   for(c = 0; c < UIP_UDP_CONNS; ++c) {
00295     if(uip_udp_conns[c].lport == 0) {
00296       conn = &uip_udp_conns[c]; 
00297       break;
00298     }
00299   }
00300 
00301   if(conn == 0) {
00302     return 0;
00303   }
00304   
00305   conn->lport = HTONS(lastport);
00306   conn->rport = HTONS(rport);
00307   conn->ripaddr[0] = ripaddr[0];
00308   conn->ripaddr[1] = ripaddr[1];
00309   
00310   return conn;
00311 }
00312 #endif /* UIP_UDP */
00313 /*-----------------------------------------------------------------------------------*/
00314 void
00315 uip_unlisten(u16_t port)
00316 {
00317   for(c = 0; c < UIP_LISTENPORTS; ++c) {
00318     if(uip_listenports[c] == port) {
00319       uip_listenports[c] = 0;
00320       return;
00321     }
00322   }
00323 }
00324 /*-----------------------------------------------------------------------------------*/
00325 void
00326 uip_listen(u16_t port)
00327 {
00328   for(c = 0; c < UIP_LISTENPORTS; ++c) {
00329     if(uip_listenports[c] == 0) {
00330       uip_listenports[c] = port;
00331       return;
00332     }
00333   }
00334 }
00335 /*-----------------------------------------------------------------------------------*/
00336 /* XXX: IP fragment reassembly: not well-tested. */
00337 
00338 #if UIP_REASSEMBLY
00339 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
00340 static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
00341 static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
00342 static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
00343                                     0x0f, 0x07, 0x03, 0x01};
00344 static u16_t uip_reasslen;
00345 static u8_t uip_reassflags;
00346 #define UIP_REASS_FLAG_LASTFRAG 0x01
00347 static u8_t uip_reasstmr;
00348 
00349 #define IP_HLEN 20
00350 #define IP_MF   0x20
00351 
00352 static u8_t
00353 uip_reass(void)
00354 {
00355   u16_t offset, len;
00356   u16_t i;
00357 
00358   /* If ip_reasstmr is zero, no packet is present in the buffer, so we
00359      write the IP header of the fragment into the reassembly
00360      buffer. The timer is updated with the maximum age. */
00361   if(uip_reasstmr == 0) {
00362     memcpy(uip_reassbuf, &BUF->vhl, IP_HLEN);
00363     uip_reasstmr = UIP_REASS_MAXAGE;
00364     uip_reassflags = 0;
00365     /* Clear the bitmap. */
00366     memset(uip_reassbitmap, sizeof(uip_reassbitmap), 0);
00367   }
00368 
00369   /* Check if the incoming fragment matches the one currently present
00370      in the reasembly buffer. If so, we proceed with copying the
00371      fragment into the buffer. */
00372   if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
00373      BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
00374      BUF->destipaddr[0] == FBUF->destipaddr[0] &&
00375      BUF->destipaddr[1] == FBUF->destipaddr[1] &&
00376      BUF->ipid[0] == FBUF->ipid[0] &&
00377      BUF->ipid[1] == FBUF->ipid[1]) {
00378 
00379     len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
00380     offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
00381 
00382     /* If the offset or the offset + fragment length overflows the
00383        reassembly buffer, we discard the entire packet. */
00384     if(offset > UIP_REASS_BUFSIZE ||
00385        offset + len > UIP_REASS_BUFSIZE) {
00386       uip_reasstmr = 0;
00387       goto nullreturn;
00388     }
00389 
00390     /* Copy the fragment into the reassembly buffer, at the right
00391        offset. */
00392     memcpy(&uip_reassbuf[IP_HLEN + offset],
00393            (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
00394            len);
00395       
00396     /* Update the bitmap. */
00397     if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
00398       /* If the two endpoints are in the same byte, we only update
00399          that byte. */
00400              
00401       uip_reassbitmap[offset / (8 * 8)] |=
00402              bitmap_bits[(offset / 8 ) & 7] &
00403              ~bitmap_bits[((offset + len) / 8 ) & 7];
00404     } else {
00405       /* If the two endpoints are in different bytes, we update the
00406          bytes in the endpoints and fill the stuff inbetween with
00407          0xff. */
00408       uip_reassbitmap[offset / (8 * 8)] |=
00409         bitmap_bits[(offset / 8 ) & 7];
00410       for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
00411         uip_reassbitmap[i] = 0xff;
00412       }      
00413       uip_reassbitmap[(offset + len) / (8 * 8)] |=
00414         ~bitmap_bits[((offset + len) / 8 ) & 7];
00415     }
00416     
00417     /* If this fragment has the More Fragments flag set to zero, we
00418        know that this is the last fragment, so we can calculate the
00419        size of the entire packet. We also set the
00420        IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
00421        the final fragment. */
00422 
00423     if((BUF->ipoffset[0] & IP_MF) == 0) {
00424       uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
00425       uip_reasslen = offset + len;
00426     }
00427     
00428     /* Finally, we check if we have a full packet in the buffer. We do
00429        this by checking if we have the last fragment and if all bits
00430        in the bitmap are set. */
00431     if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
00432       /* Check all bytes up to and including all but the last byte in
00433          the bitmap. */
00434       for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
00435         if(uip_reassbitmap[i] != 0xff) {
00436           goto nullreturn;
00437         }
00438       }
00439       /* Check the last byte in the bitmap. It should contain just the
00440          right amount of bits. */
00441       if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
00442          (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
00443         goto nullreturn;
00444       }
00445 
00446       /* If we have come this far, we have a full packet in the
00447          buffer, so we allocate a pbuf and copy the packet into it. We
00448          also reset the timer. */
00449       uip_reasstmr = 0;
00450       memcpy(BUF, FBUF, uip_reasslen);
00451 
00452       /* Pretend to be a "normal" (i.e., not fragmented) IP packet
00453          from now on. */
00454       BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
00455       BUF->len[0] = uip_reasslen >> 8;
00456       BUF->len[1] = uip_reasslen & 0xff;
00457       BUF->ipchksum = 0;
00458       BUF->ipchksum = ~(uip_ipchksum());
00459 
00460       return uip_reasslen;
00461     }
00462   }
00463 
00464  nullreturn:
00465   return 0;
00466 }
00467 #endif /* UIP_REASSEMBL */
00468 /*-----------------------------------------------------------------------------------*/
00469 static void
00470 uip_add_rcv_nxt(u16_t n)
00471 {
00472   uip_add32(uip_conn->rcv_nxt, n);
00473   uip_conn->rcv_nxt[0] = uip_acc32[0];
00474   uip_conn->rcv_nxt[1] = uip_acc32[1];
00475   uip_conn->rcv_nxt[2] = uip_acc32[2];
00476   uip_conn->rcv_nxt[3] = uip_acc32[3];
00477 }
00478 /*-----------------------------------------------------------------------------------*/
00479 void
00480 uip_process(u8_t flag)
00481 {
00482   register struct uip_conn *uip_connr = uip_conn;
00483   
00484   uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
00485 
00486   
00487   /* Check if we were invoked because of the perodic timer fireing. */
00488   if(flag == UIP_TIMER) {
00489 #if UIP_REASSEMBLY
00490     if(uip_reasstmr != 0) {
00491       --uip_reasstmr;
00492     }
00493 #endif /* UIP_REASSEMBLY */
00494     /* Increase the initial sequence number. */
00495     if(++iss[3] == 0) {
00496       if(++iss[2] == 0) {
00497         if(++iss[1] == 0) {
00498           ++iss[0];
00499         }
00500       }
00501     }    
00502     uip_len = 0;
00503     if(uip_connr->tcpstateflags == TIME_WAIT ||
00504        uip_connr->tcpstateflags == FIN_WAIT_2) {
00505       ++(uip_connr->timer);
00506       if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
00507         uip_connr->tcpstateflags = CLOSED;
00508       }
00509     } else if(uip_connr->tcpstateflags != CLOSED) {
00510       /* If the connection has outstanding data, we increase the
00511          connection's timer and see if it has reached the RTO value
00512          in which case we retransmit. */
00513       if(uip_outstanding(uip_connr)) {
00514         if(uip_connr->timer-- == 0) {
00515           if(uip_connr->nrtx == UIP_MAXRTX ||
00516              ((uip_connr->tcpstateflags == SYN_SENT ||
00517                uip_connr->tcpstateflags == SYN_RCVD) &&
00518               uip_connr->nrtx == UIP_MAXSYNRTX)) {
00519             uip_connr->tcpstateflags = CLOSED;
00520 
00521             /* We call UIP_APPCALL() with uip_flags set to
00522                UIP_TIMEDOUT to inform the application that the
00523                connection has timed out. */
00524             uip_flags = UIP_TIMEDOUT;
00525             UIP_APPCALL();
00526 
00527             /* We also send a reset packet to the remote host. */
00528             BUF->flags = TCP_RST | TCP_ACK;
00529             goto tcp_send_nodata;
00530           }
00531 
00532           /* Exponential backoff. */
00533           uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
00534                                          4:
00535                                          uip_connr->nrtx);
00536           ++(uip_connr->nrtx);
00537           
00538           /* Ok, so we need to retransmit. We do this differently
00539              depending on which state we are in. In ESTABLISHED, we
00540              call upon the application so that it may prepare the
00541              data for the retransmit. In SYN_RCVD, we resend the
00542              SYNACK that we sent earlier and in LAST_ACK we have to
00543              retransmit our FINACK. */
00544           UIP_STAT(++uip_stat.tcp.rexmit);
00545           switch(uip_connr->tcpstateflags & TS_MASK) {
00546           case SYN_RCVD:
00547             /* In the SYN_RCVD state, we should retransmit our
00548                SYNACK. */
00549             goto tcp_send_synack;
00550             
00551 #if UIP_ACTIVE_OPEN
00552           case SYN_SENT:
00553             /* In the SYN_SENT state, we retransmit out SYN. */
00554             BUF->flags = 0;
00555             goto tcp_send_syn;
00556 #endif /* UIP_ACTIVE_OPEN */
00557             
00558           case ESTABLISHED:
00559             /* In the ESTABLISHED state, we call upon the application
00560                to do the actual retransmit after which we jump into
00561                the code for sending out the packet (the apprexmit
00562                label). */
00563             uip_len = 0;
00564             uip_slen = 0;
00565             uip_flags = UIP_REXMIT;
00566             UIP_APPCALL();
00567             goto apprexmit;
00568             
00569           case FIN_WAIT_1:
00570           case CLOSING:
00571           case LAST_ACK:
00572             /* In all these states we should retransmit a FINACK. */
00573             goto tcp_send_finack;
00574             
00575           }
00576         }
00577       } else if((uip_connr->tcpstateflags & TS_MASK) == ESTABLISHED) {
00578         /* If there was no need for a retransmission, we poll the
00579            application for new data. */
00580         uip_len = 0;
00581         uip_slen = 0;
00582         uip_flags = UIP_POLL;
00583         UIP_APPCALL();
00584         goto appsend;
00585       }
00586     }
00587     goto drop;
00588   }
00589 #if UIP_UDP 
00590   if(flag == UIP_UDP_TIMER) {
00591     if(uip_udp_conn->lport != 0) {
00592       uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
00593       uip_len = uip_slen = 0;
00594       uip_flags = UIP_POLL;
00595       UIP_UDP_APPCALL();
00596       goto udp_send;
00597     } else {
00598       goto drop;
00599     }
00600   }
00601 #endif
00602 
00603   /* This is where the input processing starts. */
00604   UIP_STAT(++uip_stat.ip.recv);
00605 
00606 
00607   /* Start of IPv4 input header processing code. */
00608   
00609   /* Check validity of the IP header. */  
00610   if(BUF->vhl != 0x45)  { /* IP version and header length. */
00611     UIP_STAT(++uip_stat.ip.drop);
00612     UIP_STAT(++uip_stat.ip.vhlerr);
00613     UIP_LOG("ip: invalid version or header length.");
00614     goto drop;
00615   }
00616   
00617   /* Check the size of the packet. If the size reported to us in
00618      uip_len doesn't match the size reported in the IP header, there
00619      has been a transmission error and we drop the packet. */
00620   
00621   if(BUF->len[0] != (uip_len >> 8)) { /* IP length, high byte. */
00622     uip_len = (uip_len & 0xff) | (BUF->len[0] << 8);
00623   }
00624   if(BUF->len[1] != (uip_len & 0xff)) { /* IP length, low byte. */
00625     uip_len = (uip_len & 0xff00) | BUF->len[1];
00626   }
00627 
00628   /* Check the fragment flag. */
00629   if((BUF->ipoffset[0] & 0x3f) != 0 ||
00630      BUF->ipoffset[1] != 0) { 
00631 #if UIP_REASSEMBLY
00632     uip_len = uip_reass();
00633     if(uip_len == 0) {
00634       goto drop;
00635     }
00636 #else
00637     UIP_STAT(++uip_stat.ip.drop);
00638     UIP_STAT(++uip_stat.ip.fragerr);
00639     UIP_LOG("ip: fragment dropped.");    
00640     goto drop;
00641 #endif /* UIP_REASSEMBLY */
00642   }
00643 
00644   /* If we are configured to use ping IP address configuration and
00645      hasn't been assigned an IP address yet, we accept all ICMP
00646      packets. */
00647 #if UIP_PINGADDRCONF
00648   if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
00649     if(BUF->proto == UIP_PROTO_ICMP) {
00650       UIP_LOG("ip: possible ping config packet received.");
00651       goto icmp_input;
00652     } else {
00653       UIP_LOG("ip: packet dropped since no address assigned.");
00654       goto drop;
00655     }
00656   }
00657 #endif /* UIP_PINGADDRCONF */
00658   
00659   /* Check if the packet is destined for our IP address. */  
00660   if(BUF->destipaddr[0] != uip_hostaddr[0]) {
00661     UIP_STAT(++uip_stat.ip.drop);
00662     UIP_LOG("ip: packet not for us.");        
00663     goto drop;
00664   }
00665   if(BUF->destipaddr[1] != uip_hostaddr[1]) {
00666     UIP_STAT(++uip_stat.ip.drop);
00667     UIP_LOG("ip: packet not for us.");        
00668     goto drop;
00669   }
00670 
00671   if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
00672                                     checksum. */
00673     UIP_STAT(++uip_stat.ip.drop);
00674     UIP_STAT(++uip_stat.ip.chkerr);
00675     UIP_LOG("ip: bad checksum.");    
00676     goto drop;
00677   }
00678 
00679   if(BUF->proto == UIP_PROTO_TCP)  /* Check for TCP packet. If so, jump
00680                                      to the tcp_input label. */
00681     goto tcp_input;
00682 
00683 #if UIP_UDP
00684   if(BUF->proto == UIP_PROTO_UDP)
00685     goto udp_input;
00686 #endif /* UIP_UDP */
00687 
00688   if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
00689                                         here. */
00690     UIP_STAT(++uip_stat.ip.drop);
00691     UIP_STAT(++uip_stat.ip.protoerr);
00692     UIP_LOG("ip: neither tcp nor icmp.");        
00693     goto drop;
00694   }
00695   
00696  icmp_input:
00697   UIP_STAT(++uip_stat.icmp.recv);
00698   
00699   /* ICMP echo (i.e., ping) processing. This is simple, we only change
00700      the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
00701      checksum before we return the packet. */
00702   if(ICMPBUF->type != ICMP_ECHO) {
00703     UIP_STAT(++uip_stat.icmp.drop);
00704     UIP_STAT(++uip_stat.icmp.typeerr);
00705     UIP_LOG("icmp: not icmp echo.");
00706     goto drop;
00707   }
00708 
00709   /* If we are configured to use ping IP address assignment, we use
00710      the destination IP address of this ping packet and assign it to
00711      ourself. */
00712 #if UIP_PINGADDRCONF
00713   if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
00714     uip_hostaddr[0] = BUF->destipaddr[0];
00715     uip_hostaddr[1] = BUF->destipaddr[1];
00716   }
00717 #endif /* UIP_PINGADDRCONF */  
00718   
00719   ICMPBUF->type = ICMP_ECHO_REPLY;
00720   
00721   if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
00722     ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
00723   } else {
00724     ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
00725   }
00726   
00727   /* Swap IP addresses. */
00728   tmp16 = BUF->destipaddr[0];
00729   BUF->destipaddr[0] = BUF->srcipaddr[0];
00730   BUF->srcipaddr[0] = tmp16;
00731   tmp16 = BUF->destipaddr[1];
00732   BUF->destipaddr[1] = BUF->srcipaddr[1];
00733   BUF->srcipaddr[1] = tmp16;
00734 
00735   UIP_STAT(++uip_stat.icmp.sent);
00736   goto send;
00737 
00738   /* End of IPv4 input header processing code. */
00739   
00740 
00741 #if UIP_UDP
00742   /* UDP input processing. */
00743  udp_input:
00744   /* UDP processing is really just a hack. We don't do anything to the
00745      UDP/IP headers, but let the UDP application do all the hard
00746      work. If the application sets uip_slen, it has a packet to
00747      send. */
00748 #if UIP_UDP_CHECKSUMS
00749   if(uip_udpchksum() != 0xffff) { 
00750     UIP_STAT(++uip_stat.udp.drop);
00751     UIP_STAT(++uip_stat.udp.chkerr);
00752     UIP_LOG("udp: bad checksum.");    
00753     goto drop;
00754   }  
00755 #endif /* UIP_UDP_CHECKSUMS */
00756 
00757   /* Demultiplex this UDP packet between the UDP "connections". */
00758   for(uip_udp_conn = &uip_udp_conns[0];
00759       uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
00760       ++uip_udp_conn) {
00761 /**********************************************************
00762  *  I changed this in order to be able to receive packet's from
00763  *  any host without have to know the ip address before hand
00764  *********************************************************/             
00765 /*              
00766     if(uip_udp_conn->lport != 0 &&
00767        UDPBUF->destport == uip_udp_conn->lport &&
00768        (uip_udp_conn->rport == 0 ||
00769         UDPBUF->srcport == uip_udp_conn->rport) &&
00770        BUF->srcipaddr[0] == uip_udp_conn->ripaddr[0] &&
00771        BUF->srcipaddr[1] == uip_udp_conn->ripaddr[1]) { */
00772     if(uip_udp_conn->lport != 0 &&
00773        UDPBUF->destport == uip_udp_conn->lport ) { 
00774       goto udp_found; 
00775     }
00776   }
00777   goto drop;
00778   
00779  udp_found:
00780   uip_len = uip_len - 28;
00781   uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
00782   uip_flags = UIP_NEWDATA;
00783   uip_slen = 0;
00784   UIP_UDP_APPCALL();
00785  udp_send:
00786   if(uip_slen == 0) {
00787     goto drop;      
00788   }
00789   uip_len = uip_slen + 28;
00790 
00791   BUF->len[0] = (uip_len >> 8);
00792   BUF->len[1] = (uip_len & 0xff);
00793   
00794   BUF->proto = UIP_PROTO_UDP;
00795 
00796   UDPBUF->udplen = HTONS(uip_slen + 8);
00797   UDPBUF->udpchksum = 0;
00798 #if UIP_UDP_CHECKSUMS 
00799   /* Calculate UDP checksum. */
00800   UDPBUF->udpchksum = ~(uip_udpchksum());
00801   if(UDPBUF->udpchksum == 0) {
00802     UDPBUF->udpchksum = 0xffff;
00803   }
00804 #endif /* UIP_UDP_CHECKSUMS */
00805 
00806 /**********************************************************
00807  *  I changed this in order to be able to receive packet's from
00808  *  any host without have to know the ip address beforehand
00809  *********************************************************/
00810 
00811   BUF->destport = BUF->srcport;
00812   BUF->srcport  = uip_udp_conn->lport;
00813   
00814   BUF->destipaddr[0] = BUF->srcipaddr[0];
00815   BUF->destipaddr[1] = BUF->srcipaddr[1];
00816   BUF->srcipaddr[0] = uip_hostaddr[0];
00817   BUF->srcipaddr[1] = uip_hostaddr[1];
00818  
00819   uip_appdata = &uip_buf[UIP_LLH_LEN + 40];
00820   goto ip_send_nolen;
00821 #endif /* UIP_UDP */
00822   
00823   /* TCP input processing. */  
00824  tcp_input:
00825   UIP_STAT(++uip_stat.tcp.recv);
00826 
00827   /* Start of TCP input header processing code. */
00828   
00829   if(uip_tcpchksum() != 0xffff) {   /* Compute and check the TCP
00830                                        checksum. */
00831     UIP_STAT(++uip_stat.tcp.drop);
00832     UIP_STAT(++uip_stat.tcp.chkerr);
00833     UIP_LOG("tcp: bad checksum.");    
00834     goto drop;
00835   }
00836   
00837   /* Demultiplex this segment. */
00838   /* First check any active connections. */
00839   for(uip_connr = &uip_conns[0]; uip_connr < &uip_conns[UIP_CONNS]; ++uip_connr) {
00840     if(uip_connr->tcpstateflags != CLOSED &&
00841        BUF->destport == uip_connr->lport &&
00842        BUF->srcport == uip_connr->rport &&
00843        BUF->srcipaddr[0] == uip_connr->ripaddr[0] &&
00844        BUF->srcipaddr[1] == uip_connr->ripaddr[1]) {
00845       goto found;    
00846     }
00847   }
00848 
00849   /* If we didn't find and active connection that expected the packet,
00850      either this packet is an old duplicate, or this is a SYN packet
00851      destined for a connection in LISTEN. If the SYN flag isn't set,
00852      it is an old packet and we send a RST. */
00853   if((BUF->flags & TCP_CTL) != TCP_SYN)
00854     goto reset;
00855   
00856   tmp16 = BUF->destport;
00857   /* Next, check listening connections. */  
00858   for(c = 0; c < UIP_LISTENPORTS; ++c) {
00859     if(tmp16 == uip_listenports[c])
00860       goto found_listen;
00861   }
00862   
00863   /* No matching connection found, so we send a RST packet. */
00864   UIP_STAT(++uip_stat.tcp.synrst);
00865  reset:
00866 
00867   /* We do not send resets in response to resets. */
00868   if(BUF->flags & TCP_RST) 
00869     goto drop;
00870 
00871   UIP_STAT(++uip_stat.tcp.rst);
00872   
00873   BUF->flags = TCP_RST | TCP_ACK;
00874   uip_len = 40;
00875   BUF->tcpoffset = 5 << 4;
00876 
00877   /* Flip the seqno and ackno fields in the TCP header. */
00878   c = BUF->seqno[3];
00879   BUF->seqno[3] = BUF->ackno[3];  
00880   BUF->ackno[3] = c;
00881   
00882   c = BUF->seqno[2];
00883   BUF->seqno[2] = BUF->ackno[2];  
00884   BUF->ackno[2] = c;
00885   
00886   c = BUF->seqno[1];
00887   BUF->seqno[1] = BUF->ackno[1];
00888   BUF->ackno[1] = c;
00889   
00890   c = BUF->seqno[0];
00891   BUF->seqno[0] = BUF->ackno[0];  
00892   BUF->ackno[0] = c;
00893 
00894   /* We also have to increase the sequence number we are
00895      acknowledging. If the least significant byte overflowed, we need
00896      to propagate the carry to the other bytes as well. */
00897   if(++BUF->ackno[3] == 0) {
00898     if(++BUF->ackno[2] == 0) {
00899       if(++BUF->ackno[1] == 0) {
00900         ++BUF->ackno[0];
00901       }
00902     }
00903   }
00904  
00905   /* Swap port numbers. */
00906   tmp16 = BUF->srcport;
00907   BUF->srcport = BUF->destport;
00908   BUF->destport = tmp16;
00909   
00910   /* Swap IP addresses. */
00911   tmp16 = BUF->destipaddr[0];
00912   BUF->destipaddr[0] = BUF->srcipaddr[0];
00913   BUF->srcipaddr[0] = tmp16;
00914   tmp16 = BUF->destipaddr[1];
00915   BUF->destipaddr[1] = BUF->srcipaddr[1];
00916   BUF->srcipaddr[1] = tmp16;
00917 
00918   
00919   /* And send out the RST packet! */
00920   goto tcp_send_noconn;
00921 
00922   /* This label will be jumped to if we matched the incoming packet
00923      with a connection in LISTEN. In that case, we should create a new
00924      connection and send a SYNACK in return. */
00925  found_listen:
00926   /* First we check if there are any connections avaliable. Unused
00927      connections are kept in the same table as used connections, but
00928      unused ones have the tcpstate set to CLOSED. Also, connections in
00929      TIME_WAIT are kept track of and we'll use the oldest one if no
00930      CLOSED connections are found. Thanks to Eddie C. Dost for a very
00931      nice algorithm for the TIME_WAIT search. */
00932   uip_connr = 0;
00933   for(c = 0; c < UIP_CONNS; ++c) {
00934     if(uip_conns[c].tcpstateflags == CLOSED) {
00935       uip_connr = &uip_conns[c];
00936       break;
00937     }
00938     if(uip_conns[c].tcpstateflags == TIME_WAIT) {
00939       if(uip_connr == 0 ||
00940          uip_conns[c].timer > uip_connr->timer) {
00941         uip_connr = &uip_conns[c];
00942       }
00943     }
00944   }
00945 
00946   if(uip_connr == 0) {
00947     /* All connections are used already, we drop packet and hope that
00948        the remote end will retransmit the packet at a time when we
00949        have more spare connections. */
00950     UIP_STAT(++uip_stat.tcp.syndrop);
00951     UIP_LOG("tcp: found no unused connections.");
00952     goto drop;
00953   }
00954   uip_conn = uip_connr;
00955   
00956   /* Fill in the necessary fields for the new connection. */
00957   uip_connr->rto = uip_connr->timer = UIP_RTO;
00958   uip_connr->sa = 0;
00959   uip_connr->sv = 4;  
00960   uip_connr->nrtx = 0;
00961   uip_connr->lport = BUF->destport;
00962   uip_connr->rport = BUF->srcport;
00963   uip_connr->ripaddr[0] = BUF->srcipaddr[0];
00964   uip_connr->ripaddr[1] = BUF->srcipaddr[1];
00965   uip_connr->tcpstateflags = SYN_RCVD;
00966 
00967   uip_connr->snd_nxt[0] = iss[0];
00968   uip_connr->snd_nxt[1] = iss[1];
00969   uip_connr->snd_nxt[2] = iss[2];
00970   uip_connr->snd_nxt[3] = iss[3];
00971   uip_connr->len = 1;
00972 
00973   /* rcv_nxt should be the seqno from the incoming packet + 1. */
00974   uip_connr->rcv_nxt[3] = BUF->seqno[3];
00975   uip_connr->rcv_nxt[2] = BUF->seqno[2];
00976   uip_connr->rcv_nxt[1] = BUF->seqno[1];
00977   uip_connr->rcv_nxt[0] = BUF->seqno[0];
00978   uip_add_rcv_nxt(1);
00979 
00980   /* Parse the TCP MSS option, if present. */
00981   if((BUF->tcpoffset & 0xf0) > 0x50) {
00982     for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
00983       opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
00984       if(opt == 0x00) {
00985         /* End of options. */   
00986         break;
00987       } else if(opt == 0x01) {
00988         ++c;
00989         /* NOP option. */
00990       } else if(opt == 0x02 &&
00991                 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
00992         /* An MSS option with the right option length. */       
00993         tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
00994           (u16_t)uip_buf[40 + UIP_LLH_LEN + 3 + c];
00995         uip_connr->initialmss = uip_connr->mss =
00996           tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
00997         
00998         /* And we are done processing options. */
00999         break;
01000       } else {
01001         /* All other options have a length field, so that we easily
01002            can skip past them. */
01003         if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
01004           /* If the length field is zero, the options are malformed
01005              and we don't process them further. */
01006           break;
01007         }
01008         c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
01009       }      
01010     }
01011   }
01012   
01013   /* Our response will be a SYNACK. */
01014 #if UIP_ACTIVE_OPEN
01015  tcp_send_synack:
01016   BUF->flags = TCP_ACK;    
01017   
01018  tcp_send_syn:
01019   BUF->flags |= TCP_SYN;    
01020 #else /* UIP_ACTIVE_OPEN */
01021  tcp_send_synack:
01022   BUF->flags = TCP_SYN | TCP_ACK;    
01023 #endif /* UIP_ACTIVE_OPEN */
01024   
01025   /* We send out the TCP Maximum Segment Size option with our
01026      SYNACK. */
01027   BUF->optdata[0] = 2;
01028   BUF->optdata[1] = 4;
01029   BUF->optdata[2] = (UIP_TCP_MSS) / 256;
01030   BUF->optdata[3] = (UIP_TCP_MSS) & 255;
01031   uip_len = 44;
01032   BUF->tcpoffset = 6 << 4;
01033   goto tcp_send;
01034 
01035   /* This label will be jumped to if we found an active connection. */
01036  found:
01037   uip_conn = uip_connr;
01038   uip_flags = 0;
01039 
01040   /* We do a very naive form of TCP reset processing; we just accept
01041      any RST and kill our connection. We should in fact check if the
01042      sequence number of this reset is wihtin our advertised window
01043      before we accept the reset. */
01044   if(BUF->flags & TCP_RST) {
01045     uip_connr->tcpstateflags = CLOSED;
01046     UIP_LOG("tcp: got reset, aborting connection.");
01047     uip_flags = UIP_ABORT;
01048     UIP_APPCALL();
01049     goto drop;
01050   }      
01051   /* Calculated the length of the data, if the application has sent
01052      any data to us. */
01053   c = (BUF->tcpoffset >> 4) << 2;
01054   /* uip_len will contain the length of the actual TCP data. This is
01055      calculated by subtracing the length of the TCP header (in
01056      c) and the length of the IP header (20 bytes). */
01057   uip_len = uip_len - c - 20;
01058 
01059   /* First, check if the sequence number of the incoming packet is
01060      what we're expecting next. If not, we send out an ACK with the
01061      correct numbers in. */
01062   if(uip_len > 0 &&
01063      (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
01064       BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
01065       BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
01066       BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
01067     goto tcp_send_ack;
01068   }
01069 
01070   /* Next, check if the incoming segment acknowledges any outstanding
01071      data. If so, we update the sequence number, reset the length of
01072      the outstanding data, calculate RTT estimations, and reset the
01073      retransmission timer. */
01074   if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
01075     uip_add32(uip_connr->snd_nxt, uip_connr->len);
01076     if(BUF->ackno[0] == uip_acc32[0] &&
01077        BUF->ackno[1] == uip_acc32[1] &&
01078        BUF->ackno[2] == uip_acc32[2] &&
01079        BUF->ackno[3] == uip_acc32[3]) {
01080       /* Update sequence number. */
01081       uip_connr->snd_nxt[0] = uip_acc32[0];
01082       uip_connr->snd_nxt[1] = uip_acc32[1];
01083       uip_connr->snd_nxt[2] = uip_acc32[2];
01084       uip_connr->snd_nxt[3] = uip_acc32[3];
01085         
01086 
01087       /* Do RTT estimation, unless we have done retransmissions. */
01088       if(uip_connr->nrtx == 0) {
01089         signed char m;
01090         m = uip_connr->rto - uip_connr->timer;
01091         /* This is taken directly from VJs original code in his paper */
01092         m = m - (uip_connr->sa >> 3);
01093         uip_connr->sa += m;
01094         if(m < 0) {
01095           m = -m;
01096         }
01097         m = m - (uip_connr->sv >> 2);
01098         uip_connr->sv += m;
01099         uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
01100 
01101       }
01102       /* Set the acknowledged flag. */
01103       uip_flags = UIP_ACKDATA;
01104       /* Reset the retransmission timer. */
01105       uip_connr->timer = uip_connr->rto;
01106     }
01107     
01108   }
01109 
01110   /* Do different things depending on in what state the connection is. */
01111   switch(uip_connr->tcpstateflags & TS_MASK) {
01112     /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
01113         implemented, since we force the application to close when the
01114         peer sends a FIN (hence the application goes directly from
01115         ESTABLISHED to LAST_ACK). */
01116   case SYN_RCVD:
01117     /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
01118        we are waiting for an ACK that acknowledges the data we sent
01119        out the last time. Therefore, we want to have the UIP_ACKDATA
01120        flag set. If so, we enter the ESTABLISHED state. */
01121     if(uip_flags & UIP_ACKDATA) {
01122       uip_connr->tcpstateflags = ESTABLISHED;
01123       uip_flags = UIP_CONNECTED;
01124       uip_connr->len = 0;
01125       if(uip_len > 0) {
01126         uip_flags |= UIP_NEWDATA;
01127         uip_add_rcv_nxt(uip_len);
01128       }
01129       uip_slen = 0;
01130       UIP_APPCALL();
01131       goto appsend;
01132     }
01133     goto drop;
01134 #if UIP_ACTIVE_OPEN
01135   case SYN_SENT:
01136     /* In SYN_SENT, we wait for a SYNACK that is sent in response to
01137        our SYN. The rcv_nxt is set to sequence number in the SYNACK
01138        plus one, and we send an ACK. We move into the ESTABLISHED
01139        state. */
01140     if((uip_flags & UIP_ACKDATA) &&
01141        BUF->flags == (TCP_SYN | TCP_ACK)) {
01142 
01143       /* Parse the TCP MSS option, if present. */
01144       if((BUF->tcpoffset & 0xf0) > 0x50) {
01145         for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
01146           opt = uip_buf[40 + UIP_LLH_LEN + c];
01147           if(opt == 0x00) {
01148             /* End of options. */       
01149             break;
01150           } else if(opt == 0x01) {
01151             ++c;
01152             /* NOP option. */
01153           } else if(opt == 0x02 &&
01154                     uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
01155             /* An MSS option with the right option length. */
01156             tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
01157               uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
01158             uip_connr->initialmss =
01159               uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
01160 
01161             /* And we are done processing options. */
01162             break;
01163           } else {
01164             /* All other options have a length field, so that we easily
01165                can skip past them. */
01166             if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
01167               /* If the length field is zero, the options are malformed
01168                  and we don't process them further. */
01169               break;
01170             }
01171             c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
01172           }      
01173         }
01174       }
01175       uip_connr->tcpstateflags = ESTABLISHED;      
01176       uip_connr->rcv_nxt[0] = BUF->seqno[0];
01177       uip_connr->rcv_nxt[1] = BUF->seqno[1];
01178       uip_connr->rcv_nxt[2] = BUF->seqno[2];
01179       uip_connr->rcv_nxt[3] = BUF->seqno[3];
01180       uip_add_rcv_nxt(1);
01181       uip_flags = UIP_CONNECTED | UIP_NEWDATA;
01182       uip_connr->len = 0;
01183       uip_len = 0;
01184       uip_slen = 0;
01185       UIP_APPCALL();
01186       goto appsend;
01187     }
01188     goto reset;
01189 #endif /* UIP_ACTIVE_OPEN */
01190     
01191   case ESTABLISHED:
01192     /* In the ESTABLISHED state, we call upon the application to feed
01193     data into the uip_buf. If the UIP_ACKDATA flag is set, the
01194     application should put new data into the buffer, otherwise we are
01195     retransmitting an old segment, and the application should put that
01196     data into the buffer.
01197 
01198     If the incoming packet is a FIN, we should close the connection on
01199     this side as well, and we send out a FIN and enter the LAST_ACK
01200     state. We require that there is no outstanding data; otherwise the
01201     sequence numbers will be screwed up. */
01202 
01203     if(BUF->flags & TCP_FIN) {
01204       if(uip_outstanding(uip_connr)) {
01205         goto drop;
01206       }
01207       uip_add_rcv_nxt(1 + uip_len);      
01208       uip_flags = UIP_CLOSE;
01209       if(uip_len > 0) {
01210         uip_flags |= UIP_NEWDATA;
01211       }
01212       UIP_APPCALL();
01213       uip_connr->len = 1;
01214       uip_connr->tcpstateflags = LAST_ACK;
01215       uip_connr->nrtx = 0;
01216     tcp_send_finack:
01217       BUF->flags = TCP_FIN | TCP_ACK;      
01218       goto tcp_send_nodata;
01219     }
01220 
01221     /* Check the URG flag. If this is set, the segment carries urgent
01222        data that we must pass to the application. */
01223     if(BUF->flags & TCP_URG) {
01224 #if UIP_URGDATA > 0
01225       uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
01226       if(uip_urglen > uip_len) {
01227         /* There is more urgent data in the next segment to come. */
01228         uip_urglen = uip_len;
01229       }
01230       uip_add_rcv_nxt(uip_urglen);
01231       uip_len -= uip_urglen;
01232       uip_urgdata = uip_appdata;
01233       uip_appdata += uip_urglen;
01234     } else {
01235       uip_urglen = 0;
01236 #endif /* UIP_URGDATA > 0 */
01237       uip_appdata += (BUF->urgp[0] << 8) | BUF->urgp[1];
01238       uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
01239     }
01240     
01241     
01242     /* If uip_len > 0 we have TCP data in the packet, and we flag this
01243        by setting the UIP_NEWDATA flag and update the sequence number
01244        we acknowledge. If the application has stopped the dataflow
01245        using uip_stop(), we must not accept any data packets from the
01246        remote host. */
01247     if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
01248       uip_flags |= UIP_NEWDATA;
01249       uip_add_rcv_nxt(uip_len);
01250     }
01251 
01252     /* Check if the available buffer space advertised by the other end
01253        is smaller than the initial MSS for this connection. If so, we
01254        set the current MSS to the window size to ensure that the
01255        application does not send more data than the other end can
01256        handle.
01257 
01258        If the remote host advertises a zero window, we set the MSS to
01259        the initial MSS so that the application will send an entire MSS
01260        of data. This data will not be acknowledged by the receiver,
01261        and the application will retransmit it. This is called the
01262        "persistent timer" and uses the retransmission mechanim.
01263     */
01264     tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1];
01265     if(tmp16 > uip_connr->initialmss ||
01266        tmp16 == 0) {
01267       tmp16 = uip_connr->initialmss;
01268     }
01269     uip_connr->mss = tmp16;
01270 
01271     /* If this packet constitutes an ACK for outstanding data (flagged
01272        by the UIP_ACKDATA flag, we should call the application since it
01273        might want to send more data. If the incoming packet had data
01274        from the peer (as flagged by the UIP_NEWDATA flag), the
01275        application must also be notified.
01276 
01277        When the application is called, the global variable uip_len
01278        contains the length of the incoming data. The application can
01279        access the incoming data through the global pointer
01280        uip_appdata, which usually points 40 bytes into the uip_buf
01281        array.
01282 
01283        If the application wishes to send any data, this data should be
01284        put into the uip_appdata and the length of the data should be
01285        put into uip_len. If the application don't have any data to
01286        send, uip_len must be set to 0. */
01287     if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
01288       uip_slen = 0;
01289       UIP_APPCALL();
01290 
01291     appsend:
01292       
01293       if(uip_flags & UIP_ABORT) {
01294         uip_slen = 0;
01295         uip_connr->tcpstateflags = CLOSED;
01296         BUF->flags = TCP_RST | TCP_ACK;
01297         goto tcp_send_nodata;
01298       }
01299 
01300       if(uip_flags & UIP_CLOSE) {
01301         uip_slen = 0;
01302         uip_connr->len = 1;
01303         uip_connr->tcpstateflags = FIN_WAIT_1;
01304         uip_connr->nrtx = 0;
01305         BUF->flags = TCP_FIN | TCP_ACK;
01306         goto tcp_send_nodata;   
01307       }
01308 
01309       /* If uip_slen > 0, the application has data to be sent. */
01310       if(uip_slen > 0) {
01311 
01312         /* If the connection has acknowledged data, the contents of
01313            the ->len variable should be discarded. */ 
01314         if((uip_flags & UIP_ACKDATA) != 0) {
01315           uip_connr->len = 0;
01316         }
01317 
01318         /* If the ->len variable is non-zero the connection has
01319            already data in transit and cannot send anymore right
01320            now. */
01321         if(uip_connr->len == 0) {
01322 
01323           /* The application cannot send more than what is allowed by
01324              the mss (the minumum of the MSS and the available
01325              window). */
01326           if(uip_slen > uip_connr->mss) {
01327             uip_slen = uip_connr->mss;
01328           }
01329 
01330           /* Remember how much data we send out now so that we know
01331              when everything has been acknowledged. */
01332           uip_connr->len = uip_slen;
01333         } else {
01334 
01335           /* If the application already had unacknowledged data, we
01336              make sure that the application does not send (i.e.,
01337              retransmit) out more than it previously sent out. */
01338           uip_slen = uip_connr->len;
01339         }
01340       } else {
01341         uip_connr->len = 0;
01342       }
01343       uip_connr->nrtx = 0;
01344     apprexmit:
01345       uip_appdata = uip_sappdata;
01346       
01347       /* If the application has data to be sent, or if the incoming
01348          packet had new data in it, we must send out a packet. */
01349       if(uip_slen > 0 && uip_connr->len > 0) {
01350         /* Add the length of the IP and TCP headers. */
01351         uip_len = uip_connr->len + UIP_TCPIP_HLEN;
01352         /* We always set the ACK flag in response packets. */
01353         BUF->flags = TCP_ACK | TCP_PSH;
01354         /* Send the packet. */
01355         goto tcp_send_noopts;
01356       }
01357       /* If there is no data to send, just send out a pure ACK if
01358          there is newdata. */
01359       if(uip_flags & UIP_NEWDATA) {
01360         uip_len = UIP_TCPIP_HLEN;
01361         BUF->flags = TCP_ACK;
01362         goto tcp_send_noopts;
01363       }
01364     }
01365     goto drop;
01366   case LAST_ACK:
01367     /* We can close this connection if the peer has acknowledged our
01368        FIN. This is indicated by the UIP_ACKDATA flag. */     
01369     if(uip_flags & UIP_ACKDATA) {
01370       uip_connr->tcpstateflags = CLOSED;
01371       uip_flags = UIP_CLOSE;
01372       UIP_APPCALL();
01373     }
01374     break;
01375     
01376   case FIN_WAIT_1:
01377     /* The application has closed the connection, but the remote host
01378        hasn't closed its end yet. Thus we do nothing but wait for a
01379        FIN from the other side. */
01380     if(uip_len > 0) {
01381       uip_add_rcv_nxt(uip_len);
01382     }
01383     if(BUF->flags & TCP_FIN) {
01384       if(uip_flags & UIP_ACKDATA) {
01385         uip_connr->tcpstateflags = TIME_WAIT;
01386         uip_connr->timer = 0;
01387         uip_connr->len = 0;
01388       } else {
01389         uip_connr->tcpstateflags = CLOSING;
01390       }
01391       uip_add_rcv_nxt(1);
01392       uip_flags = UIP_CLOSE;
01393       UIP_APPCALL();
01394       goto tcp_send_ack;
01395     } else if(uip_flags & UIP_ACKDATA) {
01396       uip_connr->tcpstateflags = FIN_WAIT_2;
01397       uip_connr->len = 0;
01398       goto drop;
01399     }
01400     if(uip_len > 0) {
01401       goto tcp_send_ack;
01402     }
01403     goto drop;
01404       
01405   case FIN_WAIT_2:
01406     if(uip_len > 0) {
01407       uip_add_rcv_nxt(uip_len);
01408     }
01409     if(BUF->flags & TCP_FIN) {
01410       uip_connr->tcpstateflags = TIME_WAIT;
01411       uip_connr->timer = 0;
01412       uip_add_rcv_nxt(1);
01413       uip_flags = UIP_CLOSE;
01414       UIP_APPCALL();
01415       goto tcp_send_ack;
01416     }
01417     if(uip_len > 0) {
01418       goto tcp_send_ack;
01419     }
01420     goto drop;
01421 
01422   case TIME_WAIT:
01423     goto tcp_send_ack;
01424     
01425   case CLOSING:
01426     if(uip_flags & UIP_ACKDATA) {
01427       uip_connr->tcpstateflags = TIME_WAIT;
01428       uip_connr->timer = 0;
01429     }
01430   }  
01431   goto drop;
01432   
01433 
01434   /* We jump here when we are ready to send the packet, and just want
01435      to set the appropriate TCP sequence numbers in the TCP header. */
01436  tcp_send_ack:
01437   BUF->flags = TCP_ACK;
01438  tcp_send_nodata:
01439   uip_len = 40;
01440  tcp_send_noopts:
01441   BUF->tcpoffset = 5 << 4;
01442  tcp_send:
01443   /* We're done with the input processing. We are now ready to send a
01444      reply. Our job is to fill in all the fields of the TCP and IP
01445      headers before calculating the checksum and finally send the
01446      packet. */
01447   BUF->ackno[0] = uip_connr->rcv_nxt[0];
01448   BUF->ackno[1] = uip_connr->rcv_nxt[1];
01449   BUF->ackno[2] = uip_connr->rcv_nxt[2];
01450   BUF->ackno[3] = uip_connr->rcv_nxt[3];
01451   
01452   BUF->seqno[0] = uip_connr->snd_nxt[0];
01453   BUF->seqno[1] = uip_connr->snd_nxt[1];
01454   BUF->seqno[2] = uip_connr->snd_nxt[2];
01455   BUF->seqno[3] = uip_connr->snd_nxt[3];
01456 
01457   BUF->proto = UIP_PROTO_TCP;
01458   
01459   BUF->srcport  = uip_connr->lport;
01460   BUF->destport = uip_connr->rport;
01461 
01462   BUF->srcipaddr[0] = uip_hostaddr[0];
01463   BUF->srcipaddr[1] = uip_hostaddr[1];
01464   BUF->destipaddr[0] = uip_connr->ripaddr[0];
01465   BUF->destipaddr[1] = uip_connr->ripaddr[1];
01466  
01467 
01468   if(uip_connr->tcpstateflags & UIP_STOPPED) {
01469     /* If the connection has issued uip_stop(), we advertise a zero
01470        window so that the remote host will stop sending data. */
01471     BUF->wnd[0] = BUF->wnd[1] = 0;
01472   } else {
01473     BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
01474     BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff); 
01475   }
01476 
01477  tcp_send_noconn:
01478 
01479   BUF->len[0] = (uip_len >> 8);
01480   BUF->len[1] = (uip_len & 0xff);
01481 
01482   /* Calculate TCP checksum. */
01483   BUF->tcpchksum = 0;
01484   BUF->tcpchksum = ~(uip_tcpchksum());
01485   
01486  ip_send_nolen:
01487 
01488   BUF->vhl = 0x45;
01489   BUF->tos = 0;
01490   BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
01491   BUF->ttl  = UIP_TTL;
01492   ++ipid;
01493   BUF->ipid[0] = ipid >> 8;
01494   BUF->ipid[1] = ipid & 0xff;
01495   
01496   /* Calculate IP checksum. */
01497   BUF->ipchksum = 0;
01498   BUF->ipchksum = ~(uip_ipchksum());
01499 
01500   UIP_STAT(++uip_stat.tcp.sent);
01501  send:
01502   UIP_STAT(++uip_stat.ip.sent);
01503   /* Return and let the caller do the actual transmission. */
01504   return;
01505  drop:
01506   uip_len = 0;
01507   return;
01508 }
01509 /*-----------------------------------------------------------------------------------*/
01510 u16_t
01511 htons(u16_t val)
01512 {
01513   return HTONS(val);
01514 }
01515 /*-----------------------------------------------------------------------------------*/

Generated on Fri Jan 6 22:23:17 2006 for EtherProgs by  doxygen 1.4.5