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

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