FreeRTOS
[armadillo_firmware.git] / FreeRTOS / Common / ethernet / uIP / uip-1.0 / uip / uip.c
blobbac2527c16c0b1902ffaa892823bde45872c75ef
1 #define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/
3 /**
4 * \defgroup uip The uIP TCP/IP stack
5 * @{
7 * uIP is an implementation of the TCP/IP protocol stack intended for
8 * small 8-bit and 16-bit microcontrollers.
10 * uIP provides the necessary protocols for Internet communication,
11 * with a very small code footprint and RAM requirements - the uIP
12 * code size is on the order of a few kilobytes and RAM usage is on
13 * the order of a few hundred bytes.
16 /**
17 * \file
18 * The uIP TCP/IP stack code.
19 * \author Adam Dunkels <adam@dunkels.com>
23 * Copyright (c) 2001-2003, Adam Dunkels.
24 * All rights reserved.
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
28 * are met:
29 * 1. Redistributions of source code must retain the above copyright
30 * notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution.
34 * 3. The name of the author may not be used to endorse or promote
35 * products derived from this software without specific prior
36 * written permission.
38 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
39 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
40 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
42 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
44 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
45 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
46 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
47 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 * This file is part of the uIP TCP/IP stack.
52 * $Id: uip.c,v 1.65 2006/06/11 21:46:39 adam Exp $
57 * uIP is a small implementation of the IP, UDP and TCP protocols (as
58 * well as some basic ICMP stuff). The implementation couples the IP,
59 * UDP, TCP and the application layers very tightly. To keep the size
60 * of the compiled code down, this code frequently uses the goto
61 * statement. While it would be possible to break the uip_process()
62 * function into many smaller functions, this would increase the code
63 * size because of the overhead of parameter passing and the fact that
64 * the optimier would not be as efficient.
66 * The principle is that we have a small buffer, called the uip_buf,
67 * in which the device driver puts an incoming packet. The TCP/IP
68 * stack parses the headers in the packet, and calls the
69 * application. If the remote host has sent data to the application,
70 * this data is present in the uip_buf and the application read the
71 * data from there. It is up to the application to put this data into
72 * a byte stream if needed. The application will not be fed with data
73 * that is out of sequence.
75 * If the application whishes to send data to the peer, it should put
76 * its data into the uip_buf. The uip_appdata pointer points to the
77 * first available byte. The TCP/IP stack will calculate the
78 * checksums, and fill in the necessary header fields and finally send
79 * the packet back to the peer.
82 #include "uip.h"
83 #include "uipopt.h"
84 #include "uip_arch.h"
86 #if UIP_CONF_IPV6
87 #include "uip-neighbor.h"
88 #endif /* UIP_CONF_IPV6 */
90 #include <string.h>
92 /*---------------------------------------------------------------------------*/
93 /* Variable definitions. */
96 /* The IP address of this host. If it is defined to be fixed (by
97 setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set
98 here. Otherwise, the address */
99 #if UIP_FIXEDADDR > 0
100 const uip_ipaddr_t uip_hostaddr =
101 {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
102 HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
103 const uip_ipaddr_t uip_draddr =
104 {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
105 HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
106 const uip_ipaddr_t uip_netmask =
107 {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
108 HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
109 #else
110 uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
111 #endif /* UIP_FIXEDADDR */
113 static const uip_ipaddr_t all_ones_addr =
114 #if UIP_CONF_IPV6
115 {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff};
116 #else /* UIP_CONF_IPV6 */
117 {0xffff,0xffff};
118 #endif /* UIP_CONF_IPV6 */
119 static const uip_ipaddr_t all_zeroes_addr =
120 #if UIP_CONF_IPV6
121 {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
122 #else /* UIP_CONF_IPV6 */
123 {0x0000,0x0000};
124 #endif /* UIP_CONF_IPV6 */
126 #if UIP_FIXEDETHADDR
127 const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
128 UIP_ETHADDR1,
129 UIP_ETHADDR2,
130 UIP_ETHADDR3,
131 UIP_ETHADDR4,
132 UIP_ETHADDR5}};
133 #else
134 struct uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}};
135 #endif
137 #ifndef UIP_CONF_EXTERNAL_BUFFER
139 #ifdef __ICCARM__
140 #pragma data_alignment=4
141 u8_t uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains incoming packets. */
142 #else
143 u8_t uip_buf[UIP_BUFSIZE + 2] ALIGN_STRUCT_END; /* The packet buffer that contains incoming packets. */
144 #endif
146 #endif /* UIP_CONF_EXTERNAL_BUFFER */
148 void *uip_appdata; /* The uip_appdata pointer points to
149 application data. */
150 void *uip_sappdata; /* The uip_appdata pointer points to
151 the application data which is to
152 be sent. */
153 #if UIP_URGDATA > 0
154 void *uip_urgdata; /* The uip_urgdata pointer points to
155 urgent data (out-of-band data), if
156 present. */
157 u16_t uip_urglen, uip_surglen;
158 #endif /* UIP_URGDATA > 0 */
160 u16_t uip_len, uip_slen;
161 /* The uip_len is either 8 or 16 bits,
162 depending on the maximum packet
163 size. */
165 u8_t uip_flags; /* The uip_flags variable is used for
166 communication between the TCP/IP stack
167 and the application program. */
168 struct uip_conn *uip_conn; /* uip_conn always points to the current
169 connection. */
171 struct uip_conn uip_conns[UIP_CONNS];
172 /* The uip_conns array holds all TCP
173 connections. */
174 u16_t uip_listenports[UIP_LISTENPORTS];
175 /* The uip_listenports list all currently
176 listning ports. */
177 #if UIP_UDP
178 struct uip_udp_conn *uip_udp_conn;
179 struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
180 #endif /* UIP_UDP */
182 static u16_t ipid; /* Ths ipid variable is an increasing
183 number that is used for the IP ID
184 field. */
186 void uip_setipid(u16_t id) { ipid = id; }
188 static u8_t iss[4]; /* The iss variable is used for the TCP
189 initial sequence number. */
191 #if UIP_ACTIVE_OPEN
192 static u16_t lastport; /* Keeps track of the last port used for
193 a new connection. */
194 #endif /* UIP_ACTIVE_OPEN */
196 /* Temporary variables. */
197 u8_t uip_acc32[4];
198 static u8_t c, opt;
199 static u16_t tmp16;
201 /* Structures and definitions. */
202 #define TCP_FIN 0x01
203 #define TCP_SYN 0x02
204 #define TCP_RST 0x04
205 #define TCP_PSH 0x08
206 #define TCP_ACK 0x10
207 #define TCP_URG 0x20
208 #define TCP_CTL 0x3f
210 #define TCP_OPT_END 0 /* End of TCP options list */
211 #define TCP_OPT_NOOP 1 /* "No-operation" TCP option */
212 #define TCP_OPT_MSS 2 /* Maximum segment size TCP option */
214 #define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */
216 #define ICMP_ECHO_REPLY 0
217 #define ICMP_ECHO 8
219 #define ICMP6_ECHO_REPLY 129
220 #define ICMP6_ECHO 128
221 #define ICMP6_NEIGHBOR_SOLICITATION 135
222 #define ICMP6_NEIGHBOR_ADVERTISEMENT 136
224 #define ICMP6_FLAG_S (1 << 6)
226 #define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1
227 #define ICMP6_OPTION_TARGET_LINK_ADDRESS 2
230 /* Macros. */
231 #define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
232 #define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
233 #define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
234 #define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
237 #if UIP_STATISTICS == 1
238 struct uip_stats uip_stat;
239 #define UIP_STAT(s) s
240 #else
241 #define UIP_STAT(s)
242 #endif /* UIP_STATISTICS == 1 */
244 #if UIP_LOGGING == 1
245 #include <stdio.h>
246 void uip_log(char *msg);
247 #define UIP_LOG(m) uip_log(m)
248 #else
249 #define UIP_LOG(m)
250 #endif /* UIP_LOGGING == 1 */
252 #if ! UIP_ARCH_ADD32
253 void
254 uip_add32(u8_t *op32, u16_t op16)
256 uip_acc32[3] = op32[3] + (op16 & 0xff);
257 uip_acc32[2] = op32[2] + (op16 >> 8);
258 uip_acc32[1] = op32[1];
259 uip_acc32[0] = op32[0];
261 if(uip_acc32[2] < (op16 >> 8)) {
262 ++uip_acc32[1];
263 if(uip_acc32[1] == 0) {
264 ++uip_acc32[0];
269 if(uip_acc32[3] < (op16 & 0xff)) {
270 ++uip_acc32[2];
271 if(uip_acc32[2] == 0) {
272 ++uip_acc32[1];
273 if(uip_acc32[1] == 0) {
274 ++uip_acc32[0];
280 #endif /* UIP_ARCH_ADD32 */
282 #if ! UIP_ARCH_CHKSUM
283 /*---------------------------------------------------------------------------*/
284 static u16_t
285 chksum(u16_t sum, const u8_t *data, u16_t len)
287 u16_t t;
288 const u8_t *dataptr;
289 const u8_t *last_byte;
291 dataptr = data;
292 last_byte = data + len - 1;
294 while(dataptr < last_byte) { /* At least two more bytes */
295 t = (dataptr[0] << 8) + dataptr[1];
296 sum += t;
297 if(sum < t) {
298 sum++; /* carry */
300 dataptr += 2;
303 if(dataptr == last_byte) {
304 t = (dataptr[0] << 8) + 0;
305 sum += t;
306 if(sum < t) {
307 sum++; /* carry */
311 /* Return sum in host byte order. */
312 return sum;
314 /*---------------------------------------------------------------------------*/
315 u16_t
316 uip_chksum(u16_t *data, u16_t len)
318 return htons(chksum(0, (u8_t *)data, len));
320 /*---------------------------------------------------------------------------*/
321 #ifndef UIP_ARCH_IPCHKSUM
322 u16_t
323 uip_ipchksum(void)
325 u16_t sum;
327 sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
328 DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum);
329 return (sum == 0) ? 0xffff : htons(sum);
331 #endif
332 /*---------------------------------------------------------------------------*/
333 static u16_t
334 upper_layer_chksum(u8_t proto)
336 u16_t upper_layer_len;
337 u16_t sum;
339 #if UIP_CONF_IPV6
340 upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]);
341 #else /* UIP_CONF_IPV6 */
342 upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;
343 #endif /* UIP_CONF_IPV6 */
345 /* First sum pseudoheader. */
347 /* IP protocol and length fields. This addition cannot carry. */
348 sum = upper_layer_len + proto;
349 /* Sum IP source and destination addresses. */
350 sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t));
352 /* Sum TCP header and data. */
353 sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN],
354 upper_layer_len);
356 return (sum == 0) ? 0xffff : htons(sum);
358 /*---------------------------------------------------------------------------*/
359 #if UIP_CONF_IPV6
360 u16_t
361 uip_icmp6chksum(void)
363 return upper_layer_chksum(UIP_PROTO_ICMP6);
366 #endif /* UIP_CONF_IPV6 */
367 /*---------------------------------------------------------------------------*/
368 u16_t
369 uip_tcpchksum(void)
371 return upper_layer_chksum(UIP_PROTO_TCP);
373 /*---------------------------------------------------------------------------*/
374 #if UIP_UDP_CHECKSUMS
375 u16_t
376 uip_udpchksum(void)
378 return upper_layer_chksum(UIP_PROTO_UDP);
380 #endif /* UIP_UDP_CHECKSUMS */
381 #endif /* UIP_ARCH_CHKSUM */
382 /*---------------------------------------------------------------------------*/
383 void
384 uip_init(void)
386 for(c = 0; c < UIP_LISTENPORTS; ++c) {
387 uip_listenports[c] = 0;
389 for(c = 0; c < UIP_CONNS; ++c) {
390 uip_conns[c].tcpstateflags = UIP_CLOSED;
392 #if UIP_ACTIVE_OPEN
393 lastport = 1024;
394 #endif /* UIP_ACTIVE_OPEN */
396 #if UIP_UDP
397 for(c = 0; c < UIP_UDP_CONNS; ++c) {
398 uip_udp_conns[c].lport = 0;
400 #endif /* UIP_UDP */
403 /* IPv4 initialization. */
404 #if UIP_FIXEDADDR == 0
405 /* uip_hostaddr[0] = uip_hostaddr[1] = 0;*/
406 #endif /* UIP_FIXEDADDR */
409 /*---------------------------------------------------------------------------*/
410 #if UIP_ACTIVE_OPEN
411 struct uip_conn *
412 uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
414 register struct uip_conn *conn, *cconn;
416 /* Find an unused local port. */
417 again:
418 ++lastport;
420 if(lastport >= 32000) {
421 lastport = 4096;
424 /* Check if this port is already in use, and if so try to find
425 another one. */
426 for(c = 0; c < UIP_CONNS; ++c) {
427 conn = &uip_conns[c];
428 if(conn->tcpstateflags != UIP_CLOSED &&
429 conn->lport == htons(lastport)) {
430 goto again;
434 conn = 0;
435 for(c = 0; c < UIP_CONNS; ++c) {
436 cconn = &uip_conns[c];
437 if(cconn->tcpstateflags == UIP_CLOSED) {
438 conn = cconn;
439 break;
441 if(cconn->tcpstateflags == UIP_TIME_WAIT) {
442 if(conn == 0 ||
443 cconn->timer > conn->timer) {
444 conn = cconn;
449 if(conn == 0) {
450 return 0;
453 conn->tcpstateflags = UIP_SYN_SENT;
455 conn->snd_nxt[0] = iss[0];
456 conn->snd_nxt[1] = iss[1];
457 conn->snd_nxt[2] = iss[2];
458 conn->snd_nxt[3] = iss[3];
460 conn->initialmss = conn->mss = UIP_TCP_MSS;
462 conn->len = 1; /* TCP length of the SYN is one. */
463 conn->nrtx = 0;
464 conn->timer = 1; /* Send the SYN next time around. */
465 conn->rto = UIP_RTO;
466 conn->sa = 0;
467 conn->sv = 16; /* Initial value of the RTT variance. */
468 conn->lport = htons(lastport);
469 conn->rport = rport;
470 uip_ipaddr_copy(&conn->ripaddr, ripaddr);
472 return conn;
474 #endif /* UIP_ACTIVE_OPEN */
475 /*---------------------------------------------------------------------------*/
476 #if UIP_UDP
477 struct uip_udp_conn *
478 uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport)
480 register struct uip_udp_conn *conn;
482 /* Find an unused local port. */
483 again:
484 ++lastport;
486 if(lastport >= 32000) {
487 lastport = 4096;
490 for(c = 0; c < UIP_UDP_CONNS; ++c) {
491 if(uip_udp_conns[c].lport == htons(lastport)) {
492 goto again;
497 conn = 0;
498 for(c = 0; c < UIP_UDP_CONNS; ++c) {
499 if(uip_udp_conns[c].lport == 0) {
500 conn = &uip_udp_conns[c];
501 break;
505 if(conn == 0) {
506 return 0;
509 conn->lport = HTONS(lastport);
510 conn->rport = rport;
511 if(ripaddr == NULL) {
512 memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t));
513 } else {
514 uip_ipaddr_copy(&conn->ripaddr, ripaddr);
516 conn->ttl = UIP_TTL;
518 return conn;
520 #endif /* UIP_UDP */
521 /*---------------------------------------------------------------------------*/
522 void
523 uip_unlisten(u16_t port)
525 for(c = 0; c < UIP_LISTENPORTS; ++c) {
526 if(uip_listenports[c] == port) {
527 uip_listenports[c] = 0;
528 return;
532 /*---------------------------------------------------------------------------*/
533 void
534 uip_listen(u16_t port)
536 for(c = 0; c < UIP_LISTENPORTS; ++c) {
537 if(uip_listenports[c] == 0) {
538 uip_listenports[c] = port;
539 return;
543 /*---------------------------------------------------------------------------*/
544 /* XXX: IP fragment reassembly: not well-tested. */
546 #if UIP_REASSEMBLY && !UIP_CONF_IPV6
547 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
548 static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
549 static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
550 static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
551 0x0f, 0x07, 0x03, 0x01};
552 static u16_t uip_reasslen;
553 static u8_t uip_reassflags;
554 #define UIP_REASS_FLAG_LASTFRAG 0x01
555 static u8_t uip_reasstmr;
557 #define IP_MF 0x20
559 static u8_t
560 uip_reass(void)
562 u16_t offset, len;
563 u16_t i;
565 /* If ip_reasstmr is zero, no packet is present in the buffer, so we
566 write the IP header of the fragment into the reassembly
567 buffer. The timer is updated with the maximum age. */
568 if(uip_reasstmr == 0) {
569 memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN);
570 uip_reasstmr = UIP_REASS_MAXAGE;
571 uip_reassflags = 0;
572 /* Clear the bitmap. */
573 memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap));
576 /* Check if the incoming fragment matches the one currently present
577 in the reasembly buffer. If so, we proceed with copying the
578 fragment into the buffer. */
579 if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
580 BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
581 BUF->destipaddr[0] == FBUF->destipaddr[0] &&
582 BUF->destipaddr[1] == FBUF->destipaddr[1] &&
583 BUF->ipid[0] == FBUF->ipid[0] &&
584 BUF->ipid[1] == FBUF->ipid[1]) {
586 len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
587 offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
589 /* If the offset or the offset + fragment length overflows the
590 reassembly buffer, we discard the entire packet. */
591 if(offset > UIP_REASS_BUFSIZE ||
592 offset + len > UIP_REASS_BUFSIZE) {
593 uip_reasstmr = 0;
594 goto nullreturn;
597 /* Copy the fragment into the reassembly buffer, at the right
598 offset. */
599 memcpy(&uip_reassbuf[UIP_IPH_LEN + offset],
600 (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
601 len);
603 /* Update the bitmap. */
604 if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
605 /* If the two endpoints are in the same byte, we only update
606 that byte. */
608 uip_reassbitmap[offset / (8 * 8)] |=
609 bitmap_bits[(offset / 8 ) & 7] &
610 ~bitmap_bits[((offset + len) / 8 ) & 7];
611 } else {
612 /* If the two endpoints are in different bytes, we update the
613 bytes in the endpoints and fill the stuff inbetween with
614 0xff. */
615 uip_reassbitmap[offset / (8 * 8)] |=
616 bitmap_bits[(offset / 8 ) & 7];
617 for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
618 uip_reassbitmap[i] = 0xff;
620 uip_reassbitmap[(offset + len) / (8 * 8)] |=
621 ~bitmap_bits[((offset + len) / 8 ) & 7];
624 /* If this fragment has the More Fragments flag set to zero, we
625 know that this is the last fragment, so we can calculate the
626 size of the entire packet. We also set the
627 IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
628 the final fragment. */
630 if((BUF->ipoffset[0] & IP_MF) == 0) {
631 uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
632 uip_reasslen = offset + len;
635 /* Finally, we check if we have a full packet in the buffer. We do
636 this by checking if we have the last fragment and if all bits
637 in the bitmap are set. */
638 if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
639 /* Check all bytes up to and including all but the last byte in
640 the bitmap. */
641 for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
642 if(uip_reassbitmap[i] != 0xff) {
643 goto nullreturn;
646 /* Check the last byte in the bitmap. It should contain just the
647 right amount of bits. */
648 if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
649 (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
650 goto nullreturn;
653 /* If we have come this far, we have a full packet in the
654 buffer, so we allocate a pbuf and copy the packet into it. We
655 also reset the timer. */
656 uip_reasstmr = 0;
657 memcpy(BUF, FBUF, uip_reasslen);
659 /* Pretend to be a "normal" (i.e., not fragmented) IP packet
660 from now on. */
661 BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
662 BUF->len[0] = uip_reasslen >> 8;
663 BUF->len[1] = uip_reasslen & 0xff;
664 BUF->ipchksum = 0;
665 BUF->ipchksum = ~(uip_ipchksum());
667 return uip_reasslen;
671 nullreturn:
672 return 0;
674 #endif /* UIP_REASSEMBLY */
675 /*---------------------------------------------------------------------------*/
676 static void
677 uip_add_rcv_nxt(u16_t n)
679 uip_add32(uip_conn->rcv_nxt, n);
680 uip_conn->rcv_nxt[0] = uip_acc32[0];
681 uip_conn->rcv_nxt[1] = uip_acc32[1];
682 uip_conn->rcv_nxt[2] = uip_acc32[2];
683 uip_conn->rcv_nxt[3] = uip_acc32[3];
685 /*---------------------------------------------------------------------------*/
686 void
687 uip_process(u8_t flag)
689 register struct uip_conn *uip_connr = uip_conn;
691 ( void ) all_ones_addr;
693 #if UIP_UDP
694 if(flag == UIP_UDP_SEND_CONN) {
695 goto udp_send;
697 #endif /* UIP_UDP */
699 uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
701 /* Check if we were invoked because of a poll request for a
702 particular connection. */
703 if(flag == UIP_POLL_REQUEST) {
704 if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
705 !uip_outstanding(uip_connr)) {
706 uip_flags = UIP_POLL;
707 UIP_APPCALL();
708 goto appsend;
710 goto drop;
712 /* Check if we were invoked because of the perodic timer fireing. */
713 } else if(flag == UIP_TIMER) {
714 #if UIP_REASSEMBLY
715 if(uip_reasstmr != 0) {
716 --uip_reasstmr;
718 #endif /* UIP_REASSEMBLY */
719 /* Increase the initial sequence number. */
720 if(++iss[3] == 0) {
721 if(++iss[2] == 0) {
722 if(++iss[1] == 0) {
723 ++iss[0];
728 /* Reset the length variables. */
729 uip_len = 0;
730 uip_slen = 0;
732 /* Check if the connection is in a state in which we simply wait
733 for the connection to time out. If so, we increase the
734 connection's timer and remove the connection if it times
735 out. */
736 if(uip_connr->tcpstateflags == UIP_TIME_WAIT ||
737 uip_connr->tcpstateflags == UIP_FIN_WAIT_2) {
738 ++(uip_connr->timer);
739 if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
740 uip_connr->tcpstateflags = UIP_CLOSED;
742 } else if(uip_connr->tcpstateflags != UIP_CLOSED) {
743 /* If the connection has outstanding data, we increase the
744 connection's timer and see if it has reached the RTO value
745 in which case we retransmit. */
746 if(uip_outstanding(uip_connr)) {
747 uip_connr->timer = uip_connr->timer - 1;
748 if(uip_connr->timer == 0) {
749 if(uip_connr->nrtx == UIP_MAXRTX ||
750 ((uip_connr->tcpstateflags == UIP_SYN_SENT ||
751 uip_connr->tcpstateflags == UIP_SYN_RCVD) &&
752 uip_connr->nrtx == UIP_MAXSYNRTX)) {
753 uip_connr->tcpstateflags = UIP_CLOSED;
755 /* We call UIP_APPCALL() with uip_flags set to
756 UIP_TIMEDOUT to inform the application that the
757 connection has timed out. */
758 uip_flags = UIP_TIMEDOUT;
759 UIP_APPCALL();
761 /* We also send a reset packet to the remote host. */
762 BUF->flags = TCP_RST | TCP_ACK;
763 goto tcp_send_nodata;
766 /* Exponential backoff. */
767 uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
769 uip_connr->nrtx);
770 ++(uip_connr->nrtx);
772 /* Ok, so we need to retransmit. We do this differently
773 depending on which state we are in. In ESTABLISHED, we
774 call upon the application so that it may prepare the
775 data for the retransmit. In SYN_RCVD, we resend the
776 SYNACK that we sent earlier and in LAST_ACK we have to
777 retransmit our FINACK. */
778 UIP_STAT(++uip_stat.tcp.rexmit);
779 switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
780 case UIP_SYN_RCVD:
781 /* In the SYN_RCVD state, we should retransmit our
782 SYNACK. */
783 goto tcp_send_synack;
785 #if UIP_ACTIVE_OPEN
786 case UIP_SYN_SENT:
787 /* In the SYN_SENT state, we retransmit out SYN. */
788 BUF->flags = 0;
789 goto tcp_send_syn;
790 #endif /* UIP_ACTIVE_OPEN */
792 case UIP_ESTABLISHED:
793 /* In the ESTABLISHED state, we call upon the application
794 to do the actual retransmit after which we jump into
795 the code for sending out the packet (the apprexmit
796 label). */
797 uip_flags = UIP_REXMIT;
798 UIP_APPCALL();
799 goto apprexmit;
801 case UIP_FIN_WAIT_1:
802 case UIP_CLOSING:
803 case UIP_LAST_ACK:
804 /* In all these states we should retransmit a FINACK. */
805 goto tcp_send_finack;
809 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
810 /* If there was no need for a retransmission, we poll the
811 application for new data. */
812 uip_flags = UIP_POLL;
813 UIP_APPCALL();
814 goto appsend;
817 goto drop;
819 #if UIP_UDP
820 if(flag == UIP_UDP_TIMER) {
821 if(uip_udp_conn->lport != 0) {
822 uip_conn = NULL;
823 uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
824 uip_len = uip_slen = 0;
825 uip_flags = UIP_POLL;
826 UIP_UDP_APPCALL();
827 goto udp_send;
828 } else {
829 goto drop;
832 #endif
834 /* This is where the input processing starts. */
835 UIP_STAT(++uip_stat.ip.recv);
837 /* Start of IP input header processing code. */
839 #if UIP_CONF_IPV6
840 /* Check validity of the IP header. */
841 if((BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */
842 UIP_STAT(++uip_stat.ip.drop);
843 UIP_STAT(++uip_stat.ip.vhlerr);
844 UIP_LOG("ipv6: invalid version.");
845 goto drop;
847 #else /* UIP_CONF_IPV6 */
848 /* Check validity of the IP header. */
849 if(BUF->vhl != 0x45) { /* IP version and header length. */
850 UIP_STAT(++uip_stat.ip.drop);
851 UIP_STAT(++uip_stat.ip.vhlerr);
852 UIP_LOG("ip: invalid version or header length.");
853 goto drop;
855 #endif /* UIP_CONF_IPV6 */
857 /* Check the size of the packet. If the size reported to us in
858 uip_len is smaller the size reported in the IP header, we assume
859 that the packet has been corrupted in transit. If the size of
860 uip_len is larger than the size reported in the IP packet header,
861 the packet has been padded and we set uip_len to the correct
862 value.. */
864 if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) {
865 uip_len = (BUF->len[0] << 8) + BUF->len[1];
866 #if UIP_CONF_IPV6
867 uip_len += 40; /* The length reported in the IPv6 header is the
868 length of the payload that follows the
869 header. However, uIP uses the uip_len variable
870 for holding the size of the entire packet,
871 including the IP header. For IPv4 this is not a
872 problem as the length field in the IPv4 header
873 contains the length of the entire packet. But
874 for IPv6 we need to add the size of the IPv6
875 header (40 bytes). */
876 #endif /* UIP_CONF_IPV6 */
877 } else {
878 UIP_LOG("ip: packet shorter than reported in IP header.");
879 goto drop;
882 #if !UIP_CONF_IPV6
883 /* Check the fragment flag. */
884 if((BUF->ipoffset[0] & 0x3f) != 0 ||
885 BUF->ipoffset[1] != 0) {
886 #if UIP_REASSEMBLY
887 uip_len = uip_reass();
888 if(uip_len == 0) {
889 goto drop;
891 #else /* UIP_REASSEMBLY */
892 UIP_STAT(++uip_stat.ip.drop);
893 UIP_STAT(++uip_stat.ip.fragerr);
894 UIP_LOG("ip: fragment dropped.");
895 goto drop;
896 #endif /* UIP_REASSEMBLY */
898 #endif /* UIP_CONF_IPV6 */
900 if(uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) {
901 /* If we are configured to use ping IP address configuration and
902 hasn't been assigned an IP address yet, we accept all ICMP
903 packets. */
904 #if UIP_PINGADDRCONF && !UIP_CONF_IPV6
905 if(BUF->proto == UIP_PROTO_ICMP) {
906 UIP_LOG("ip: possible ping config packet received.");
907 goto icmp_input;
908 } else {
909 UIP_LOG("ip: packet dropped since no address assigned.");
910 goto drop;
912 #endif /* UIP_PINGADDRCONF */
914 } else {
915 /* If IP broadcast support is configured, we check for a broadcast
916 UDP packet, which may be destined to us. */
917 #if UIP_BROADCAST
918 DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum());
919 if(BUF->proto == UIP_PROTO_UDP &&
920 uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr)
921 /*&&
922 uip_ipchksum() == 0xffff*/) {
923 goto udp_input;
925 #endif /* UIP_BROADCAST */
927 /* Check if the packet is destined for our IP address. */
928 #if !UIP_CONF_IPV6
929 if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr)) {
930 UIP_STAT(++uip_stat.ip.drop);
931 goto drop;
933 #else /* UIP_CONF_IPV6 */
934 /* For IPv6, packet reception is a little trickier as we need to
935 make sure that we listen to certain multicast addresses (all
936 hosts multicast address, and the solicited-node multicast
937 address) as well. However, we will cheat here and accept all
938 multicast packets that are sent to the ff02::/16 addresses. */
939 if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) &&
940 BUF->destipaddr[0] != HTONS(0xff02)) {
941 UIP_STAT(++uip_stat.ip.drop);
942 goto drop;
944 #endif /* UIP_CONF_IPV6 */
947 #if !UIP_CONF_IPV6
948 if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
949 checksum. */
950 UIP_STAT(++uip_stat.ip.drop);
951 UIP_STAT(++uip_stat.ip.chkerr);
952 UIP_LOG("ip: bad checksum.");
953 goto drop;
955 #endif /* UIP_CONF_IPV6 */
957 if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so,
958 proceed with TCP input
959 processing. */
960 goto tcp_input;
963 #if UIP_UDP
964 if(BUF->proto == UIP_PROTO_UDP) {
965 goto udp_input;
967 #endif /* UIP_UDP */
969 #if !UIP_CONF_IPV6
970 /* ICMPv4 processing code follows. */
971 if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
972 here. */
973 UIP_STAT(++uip_stat.ip.drop);
974 UIP_STAT(++uip_stat.ip.protoerr);
975 UIP_LOG("ip: neither tcp nor icmp.");
976 goto drop;
979 #if UIP_PINGADDRCONF
980 icmp_input:
981 #endif /* UIP_PINGADDRCONF */
982 UIP_STAT(++uip_stat.icmp.recv);
984 /* ICMP echo (i.e., ping) processing. This is simple, we only change
985 the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
986 checksum before we return the packet. */
987 if(ICMPBUF->type != ICMP_ECHO) {
988 UIP_STAT(++uip_stat.icmp.drop);
989 UIP_STAT(++uip_stat.icmp.typeerr);
990 UIP_LOG("icmp: not icmp echo.");
991 goto drop;
994 /* If we are configured to use ping IP address assignment, we use
995 the destination IP address of this ping packet and assign it to
996 ourself. */
997 #if UIP_PINGADDRCONF
998 if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
999 uip_hostaddr[0] = BUF->destipaddr[0];
1000 uip_hostaddr[1] = BUF->destipaddr[1];
1002 #endif /* UIP_PINGADDRCONF */
1004 ICMPBUF->type = ICMP_ECHO_REPLY;
1006 if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
1007 ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
1008 } else {
1009 ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
1012 /* Swap IP addresses. */
1013 uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
1014 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
1016 UIP_STAT(++uip_stat.icmp.sent);
1017 goto send;
1019 /* End of IPv4 input header processing code. */
1020 #else /* !UIP_CONF_IPV6 */
1022 /* This is IPv6 ICMPv6 processing code. */
1023 DEBUG_PRINTF("icmp6_input: length %d\n", uip_len);
1025 if(BUF->proto != UIP_PROTO_ICMP6) { /* We only allow ICMPv6 packets from
1026 here. */
1027 UIP_STAT(++uip_stat.ip.drop);
1028 UIP_STAT(++uip_stat.ip.protoerr);
1029 UIP_LOG("ip: neither tcp nor icmp6.");
1030 goto drop;
1033 UIP_STAT(++uip_stat.icmp.recv);
1035 /* If we get a neighbor solicitation for our address we should send
1036 a neighbor advertisement message back. */
1037 if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) {
1038 if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) {
1040 if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) {
1041 /* Save the sender's address in our neighbor list. */
1042 uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2]));
1045 /* We should now send a neighbor advertisement back to where the
1046 neighbor solicication came from. */
1047 ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
1048 ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */
1050 ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;
1052 uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr);
1053 uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr);
1054 ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS;
1055 ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */
1056 memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr));
1057 ICMPBUF->icmpchksum = 0;
1058 ICMPBUF->icmpchksum = ~uip_icmp6chksum();
1059 goto send;
1062 goto drop;
1063 } else if(ICMPBUF->type == ICMP6_ECHO) {
1064 /* ICMP echo (i.e., ping) processing. This is simple, we only
1065 change the ICMP type from ECHO to ECHO_REPLY and update the
1066 ICMP checksum before we return the packet. */
1068 ICMPBUF->type = ICMP6_ECHO_REPLY;
1070 uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
1071 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
1072 ICMPBUF->icmpchksum = 0;
1073 ICMPBUF->icmpchksum = ~uip_icmp6chksum();
1075 UIP_STAT(++uip_stat.icmp.sent);
1076 goto send;
1077 } else {
1078 DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type);
1079 UIP_STAT(++uip_stat.icmp.drop);
1080 UIP_STAT(++uip_stat.icmp.typeerr);
1081 UIP_LOG("icmp: unknown ICMP message.");
1082 goto drop;
1085 /* End of IPv6 ICMP processing. */
1087 #endif /* !UIP_CONF_IPV6 */
1089 #if UIP_UDP
1090 /* UDP input processing. */
1091 udp_input:
1092 /* UDP processing is really just a hack. We don't do anything to the
1093 UDP/IP headers, but let the UDP application do all the hard
1094 work. If the application sets uip_slen, it has a packet to
1095 send. */
1096 #if UIP_UDP_CHECKSUMS
1097 uip_len = uip_len - UIP_IPUDPH_LEN;
1098 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
1099 if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
1100 UIP_STAT(++uip_stat.udp.drop);
1101 UIP_STAT(++uip_stat.udp.chkerr);
1102 UIP_LOG("udp: bad checksum.");
1103 goto drop;
1105 #else /* UIP_UDP_CHECKSUMS */
1106 uip_len = uip_len - UIP_IPUDPH_LEN;
1107 #endif /* UIP_UDP_CHECKSUMS */
1109 /* Demultiplex this UDP packet between the UDP "connections". */
1110 for(uip_udp_conn = &uip_udp_conns[0];
1111 uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
1112 ++uip_udp_conn) {
1113 /* If the local UDP port is non-zero, the connection is considered
1114 to be used. If so, the local port number is checked against the
1115 destination port number in the received packet. If the two port
1116 numbers match, the remote port number is checked if the
1117 connection is bound to a remote port. Finally, if the
1118 connection is bound to a remote IP address, the source IP
1119 address of the packet is checked. */
1120 if(uip_udp_conn->lport != 0 &&
1121 UDPBUF->destport == uip_udp_conn->lport &&
1122 (uip_udp_conn->rport == 0 ||
1123 UDPBUF->srcport == uip_udp_conn->rport) &&
1124 (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) ||
1125 uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) ||
1126 uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) {
1127 goto udp_found;
1130 UIP_LOG("udp: no matching connection found");
1131 goto drop;
1133 udp_found:
1134 UIP_STAT(++uip_stat.udp.recv);
1135 uip_conn = NULL;
1136 uip_flags = UIP_NEWDATA;
1137 uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
1138 uip_slen = 0;
1139 UIP_UDP_APPCALL();
1140 udp_send:
1141 if(uip_slen == 0) {
1142 goto drop;
1144 uip_len = uip_slen + UIP_IPUDPH_LEN;
1146 #if UIP_CONF_IPV6
1147 /* For IPv6, the IP length field does not include the IPv6 IP header
1148 length. */
1149 BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
1150 BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
1151 #else /* UIP_CONF_IPV6 */
1152 BUF->len[0] = (uip_len >> 8);
1153 BUF->len[1] = (uip_len & 0xff);
1154 #endif /* UIP_CONF_IPV6 */
1156 BUF->ttl = uip_udp_conn->ttl;
1157 BUF->proto = UIP_PROTO_UDP;
1159 UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN);
1160 UDPBUF->udpchksum = 0;
1162 BUF->srcport = uip_udp_conn->lport;
1163 BUF->destport = uip_udp_conn->rport;
1165 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
1166 uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr);
1168 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
1170 #if UIP_UDP_CHECKSUMS
1171 /* Calculate UDP checksum. */
1172 UDPBUF->udpchksum = ~(uip_udpchksum());
1173 if(UDPBUF->udpchksum == 0) {
1174 UDPBUF->udpchksum = 0xffff;
1176 #endif /* UIP_UDP_CHECKSUMS */
1177 UIP_STAT(++uip_stat.udp.sent);
1178 goto ip_send_nolen;
1179 #endif /* UIP_UDP */
1181 /* TCP input processing. */
1182 tcp_input:
1183 UIP_STAT(++uip_stat.tcp.recv);
1185 /* Start of TCP input header processing code. */
1187 if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
1188 checksum. */
1189 UIP_STAT(++uip_stat.tcp.drop);
1190 UIP_STAT(++uip_stat.tcp.chkerr);
1191 UIP_LOG("tcp: bad checksum.");
1192 goto drop;
1196 /* Demultiplex this segment. */
1197 /* First check any active connections. */
1198 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
1199 ++uip_connr) {
1200 if(uip_connr->tcpstateflags != UIP_CLOSED &&
1201 BUF->destport == uip_connr->lport &&
1202 BUF->srcport == uip_connr->rport &&
1203 uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) {
1204 goto found;
1208 /* If we didn't find and active connection that expected the packet,
1209 either this packet is an old duplicate, or this is a SYN packet
1210 destined for a connection in LISTEN. If the SYN flag isn't set,
1211 it is an old packet and we send a RST. */
1212 if((BUF->flags & TCP_CTL) != TCP_SYN) {
1213 goto reset;
1216 tmp16 = BUF->destport;
1217 /* Next, check listening connections. */
1218 for(c = 0; c < UIP_LISTENPORTS; ++c) {
1219 if(tmp16 == uip_listenports[c])
1220 goto found_listen;
1223 /* No matching connection found, so we send a RST packet. */
1224 UIP_STAT(++uip_stat.tcp.synrst);
1225 reset:
1227 /* We do not send resets in response to resets. */
1228 if(BUF->flags & TCP_RST) {
1229 goto drop;
1232 UIP_STAT(++uip_stat.tcp.rst);
1234 BUF->flags = TCP_RST | TCP_ACK;
1235 uip_len = UIP_IPTCPH_LEN;
1236 BUF->tcpoffset = 5 << 4;
1238 /* Flip the seqno and ackno fields in the TCP header. */
1239 c = BUF->seqno[3];
1240 BUF->seqno[3] = BUF->ackno[3];
1241 BUF->ackno[3] = c;
1243 c = BUF->seqno[2];
1244 BUF->seqno[2] = BUF->ackno[2];
1245 BUF->ackno[2] = c;
1247 c = BUF->seqno[1];
1248 BUF->seqno[1] = BUF->ackno[1];
1249 BUF->ackno[1] = c;
1251 c = BUF->seqno[0];
1252 BUF->seqno[0] = BUF->ackno[0];
1253 BUF->ackno[0] = c;
1255 /* We also have to increase the sequence number we are
1256 acknowledging. If the least significant byte overflowed, we need
1257 to propagate the carry to the other bytes as well. */
1258 if(++BUF->ackno[3] == 0) {
1259 if(++BUF->ackno[2] == 0) {
1260 if(++BUF->ackno[1] == 0) {
1261 ++BUF->ackno[0];
1266 /* Swap port numbers. */
1267 tmp16 = BUF->srcport;
1268 BUF->srcport = BUF->destport;
1269 BUF->destport = tmp16;
1271 /* Swap IP addresses. */
1272 uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
1273 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
1275 /* And send out the RST packet! */
1276 goto tcp_send_noconn;
1278 /* This label will be jumped to if we matched the incoming packet
1279 with a connection in LISTEN. In that case, we should create a new
1280 connection and send a SYNACK in return. */
1281 found_listen:
1282 /* First we check if there are any connections avaliable. Unused
1283 connections are kept in the same table as used connections, but
1284 unused ones have the tcpstate set to CLOSED. Also, connections in
1285 TIME_WAIT are kept track of and we'll use the oldest one if no
1286 CLOSED connections are found. Thanks to Eddie C. Dost for a very
1287 nice algorithm for the TIME_WAIT search. */
1288 uip_connr = 0;
1289 for(c = 0; c < UIP_CONNS; ++c) {
1290 if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
1291 uip_connr = &uip_conns[c];
1292 break;
1294 if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
1295 if(uip_connr == 0 ||
1296 uip_conns[c].timer > uip_connr->timer) {
1297 uip_connr = &uip_conns[c];
1302 if(uip_connr == 0) {
1303 /* All connections are used already, we drop packet and hope that
1304 the remote end will retransmit the packet at a time when we
1305 have more spare connections. */
1306 UIP_STAT(++uip_stat.tcp.syndrop);
1307 UIP_LOG("tcp: found no unused connections.");
1308 goto drop;
1310 uip_conn = uip_connr;
1312 /* Fill in the necessary fields for the new connection. */
1313 uip_connr->rto = uip_connr->timer = UIP_RTO;
1314 uip_connr->sa = 0;
1315 uip_connr->sv = 4;
1316 uip_connr->nrtx = 0;
1317 uip_connr->lport = BUF->destport;
1318 uip_connr->rport = BUF->srcport;
1319 uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr);
1320 uip_connr->tcpstateflags = UIP_SYN_RCVD;
1322 uip_connr->snd_nxt[0] = iss[0];
1323 uip_connr->snd_nxt[1] = iss[1];
1324 uip_connr->snd_nxt[2] = iss[2];
1325 uip_connr->snd_nxt[3] = iss[3];
1326 uip_connr->len = 1;
1328 /* rcv_nxt should be the seqno from the incoming packet + 1. */
1329 uip_connr->rcv_nxt[3] = BUF->seqno[3];
1330 uip_connr->rcv_nxt[2] = BUF->seqno[2];
1331 uip_connr->rcv_nxt[1] = BUF->seqno[1];
1332 uip_connr->rcv_nxt[0] = BUF->seqno[0];
1333 uip_add_rcv_nxt(1);
1335 /* Parse the TCP MSS option, if present. */
1336 if((BUF->tcpoffset & 0xf0) > 0x50) {
1337 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
1338 opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
1339 if(opt == TCP_OPT_END) {
1340 /* End of options. */
1341 break;
1342 } else if(opt == TCP_OPT_NOOP) {
1343 ++c;
1344 /* NOP option. */
1345 } else if(opt == TCP_OPT_MSS &&
1346 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
1347 /* An MSS option with the right option length. */
1348 tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
1349 (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
1350 uip_connr->initialmss = uip_connr->mss =
1351 tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
1353 /* And we are done processing options. */
1354 break;
1355 } else {
1356 /* All other options have a length field, so that we easily
1357 can skip past them. */
1358 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
1359 /* If the length field is zero, the options are malformed
1360 and we don't process them further. */
1361 break;
1363 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
1368 /* Our response will be a SYNACK. */
1369 #if UIP_ACTIVE_OPEN
1370 tcp_send_synack:
1371 BUF->flags = TCP_ACK;
1373 tcp_send_syn:
1374 BUF->flags |= TCP_SYN;
1375 #else /* UIP_ACTIVE_OPEN */
1376 tcp_send_synack:
1377 BUF->flags = TCP_SYN | TCP_ACK;
1378 #endif /* UIP_ACTIVE_OPEN */
1380 /* We send out the TCP Maximum Segment Size option with our
1381 SYNACK. */
1382 BUF->optdata[0] = TCP_OPT_MSS;
1383 BUF->optdata[1] = TCP_OPT_MSS_LEN;
1384 BUF->optdata[2] = (UIP_TCP_MSS) / 256;
1385 BUF->optdata[3] = (UIP_TCP_MSS) & 255;
1386 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
1387 BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
1388 goto tcp_send;
1390 /* This label will be jumped to if we found an active connection. */
1391 found:
1392 uip_conn = uip_connr;
1393 uip_flags = 0;
1394 /* We do a very naive form of TCP reset processing; we just accept
1395 any RST and kill our connection. We should in fact check if the
1396 sequence number of this reset is wihtin our advertised window
1397 before we accept the reset. */
1398 if(BUF->flags & TCP_RST) {
1399 uip_connr->tcpstateflags = UIP_CLOSED;
1400 UIP_LOG("tcp: got reset, aborting connection.");
1401 uip_flags = UIP_ABORT;
1402 UIP_APPCALL();
1403 goto drop;
1405 /* Calculated the length of the data, if the application has sent
1406 any data to us. */
1407 c = (BUF->tcpoffset >> 4) << 2;
1408 /* uip_len will contain the length of the actual TCP data. This is
1409 calculated by subtracing the length of the TCP header (in
1410 c) and the length of the IP header (20 bytes). */
1411 uip_len = uip_len - c - UIP_IPH_LEN;
1413 /* First, check if the sequence number of the incoming packet is
1414 what we're expecting next. If not, we send out an ACK with the
1415 correct numbers in. */
1416 if(!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
1417 ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) {
1418 if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
1419 (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
1420 BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
1421 BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
1422 BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
1423 goto tcp_send_ack;
1427 /* Next, check if the incoming segment acknowledges any outstanding
1428 data. If so, we update the sequence number, reset the length of
1429 the outstanding data, calculate RTT estimations, and reset the
1430 retransmission timer. */
1431 if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
1432 uip_add32(uip_connr->snd_nxt, uip_connr->len);
1434 if(BUF->ackno[0] == uip_acc32[0] &&
1435 BUF->ackno[1] == uip_acc32[1] &&
1436 BUF->ackno[2] == uip_acc32[2] &&
1437 BUF->ackno[3] == uip_acc32[3]) {
1438 /* Update sequence number. */
1439 uip_connr->snd_nxt[0] = uip_acc32[0];
1440 uip_connr->snd_nxt[1] = uip_acc32[1];
1441 uip_connr->snd_nxt[2] = uip_acc32[2];
1442 uip_connr->snd_nxt[3] = uip_acc32[3];
1445 /* Do RTT estimation, unless we have done retransmissions. */
1446 if(uip_connr->nrtx == 0) {
1447 signed char m;
1448 m = uip_connr->rto - uip_connr->timer;
1449 /* This is taken directly from VJs original code in his paper */
1450 m = m - (uip_connr->sa >> 3);
1451 uip_connr->sa += m;
1452 if(m < 0) {
1453 m = -m;
1455 m = m - (uip_connr->sv >> 2);
1456 uip_connr->sv += m;
1457 uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
1460 /* Set the acknowledged flag. */
1461 uip_flags = UIP_ACKDATA;
1462 /* Reset the retransmission timer. */
1463 uip_connr->timer = uip_connr->rto;
1465 /* Reset length of outstanding data. */
1466 uip_connr->len = 0;
1471 /* Do different things depending on in what state the connection is. */
1472 switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
1473 /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
1474 implemented, since we force the application to close when the
1475 peer sends a FIN (hence the application goes directly from
1476 ESTABLISHED to LAST_ACK). */
1477 case UIP_SYN_RCVD:
1478 /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
1479 we are waiting for an ACK that acknowledges the data we sent
1480 out the last time. Therefore, we want to have the UIP_ACKDATA
1481 flag set. If so, we enter the ESTABLISHED state. */
1482 if(uip_flags & UIP_ACKDATA) {
1483 uip_connr->tcpstateflags = UIP_ESTABLISHED;
1484 uip_flags = UIP_CONNECTED;
1485 uip_connr->len = 0;
1486 if(uip_len > 0) {
1487 uip_flags |= UIP_NEWDATA;
1488 uip_add_rcv_nxt(uip_len);
1490 uip_slen = 0;
1491 UIP_APPCALL();
1492 goto appsend;
1494 goto drop;
1495 #if UIP_ACTIVE_OPEN
1496 case UIP_SYN_SENT:
1497 /* In SYN_SENT, we wait for a SYNACK that is sent in response to
1498 our SYN. The rcv_nxt is set to sequence number in the SYNACK
1499 plus one, and we send an ACK. We move into the ESTABLISHED
1500 state. */
1501 if((uip_flags & UIP_ACKDATA) &&
1502 (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
1504 /* Parse the TCP MSS option, if present. */
1505 if((BUF->tcpoffset & 0xf0) > 0x50) {
1506 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
1507 opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
1508 if(opt == TCP_OPT_END) {
1509 /* End of options. */
1510 break;
1511 } else if(opt == TCP_OPT_NOOP) {
1512 ++c;
1513 /* NOP option. */
1514 } else if(opt == TCP_OPT_MSS &&
1515 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
1516 /* An MSS option with the right option length. */
1517 tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
1518 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
1519 uip_connr->initialmss =
1520 uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
1522 /* And we are done processing options. */
1523 break;
1524 } else {
1525 /* All other options have a length field, so that we easily
1526 can skip past them. */
1527 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
1528 /* If the length field is zero, the options are malformed
1529 and we don't process them further. */
1530 break;
1532 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
1536 uip_connr->tcpstateflags = UIP_ESTABLISHED;
1537 uip_connr->rcv_nxt[0] = BUF->seqno[0];
1538 uip_connr->rcv_nxt[1] = BUF->seqno[1];
1539 uip_connr->rcv_nxt[2] = BUF->seqno[2];
1540 uip_connr->rcv_nxt[3] = BUF->seqno[3];
1541 uip_add_rcv_nxt(1);
1542 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
1543 uip_connr->len = 0;
1544 uip_len = 0;
1545 uip_slen = 0;
1546 UIP_APPCALL();
1547 goto appsend;
1549 /* Inform the application that the connection failed */
1550 uip_flags = UIP_ABORT;
1551 UIP_APPCALL();
1552 /* The connection is closed after we send the RST */
1553 uip_conn->tcpstateflags = UIP_CLOSED;
1554 goto reset;
1555 #endif /* UIP_ACTIVE_OPEN */
1557 case UIP_ESTABLISHED:
1558 /* In the ESTABLISHED state, we call upon the application to feed
1559 data into the uip_buf. If the UIP_ACKDATA flag is set, the
1560 application should put new data into the buffer, otherwise we are
1561 retransmitting an old segment, and the application should put that
1562 data into the buffer.
1564 If the incoming packet is a FIN, we should close the connection on
1565 this side as well, and we send out a FIN and enter the LAST_ACK
1566 state. We require that there is no outstanding data; otherwise the
1567 sequence numbers will be screwed up. */
1569 if(BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
1570 if(uip_outstanding(uip_connr)) {
1571 goto drop;
1573 uip_add_rcv_nxt(1 + uip_len);
1574 uip_flags |= UIP_CLOSE;
1575 if(uip_len > 0) {
1576 uip_flags |= UIP_NEWDATA;
1578 UIP_APPCALL();
1579 uip_connr->len = 1;
1580 uip_connr->tcpstateflags = UIP_LAST_ACK;
1581 uip_connr->nrtx = 0;
1582 tcp_send_finack:
1583 BUF->flags = TCP_FIN | TCP_ACK;
1584 goto tcp_send_nodata;
1587 /* Check the URG flag. If this is set, the segment carries urgent
1588 data that we must pass to the application. */
1589 if((BUF->flags & TCP_URG) != 0) {
1590 #if UIP_URGDATA > 0
1591 uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
1592 if(uip_urglen > uip_len) {
1593 /* There is more urgent data in the next segment to come. */
1594 uip_urglen = uip_len;
1596 uip_add_rcv_nxt(uip_urglen);
1597 uip_len -= uip_urglen;
1598 uip_urgdata = uip_appdata;
1599 uip_appdata += uip_urglen;
1600 } else {
1601 uip_urglen = 0;
1602 #else /* UIP_URGDATA > 0 */
1603 uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]);
1604 uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
1605 #endif /* UIP_URGDATA > 0 */
1608 /* If uip_len > 0 we have TCP data in the packet, and we flag this
1609 by setting the UIP_NEWDATA flag and update the sequence number
1610 we acknowledge. If the application has stopped the dataflow
1611 using uip_stop(), we must not accept any data packets from the
1612 remote host. */
1613 if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
1614 uip_flags |= UIP_NEWDATA;
1615 uip_add_rcv_nxt(uip_len);
1618 /* Check if the available buffer space advertised by the other end
1619 is smaller than the initial MSS for this connection. If so, we
1620 set the current MSS to the window size to ensure that the
1621 application does not send more data than the other end can
1622 handle.
1624 If the remote host advertises a zero window, we set the MSS to
1625 the initial MSS so that the application will send an entire MSS
1626 of data. This data will not be acknowledged by the receiver,
1627 and the application will retransmit it. This is called the
1628 "persistent timer" and uses the retransmission mechanim.
1630 tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1];
1631 if(tmp16 > uip_connr->initialmss ||
1632 tmp16 == 0) {
1633 tmp16 = uip_connr->initialmss;
1635 uip_connr->mss = tmp16;
1637 /* If this packet constitutes an ACK for outstanding data (flagged
1638 by the UIP_ACKDATA flag, we should call the application since it
1639 might want to send more data. If the incoming packet had data
1640 from the peer (as flagged by the UIP_NEWDATA flag), the
1641 application must also be notified.
1643 When the application is called, the global variable uip_len
1644 contains the length of the incoming data. The application can
1645 access the incoming data through the global pointer
1646 uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN
1647 bytes into the uip_buf array.
1649 If the application wishes to send any data, this data should be
1650 put into the uip_appdata and the length of the data should be
1651 put into uip_len. If the application don't have any data to
1652 send, uip_len must be set to 0. */
1653 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
1654 uip_slen = 0;
1655 UIP_APPCALL();
1657 appsend:
1659 if(uip_flags & UIP_ABORT) {
1660 uip_slen = 0;
1661 uip_connr->tcpstateflags = UIP_CLOSED;
1662 BUF->flags = TCP_RST | TCP_ACK;
1663 goto tcp_send_nodata;
1666 if(uip_flags & UIP_CLOSE) {
1667 uip_slen = 0;
1668 uip_connr->len = 1;
1669 uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
1670 uip_connr->nrtx = 0;
1671 BUF->flags = TCP_FIN | TCP_ACK;
1672 goto tcp_send_nodata;
1675 /* If uip_slen > 0, the application has data to be sent. */
1676 if(uip_slen > 0) {
1678 /* If the connection has acknowledged data, the contents of
1679 the ->len variable should be discarded. */
1680 if((uip_flags & UIP_ACKDATA) != 0) {
1681 uip_connr->len = 0;
1684 /* If the ->len variable is non-zero the connection has
1685 already data in transit and cannot send anymore right
1686 now. */
1687 if(uip_connr->len == 0) {
1689 /* The application cannot send more than what is allowed by
1690 the mss (the minumum of the MSS and the available
1691 window). */
1692 if(uip_slen > uip_connr->mss) {
1693 uip_slen = uip_connr->mss;
1696 /* Remember how much data we send out now so that we know
1697 when everything has been acknowledged. */
1698 uip_connr->len = uip_slen;
1699 } else {
1701 /* If the application already had unacknowledged data, we
1702 make sure that the application does not send (i.e.,
1703 retransmit) out more than it previously sent out. */
1704 uip_slen = uip_connr->len;
1707 uip_connr->nrtx = 0;
1708 apprexmit:
1709 uip_appdata = uip_sappdata;
1711 /* If the application has data to be sent, or if the incoming
1712 packet had new data in it, we must send out a packet. */
1713 if(uip_slen > 0 && uip_connr->len > 0) {
1714 /* Add the length of the IP and TCP headers. */
1715 uip_len = uip_connr->len + UIP_TCPIP_HLEN;
1716 /* We always set the ACK flag in response packets. */
1717 BUF->flags = TCP_ACK | TCP_PSH;
1718 /* Send the packet. */
1719 goto tcp_send_noopts;
1721 /* If there is no data to send, just send out a pure ACK if
1722 there is newdata. */
1723 if(uip_flags & UIP_NEWDATA) {
1724 uip_len = UIP_TCPIP_HLEN;
1725 BUF->flags = TCP_ACK;
1726 goto tcp_send_noopts;
1729 goto drop;
1730 case UIP_LAST_ACK:
1731 /* We can close this connection if the peer has acknowledged our
1732 FIN. This is indicated by the UIP_ACKDATA flag. */
1733 if(uip_flags & UIP_ACKDATA) {
1734 uip_connr->tcpstateflags = UIP_CLOSED;
1735 uip_flags = UIP_CLOSE;
1736 UIP_APPCALL();
1738 break;
1740 case UIP_FIN_WAIT_1:
1741 /* The application has closed the connection, but the remote host
1742 hasn't closed its end yet. Thus we do nothing but wait for a
1743 FIN from the other side. */
1744 if(uip_len > 0) {
1745 uip_add_rcv_nxt(uip_len);
1747 if(BUF->flags & TCP_FIN) {
1748 if(uip_flags & UIP_ACKDATA) {
1749 uip_connr->tcpstateflags = UIP_TIME_WAIT;
1750 uip_connr->timer = 0;
1751 uip_connr->len = 0;
1752 } else {
1753 uip_connr->tcpstateflags = UIP_CLOSING;
1755 uip_add_rcv_nxt(1);
1756 uip_flags = UIP_CLOSE;
1757 UIP_APPCALL();
1758 goto tcp_send_ack;
1759 } else if(uip_flags & UIP_ACKDATA) {
1760 uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
1761 uip_connr->len = 0;
1762 goto drop;
1764 if(uip_len > 0) {
1765 goto tcp_send_ack;
1767 goto drop;
1769 case UIP_FIN_WAIT_2:
1770 if(uip_len > 0) {
1771 uip_add_rcv_nxt(uip_len);
1773 if(BUF->flags & TCP_FIN) {
1774 uip_connr->tcpstateflags = UIP_TIME_WAIT;
1775 uip_connr->timer = 0;
1776 uip_add_rcv_nxt(1);
1777 uip_flags = UIP_CLOSE;
1778 UIP_APPCALL();
1779 goto tcp_send_ack;
1781 if(uip_len > 0) {
1782 goto tcp_send_ack;
1784 goto drop;
1786 case UIP_TIME_WAIT:
1787 goto tcp_send_ack;
1789 case UIP_CLOSING:
1790 if(uip_flags & UIP_ACKDATA) {
1791 uip_connr->tcpstateflags = UIP_TIME_WAIT;
1792 uip_connr->timer = 0;
1795 goto drop;
1798 /* We jump here when we are ready to send the packet, and just want
1799 to set the appropriate TCP sequence numbers in the TCP header. */
1800 tcp_send_ack:
1801 BUF->flags = TCP_ACK;
1802 tcp_send_nodata:
1803 uip_len = UIP_IPTCPH_LEN;
1804 tcp_send_noopts:
1805 BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
1806 tcp_send:
1807 /* We're done with the input processing. We are now ready to send a
1808 reply. Our job is to fill in all the fields of the TCP and IP
1809 headers before calculating the checksum and finally send the
1810 packet. */
1811 BUF->ackno[0] = uip_connr->rcv_nxt[0];
1812 BUF->ackno[1] = uip_connr->rcv_nxt[1];
1813 BUF->ackno[2] = uip_connr->rcv_nxt[2];
1814 BUF->ackno[3] = uip_connr->rcv_nxt[3];
1816 BUF->seqno[0] = uip_connr->snd_nxt[0];
1817 BUF->seqno[1] = uip_connr->snd_nxt[1];
1818 BUF->seqno[2] = uip_connr->snd_nxt[2];
1819 BUF->seqno[3] = uip_connr->snd_nxt[3];
1821 BUF->proto = UIP_PROTO_TCP;
1823 BUF->srcport = uip_connr->lport;
1824 BUF->destport = uip_connr->rport;
1826 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
1827 uip_ipaddr_copy(BUF->destipaddr, uip_connr->ripaddr);
1829 if(uip_connr->tcpstateflags & UIP_STOPPED) {
1830 /* If the connection has issued uip_stop(), we advertise a zero
1831 window so that the remote host will stop sending data. */
1832 BUF->wnd[0] = BUF->wnd[1] = 0;
1833 } else {
1834 BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
1835 BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
1838 tcp_send_noconn:
1839 BUF->ttl = UIP_TTL;
1840 #if UIP_CONF_IPV6
1841 /* For IPv6, the IP length field does not include the IPv6 IP header
1842 length. */
1843 BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
1844 BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
1845 #else /* UIP_CONF_IPV6 */
1846 BUF->len[0] = (uip_len >> 8);
1847 BUF->len[1] = (uip_len & 0xff);
1848 #endif /* UIP_CONF_IPV6 */
1850 BUF->urgp[0] = BUF->urgp[1] = 0;
1852 /* Calculate TCP checksum. */
1853 BUF->tcpchksum = 0;
1854 BUF->tcpchksum = ~(uip_tcpchksum());
1856 #if UIP_UDP
1857 ip_send_nolen:
1858 #endif /* UIP_UDP */
1860 #if UIP_CONF_IPV6
1861 BUF->vtc = 0x60;
1862 BUF->tcflow = 0x00;
1863 BUF->flow = 0x00;
1864 #else /* UIP_CONF_IPV6 */
1865 BUF->vhl = 0x45;
1866 BUF->tos = 0;
1867 BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
1868 ++ipid;
1869 BUF->ipid[0] = ipid >> 8;
1870 BUF->ipid[1] = ipid & 0xff;
1871 /* Calculate IP checksum. */
1872 BUF->ipchksum = 0;
1873 BUF->ipchksum = ~(uip_ipchksum());
1874 DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum());
1875 #endif /* UIP_CONF_IPV6 */
1877 UIP_STAT(++uip_stat.tcp.sent);
1878 send:
1879 DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len,
1880 (BUF->len[0] << 8) | BUF->len[1]);
1882 UIP_STAT(++uip_stat.ip.sent);
1883 /* Return and let the caller do the actual transmission. */
1884 uip_flags = 0;
1885 return;
1886 drop:
1887 uip_len = 0;
1888 uip_flags = 0;
1889 return;
1891 /*---------------------------------------------------------------------------*/
1892 u16_t
1893 htons(u16_t val)
1895 return HTONS(val);
1897 /*---------------------------------------------------------------------------*/
1898 void
1899 uip_send(const void *data, int len)
1901 if(len > 0) {
1902 uip_slen = len;
1903 if(data != uip_sappdata) {
1904 memcpy(uip_sappdata, (data), uip_slen);
1908 /** @} */