Contiki 2.6

uip6.c

Go to the documentation of this file.
00001 /**
00002  * \addtogroup uip6
00003  * @{
00004  */
00005 
00006 /**
00007  * \file
00008  *         The uIP TCP/IPv6 stack code.
00009  *
00010  * \author Adam Dunkels <adam@sics.se>
00011  * \author Julien Abeille <jabeille@cisco.com> (IPv6 related code)
00012  * \author Mathilde Durvy <mdurvy@cisco.com> (IPv6 related code)
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: uip6.c,v 1.25 2011/01/04 22:11:37 joxe 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-icmp6.h"
00077 #include "net/uip-nd6.h"
00078 #include "net/uip-ds6.h"
00079 
00080 #include <string.h>
00081 
00082 /*---------------------------------------------------------------------------*/
00083 /* For Debug, logging, statistics                                            */
00084 /*---------------------------------------------------------------------------*/
00085 
00086 #define DEBUG DEBUG_NONE
00087 #include "net/uip-debug.h"
00088 
00089 #if UIP_CONF_IPV6_RPL
00090 #include "rpl/rpl.h"
00091 #endif /* UIP_CONF_IPV6_RPL */
00092 
00093 #if UIP_LOGGING == 1
00094 #include <stdio.h>
00095 void uip_log(char *msg);
00096 #define UIP_LOG(m) uip_log(m)
00097 #else
00098 #define UIP_LOG(m)
00099 #endif /* UIP_LOGGING == 1 */
00100 
00101 #if UIP_STATISTICS == 1
00102 struct uip_stats uip_stat;
00103 #endif /* UIP_STATISTICS == 1 */
00104  
00105 
00106 /*---------------------------------------------------------------------------*/
00107 /** @{ \name Layer 2 variables */
00108 /*---------------------------------------------------------------------------*/
00109 /** Host L2 address */
00110 #if UIP_CONF_LL_802154
00111 uip_lladdr_t uip_lladdr;
00112 #else /*UIP_CONF_LL_802154*/
00113 uip_lladdr_t uip_lladdr = {{0x00,0x06,0x98,0x00,0x02,0x32}};
00114 #endif /*UIP_CONF_LL_802154*/
00115 /** @} */
00116 
00117 /*---------------------------------------------------------------------------*/
00118 /** @{ \name Layer 3 variables */
00119 /*---------------------------------------------------------------------------*/
00120 /**
00121  * \brief Type of the next header in IPv6 header or extension headers
00122  *
00123  * Can be the next header field in the IPv6 header or in an extension header.
00124  * When doing fragment reassembly, we must change the value of the next header
00125  * field in the header before the fragmentation header, hence we need a pointer
00126  * to this field.
00127  */
00128 uint8_t *uip_next_hdr;
00129 /** \brief bitmap we use to record which IPv6 headers we have already seen */
00130 uint8_t uip_ext_bitmap = 0;
00131 /**
00132  * \brief length of the extension headers read. updated each time we process
00133  * a header
00134  */
00135 uint8_t uip_ext_len = 0;
00136 /** \brief length of the header options read */
00137 uint8_t uip_ext_opt_offset = 0;
00138 /** @} */
00139 
00140 /*---------------------------------------------------------------------------*/
00141 /* Buffers                                                                   */
00142 /*---------------------------------------------------------------------------*/
00143 /** \name Buffer defines
00144  *  @{
00145  */
00146 #define FBUF                             ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
00147 #define UIP_IP_BUF                          ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
00148 #define UIP_ICMP_BUF                      ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
00149 #define UIP_UDP_BUF                        ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
00150 #define UIP_TCP_BUF                        ((struct uip_tcp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
00151 #define UIP_EXT_BUF                        ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len])
00152 #define UIP_ROUTING_BUF                ((struct uip_routing_hdr *)&uip_buf[uip_l2_l3_hdr_len])
00153 #define UIP_FRAG_BUF                      ((struct uip_frag_hdr *)&uip_buf[uip_l2_l3_hdr_len])
00154 #define UIP_HBHO_BUF                      ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len])
00155 #define UIP_DESTO_BUF                    ((struct uip_desto_hdr *)&uip_buf[uip_l2_l3_hdr_len])
00156 #define UIP_EXT_HDR_OPT_BUF            ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
00157 #define UIP_EXT_HDR_OPT_PADN_BUF  ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
00158 #if UIP_CONF_IPV6_RPL
00159 #define UIP_EXT_HDR_OPT_RPL_BUF    ((struct uip_ext_hdr_opt_rpl *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
00160 #endif /* UIP_CONF_IPV6_RPL */
00161 #define UIP_ICMP6_ERROR_BUF            ((struct uip_icmp6_error *)&uip_buf[uip_l2_l3_icmp_hdr_len])
00162 /** @} */
00163 /** \name Buffer variables
00164  *  @{
00165  */
00166 /** Packet buffer for incoming and outgoing packets */
00167 #ifndef UIP_CONF_EXTERNAL_BUFFER
00168 uip_buf_t uip_aligned_buf;
00169 #endif /* UIP_CONF_EXTERNAL_BUFFER */
00170 
00171 /* The uip_appdata pointer points to application data. */
00172 void *uip_appdata;
00173 /* The uip_appdata pointer points to the application data which is to be sent*/
00174 void *uip_sappdata;
00175 
00176 #if UIP_URGDATA > 0
00177 /* The uip_urgdata pointer points to urgent data (out-of-band data), if present */
00178 void *uip_urgdata;
00179 uint16_t uip_urglen, uip_surglen;
00180 #endif /* UIP_URGDATA > 0 */
00181 
00182 /* The uip_len is either 8 or 16 bits, depending on the maximum packet size.*/
00183 uint16_t uip_len, uip_slen;
00184 /** @} */
00185 
00186 /*---------------------------------------------------------------------------*/
00187 /** @{ \name General variables                                               */
00188 /*---------------------------------------------------------------------------*/
00189 
00190 /* The uip_flags variable is used for communication between the TCP/IP stack
00191 and the application program. */
00192 uint8_t uip_flags;
00193 
00194 /* uip_conn always points to the current connection (set to NULL for UDP). */
00195 struct uip_conn *uip_conn;
00196 
00197 /* Temporary variables. */
00198 #if (UIP_TCP || UIP_UDP)
00199 static uint8_t c;
00200 #endif
00201 
00202 #if UIP_ACTIVE_OPEN || UIP_UDP
00203 /* Keeps track of the last port used for a new connection. */
00204 static uint16_t lastport;
00205 #endif /* UIP_ACTIVE_OPEN || UIP_UDP */
00206 /** @} */
00207 
00208 /*---------------------------------------------------------------------------*/
00209 /* TCP                                                                       */
00210 /*---------------------------------------------------------------------------*/
00211 /** \name TCP defines
00212  *@{
00213  */
00214 /* Structures and definitions. */
00215 #define TCP_FIN 0x01
00216 #define TCP_SYN 0x02
00217 #define TCP_RST 0x04
00218 #define TCP_PSH 0x08
00219 #define TCP_ACK 0x10
00220 #define TCP_URG 0x20
00221 #define TCP_CTL 0x3f
00222 
00223 #define TCP_OPT_END     0   /* End of TCP options list */
00224 #define TCP_OPT_NOOP    1   /* "No-operation" TCP option */
00225 #define TCP_OPT_MSS     2   /* Maximum segment size TCP option */
00226 
00227 #define TCP_OPT_MSS_LEN 4   /* Length of TCP MSS option. */
00228 /** @} */
00229 /** \name TCP variables
00230  *@{
00231  */
00232 #if UIP_TCP
00233 /* The uip_conns array holds all TCP connections. */
00234 struct uip_conn uip_conns[UIP_CONNS];
00235 
00236 /* The uip_listenports list all currently listning ports. */
00237 uint16_t uip_listenports[UIP_LISTENPORTS];
00238 
00239 /* The iss variable is used for the TCP initial sequence number. */
00240 static uint8_t iss[4];
00241 
00242 /* Temporary variables. */
00243 uint8_t uip_acc32[4];
00244 static uint8_t opt;
00245 static uint16_t tmp16;
00246 #endif /* UIP_TCP */
00247 /** @} */
00248 
00249 /*---------------------------------------------------------------------------*/
00250 /** @{ \name UDP variables                                                   */
00251 /*---------------------------------------------------------------------------*/
00252 #if UIP_UDP
00253 struct uip_udp_conn *uip_udp_conn;
00254 struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
00255 #endif /* UIP_UDP */
00256 /** @} */
00257 
00258 /*---------------------------------------------------------------------------*/
00259 /** @{ \name ICMPv6 variables                                                */
00260 /*---------------------------------------------------------------------------*/
00261 #if UIP_CONF_ICMP6
00262 /** single possible icmpv6 "connection" */
00263 struct uip_icmp6_conn uip_icmp6_conns;
00264 #endif /*UIP_CONF_ICMP6*/
00265 
00266 /*---------------------------------------------------------------------------*/
00267 /* Functions                                                                 */
00268 /*---------------------------------------------------------------------------*/
00269 #if (!UIP_ARCH_ADD32 && UIP_TCP)
00270 void
00271 uip_add32(uint8_t *op32, uint16_t op16)
00272 {
00273   uip_acc32[3] = op32[3] + (op16 & 0xff);
00274   uip_acc32[2] = op32[2] + (op16 >> 8);
00275   uip_acc32[1] = op32[1];
00276   uip_acc32[0] = op32[0];
00277   
00278   if(uip_acc32[2] < (op16 >> 8)) {
00279     ++uip_acc32[1];
00280     if(uip_acc32[1] == 0) {
00281       ++uip_acc32[0];
00282     }
00283   }
00284   
00285   
00286   if(uip_acc32[3] < (op16 & 0xff)) {
00287     ++uip_acc32[2];
00288     if(uip_acc32[2] == 0) {
00289       ++uip_acc32[1];
00290       if(uip_acc32[1] == 0) {
00291         ++uip_acc32[0];
00292       }
00293     }
00294   }
00295 }
00296 
00297 #endif /* UIP_ARCH_ADD32 && UIP_TCP */
00298 
00299 #if ! UIP_ARCH_CHKSUM
00300 /*---------------------------------------------------------------------------*/
00301 static uint16_t
00302 chksum(uint16_t sum, const uint8_t *data, uint16_t len)
00303 {
00304   uint16_t t;
00305   const uint8_t *dataptr;
00306   const uint8_t *last_byte;
00307 
00308   dataptr = data;
00309   last_byte = data + len - 1;
00310   
00311   while(dataptr < last_byte) {   /* At least two more bytes */
00312     t = (dataptr[0] << 8) + dataptr[1];
00313     sum += t;
00314     if(sum < t) {
00315       sum++;      /* carry */
00316     }
00317     dataptr += 2;
00318   }
00319   
00320   if(dataptr == last_byte) {
00321     t = (dataptr[0] << 8) + 0;
00322     sum += t;
00323     if(sum < t) {
00324       sum++;      /* carry */
00325     }
00326   }
00327 
00328   /* Return sum in host byte order. */
00329   return sum;
00330 }
00331 /*---------------------------------------------------------------------------*/
00332 uint16_t
00333 uip_chksum(uint16_t *data, uint16_t len)
00334 {
00335   return uip_htons(chksum(0, (uint8_t *)data, len));
00336 }
00337 /*---------------------------------------------------------------------------*/
00338 #ifndef UIP_ARCH_IPCHKSUM
00339 uint16_t
00340 uip_ipchksum(void)
00341 {
00342   uint16_t sum;
00343 
00344   sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
00345   PRINTF("uip_ipchksum: sum 0x%04x\n", sum);
00346   return (sum == 0) ? 0xffff : uip_htons(sum);
00347 }
00348 #endif
00349 /*---------------------------------------------------------------------------*/
00350 static uint16_t
00351 upper_layer_chksum(uint8_t proto)
00352 {
00353 /* gcc 4.4.0 - 4.6.1 (maybe 4.3...) with -Os on 8 bit CPUS incorrectly compiles:
00354  * int bar (int);
00355  * int foo (unsigned char a, unsigned char b) {
00356  *   int len = (a << 8) + b; //len becomes 0xff00&<random>+b
00357  *   return len + bar (len);
00358  * }
00359  * upper_layer_len triggers this bug unless it is declared volatile.
00360  * See https://sourceforge.net/apps/mantisbt/contiki/view.php?id=3
00361  */
00362   volatile uint16_t upper_layer_len;
00363   uint16_t sum;
00364   
00365   upper_layer_len = (((uint16_t)(UIP_IP_BUF->len[0]) << 8) + UIP_IP_BUF->len[1] - uip_ext_len);
00366   
00367   PRINTF("Upper layer checksum len: %d from: %d\n", upper_layer_len,
00368          UIP_IPH_LEN + UIP_LLH_LEN + uip_ext_len);
00369 
00370   /* First sum pseudoheader. */
00371   /* IP protocol and length fields. This addition cannot carry. */
00372   sum = upper_layer_len + proto;
00373   /* Sum IP source and destination addresses. */
00374   sum = chksum(sum, (uint8_t *)&UIP_IP_BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t));
00375 
00376   /* Sum TCP header and data. */
00377   sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN + uip_ext_len],
00378                upper_layer_len);
00379     
00380   return (sum == 0) ? 0xffff : uip_htons(sum);
00381 }
00382 /*---------------------------------------------------------------------------*/
00383 uint16_t
00384 uip_icmp6chksum(void)
00385 {
00386   return upper_layer_chksum(UIP_PROTO_ICMP6);
00387   
00388 }
00389 /*---------------------------------------------------------------------------*/
00390 #if UIP_TCP
00391 uint16_t
00392 uip_tcpchksum(void)
00393 {
00394   return upper_layer_chksum(UIP_PROTO_TCP);
00395 }
00396 #endif /* UIP_TCP */
00397 /*---------------------------------------------------------------------------*/
00398 #if UIP_UDP && UIP_UDP_CHECKSUMS
00399 uint16_t
00400 uip_udpchksum(void)
00401 {
00402   return upper_layer_chksum(UIP_PROTO_UDP);
00403 }
00404 #endif /* UIP_UDP && UIP_UDP_CHECKSUMS */
00405 #endif /* UIP_ARCH_CHKSUM */
00406 /*---------------------------------------------------------------------------*/
00407 void
00408 uip_init(void)
00409 {
00410    
00411   uip_ds6_init();
00412 
00413 #if UIP_TCP
00414   for(c = 0; c < UIP_LISTENPORTS; ++c) {
00415     uip_listenports[c] = 0;
00416   }
00417   for(c = 0; c < UIP_CONNS; ++c) {
00418     uip_conns[c].tcpstateflags = UIP_CLOSED;
00419   }
00420 #endif /* UIP_TCP */
00421 
00422 #if UIP_ACTIVE_OPEN || UIP_UDP
00423   lastport = 1024;
00424 #endif /* UIP_ACTIVE_OPEN || UIP_UDP */
00425 
00426 #if UIP_UDP
00427   for(c = 0; c < UIP_UDP_CONNS; ++c) {
00428     uip_udp_conns[c].lport = 0;
00429   }
00430 #endif /* UIP_UDP */
00431 }
00432 /*---------------------------------------------------------------------------*/
00433 #if UIP_TCP && UIP_ACTIVE_OPEN
00434 struct uip_conn *
00435 uip_connect(uip_ipaddr_t *ripaddr, uint16_t rport)
00436 {
00437   register struct uip_conn *conn, *cconn;
00438   
00439   /* Find an unused local port. */
00440  again:
00441   ++lastport;
00442 
00443   if(lastport >= 32000) {
00444     lastport = 4096;
00445   }
00446 
00447   /* Check if this port is already in use, and if so try to find
00448      another one. */
00449   for(c = 0; c < UIP_CONNS; ++c) {
00450     conn = &uip_conns[c];
00451     if(conn->tcpstateflags != UIP_CLOSED &&
00452        conn->lport == uip_htons(lastport)) {
00453       goto again;
00454     }
00455   }
00456 
00457   conn = 0;
00458   for(c = 0; c < UIP_CONNS; ++c) {
00459     cconn = &uip_conns[c];
00460     if(cconn->tcpstateflags == UIP_CLOSED) {
00461       conn = cconn;
00462       break;
00463     }
00464     if(cconn->tcpstateflags == UIP_TIME_WAIT) {
00465       if(conn == 0 ||
00466          cconn->timer > conn->timer) {
00467         conn = cconn;
00468       }
00469     }
00470   }
00471 
00472   if(conn == 0) {
00473     return 0;
00474   }
00475   
00476   conn->tcpstateflags = UIP_SYN_SENT;
00477 
00478   conn->snd_nxt[0] = iss[0];
00479   conn->snd_nxt[1] = iss[1];
00480   conn->snd_nxt[2] = iss[2];
00481   conn->snd_nxt[3] = iss[3];
00482 
00483   conn->rcv_nxt[0] = 0;
00484   conn->rcv_nxt[1] = 0;
00485   conn->rcv_nxt[2] = 0;
00486   conn->rcv_nxt[3] = 0;
00487 
00488   conn->initialmss = conn->mss = UIP_TCP_MSS;
00489   
00490   conn->len = 1;   /* TCP length of the SYN is one. */
00491   conn->nrtx = 0;
00492   conn->timer = 1; /* Send the SYN next time around. */
00493   conn->rto = UIP_RTO;
00494   conn->sa = 0;
00495   conn->sv = 16;   /* Initial value of the RTT variance. */
00496   conn->lport = uip_htons(lastport);
00497   conn->rport = rport;
00498   uip_ipaddr_copy(&conn->ripaddr, ripaddr);
00499   
00500   return conn;
00501 }
00502 #endif /* UIP_TCP && UIP_ACTIVE_OPEN */
00503 /*---------------------------------------------------------------------------*/
00504 void
00505 remove_ext_hdr(void)
00506 {
00507   /* Remove ext header before TCP/UDP processing. */
00508   if(uip_ext_len > 0) {
00509     PRINTF("Cutting ext-header before processing (extlen: %d, uiplen: %d)\n",
00510            uip_ext_len, uip_len);
00511     if(uip_len - UIP_IPH_LEN - uip_ext_len < 0) {
00512       PRINTF("ERROR: uip_len too short compared to ext len\n");
00513       uip_ext_len = 0;
00514       uip_len = 0;
00515       return;
00516     }
00517     memmove(((uint8_t *)UIP_TCP_BUF), (uint8_t *)UIP_TCP_BUF + uip_ext_len,
00518             uip_len - UIP_IPH_LEN - uip_ext_len);
00519 
00520     uip_len -= uip_ext_len;
00521 
00522     /* Update the IP length. */
00523     UIP_IP_BUF->len[0] = (uip_len - UIP_IPH_LEN) >> 8;
00524     UIP_IP_BUF->len[1] = (uip_len - UIP_IPH_LEN) & 0xff;
00525     uip_ext_len = 0;
00526   }
00527 }
00528 /*---------------------------------------------------------------------------*/
00529 #if UIP_UDP
00530 struct uip_udp_conn *
00531 uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport)
00532 {
00533   register struct uip_udp_conn *conn;
00534   
00535   /* Find an unused local port. */
00536  again:
00537   ++lastport;
00538 
00539   if(lastport >= 32000) {
00540     lastport = 4096;
00541   }
00542   
00543   for(c = 0; c < UIP_UDP_CONNS; ++c) {
00544     if(uip_udp_conns[c].lport == uip_htons(lastport)) {
00545       goto again;
00546     }
00547   }
00548 
00549   conn = 0;
00550   for(c = 0; c < UIP_UDP_CONNS; ++c) {
00551     if(uip_udp_conns[c].lport == 0) {
00552       conn = &uip_udp_conns[c];
00553       break;
00554     }
00555   }
00556 
00557   if(conn == 0) {
00558     return 0;
00559   }
00560   
00561   conn->lport = UIP_HTONS(lastport);
00562   conn->rport = rport;
00563   if(ripaddr == NULL) {
00564     memset(&conn->ripaddr, 0, sizeof(uip_ipaddr_t));
00565   } else {
00566     uip_ipaddr_copy(&conn->ripaddr, ripaddr);
00567   }
00568   conn->ttl = uip_ds6_if.cur_hop_limit;
00569   
00570   return conn;
00571 }
00572 #endif /* UIP_UDP */
00573 /*---------------------------------------------------------------------------*/
00574 #if UIP_TCP
00575 void
00576 uip_unlisten(uint16_t port)
00577 {
00578   for(c = 0; c < UIP_LISTENPORTS; ++c) {
00579     if(uip_listenports[c] == port) {
00580       uip_listenports[c] = 0;
00581       return;
00582     }
00583   }
00584 }
00585 /*---------------------------------------------------------------------------*/
00586 void
00587 uip_listen(uint16_t port)
00588 {
00589   for(c = 0; c < UIP_LISTENPORTS; ++c) {
00590     if(uip_listenports[c] == 0) {
00591       uip_listenports[c] = port;
00592       return;
00593     }
00594   }
00595 }
00596 #endif
00597 /*---------------------------------------------------------------------------*/
00598 
00599 #if UIP_CONF_IPV6_REASSEMBLY
00600 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
00601 
00602 static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE];
00603 
00604 static uint8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
00605 /*the first byte of an IP fragment is aligned on an 8-byte boundary */
00606 
00607 static const uint8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
00608                                     0x0f, 0x07, 0x03, 0x01};
00609 static uint16_t uip_reasslen;
00610 static uint8_t uip_reassflags;
00611 
00612 #define UIP_REASS_FLAG_LASTFRAG 0x01
00613 #define UIP_REASS_FLAG_FIRSTFRAG 0x02
00614 #define UIP_REASS_FLAG_ERROR_MSG 0x04
00615 
00616 
00617 /*
00618  * See RFC 2460 for a description of fragmentation in IPv6
00619  * A typical Ipv6 fragment
00620  *  +------------------+--------+--------------+
00621  *  |  Unfragmentable  |Fragment|    first     |
00622  *  |       Part       | Header |   fragment   |
00623  *  +------------------+--------+--------------+
00624  */
00625 
00626 
00627 struct etimer uip_reass_timer; /* timer for reassembly */
00628 uint8_t uip_reass_on; /* equal to 1 if we are currently reassembling a packet */
00629 
00630 static uint32_t uip_id; /* For every packet that is to be fragmented, the source
00631                         node generates an Identification value that is present
00632                         in all the fragments */
00633 #define IP_MF   0x0001
00634 
00635 static uint16_t
00636 uip_reass(void)
00637 {
00638   uint16_t offset=0;
00639   uint16_t len;
00640   uint16_t i;
00641   
00642   /* If ip_reasstmr is zero, no packet is present in the buffer */
00643   /* We first write the unfragmentable part of IP header into the reassembly
00644      buffer. The reset the other reassembly variables. */
00645   if(uip_reass_on == 0) {
00646     PRINTF("Starting reassembly\n");
00647     memcpy(FBUF, UIP_IP_BUF, uip_ext_len + UIP_IPH_LEN);
00648     /* temporary in case we do not receive the fragment with offset 0 first */
00649     etimer_set(&uip_reass_timer, UIP_REASS_MAXAGE*CLOCK_SECOND);
00650     uip_reass_on = 1;
00651     uip_reassflags = 0;
00652     uip_id = UIP_FRAG_BUF->id;
00653     /* Clear the bitmap. */
00654     memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap));
00655   }
00656   /*
00657    * Check if the incoming fragment matches the one currently present
00658    * in the reasembly buffer. If so, we proceed with copying the fragment
00659    * into the buffer.
00660    */
00661   if(uip_ipaddr_cmp(&FBUF->srcipaddr, &UIP_IP_BUF->srcipaddr) &&
00662      uip_ipaddr_cmp(&FBUF->destipaddr, &UIP_IP_BUF->destipaddr) &&
00663      UIP_FRAG_BUF->id == uip_id) {
00664     len = uip_len - uip_ext_len - UIP_IPH_LEN - UIP_FRAGH_LEN;
00665     offset = (uip_ntohs(UIP_FRAG_BUF->offsetresmore) & 0xfff8);
00666     /* in byte, originaly in multiple of 8 bytes*/
00667     PRINTF("len %d\n", len);
00668     PRINTF("offset %d\n", offset);
00669     if(offset == 0){
00670       uip_reassflags |= UIP_REASS_FLAG_FIRSTFRAG;
00671       /*
00672        * The Next Header field of the last header of the Unfragmentable
00673        * Part is obtained from the Next Header field of the first
00674        * fragment's Fragment header.
00675        */
00676       *uip_next_hdr = UIP_FRAG_BUF->next;
00677       memcpy(FBUF, UIP_IP_BUF, uip_ext_len + UIP_IPH_LEN);
00678       PRINTF("src ");
00679       PRINT6ADDR(&FBUF->srcipaddr);
00680       PRINTF("dest ");
00681       PRINT6ADDR(&FBUF->destipaddr);
00682       PRINTF("next %d\n", UIP_IP_BUF->proto);
00683       
00684     }
00685     
00686     /* If the offset or the offset + fragment length overflows the
00687        reassembly buffer, we discard the entire packet. */
00688     if(offset > UIP_REASS_BUFSIZE ||
00689        offset + len > UIP_REASS_BUFSIZE) {
00690       uip_reass_on = 0;
00691       etimer_stop(&uip_reass_timer);
00692       return 0;
00693     }
00694 
00695     /* If this fragment has the More Fragments flag set to zero, it is the
00696        last fragment*/
00697     if((uip_ntohs(UIP_FRAG_BUF->offsetresmore) & IP_MF) == 0) {
00698       uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
00699       /*calculate the size of the entire packet*/
00700       uip_reasslen = offset + len;
00701       PRINTF("LAST FRAGMENT reasslen %d\n", uip_reasslen);
00702     } else {
00703       /* If len is not a multiple of 8 octets and the M flag of that fragment
00704          is 1, then that fragment must be discarded and an ICMP Parameter
00705          Problem, Code 0, message should be sent to the source of the fragment,
00706          pointing to the Payload Length field of the fragment packet. */
00707       if(len % 8 != 0){
00708         uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, 4);
00709         uip_reassflags |= UIP_REASS_FLAG_ERROR_MSG;
00710         /* not clear if we should interrupt reassembly, but it seems so from
00711            the conformance tests */
00712         uip_reass_on = 0;
00713         etimer_stop(&uip_reass_timer);
00714         return uip_len;
00715       }
00716     }
00717     
00718     /* Copy the fragment into the reassembly buffer, at the right
00719        offset. */
00720     memcpy((uint8_t *)FBUF + UIP_IPH_LEN + uip_ext_len + offset,
00721            (uint8_t *)UIP_FRAG_BUF + UIP_FRAGH_LEN, len);
00722     
00723     /* Update the bitmap. */
00724     if(offset >> 6 == (offset + len) >> 6) {
00725       uip_reassbitmap[offset >> 6] |=
00726         bitmap_bits[(offset >> 3) & 7] &
00727         ~bitmap_bits[((offset + len) >> 3)  & 7];
00728     } else {
00729       /* If the two endpoints are in different bytes, we update the
00730          bytes in the endpoints and fill the stuff inbetween with
00731          0xff. */
00732       uip_reassbitmap[offset >> 6] |= bitmap_bits[(offset >> 3) & 7];
00733  
00734       for(i = (1 + (offset >> 6)); i < ((offset + len) >> 6); ++i) {
00735         uip_reassbitmap[i] = 0xff;
00736       }
00737       uip_reassbitmap[(offset + len) >> 6] |=
00738         ~bitmap_bits[((offset + len) >> 3) & 7];
00739     }
00740   
00741     /* Finally, we check if we have a full packet in the buffer. We do
00742        this by checking if we have the last fragment and if all bits
00743        in the bitmap are set. */
00744     
00745     if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
00746       /* Check all bytes up to and including all but the last byte in
00747          the bitmap. */
00748       for(i = 0; i < (uip_reasslen >> 6); ++i) {
00749         if(uip_reassbitmap[i] != 0xff) {
00750           return 0;
00751         }
00752       }
00753       /* Check the last byte in the bitmap. It should contain just the
00754          right amount of bits. */
00755       if(uip_reassbitmap[uip_reasslen >> 6] !=
00756          (uint8_t)~bitmap_bits[(uip_reasslen >> 3) & 7]) {
00757         return 0;
00758       }
00759 
00760      /* If we have come this far, we have a full packet in the
00761          buffer, so we copy it to uip_buf. We also reset the timer. */
00762       uip_reass_on = 0;
00763       etimer_stop(&uip_reass_timer);
00764 
00765       uip_reasslen += UIP_IPH_LEN + uip_ext_len;
00766       memcpy(UIP_IP_BUF, FBUF, uip_reasslen);
00767       UIP_IP_BUF->len[0] = ((uip_reasslen - UIP_IPH_LEN) >> 8);
00768       UIP_IP_BUF->len[1] = ((uip_reasslen - UIP_IPH_LEN) & 0xff);
00769       PRINTF("REASSEMBLED PAQUET %d (%d)\n", uip_reasslen,
00770              (UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]);
00771    
00772       return uip_reasslen;
00773       
00774     }
00775   } else {
00776     PRINTF("Already reassembling another paquet\n");
00777   }
00778   return 0;
00779 }
00780 
00781 void
00782 uip_reass_over(void)
00783 {
00784    /* to late, we abandon the reassembly of the packet */
00785 
00786   uip_reass_on = 0;
00787   etimer_stop(&uip_reass_timer);
00788 
00789   if(uip_reassflags & UIP_REASS_FLAG_FIRSTFRAG){
00790     PRINTF("FRAG INTERRUPTED TOO LATE\n");
00791     /* If the first fragment has been received, an ICMP Time Exceeded
00792        -- Fragment Reassembly Time Exceeded message should be sent to the
00793        source of that fragment. */
00794     /** \note
00795      * We don't have a complete packet to put in the error message.
00796      * We could include the first fragment but since its not mandated by
00797      * any RFC, we decided not to include it as it reduces the size of
00798      * the packet.
00799      */
00800     uip_len = 0;
00801     uip_ext_len = 0;
00802     memcpy(UIP_IP_BUF, FBUF, UIP_IPH_LEN); /* copy the header for src
00803                                               and dest address*/
00804     uip_icmp6_error_output(ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_REASSEMBLY, 0);
00805     
00806     UIP_STAT(++uip_stat.ip.sent);
00807     uip_flags = 0;
00808   }
00809 }
00810 
00811 #endif /* UIP_CONF_IPV6_REASSEMBLY */
00812 
00813 /*---------------------------------------------------------------------------*/
00814 #if UIP_TCP
00815 static void
00816 uip_add_rcv_nxt(uint16_t n)
00817 {
00818   uip_add32(uip_conn->rcv_nxt, n);
00819   uip_conn->rcv_nxt[0] = uip_acc32[0];
00820   uip_conn->rcv_nxt[1] = uip_acc32[1];
00821   uip_conn->rcv_nxt[2] = uip_acc32[2];
00822   uip_conn->rcv_nxt[3] = uip_acc32[3];
00823 }
00824 #endif
00825 /*---------------------------------------------------------------------------*/
00826 
00827 /**
00828  * \brief Process the options in Destination and Hop By Hop extension headers
00829  */
00830 static uint8_t
00831 ext_hdr_options_process(void)
00832 {
00833  /*
00834   * Length field in the extension header: length of the header in units of
00835   * 8 bytes, excluding the first 8 bytes
00836   * length field in an option : the length of data in the option
00837   */
00838   uip_ext_opt_offset = 2;
00839   while(uip_ext_opt_offset < ((UIP_EXT_BUF->len << 3) + 8)) {
00840     switch(UIP_EXT_HDR_OPT_BUF->type) {
00841       /*
00842        * for now we do not support any options except padding ones
00843        * PAD1 does not make sense as the header must be 8bytes aligned,
00844        * hence we can only have
00845        */
00846       case UIP_EXT_HDR_OPT_PAD1:
00847         PRINTF("Processing PAD1 option\n");
00848         uip_ext_opt_offset += 1;
00849         break;
00850       case UIP_EXT_HDR_OPT_PADN:
00851         PRINTF("Processing PADN option\n");
00852         uip_ext_opt_offset += UIP_EXT_HDR_OPT_PADN_BUF->opt_len + 2;
00853         break;
00854 #if UIP_CONF_IPV6_RPL
00855       case UIP_EXT_HDR_OPT_RPL:
00856         PRINTF("Processing RPL option\n");
00857         if(rpl_verify_header(uip_ext_opt_offset)) {
00858           PRINTF("RPL Option Error : Dropping Packet");
00859           return 1;
00860         }
00861         uip_ext_opt_offset += (UIP_EXT_HDR_OPT_RPL_BUF->opt_len) + 2;
00862         return 0;
00863 #endif /* UIP_CONF_IPV6_RPL */
00864       default:
00865         /*
00866          * check the two highest order bits of the option
00867          * - 00 skip over this option and continue processing the header.
00868          * - 01 discard the packet.
00869          * - 10 discard the packet and, regardless of whether or not the
00870          *   packet's Destination Address was a multicast address, send an
00871          *   ICMP Parameter Problem, Code 2, message to the packet's
00872          *   Source Address, pointing to the unrecognized Option Type.
00873          * - 11 discard the packet and, only if the packet's Destination
00874          *   Address was not a multicast address, send an ICMP Parameter
00875          *   Problem, Code 2, message to the packet's Source Address,
00876          *   pointing to the unrecognized Option Type.
00877          */
00878         PRINTF("MSB %x\n", UIP_EXT_HDR_OPT_BUF->type);
00879         switch(UIP_EXT_HDR_OPT_BUF->type & 0xC0) {
00880           case 0:
00881             break;
00882           case 0x40:
00883             return 1;
00884           case 0xC0:
00885             if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
00886               return 1;
00887             }
00888           case 0x80:
00889             uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION,
00890                              (uint32_t)UIP_IPH_LEN + uip_ext_len + uip_ext_opt_offset);
00891             return 2;
00892         }
00893         /* in the cases were we did not discard, update ext_opt* */
00894         uip_ext_opt_offset += UIP_EXT_HDR_OPT_BUF->len + 2;
00895         break;
00896     }
00897   }
00898   return 0;
00899 }
00900 
00901 
00902 /*---------------------------------------------------------------------------*/
00903 void
00904 uip_process(uint8_t flag)
00905 {
00906 #if UIP_TCP
00907   register struct uip_conn *uip_connr = uip_conn;
00908 #endif /* UIP_TCP */
00909 #if UIP_UDP
00910   if(flag == UIP_UDP_SEND_CONN) {
00911     goto udp_send;
00912   }
00913 #endif /* UIP_UDP */
00914   uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
00915    
00916   /* Check if we were invoked because of a poll request for a
00917      particular connection. */
00918   if(flag == UIP_POLL_REQUEST) {
00919 #if UIP_TCP
00920     if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
00921        !uip_outstanding(uip_connr)) {
00922       uip_flags = UIP_POLL;
00923       UIP_APPCALL();
00924       goto appsend;
00925 #if UIP_ACTIVE_OPEN
00926     } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
00927       /* In the SYN_SENT state, we retransmit out SYN. */
00928       UIP_TCP_BUF->flags = 0;
00929       goto tcp_send_syn;
00930 #endif /* UIP_ACTIVE_OPEN */
00931     }
00932     goto drop;
00933 #endif /* UIP_TCP */
00934     /* Check if we were invoked because of the perodic timer fireing. */
00935   } else if(flag == UIP_TIMER) {
00936     /* Reset the length variables. */
00937 #if UIP_TCP
00938     uip_len = 0;
00939     uip_slen = 0;
00940     
00941     /* Increase the initial sequence number. */
00942     if(++iss[3] == 0) {
00943       if(++iss[2] == 0) {
00944         if(++iss[1] == 0) {
00945           ++iss[0];
00946         }
00947       }
00948     }
00949     
00950     /*
00951      * Check if the connection is in a state in which we simply wait
00952      * for the connection to time out. If so, we increase the
00953      * connection's timer and remove the connection if it times
00954      * out.
00955      */
00956     if(uip_connr->tcpstateflags == UIP_TIME_WAIT ||
00957        uip_connr->tcpstateflags == UIP_FIN_WAIT_2) {
00958       ++(uip_connr->timer);
00959       if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
00960         uip_connr->tcpstateflags = UIP_CLOSED;
00961       }
00962     } else if(uip_connr->tcpstateflags != UIP_CLOSED) {
00963       /*
00964        * If the connection has outstanding data, we increase the
00965        * connection's timer and see if it has reached the RTO value
00966        * in which case we retransmit.
00967        */
00968       if(uip_outstanding(uip_connr)) {
00969         if(uip_connr->timer-- == 0) {
00970           if(uip_connr->nrtx == UIP_MAXRTX ||
00971              ((uip_connr->tcpstateflags == UIP_SYN_SENT ||
00972                uip_connr->tcpstateflags == UIP_SYN_RCVD) &&
00973               uip_connr->nrtx == UIP_MAXSYNRTX)) {
00974             uip_connr->tcpstateflags = UIP_CLOSED;
00975                   
00976             /*
00977              * We call UIP_APPCALL() with uip_flags set to
00978              * UIP_TIMEDOUT to inform the application that the
00979              * connection has timed out.
00980              */
00981             uip_flags = UIP_TIMEDOUT;
00982             UIP_APPCALL();
00983                   
00984             /* We also send a reset packet to the remote host. */
00985             UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
00986             goto tcp_send_nodata;
00987           }
00988                
00989           /* Exponential backoff. */
00990           uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
00991                                          4:
00992                                          uip_connr->nrtx);
00993           ++(uip_connr->nrtx);
00994                
00995           /*
00996            * Ok, so we need to retransmit. We do this differently
00997            * depending on which state we are in. In ESTABLISHED, we
00998            * call upon the application so that it may prepare the
00999            * data for the retransmit. In SYN_RCVD, we resend the
01000            * SYNACK that we sent earlier and in LAST_ACK we have to
01001            * retransmit our FINACK.
01002            */
01003           UIP_STAT(++uip_stat.tcp.rexmit);
01004           switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
01005             case UIP_SYN_RCVD:
01006               /* In the SYN_RCVD state, we should retransmit our SYNACK. */
01007               goto tcp_send_synack;
01008                      
01009 #if UIP_ACTIVE_OPEN
01010             case UIP_SYN_SENT:
01011               /* In the SYN_SENT state, we retransmit out SYN. */
01012               UIP_TCP_BUF->flags = 0;
01013               goto tcp_send_syn;
01014 #endif /* UIP_ACTIVE_OPEN */
01015                      
01016             case UIP_ESTABLISHED:
01017               /*
01018                * In the ESTABLISHED state, we call upon the application
01019                * to do the actual retransmit after which we jump into
01020                * the code for sending out the packet (the apprexmit
01021                * label).
01022                */
01023               uip_flags = UIP_REXMIT;
01024               UIP_APPCALL();
01025               goto apprexmit;
01026                      
01027             case UIP_FIN_WAIT_1:
01028             case UIP_CLOSING:
01029             case UIP_LAST_ACK:
01030               /* In all these states we should retransmit a FINACK. */
01031               goto tcp_send_finack;
01032           }
01033         }
01034       } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
01035         /*
01036          * If there was no need for a retransmission, we poll the
01037          * application for new data.
01038          */
01039         uip_flags = UIP_POLL;
01040         UIP_APPCALL();
01041         goto appsend;
01042       }
01043     }
01044     goto drop;
01045 #endif /* UIP_TCP */
01046   }
01047 #if UIP_UDP
01048   if(flag == UIP_UDP_TIMER) {
01049     if(uip_udp_conn->lport != 0) {
01050       uip_conn = NULL;
01051       uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN];
01052       uip_len = uip_slen = 0;
01053       uip_flags = UIP_POLL;
01054       UIP_UDP_APPCALL();
01055       goto udp_send;
01056     } else {
01057       goto drop;
01058     }
01059   }
01060 #endif /* UIP_UDP */
01061 
01062   
01063   /* This is where the input processing starts. */
01064   UIP_STAT(++uip_stat.ip.recv);
01065    
01066   /* Start of IP input header processing code. */
01067    
01068   /* Check validity of the IP header. */
01069   if((UIP_IP_BUF->vtc & 0xf0) != 0x60)  { /* IP version and header length. */
01070     UIP_STAT(++uip_stat.ip.drop);
01071     UIP_STAT(++uip_stat.ip.vhlerr);
01072     UIP_LOG("ipv6: invalid version.");
01073     goto drop;
01074   }
01075   /*
01076    * Check the size of the packet. If the size reported to us in
01077    * uip_len is smaller the size reported in the IP header, we assume
01078    * that the packet has been corrupted in transit. If the size of
01079    * uip_len is larger than the size reported in the IP packet header,
01080    * the packet has been padded and we set uip_len to the correct
01081    * value..
01082    */
01083    
01084   if((UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] <= uip_len) {
01085     uip_len = (UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] + UIP_IPH_LEN;
01086     /*
01087      * The length reported in the IPv6 header is the
01088      * length of the payload that follows the
01089      * header. However, uIP uses the uip_len variable
01090      * for holding the size of the entire packet,
01091      * including the IP header. For IPv4 this is not a
01092      * problem as the length field in the IPv4 header
01093      * contains the length of the entire packet. But
01094      * for IPv6 we need to add the size of the IPv6
01095      * header (40 bytes).
01096      */
01097   } else {
01098     UIP_LOG("ip: packet shorter than reported in IP header.");
01099     goto drop;
01100   }
01101   
01102   PRINTF("IPv6 packet received from ");
01103   PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
01104   PRINTF(" to ");
01105   PRINT6ADDR(&UIP_IP_BUF->destipaddr);
01106   PRINTF("\n");
01107 
01108   if(uip_is_addr_mcast(&UIP_IP_BUF->srcipaddr)){
01109     UIP_STAT(++uip_stat.ip.drop);
01110     PRINTF("Dropping packet, src is mcast\n");
01111     goto drop;
01112   }
01113 
01114 #if UIP_CONF_ROUTER
01115   /*
01116    * Next header field processing. In IPv6, we can have extension headers,
01117    * if present, the Hop-by-Hop Option must be processed before forwarding
01118    * the packet.
01119    */
01120   uip_next_hdr = &UIP_IP_BUF->proto;
01121   uip_ext_len = 0;
01122   uip_ext_bitmap = 0;
01123   if(*uip_next_hdr == UIP_PROTO_HBHO) {
01124 #if UIP_CONF_IPV6_CHECKS
01125     uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO;
01126 #endif /*UIP_CONF_IPV6_CHECKS*/
01127     switch(ext_hdr_options_process()) {
01128       case 0:
01129         /*continue*/
01130         uip_next_hdr = &UIP_EXT_BUF->next;
01131         uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
01132         break;
01133       case 1:
01134         /*silently discard*/
01135         goto drop;
01136       case 2:
01137         /* send icmp error message (created in ext_hdr_options_process)
01138          * and discard*/
01139         goto send;
01140     }
01141   }
01142 
01143 
01144   /* TBD Some Parameter problem messages */
01145   if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) &&
01146      !uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr)) {
01147     if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr) &&
01148        !uip_is_addr_link_local(&UIP_IP_BUF->destipaddr) &&
01149        !uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr) &&
01150        !uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr) &&
01151        !uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) {
01152 
01153 
01154       /* Check MTU */
01155       if(uip_len > UIP_LINK_MTU) {
01156         uip_icmp6_error_output(ICMP6_PACKET_TOO_BIG, 0, UIP_LINK_MTU);
01157         UIP_STAT(++uip_stat.ip.drop);
01158         goto send;
01159       }
01160       /* Check Hop Limit */
01161       if(UIP_IP_BUF->ttl <= 1) {
01162         uip_icmp6_error_output(ICMP6_TIME_EXCEEDED,
01163                                ICMP6_TIME_EXCEED_TRANSIT, 0);
01164         UIP_STAT(++uip_stat.ip.drop);
01165         goto send;
01166       }
01167 
01168 #if UIP_CONF_IPV6_RPL
01169       rpl_update_header_empty();
01170 #endif /* UIP_CONF_IPV6_RPL */
01171 
01172       UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1;
01173       PRINTF("Forwarding packet to ");
01174       PRINT6ADDR(&UIP_IP_BUF->destipaddr);
01175       PRINTF("\n");
01176       UIP_STAT(++uip_stat.ip.forwarded);
01177       goto send;
01178     } else {
01179       if((uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)) &&
01180          (!uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) &&
01181          (!uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) &&
01182          (!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) &&
01183          (!uip_ds6_is_addr_onlink((&UIP_IP_BUF->destipaddr)))) {
01184         PRINTF("LL source address with off link destination, dropping\n");
01185         uip_icmp6_error_output(ICMP6_DST_UNREACH,
01186                                ICMP6_DST_UNREACH_NOTNEIGHBOR, 0);
01187         goto send;
01188       }
01189       PRINTF("Dropping packet, not for me and link local or multicast\n");
01190       UIP_STAT(++uip_stat.ip.drop);
01191       goto drop;
01192     }
01193   }
01194 #else /* UIP_CONF_ROUTER */
01195   if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) &&
01196      !uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr) &&
01197      !uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
01198     PRINTF("Dropping packet, not for me\n");
01199     UIP_STAT(++uip_stat.ip.drop);
01200     goto drop;
01201   }
01202 
01203   /*
01204    * Next header field processing. In IPv6, we can have extension headers,
01205    * they are processed here
01206    */
01207   uip_next_hdr = &UIP_IP_BUF->proto;
01208   uip_ext_len = 0;
01209   uip_ext_bitmap = 0;
01210 #endif /* UIP_CONF_ROUTER */
01211 
01212   while(1) {
01213     switch(*uip_next_hdr){
01214 #if UIP_TCP
01215       case UIP_PROTO_TCP:
01216         /* TCP, for both IPv4 and IPv6 */
01217         goto tcp_input;
01218 #endif /* UIP_TCP */
01219 #if UIP_UDP
01220       case UIP_PROTO_UDP:
01221         /* UDP, for both IPv4 and IPv6 */
01222         goto udp_input;
01223 #endif /* UIP_UDP */
01224       case UIP_PROTO_ICMP6:
01225         /* ICMPv6 */
01226         goto icmp6_input;
01227       case UIP_PROTO_HBHO:
01228         PRINTF("Processing hbh header\n");
01229         /* Hop by hop option header */
01230 #if UIP_CONF_IPV6_CHECKS
01231         /* Hop by hop option header. If we saw one HBH already, drop */
01232         if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_HBHO) {
01233           goto bad_hdr;
01234         } else {
01235           uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO;
01236         }
01237 #endif /*UIP_CONF_IPV6_CHECKS*/
01238         switch(ext_hdr_options_process()) {
01239           case 0:
01240             /*continue*/
01241             uip_next_hdr = &UIP_EXT_BUF->next;
01242             uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
01243             break;
01244           case 1:
01245             /*silently discard*/
01246             goto drop;
01247           case 2:
01248             /* send icmp error message (created in ext_hdr_options_process)
01249              * and discard*/
01250             goto send;
01251         }
01252         break;
01253       case UIP_PROTO_DESTO:
01254 #if UIP_CONF_IPV6_CHECKS
01255         /* Destination option header. if we saw two already, drop */
01256         PRINTF("Processing desto header\n");
01257         if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO1) {
01258           if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO2) {
01259             goto bad_hdr;
01260           } else{
01261             uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO2;
01262           }
01263         } else {
01264           uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO1;
01265         }
01266 #endif /*UIP_CONF_IPV6_CHECKS*/
01267         switch(ext_hdr_options_process()) {
01268           case 0:
01269             /*continue*/
01270             uip_next_hdr = &UIP_EXT_BUF->next;
01271             uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
01272             break;
01273           case 1:
01274             /*silently discard*/
01275             goto drop;
01276           case 2:
01277             /* send icmp error message (created in ext_hdr_options_process)
01278              * and discard*/
01279             goto send;
01280         }
01281         break;
01282       case UIP_PROTO_ROUTING:
01283 #if UIP_CONF_IPV6_CHECKS
01284         /* Routing header. If we saw one already, drop */
01285         if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_ROUTING) {
01286           goto bad_hdr;
01287         } else {
01288           uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_ROUTING;
01289         }
01290 #endif /*UIP_CONF_IPV6_CHECKS*/
01291         /*
01292          * Routing Header  length field is in units of 8 bytes, excluding
01293          * As per RFC2460 section 4.4, if routing type is unrecognized:
01294          * if segments left = 0, ignore the header
01295          * if segments left > 0, discard packet and send icmp error pointing
01296          * to the routing type
01297          */
01298 
01299         PRINTF("Processing Routing header\n");
01300         if(UIP_ROUTING_BUF->seg_left > 0) {
01301           uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, UIP_IPH_LEN + uip_ext_len + 2);
01302           UIP_STAT(++uip_stat.ip.drop);
01303           UIP_LOG("ip6: unrecognized routing type");
01304           goto send;
01305         }
01306         uip_next_hdr = &UIP_EXT_BUF->next;
01307         uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
01308         break;
01309       case UIP_PROTO_FRAG:
01310         /* Fragmentation header:call the reassembly function, then leave */
01311 #if UIP_CONF_IPV6_REASSEMBLY
01312         PRINTF("Processing frag header\n");
01313         uip_len = uip_reass();
01314         if(uip_len == 0) {
01315           goto drop;
01316         }
01317         if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG){
01318           /* we are not done with reassembly, this is an error message */
01319           goto send;
01320         }
01321         /*packet is reassembled, reset the next hdr to the beginning
01322            of the IP header and restart the parsing of the reassembled pkt*/
01323         PRINTF("Processing reassembled packet\n");
01324         uip_ext_len = 0;
01325         uip_ext_bitmap = 0;
01326         uip_next_hdr = &UIP_IP_BUF->proto;
01327         break;
01328 #else /* UIP_CONF_IPV6_REASSEMBLY */
01329         UIP_STAT(++uip_stat.ip.drop);
01330         UIP_STAT(++uip_stat.ip.fragerr);
01331         UIP_LOG("ip: fragment dropped.");
01332         goto drop;
01333 #endif /* UIP_CONF_IPV6_REASSEMBLY */
01334       case UIP_PROTO_NONE:
01335         goto drop;
01336       default:
01337         goto bad_hdr;
01338     }
01339   }
01340   bad_hdr:
01341   /*
01342    * RFC 2460 send error message parameterr problem, code unrecognized
01343    * next header, pointing to the next header field
01344    */
01345   uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_NEXTHEADER, (uint32_t)(uip_next_hdr - (uint8_t *)UIP_IP_BUF));
01346   UIP_STAT(++uip_stat.ip.drop);
01347   UIP_STAT(++uip_stat.ip.protoerr);
01348   UIP_LOG("ip6: unrecognized header");
01349   goto send;
01350   /* End of headers processing */
01351   
01352   icmp6_input:
01353   /* This is IPv6 ICMPv6 processing code. */
01354   PRINTF("icmp6_input: length %d type: %d \n", uip_len, UIP_ICMP_BUF->type);
01355 
01356 #if UIP_CONF_IPV6_CHECKS
01357   /* Compute and check the ICMP header checksum */
01358   if(uip_icmp6chksum() != 0xffff) {
01359     UIP_STAT(++uip_stat.icmp.drop);
01360     UIP_STAT(++uip_stat.icmp.chkerr);
01361     UIP_LOG("icmpv6: bad checksum.");
01362     PRINTF("icmpv6: bad checksum.");
01363     goto drop;
01364   }
01365 #endif /*UIP_CONF_IPV6_CHECKS*/
01366 
01367   UIP_STAT(++uip_stat.icmp.recv);
01368   /*
01369    * Here we process incoming ICMPv6 packets
01370    * For echo request, we send echo reply
01371    * For ND pkts, we call the appropriate function in uip-nd6.c
01372    * We do not treat Error messages for now
01373    * If no pkt is to be sent as an answer to the incoming one, we
01374    * "goto drop". Else we just break; then at the after the "switch"
01375    * we "goto send"
01376    */
01377 #if UIP_CONF_ICMP6
01378   UIP_ICMP6_APPCALL(UIP_ICMP_BUF->type);
01379 #endif /*UIP_CONF_ICMP6*/
01380 
01381   switch(UIP_ICMP_BUF->type) {
01382     case ICMP6_NS:
01383       uip_nd6_ns_input();
01384       break;
01385     case ICMP6_NA:
01386       uip_nd6_na_input();
01387       break;
01388     case ICMP6_RS:
01389 #if UIP_CONF_ROUTER && UIP_ND6_SEND_RA
01390     uip_nd6_rs_input();
01391 #else /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */
01392     UIP_STAT(++uip_stat.icmp.drop);
01393     uip_len = 0;
01394 #endif /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */
01395     break;
01396   case ICMP6_RA:
01397 #if UIP_CONF_ROUTER
01398     UIP_STAT(++uip_stat.icmp.drop);
01399     uip_len = 0;
01400 #else /* UIP_CONF_ROUTER */
01401     uip_nd6_ra_input();
01402 #endif /* UIP_CONF_ROUTER */
01403     break;
01404 #if UIP_CONF_IPV6_RPL
01405   case ICMP6_RPL:
01406     uip_rpl_input();
01407     break;
01408 #endif /* UIP_CONF_IPV6_RPL */
01409     case ICMP6_ECHO_REQUEST:
01410       uip_icmp6_echo_request_input();
01411       break;
01412     case ICMP6_ECHO_REPLY:
01413       /** \note We don't implement any application callback for now */
01414       PRINTF("Received an icmp6 echo reply\n");
01415       UIP_STAT(++uip_stat.icmp.recv);
01416       uip_len = 0;
01417       break;
01418     default:
01419       PRINTF("Unknown icmp6 message type %d\n", UIP_ICMP_BUF->type);
01420       UIP_STAT(++uip_stat.icmp.drop);
01421       UIP_STAT(++uip_stat.icmp.typeerr);
01422       UIP_LOG("icmp6: unknown ICMP message.");
01423       uip_len = 0;
01424       break;
01425   }
01426   
01427   if(uip_len > 0) {
01428     goto send;
01429   } else {
01430     goto drop;
01431   }
01432   /* End of IPv6 ICMP processing. */
01433    
01434 
01435 #if UIP_UDP
01436   /* UDP input processing. */
01437  udp_input:
01438 
01439   remove_ext_hdr();
01440 
01441   PRINTF("Receiving UDP packet\n");
01442   UIP_STAT(++uip_stat.udp.recv);
01443  
01444   /* UDP processing is really just a hack. We don't do anything to the
01445      UDP/IP headers, but let the UDP application do all the hard
01446      work. If the application sets uip_slen, it has a packet to
01447      send. */
01448 #if UIP_UDP_CHECKSUMS
01449   uip_len = uip_len - UIP_IPUDPH_LEN;
01450   uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN];
01451   if(UIP_UDP_BUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
01452     UIP_STAT(++uip_stat.udp.drop);
01453     UIP_STAT(++uip_stat.udp.chkerr);
01454     PRINTF("udp: bad checksum 0x%04x 0x%04x\n", UIP_UDP_BUF->udpchksum,
01455            uip_udpchksum());
01456     goto drop;
01457   }
01458 #else /* UIP_UDP_CHECKSUMS */
01459   uip_len = uip_len - UIP_IPUDPH_LEN;
01460 #endif /* UIP_UDP_CHECKSUMS */
01461 
01462   /* Make sure that the UDP destination port number is not zero. */
01463   if(UIP_UDP_BUF->destport == 0) {
01464     PRINTF("udp: zero port.\n");
01465     goto drop;
01466   }
01467 
01468   /* Demultiplex this UDP packet between the UDP "connections". */
01469   for(uip_udp_conn = &uip_udp_conns[0];
01470       uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
01471       ++uip_udp_conn) {
01472     /* If the local UDP port is non-zero, the connection is considered
01473        to be used. If so, the local port number is checked against the
01474        destination port number in the received packet. If the two port
01475        numbers match, the remote port number is checked if the
01476        connection is bound to a remote port. Finally, if the
01477        connection is bound to a remote IP address, the source IP
01478        address of the packet is checked. */
01479     if(uip_udp_conn->lport != 0 &&
01480        UIP_UDP_BUF->destport == uip_udp_conn->lport &&
01481        (uip_udp_conn->rport == 0 ||
01482         UIP_UDP_BUF->srcport == uip_udp_conn->rport) &&
01483        (uip_is_addr_unspecified(&uip_udp_conn->ripaddr) ||
01484         uip_ipaddr_cmp(&UIP_IP_BUF->srcipaddr, &uip_udp_conn->ripaddr))) {
01485       goto udp_found;
01486     }
01487   }
01488   PRINTF("udp: no matching connection found\n");
01489 
01490 #if UIP_UDP_SEND_UNREACH_NOPORT
01491   uip_icmp6_error_output(ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
01492   UIP_STAT(++uip_stat.ip.drop);
01493   goto send;
01494 #else
01495   goto drop;
01496 #endif
01497 
01498  udp_found:
01499   PRINTF("In udp_found\n");
01500  
01501   uip_conn = NULL;
01502   uip_flags = UIP_NEWDATA;
01503   uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN];
01504   uip_slen = 0;
01505   UIP_UDP_APPCALL();
01506 
01507  udp_send:
01508   PRINTF("In udp_send\n");
01509 
01510   if(uip_slen == 0) {
01511     goto drop;
01512   }
01513   uip_len = uip_slen + UIP_IPUDPH_LEN;
01514 
01515   /* For IPv6, the IP length field does not include the IPv6 IP header
01516      length. */
01517   UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
01518   UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
01519 
01520   UIP_IP_BUF->ttl = uip_udp_conn->ttl;
01521   UIP_IP_BUF->proto = UIP_PROTO_UDP;
01522 
01523   UIP_UDP_BUF->udplen = UIP_HTONS(uip_slen + UIP_UDPH_LEN);
01524   UIP_UDP_BUF->udpchksum = 0;
01525 
01526   UIP_UDP_BUF->srcport  = uip_udp_conn->lport;
01527   UIP_UDP_BUF->destport = uip_udp_conn->rport;
01528 
01529   uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_udp_conn->ripaddr);
01530   uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
01531 
01532   uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
01533 
01534 #if UIP_UDP_CHECKSUMS
01535   /* Calculate UDP checksum. */
01536   UIP_UDP_BUF->udpchksum = ~(uip_udpchksum());
01537   if(UIP_UDP_BUF->udpchksum == 0) {
01538     UIP_UDP_BUF->udpchksum = 0xffff;
01539   }
01540 #endif /* UIP_UDP_CHECKSUMS */
01541   UIP_STAT(++uip_stat.udp.sent);
01542   goto ip_send_nolen;
01543 #endif /* UIP_UDP */
01544 
01545 #if UIP_TCP
01546   /* TCP input processing. */
01547  tcp_input:
01548 
01549   remove_ext_hdr();
01550 
01551   UIP_STAT(++uip_stat.tcp.recv);
01552   PRINTF("Receiving TCP packet\n");
01553   /* Start of TCP input header processing code. */
01554   
01555   if(uip_tcpchksum() != 0xffff) {   /* Compute and check the TCP
01556                                        checksum. */
01557     UIP_STAT(++uip_stat.tcp.drop);
01558     UIP_STAT(++uip_stat.tcp.chkerr);
01559     PRINTF("tcp: bad checksum 0x%04x 0x%04x\n", UIP_TCP_BUF->tcpchksum,
01560            uip_tcpchksum());
01561     goto drop;
01562   }
01563 
01564   /* Make sure that the TCP port number is not zero. */
01565   if(UIP_TCP_BUF->destport == 0 || UIP_TCP_BUF->srcport == 0) {
01566     PRINTF("tcp: zero port.");
01567     goto drop;
01568   }
01569 
01570   /* Demultiplex this segment. */
01571   /* First check any active connections. */
01572   for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
01573       ++uip_connr) {
01574     if(uip_connr->tcpstateflags != UIP_CLOSED &&
01575        UIP_TCP_BUF->destport == uip_connr->lport &&
01576        UIP_TCP_BUF->srcport == uip_connr->rport &&
01577        uip_ipaddr_cmp(&UIP_IP_BUF->srcipaddr, &uip_connr->ripaddr)) {
01578       goto found;
01579     }
01580   }
01581 
01582   /* If we didn't find and active connection that expected the packet,
01583      either this packet is an old duplicate, or this is a SYN packet
01584      destined for a connection in LISTEN. If the SYN flag isn't set,
01585      it is an old packet and we send a RST. */
01586   if((UIP_TCP_BUF->flags & TCP_CTL) != TCP_SYN) {
01587     goto reset;
01588   }
01589   
01590   tmp16 = UIP_TCP_BUF->destport;
01591   /* Next, check listening connections. */
01592   for(c = 0; c < UIP_LISTENPORTS; ++c) {
01593     if(tmp16 == uip_listenports[c]) {
01594       goto found_listen;
01595     }
01596   }
01597   
01598   /* No matching connection found, so we send a RST packet. */
01599   UIP_STAT(++uip_stat.tcp.synrst);
01600 
01601  reset:
01602   PRINTF("In reset\n");
01603   /* We do not send resets in response to resets. */
01604   if(UIP_TCP_BUF->flags & TCP_RST) {
01605     goto drop;
01606   }
01607 
01608   UIP_STAT(++uip_stat.tcp.rst);
01609   
01610   UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
01611   uip_len = UIP_IPTCPH_LEN;
01612   UIP_TCP_BUF->tcpoffset = 5 << 4;
01613 
01614   /* Flip the seqno and ackno fields in the TCP header. */
01615   c = UIP_TCP_BUF->seqno[3];
01616   UIP_TCP_BUF->seqno[3] = UIP_TCP_BUF->ackno[3];
01617   UIP_TCP_BUF->ackno[3] = c;
01618   
01619   c = UIP_TCP_BUF->seqno[2];
01620   UIP_TCP_BUF->seqno[2] = UIP_TCP_BUF->ackno[2];
01621   UIP_TCP_BUF->ackno[2] = c;
01622   
01623   c = UIP_TCP_BUF->seqno[1];
01624   UIP_TCP_BUF->seqno[1] = UIP_TCP_BUF->ackno[1];
01625   UIP_TCP_BUF->ackno[1] = c;
01626   
01627   c = UIP_TCP_BUF->seqno[0];
01628   UIP_TCP_BUF->seqno[0] = UIP_TCP_BUF->ackno[0];
01629   UIP_TCP_BUF->ackno[0] = c;
01630 
01631   /* We also have to increase the sequence number we are
01632      acknowledging. If the least significant byte overflowed, we need
01633      to propagate the carry to the other bytes as well. */
01634   if(++UIP_TCP_BUF->ackno[3] == 0) {
01635     if(++UIP_TCP_BUF->ackno[2] == 0) {
01636       if(++UIP_TCP_BUF->ackno[1] == 0) {
01637         ++UIP_TCP_BUF->ackno[0];
01638       }
01639     }
01640   }
01641  
01642   /* Swap port numbers. */
01643   tmp16 = UIP_TCP_BUF->srcport;
01644   UIP_TCP_BUF->srcport = UIP_TCP_BUF->destport;
01645   UIP_TCP_BUF->destport = tmp16;
01646   
01647   /* Swap IP addresses. */
01648   uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr);
01649   uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
01650   /* And send out the RST packet! */
01651   goto tcp_send_noconn;
01652 
01653   /* This label will be jumped to if we matched the incoming packet
01654      with a connection in LISTEN. In that case, we should create a new
01655      connection and send a SYNACK in return. */
01656  found_listen:
01657   PRINTF("In found listen\n");
01658   /* First we check if there are any connections avaliable. Unused
01659      connections are kept in the same table as used connections, but
01660      unused ones have the tcpstate set to CLOSED. Also, connections in
01661      TIME_WAIT are kept track of and we'll use the oldest one if no
01662      CLOSED connections are found. Thanks to Eddie C. Dost for a very
01663      nice algorithm for the TIME_WAIT search. */
01664   uip_connr = 0;
01665   for(c = 0; c < UIP_CONNS; ++c) {
01666     if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
01667       uip_connr = &uip_conns[c];
01668       break;
01669     }
01670     if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
01671       if(uip_connr == 0 ||
01672          uip_conns[c].timer > uip_connr->timer) {
01673         uip_connr = &uip_conns[c];
01674       }
01675     }
01676   }
01677 
01678   if(uip_connr == 0) {
01679     /* All connections are used already, we drop packet and hope that
01680        the remote end will retransmit the packet at a time when we
01681        have more spare connections. */
01682     UIP_STAT(++uip_stat.tcp.syndrop);
01683     UIP_LOG("tcp: found no unused connections.");
01684     goto drop;
01685   }
01686   uip_conn = uip_connr;
01687   
01688   /* Fill in the necessary fields for the new connection. */
01689   uip_connr->rto = uip_connr->timer = UIP_RTO;
01690   uip_connr->sa = 0;
01691   uip_connr->sv = 4;
01692   uip_connr->nrtx = 0;
01693   uip_connr->lport = UIP_TCP_BUF->destport;
01694   uip_connr->rport = UIP_TCP_BUF->srcport;
01695   uip_ipaddr_copy(&uip_connr->ripaddr, &UIP_IP_BUF->srcipaddr);
01696   uip_connr->tcpstateflags = UIP_SYN_RCVD;
01697 
01698   uip_connr->snd_nxt[0] = iss[0];
01699   uip_connr->snd_nxt[1] = iss[1];
01700   uip_connr->snd_nxt[2] = iss[2];
01701   uip_connr->snd_nxt[3] = iss[3];
01702   uip_connr->len = 1;
01703 
01704   /* rcv_nxt should be the seqno from the incoming packet + 1. */
01705   uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
01706   uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
01707   uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
01708   uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
01709   uip_add_rcv_nxt(1);
01710 
01711   /* Parse the TCP MSS option, if present. */
01712   if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) {
01713     for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
01714       opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
01715       if(opt == TCP_OPT_END) {
01716         /* End of options. */
01717         break;
01718       } else if(opt == TCP_OPT_NOOP) {
01719         ++c;
01720         /* NOP option. */
01721       } else if(opt == TCP_OPT_MSS &&
01722                 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
01723         /* An MSS option with the right option length. */
01724         tmp16 = ((uint16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
01725           (uint16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
01726         uip_connr->initialmss = uip_connr->mss =
01727           tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
01728    
01729         /* And we are done processing options. */
01730         break;
01731       } else {
01732         /* All other options have a length field, so that we easily
01733            can skip past them. */
01734         if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
01735           /* If the length field is zero, the options are malformed
01736              and we don't process them further. */
01737           break;
01738         }
01739         c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
01740       }
01741     }
01742   }
01743   
01744   /* Our response will be a SYNACK. */
01745 #if UIP_ACTIVE_OPEN
01746  tcp_send_synack:
01747   UIP_TCP_BUF->flags = TCP_ACK;
01748   
01749  tcp_send_syn:
01750   UIP_TCP_BUF->flags |= TCP_SYN;
01751 #else /* UIP_ACTIVE_OPEN */
01752  tcp_send_synack:
01753   UIP_TCP_BUF->flags = TCP_SYN | TCP_ACK;
01754 #endif /* UIP_ACTIVE_OPEN */
01755   
01756   /* We send out the TCP Maximum Segment Size option with our
01757      SYNACK. */
01758   UIP_TCP_BUF->optdata[0] = TCP_OPT_MSS;
01759   UIP_TCP_BUF->optdata[1] = TCP_OPT_MSS_LEN;
01760   UIP_TCP_BUF->optdata[2] = (UIP_TCP_MSS) / 256;
01761   UIP_TCP_BUF->optdata[3] = (UIP_TCP_MSS) & 255;
01762   uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
01763   UIP_TCP_BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
01764   goto tcp_send;
01765 
01766   /* This label will be jumped to if we found an active connection. */
01767  found:
01768   PRINTF("In found\n");
01769   uip_conn = uip_connr;
01770   uip_flags = 0;
01771   /* We do a very naive form of TCP reset processing; we just accept
01772      any RST and kill our connection. We should in fact check if the
01773      sequence number of this reset is wihtin our advertised window
01774      before we accept the reset. */
01775   if(UIP_TCP_BUF->flags & TCP_RST) {
01776     uip_connr->tcpstateflags = UIP_CLOSED;
01777     UIP_LOG("tcp: got reset, aborting connection.");
01778     uip_flags = UIP_ABORT;
01779     UIP_APPCALL();
01780     goto drop;
01781   }
01782   /* Calculate the length of the data, if the application has sent
01783      any data to us. */
01784   c = (UIP_TCP_BUF->tcpoffset >> 4) << 2;
01785   /* uip_len will contain the length of the actual TCP data. This is
01786      calculated by subtracing the length of the TCP header (in
01787      c) and the length of the IP header (20 bytes). */
01788   uip_len = uip_len - c - UIP_IPH_LEN;
01789 
01790   /* First, check if the sequence number of the incoming packet is
01791      what we're expecting next. If not, we send out an ACK with the
01792      correct numbers in, unless we are in the SYN_RCVD state and
01793      receive a SYN, in which case we should retransmit our SYNACK
01794      (which is done futher down). */
01795   if(!((((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
01796         ((UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
01797        (((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) &&
01798         ((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN)))) {
01799     if((uip_len > 0 || ((UIP_TCP_BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
01800        (UIP_TCP_BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
01801         UIP_TCP_BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
01802         UIP_TCP_BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
01803         UIP_TCP_BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
01804 
01805       if(UIP_TCP_BUF->flags & TCP_SYN) {
01806         goto tcp_send_synack;
01807       }
01808       goto tcp_send_ack;
01809     }
01810   }
01811 
01812   /* Next, check if the incoming segment acknowledges any outstanding
01813      data. If so, we update the sequence number, reset the length of
01814      the outstanding data, calculate RTT estimations, and reset the
01815      retransmission timer. */
01816   if((UIP_TCP_BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
01817     uip_add32(uip_connr->snd_nxt, uip_connr->len);
01818 
01819     if(UIP_TCP_BUF->ackno[0] == uip_acc32[0] &&
01820        UIP_TCP_BUF->ackno[1] == uip_acc32[1] &&
01821        UIP_TCP_BUF->ackno[2] == uip_acc32[2] &&
01822        UIP_TCP_BUF->ackno[3] == uip_acc32[3]) {
01823       /* Update sequence number. */
01824       uip_connr->snd_nxt[0] = uip_acc32[0];
01825       uip_connr->snd_nxt[1] = uip_acc32[1];
01826       uip_connr->snd_nxt[2] = uip_acc32[2];
01827       uip_connr->snd_nxt[3] = uip_acc32[3];
01828    
01829       /* Do RTT estimation, unless we have done retransmissions. */
01830       if(uip_connr->nrtx == 0) {
01831         signed char m;
01832         m = uip_connr->rto - uip_connr->timer;
01833         /* This is taken directly from VJs original code in his paper */
01834         m = m - (uip_connr->sa >> 3);
01835         uip_connr->sa += m;
01836         if(m < 0) {
01837           m = -m;
01838         }
01839         m = m - (uip_connr->sv >> 2);
01840         uip_connr->sv += m;
01841         uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
01842 
01843       }
01844       /* Set the acknowledged flag. */
01845       uip_flags = UIP_ACKDATA;
01846       /* Reset the retransmission timer. */
01847       uip_connr->timer = uip_connr->rto;
01848 
01849       /* Reset length of outstanding data. */
01850       uip_connr->len = 0;
01851     }
01852     
01853   }
01854 
01855   /* Do different things depending on in what state the connection is. */
01856   switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
01857     /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
01858        implemented, since we force the application to close when the
01859        peer sends a FIN (hence the application goes directly from
01860        ESTABLISHED to LAST_ACK). */
01861     case UIP_SYN_RCVD:
01862       /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
01863          we are waiting for an ACK that acknowledges the data we sent
01864          out the last time. Therefore, we want to have the UIP_ACKDATA
01865          flag set. If so, we enter the ESTABLISHED state. */
01866       if(uip_flags & UIP_ACKDATA) {
01867         uip_connr->tcpstateflags = UIP_ESTABLISHED;
01868         uip_flags = UIP_CONNECTED;
01869         uip_connr->len = 0;
01870         if(uip_len > 0) {
01871           uip_flags |= UIP_NEWDATA;
01872           uip_add_rcv_nxt(uip_len);
01873         }
01874         uip_slen = 0;
01875         UIP_APPCALL();
01876         goto appsend;
01877       }
01878       /* We need to retransmit the SYNACK */
01879       if((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN) {
01880         goto tcp_send_synack;
01881       }
01882       goto drop;
01883 #if UIP_ACTIVE_OPEN
01884     case UIP_SYN_SENT:
01885       /* In SYN_SENT, we wait for a SYNACK that is sent in response to
01886          our SYN. The rcv_nxt is set to sequence number in the SYNACK
01887          plus one, and we send an ACK. We move into the ESTABLISHED
01888          state. */
01889       if((uip_flags & UIP_ACKDATA) &&
01890          (UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
01891 
01892         /* Parse the TCP MSS option, if present. */
01893         if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) {
01894           for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
01895             opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
01896             if(opt == TCP_OPT_END) {
01897               /* End of options. */
01898               break;
01899             } else if(opt == TCP_OPT_NOOP) {
01900               ++c;
01901               /* NOP option. */
01902             } else if(opt == TCP_OPT_MSS &&
01903                       uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
01904               /* An MSS option with the right option length. */
01905               tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
01906                 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
01907               uip_connr->initialmss =
01908                 uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
01909 
01910               /* And we are done processing options. */
01911               break;
01912             } else {
01913               /* All other options have a length field, so that we easily
01914                  can skip past them. */
01915               if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
01916                 /* If the length field is zero, the options are malformed
01917                    and we don't process them further. */
01918                 break;
01919               }
01920               c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
01921             }
01922           }
01923         }
01924         uip_connr->tcpstateflags = UIP_ESTABLISHED;
01925         uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
01926         uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
01927         uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
01928         uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
01929         uip_add_rcv_nxt(1);
01930         uip_flags = UIP_CONNECTED | UIP_NEWDATA;
01931         uip_connr->len = 0;
01932         uip_len = 0;
01933         uip_slen = 0;
01934         UIP_APPCALL();
01935         goto appsend;
01936       }
01937       /* Inform the application that the connection failed */
01938       uip_flags = UIP_ABORT;
01939       UIP_APPCALL();
01940       /* The connection is closed after we send the RST */
01941       uip_conn->tcpstateflags = UIP_CLOSED;
01942       goto reset;
01943 #endif /* UIP_ACTIVE_OPEN */
01944     
01945     case UIP_ESTABLISHED:
01946       /* In the ESTABLISHED state, we call upon the application to feed
01947          data into the uip_buf. If the UIP_ACKDATA flag is set, the
01948          application should put new data into the buffer, otherwise we are
01949          retransmitting an old segment, and the application should put that
01950          data into the buffer.
01951 
01952          If the incoming packet is a FIN, we should close the connection on
01953          this side as well, and we send out a FIN and enter the LAST_ACK
01954          state. We require that there is no outstanding data; otherwise the
01955          sequence numbers will be screwed up. */
01956 
01957       if(UIP_TCP_BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
01958         if(uip_outstanding(uip_connr)) {
01959           goto drop;
01960         }
01961         uip_add_rcv_nxt(1 + uip_len);
01962         uip_flags |= UIP_CLOSE;
01963         if(uip_len > 0) {
01964           uip_flags |= UIP_NEWDATA;
01965         }
01966         UIP_APPCALL();
01967         uip_connr->len = 1;
01968         uip_connr->tcpstateflags = UIP_LAST_ACK;
01969         uip_connr->nrtx = 0;
01970       tcp_send_finack:
01971         UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
01972         goto tcp_send_nodata;
01973       }
01974 
01975       /* Check the URG flag. If this is set, the segment carries urgent
01976          data that we must pass to the application. */
01977       if((UIP_TCP_BUF->flags & TCP_URG) != 0) {
01978 #if UIP_URGDATA > 0
01979         uip_urglen = (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1];
01980         if(uip_urglen > uip_len) {
01981           /* There is more urgent data in the next segment to come. */
01982           uip_urglen = uip_len;
01983         }
01984         uip_add_rcv_nxt(uip_urglen);
01985         uip_len -= uip_urglen;
01986         uip_urgdata = uip_appdata;
01987         uip_appdata += uip_urglen;
01988       } else {
01989         uip_urglen = 0;
01990 #else /* UIP_URGDATA > 0 */
01991         uip_appdata = ((char *)uip_appdata) + ((UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]);
01992         uip_len -= (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1];
01993 #endif /* UIP_URGDATA > 0 */
01994       }
01995 
01996       /* If uip_len > 0 we have TCP data in the packet, and we flag this
01997          by setting the UIP_NEWDATA flag and update the sequence number
01998          we acknowledge. If the application has stopped the dataflow
01999          using uip_stop(), we must not accept any data packets from the
02000          remote host. */
02001       if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
02002         uip_flags |= UIP_NEWDATA;
02003         uip_add_rcv_nxt(uip_len);
02004       }
02005 
02006       /* Check if the available buffer space advertised by the other end
02007          is smaller than the initial MSS for this connection. If so, we
02008          set the current MSS to the window size to ensure that the
02009          application does not send more data than the other end can
02010          handle.
02011 
02012          If the remote host advertises a zero window, we set the MSS to
02013          the initial MSS so that the application will send an entire MSS
02014          of data. This data will not be acknowledged by the receiver,
02015          and the application will retransmit it. This is called the
02016          "persistent timer" and uses the retransmission mechanim.
02017       */
02018       tmp16 = ((uint16_t)UIP_TCP_BUF->wnd[0] << 8) + (uint16_t)UIP_TCP_BUF->wnd[1];
02019       if(tmp16 > uip_connr->initialmss ||
02020          tmp16 == 0) {
02021         tmp16 = uip_connr->initialmss;
02022       }
02023       uip_connr->mss = tmp16;
02024 
02025       /* If this packet constitutes an ACK for outstanding data (flagged
02026          by the UIP_ACKDATA flag, we should call the application since it
02027          might want to send more data. If the incoming packet had data
02028          from the peer (as flagged by the UIP_NEWDATA flag), the
02029          application must also be notified.
02030 
02031          When the application is called, the global variable uip_len
02032          contains the length of the incoming data. The application can
02033          access the incoming data through the global pointer
02034          uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN
02035          bytes into the uip_buf array.
02036 
02037          If the application wishes to send any data, this data should be
02038          put into the uip_appdata and the length of the data should be
02039          put into uip_len. If the application don't have any data to
02040          send, uip_len must be set to 0. */
02041       if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
02042         uip_slen = 0;
02043         UIP_APPCALL();
02044 
02045       appsend:
02046       
02047         if(uip_flags & UIP_ABORT) {
02048           uip_slen = 0;
02049           uip_connr->tcpstateflags = UIP_CLOSED;
02050           UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
02051           goto tcp_send_nodata;
02052         }
02053 
02054         if(uip_flags & UIP_CLOSE) {
02055           uip_slen = 0;
02056           uip_connr->len = 1;
02057           uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
02058           uip_connr->nrtx = 0;
02059           UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
02060           goto tcp_send_nodata;
02061         }
02062 
02063         /* If uip_slen > 0, the application has data to be sent. */
02064         if(uip_slen > 0) {
02065 
02066           /* If the connection has acknowledged data, the contents of
02067              the ->len variable should be discarded. */
02068           if((uip_flags & UIP_ACKDATA) != 0) {
02069             uip_connr->len = 0;
02070           }
02071 
02072           /* If the ->len variable is non-zero the connection has
02073              already data in transit and cannot send anymore right
02074              now. */
02075           if(uip_connr->len == 0) {
02076 
02077             /* The application cannot send more than what is allowed by
02078                the mss (the minumum of the MSS and the available
02079                window). */
02080             if(uip_slen > uip_connr->mss) {
02081               uip_slen = uip_connr->mss;
02082             }
02083 
02084             /* Remember how much data we send out now so that we know
02085                when everything has been acknowledged. */
02086             uip_connr->len = uip_slen;
02087           } else {
02088 
02089             /* If the application already had unacknowledged data, we
02090                make sure that the application does not send (i.e.,
02091                retransmit) out more than it previously sent out. */
02092             uip_slen = uip_connr->len;
02093           }
02094         }
02095         uip_connr->nrtx = 0;
02096       apprexmit:
02097         uip_appdata = uip_sappdata;
02098       
02099         /* If the application has data to be sent, or if the incoming
02100            packet had new data in it, we must send out a packet. */
02101         if(uip_slen > 0 && uip_connr->len > 0) {
02102           /* Add the length of the IP and TCP headers. */
02103           uip_len = uip_connr->len + UIP_TCPIP_HLEN;
02104           /* We always set the ACK flag in response packets. */
02105           UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH;
02106           /* Send the packet. */
02107           goto tcp_send_noopts;
02108         }
02109         /* If there is no data to send, just send out a pure ACK if
02110            there is newdata. */
02111         if(uip_flags & UIP_NEWDATA) {
02112           uip_len = UIP_TCPIP_HLEN;
02113           UIP_TCP_BUF->flags = TCP_ACK;
02114           goto tcp_send_noopts;
02115         }
02116       }
02117       goto drop;
02118     case UIP_LAST_ACK:
02119       /* We can close this connection if the peer has acknowledged our
02120          FIN. This is indicated by the UIP_ACKDATA flag. */
02121       if(uip_flags & UIP_ACKDATA) {
02122         uip_connr->tcpstateflags = UIP_CLOSED;
02123         uip_flags = UIP_CLOSE;
02124         UIP_APPCALL();
02125       }
02126       break;
02127     
02128     case UIP_FIN_WAIT_1:
02129       /* The application has closed the connection, but the remote host
02130          hasn't closed its end yet. Thus we do nothing but wait for a
02131          FIN from the other side. */
02132       if(uip_len > 0) {
02133         uip_add_rcv_nxt(uip_len);
02134       }
02135       if(UIP_TCP_BUF->flags & TCP_FIN) {
02136         if(uip_flags & UIP_ACKDATA) {
02137           uip_connr->tcpstateflags = UIP_TIME_WAIT;
02138           uip_connr->timer = 0;
02139           uip_connr->len = 0;
02140         } else {
02141           uip_connr->tcpstateflags = UIP_CLOSING;
02142         }
02143         uip_add_rcv_nxt(1);
02144         uip_flags = UIP_CLOSE;
02145         UIP_APPCALL();
02146         goto tcp_send_ack;
02147       } else if(uip_flags & UIP_ACKDATA) {
02148         uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
02149         uip_connr->len = 0;
02150         goto drop;
02151       }
02152       if(uip_len > 0) {
02153         goto tcp_send_ack;
02154       }
02155       goto drop;
02156       
02157     case UIP_FIN_WAIT_2:
02158       if(uip_len > 0) {
02159         uip_add_rcv_nxt(uip_len);
02160       }
02161       if(UIP_TCP_BUF->flags & TCP_FIN) {
02162         uip_connr->tcpstateflags = UIP_TIME_WAIT;
02163         uip_connr->timer = 0;
02164         uip_add_rcv_nxt(1);
02165         uip_flags = UIP_CLOSE;
02166         UIP_APPCALL();
02167         goto tcp_send_ack;
02168       }
02169       if(uip_len > 0) {
02170         goto tcp_send_ack;
02171       }
02172       goto drop;
02173 
02174     case UIP_TIME_WAIT:
02175       goto tcp_send_ack;
02176     
02177     case UIP_CLOSING:
02178       if(uip_flags & UIP_ACKDATA) {
02179         uip_connr->tcpstateflags = UIP_TIME_WAIT;
02180         uip_connr->timer = 0;
02181       }
02182   }
02183   goto drop;
02184   
02185   /* We jump here when we are ready to send the packet, and just want
02186      to set the appropriate TCP sequence numbers in the TCP header. */
02187  tcp_send_ack:
02188   UIP_TCP_BUF->flags = TCP_ACK;
02189 
02190  tcp_send_nodata:
02191   uip_len = UIP_IPTCPH_LEN;
02192 
02193  tcp_send_noopts:
02194   UIP_TCP_BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
02195 
02196   /* We're done with the input processing. We are now ready to send a
02197      reply. Our job is to fill in all the fields of the TCP and IP
02198      headers before calculating the checksum and finally send the
02199      packet. */
02200  tcp_send:
02201   PRINTF("In tcp_send\n");
02202    
02203   UIP_TCP_BUF->ackno[0] = uip_connr->rcv_nxt[0];
02204   UIP_TCP_BUF->ackno[1] = uip_connr->rcv_nxt[1];
02205   UIP_TCP_BUF->ackno[2] = uip_connr->rcv_nxt[2];
02206   UIP_TCP_BUF->ackno[3] = uip_connr->rcv_nxt[3];
02207   
02208   UIP_TCP_BUF->seqno[0] = uip_connr->snd_nxt[0];
02209   UIP_TCP_BUF->seqno[1] = uip_connr->snd_nxt[1];
02210   UIP_TCP_BUF->seqno[2] = uip_connr->snd_nxt[2];
02211   UIP_TCP_BUF->seqno[3] = uip_connr->snd_nxt[3];
02212 
02213   UIP_IP_BUF->proto = UIP_PROTO_TCP;
02214   
02215   UIP_TCP_BUF->srcport  = uip_connr->lport;
02216   UIP_TCP_BUF->destport = uip_connr->rport;
02217 
02218 
02219   uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_connr->ripaddr);
02220   uip_ds6_select_src(&UIP_IP_BUF->srcipaddr,&UIP_IP_BUF->destipaddr);
02221   PRINTF("Sending TCP packet to");
02222   PRINT6ADDR(&UIP_IP_BUF->destipaddr);
02223   PRINTF("from");
02224   PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
02225   PRINTF("\n");
02226       
02227   if(uip_connr->tcpstateflags & UIP_STOPPED) {
02228     /* If the connection has issued uip_stop(), we advertise a zero
02229        window so that the remote host will stop sending data. */
02230     UIP_TCP_BUF->wnd[0] = UIP_TCP_BUF->wnd[1] = 0;
02231   } else {
02232     UIP_TCP_BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
02233     UIP_TCP_BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
02234   }
02235 
02236  tcp_send_noconn:
02237   UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit;
02238   UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
02239   UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
02240 
02241   UIP_TCP_BUF->urgp[0] = UIP_TCP_BUF->urgp[1] = 0;
02242   
02243   /* Calculate TCP checksum. */
02244   UIP_TCP_BUF->tcpchksum = 0;
02245   UIP_TCP_BUF->tcpchksum = ~(uip_tcpchksum());
02246   UIP_STAT(++uip_stat.tcp.sent);
02247 
02248 #endif /* UIP_TCP */
02249 #if UIP_UDP
02250  ip_send_nolen:
02251 #endif
02252   UIP_IP_BUF->vtc = 0x60;
02253   UIP_IP_BUF->tcflow = 0x00;
02254   UIP_IP_BUF->flow = 0x00;
02255  send:
02256   PRINTF("Sending packet with length %d (%d)\n", uip_len,
02257          (UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]);
02258   
02259   UIP_STAT(++uip_stat.ip.sent);
02260   /* Return and let the caller do the actual transmission. */
02261   uip_flags = 0;
02262   return;
02263 
02264  drop:
02265   uip_len = 0;
02266   uip_ext_len = 0;
02267   uip_ext_bitmap = 0;
02268   uip_flags = 0;
02269   return;
02270 }
02271 /*---------------------------------------------------------------------------*/
02272 uint16_t
02273 uip_htons(uint16_t val)
02274 {
02275   return UIP_HTONS(val);
02276 }
02277 
02278 uint32_t
02279 uip_htonl(uint32_t val)
02280 {
02281   return UIP_HTONL(val);
02282 }
02283 /*---------------------------------------------------------------------------*/
02284 void
02285 uip_send(const void *data, int len)
02286 {
02287   int copylen;
02288 #define MIN(a,b) ((a) < (b)? (a): (b))
02289   copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN -
02290                 (int)((char *)uip_sappdata - (char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]));
02291   if(copylen > 0) {
02292     uip_slen = copylen;
02293     if(data != uip_sappdata) {
02294       memcpy(uip_sappdata, (data), uip_slen);
02295     }
02296   }
02297 }
02298 /*---------------------------------------------------------------------------*/
02299 /** @} */