uip.c

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

Generated on Mon Apr 11 14:23:32 2011 for Contiki 2.5 by  doxygen 1.6.1