Fork for fixes

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