uIP 1.0 based webserver for LPC1114 + ENC28J60

Dependencies:   mbed TMP102

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers uip.c Source File

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