mbed OS5

Fork of UIPEthernet by Zoltan Hudak

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers uip.c Source File

uip.c

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