Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Examples

uip.c

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

Generated on Thu Jun 22 17:45:43 2006 for Contiki 2.x by  doxygen 1.4.4