uip/uip.c

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

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  doxygen 1.4.6