- Main Page
- Modules
- Data Structures
- Files
- Examples

- File List
- Globals

# uip/uip.c

Go to the documentation of this file.

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