Added support for the FTP standalone client to the c64 target.
[contiki-2.x.git] / core / net / uip.c
blob3fe8dfff000e422b14145d95a5925e5c13ade295
1 #define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/
3 /**
4 * \addtogroup uip
5 * @{
6 */
8 /**
9 * \file
10 * The uIP TCP/IP stack code.
11 * \author Adam Dunkels <adam@dunkels.com>
15 * Copyright (c) 2001-2003, Adam Dunkels.
16 * All rights reserved.
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 * 3. The name of the author may not be used to endorse or promote
27 * products derived from this software without specific prior
28 * written permission.
30 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
31 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
34 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
36 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
37 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
38 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
39 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 * This file is part of the uIP TCP/IP stack.
44 * $Id: uip.c,v 1.30 2010/10/19 18:29:04 adamdunkels Exp $
49 * uIP is a small implementation of the IP, UDP and TCP protocols (as
50 * well as some basic ICMP stuff). The implementation couples the IP,
51 * UDP, TCP and the application layers very tightly. To keep the size
52 * of the compiled code down, this code frequently uses the goto
53 * statement. While it would be possible to break the uip_process()
54 * function into many smaller functions, this would increase the code
55 * size because of the overhead of parameter passing and the fact that
56 * the optimier would not be as efficient.
58 * The principle is that we have a small buffer, called the uip_buf,
59 * in which the device driver puts an incoming packet. The TCP/IP
60 * stack parses the headers in the packet, and calls the
61 * application. If the remote host has sent data to the application,
62 * this data is present in the uip_buf and the application read the
63 * data from there. It is up to the application to put this data into
64 * a byte stream if needed. The application will not be fed with data
65 * that is out of sequence.
67 * If the application whishes to send data to the peer, it should put
68 * its data into the uip_buf. The uip_appdata pointer points to the
69 * first available byte. The TCP/IP stack will calculate the
70 * checksums, and fill in the necessary header fields and finally send
71 * the packet back to the peer.
74 #include "net/uip.h"
75 #include "net/uipopt.h"
76 #include "net/uip_arp.h"
77 #include "net/uip_arch.h"
79 #if !UIP_CONF_IPV6 /* If UIP_CONF_IPV6 is defined, we compile the
80 uip6.c file instead of this one. Therefore
81 this #ifndef removes the entire compilation
82 output of the uip.c file */
85 #if UIP_CONF_IPV6
86 #include "net/uip-neighbor.h"
87 #endif /* UIP_CONF_IPV6 */
89 #include <string.h>
91 /*---------------------------------------------------------------------------*/
92 /* Variable definitions. */
95 /* The IP address of this host. If it is defined to be fixed (by
96 setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set
97 here. Otherwise, the address */
98 #if UIP_FIXEDADDR > 0
99 const uip_ipaddr_t uip_hostaddr =
100 { UIP_IPADDR0, UIP_IPADDR1, UIP_IPADDR2, UIP_IPADDR3 };
101 const uip_ipaddr_t uip_draddr =
102 { UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3 };
103 const uip_ipaddr_t uip_netmask =
104 { UIP_NETMASK0, UIP_NETMASK1, UIP_NETMASK2, UIP_NETMASK3 };
105 #else
106 uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
107 #endif /* UIP_FIXEDADDR */
109 const uip_ipaddr_t uip_broadcast_addr =
110 #if UIP_CONF_IPV6
111 { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
112 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
113 #else /* UIP_CONF_IPV6 */
114 { { 0xff, 0xff, 0xff, 0xff } };
115 #endif /* UIP_CONF_IPV6 */
116 const uip_ipaddr_t uip_all_zeroes_addr = { { 0x0, /* rest is 0 */ } };
118 #if UIP_FIXEDETHADDR
119 const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
120 UIP_ETHADDR1,
121 UIP_ETHADDR2,
122 UIP_ETHADDR3,
123 UIP_ETHADDR4,
124 UIP_ETHADDR5}};
125 #else
126 struct uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}};
127 #endif
129 /* The packet buffer that contains incoming packets. */
130 uip_buf_t uip_aligned_buf;
132 void *uip_appdata; /* The uip_appdata pointer points to
133 application data. */
134 void *uip_sappdata; /* The uip_appdata pointer points to
135 the application data which is to
136 be sent. */
137 #if UIP_URGDATA > 0
138 void *uip_urgdata; /* The uip_urgdata pointer points to
139 urgent data (out-of-band data), if
140 present. */
141 u16_t uip_urglen, uip_surglen;
142 #endif /* UIP_URGDATA > 0 */
144 u16_t uip_len, uip_slen;
145 /* The uip_len is either 8 or 16 bits,
146 depending on the maximum packet
147 size. */
149 u8_t uip_flags; /* The uip_flags variable is used for
150 communication between the TCP/IP stack
151 and the application program. */
152 struct uip_conn *uip_conn; /* uip_conn always points to the current
153 connection. */
155 struct uip_conn uip_conns[UIP_CONNS];
156 /* The uip_conns array holds all TCP
157 connections. */
158 u16_t uip_listenports[UIP_LISTENPORTS];
159 /* The uip_listenports list all currently
160 listning ports. */
161 #if UIP_UDP
162 struct uip_udp_conn *uip_udp_conn;
163 struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
164 #endif /* UIP_UDP */
166 static u16_t ipid; /* Ths ipid variable is an increasing
167 number that is used for the IP ID
168 field. */
170 void uip_setipid(u16_t id) { ipid = id; }
172 static u8_t iss[4]; /* The iss variable is used for the TCP
173 initial sequence number. */
175 #if UIP_ACTIVE_OPEN || UIP_UDP
176 static u16_t lastport; /* Keeps track of the last port used for
177 a new connection. */
178 #endif /* UIP_ACTIVE_OPEN || UIP_UDP */
180 /* Temporary variables. */
181 u8_t uip_acc32[4];
182 static u8_t c, opt;
183 static u16_t tmp16;
185 /* Structures and definitions. */
186 #define TCP_FIN 0x01
187 #define TCP_SYN 0x02
188 #define TCP_RST 0x04
189 #define TCP_PSH 0x08
190 #define TCP_ACK 0x10
191 #define TCP_URG 0x20
192 #define TCP_CTL 0x3f
194 #define TCP_OPT_END 0 /* End of TCP options list */
195 #define TCP_OPT_NOOP 1 /* "No-operation" TCP option */
196 #define TCP_OPT_MSS 2 /* Maximum segment size TCP option */
198 #define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */
200 #define ICMP_ECHO_REPLY 0
201 #define ICMP_ECHO 8
203 #define ICMP_DEST_UNREACHABLE 3
204 #define ICMP_PORT_UNREACHABLE 3
206 #define ICMP6_ECHO_REPLY 129
207 #define ICMP6_ECHO 128
208 #define ICMP6_NEIGHBOR_SOLICITATION 135
209 #define ICMP6_NEIGHBOR_ADVERTISEMENT 136
211 #define ICMP6_FLAG_S (1 << 6)
213 #define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1
214 #define ICMP6_OPTION_TARGET_LINK_ADDRESS 2
217 /* Macros. */
218 #define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
219 #define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
220 #define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
221 #define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
224 #if UIP_STATISTICS == 1
225 struct uip_stats uip_stat;
226 #define UIP_STAT(s) s
227 #else
228 #define UIP_STAT(s)
229 #endif /* UIP_STATISTICS == 1 */
231 #if UIP_LOGGING == 1
232 #include <stdio.h>
233 void uip_log(char *msg);
234 #define UIP_LOG(m) uip_log(m)
235 #else
236 #define UIP_LOG(m)
237 #endif /* UIP_LOGGING == 1 */
239 #if ! UIP_ARCH_ADD32
240 void
241 uip_add32(u8_t *op32, u16_t op16)
243 uip_acc32[3] = op32[3] + (op16 & 0xff);
244 uip_acc32[2] = op32[2] + (op16 >> 8);
245 uip_acc32[1] = op32[1];
246 uip_acc32[0] = op32[0];
248 if(uip_acc32[2] < (op16 >> 8)) {
249 ++uip_acc32[1];
250 if(uip_acc32[1] == 0) {
251 ++uip_acc32[0];
256 if(uip_acc32[3] < (op16 & 0xff)) {
257 ++uip_acc32[2];
258 if(uip_acc32[2] == 0) {
259 ++uip_acc32[1];
260 if(uip_acc32[1] == 0) {
261 ++uip_acc32[0];
267 #endif /* UIP_ARCH_ADD32 */
269 #if ! UIP_ARCH_CHKSUM
270 /*---------------------------------------------------------------------------*/
271 static u16_t
272 chksum(u16_t sum, const u8_t *data, u16_t len)
274 u16_t t;
275 const u8_t *dataptr;
276 const u8_t *last_byte;
278 dataptr = data;
279 last_byte = data + len - 1;
281 while(dataptr < last_byte) { /* At least two more bytes */
282 t = (dataptr[0] << 8) + dataptr[1];
283 sum += t;
284 if(sum < t) {
285 sum++; /* carry */
287 dataptr += 2;
290 if(dataptr == last_byte) {
291 t = (dataptr[0] << 8) + 0;
292 sum += t;
293 if(sum < t) {
294 sum++; /* carry */
298 /* Return sum in host byte order. */
299 return sum;
301 /*---------------------------------------------------------------------------*/
302 u16_t
303 uip_chksum(u16_t *data, u16_t len)
305 return uip_htons(chksum(0, (u8_t *)data, len));
307 /*---------------------------------------------------------------------------*/
308 #ifndef UIP_ARCH_IPCHKSUM
309 u16_t
310 uip_ipchksum(void)
312 u16_t sum;
314 sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
315 DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum);
316 return (sum == 0) ? 0xffff : uip_htons(sum);
318 #endif
319 /*---------------------------------------------------------------------------*/
320 static u16_t
321 upper_layer_chksum(u8_t proto)
323 u16_t upper_layer_len;
324 u16_t sum;
326 #if UIP_CONF_IPV6
327 upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]);
328 #else /* UIP_CONF_IPV6 */
329 upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;
330 #endif /* UIP_CONF_IPV6 */
332 /* First sum pseudoheader. */
334 /* IP protocol and length fields. This addition cannot carry. */
335 sum = upper_layer_len + proto;
336 /* Sum IP source and destination addresses. */
337 sum = chksum(sum, (u8_t *)&BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t));
339 /* Sum TCP header and data. */
340 sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN],
341 upper_layer_len);
343 return (sum == 0) ? 0xffff : uip_htons(sum);
345 /*---------------------------------------------------------------------------*/
346 #if UIP_CONF_IPV6
347 u16_t
348 uip_icmp6chksum(void)
350 return upper_layer_chksum(UIP_PROTO_ICMP6);
353 #endif /* UIP_CONF_IPV6 */
354 /*---------------------------------------------------------------------------*/
355 u16_t
356 uip_tcpchksum(void)
358 return upper_layer_chksum(UIP_PROTO_TCP);
360 /*---------------------------------------------------------------------------*/
361 #if UIP_UDP_CHECKSUMS
362 u16_t
363 uip_udpchksum(void)
365 return upper_layer_chksum(UIP_PROTO_UDP);
367 #endif /* UIP_UDP_CHECKSUMS */
368 #endif /* UIP_ARCH_CHKSUM */
369 /*---------------------------------------------------------------------------*/
370 void
371 uip_init(void)
373 for(c = 0; c < UIP_LISTENPORTS; ++c) {
374 uip_listenports[c] = 0;
376 for(c = 0; c < UIP_CONNS; ++c) {
377 uip_conns[c].tcpstateflags = UIP_CLOSED;
379 #if UIP_ACTIVE_OPEN || UIP_UDP
380 lastport = 1024;
381 #endif /* UIP_ACTIVE_OPEN || UIP_UDP */
383 #if UIP_UDP
384 for(c = 0; c < UIP_UDP_CONNS; ++c) {
385 uip_udp_conns[c].lport = 0;
387 #endif /* UIP_UDP */
390 /* IPv4 initialization. */
391 #if UIP_FIXEDADDR == 0
392 /* uip_hostaddr[0] = uip_hostaddr[1] = 0;*/
393 #endif /* UIP_FIXEDADDR */
396 /*---------------------------------------------------------------------------*/
397 #if UIP_ACTIVE_OPEN
398 struct uip_conn *
399 uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
401 register struct uip_conn *conn, *cconn;
403 /* Find an unused local port. */
404 again:
405 ++lastport;
407 if(lastport >= 32000) {
408 lastport = 4096;
411 /* Check if this port is already in use, and if so try to find
412 another one. */
413 for(c = 0; c < UIP_CONNS; ++c) {
414 conn = &uip_conns[c];
415 if(conn->tcpstateflags != UIP_CLOSED &&
416 conn->lport == uip_htons(lastport)) {
417 goto again;
421 conn = 0;
422 for(c = 0; c < UIP_CONNS; ++c) {
423 cconn = &uip_conns[c];
424 if(cconn->tcpstateflags == UIP_CLOSED) {
425 conn = cconn;
426 break;
428 if(cconn->tcpstateflags == UIP_TIME_WAIT) {
429 if(conn == 0 ||
430 cconn->timer > conn->timer) {
431 conn = cconn;
436 if(conn == 0) {
437 return 0;
440 conn->tcpstateflags = UIP_SYN_SENT;
442 conn->snd_nxt[0] = iss[0];
443 conn->snd_nxt[1] = iss[1];
444 conn->snd_nxt[2] = iss[2];
445 conn->snd_nxt[3] = iss[3];
447 conn->initialmss = conn->mss = UIP_TCP_MSS;
449 conn->len = 1; /* TCP length of the SYN is one. */
450 conn->nrtx = 0;
451 conn->timer = 1; /* Send the SYN next time around. */
452 conn->rto = UIP_RTO;
453 conn->sa = 0;
454 conn->sv = 16; /* Initial value of the RTT variance. */
455 conn->lport = uip_htons(lastport);
456 conn->rport = rport;
457 uip_ipaddr_copy(&conn->ripaddr, ripaddr);
459 return conn;
461 #endif /* UIP_ACTIVE_OPEN */
462 /*---------------------------------------------------------------------------*/
463 #if UIP_UDP
464 struct uip_udp_conn *
465 uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport)
467 register struct uip_udp_conn *conn;
469 /* Find an unused local port. */
470 again:
471 ++lastport;
473 if(lastport >= 32000) {
474 lastport = 4096;
477 for(c = 0; c < UIP_UDP_CONNS; ++c) {
478 if(uip_udp_conns[c].lport == uip_htons(lastport)) {
479 goto again;
484 conn = 0;
485 for(c = 0; c < UIP_UDP_CONNS; ++c) {
486 if(uip_udp_conns[c].lport == 0) {
487 conn = &uip_udp_conns[c];
488 break;
492 if(conn == 0) {
493 return 0;
496 conn->lport = UIP_HTONS(lastport);
497 conn->rport = rport;
498 if(ripaddr == NULL) {
499 memset(&conn->ripaddr, 0, sizeof(uip_ipaddr_t));
500 } else {
501 uip_ipaddr_copy(&conn->ripaddr, ripaddr);
503 conn->ttl = UIP_TTL;
505 return conn;
507 #endif /* UIP_UDP */
508 /*---------------------------------------------------------------------------*/
509 void
510 uip_unlisten(u16_t port)
512 for(c = 0; c < UIP_LISTENPORTS; ++c) {
513 if(uip_listenports[c] == port) {
514 uip_listenports[c] = 0;
515 return;
519 /*---------------------------------------------------------------------------*/
520 void
521 uip_listen(u16_t port)
523 for(c = 0; c < UIP_LISTENPORTS; ++c) {
524 if(uip_listenports[c] == 0) {
525 uip_listenports[c] = port;
526 return;
530 /*---------------------------------------------------------------------------*/
531 /* XXX: IP fragment reassembly: not well-tested. */
533 #if UIP_REASSEMBLY && !UIP_CONF_IPV6
534 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
535 static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
536 static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
537 static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
538 0x0f, 0x07, 0x03, 0x01};
539 static u16_t uip_reasslen;
540 static u8_t uip_reassflags;
541 #define UIP_REASS_FLAG_LASTFRAG 0x01
542 static u8_t uip_reasstmr;
544 #define IP_MF 0x20
546 static u8_t
547 uip_reass(void)
549 u16_t offset, len;
550 u16_t i;
552 /* If ip_reasstmr is zero, no packet is present in the buffer, so we
553 write the IP header of the fragment into the reassembly
554 buffer. The timer is updated with the maximum age. */
555 if(uip_reasstmr == 0) {
556 memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN);
557 uip_reasstmr = UIP_REASS_MAXAGE;
558 uip_reassflags = 0;
559 /* Clear the bitmap. */
560 memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap));
563 /* Check if the incoming fragment matches the one currently present
564 in the reasembly buffer. If so, we proceed with copying the
565 fragment into the buffer. */
566 if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
567 BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
568 BUF->destipaddr[0] == FBUF->destipaddr[0] &&
569 BUF->destipaddr[1] == FBUF->destipaddr[1] &&
570 BUF->ipid[0] == FBUF->ipid[0] &&
571 BUF->ipid[1] == FBUF->ipid[1]) {
573 len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
574 offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
576 /* If the offset or the offset + fragment length overflows the
577 reassembly buffer, we discard the entire packet. */
578 if(offset > UIP_REASS_BUFSIZE ||
579 offset + len > UIP_REASS_BUFSIZE) {
580 uip_reasstmr = 0;
581 goto nullreturn;
584 /* Copy the fragment into the reassembly buffer, at the right
585 offset. */
586 memcpy(&uip_reassbuf[UIP_IPH_LEN + offset],
587 (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
588 len);
590 /* Update the bitmap. */
591 if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
592 /* If the two endpoints are in the same byte, we only update
593 that byte. */
595 uip_reassbitmap[offset / (8 * 8)] |=
596 bitmap_bits[(offset / 8 ) & 7] &
597 ~bitmap_bits[((offset + len) / 8 ) & 7];
598 } else {
599 /* If the two endpoints are in different bytes, we update the
600 bytes in the endpoints and fill the stuff inbetween with
601 0xff. */
602 uip_reassbitmap[offset / (8 * 8)] |=
603 bitmap_bits[(offset / 8 ) & 7];
604 for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
605 uip_reassbitmap[i] = 0xff;
607 uip_reassbitmap[(offset + len) / (8 * 8)] |=
608 ~bitmap_bits[((offset + len) / 8 ) & 7];
611 /* If this fragment has the More Fragments flag set to zero, we
612 know that this is the last fragment, so we can calculate the
613 size of the entire packet. We also set the
614 IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
615 the final fragment. */
617 if((BUF->ipoffset[0] & IP_MF) == 0) {
618 uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
619 uip_reasslen = offset + len;
622 /* Finally, we check if we have a full packet in the buffer. We do
623 this by checking if we have the last fragment and if all bits
624 in the bitmap are set. */
625 if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
626 /* Check all bytes up to and including all but the last byte in
627 the bitmap. */
628 for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
629 if(uip_reassbitmap[i] != 0xff) {
630 goto nullreturn;
633 /* Check the last byte in the bitmap. It should contain just the
634 right amount of bits. */
635 if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
636 (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
637 goto nullreturn;
640 /* If we have come this far, we have a full packet in the
641 buffer, so we allocate a pbuf and copy the packet into it. We
642 also reset the timer. */
643 uip_reasstmr = 0;
644 memcpy(BUF, FBUF, uip_reasslen);
646 /* Pretend to be a "normal" (i.e., not fragmented) IP packet
647 from now on. */
648 BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
649 BUF->len[0] = uip_reasslen >> 8;
650 BUF->len[1] = uip_reasslen & 0xff;
651 BUF->ipchksum = 0;
652 BUF->ipchksum = ~(uip_ipchksum());
654 return uip_reasslen;
658 nullreturn:
659 return 0;
661 #endif /* UIP_REASSEMBLY */
662 /*---------------------------------------------------------------------------*/
663 static void
664 uip_add_rcv_nxt(u16_t n)
666 uip_add32(uip_conn->rcv_nxt, n);
667 uip_conn->rcv_nxt[0] = uip_acc32[0];
668 uip_conn->rcv_nxt[1] = uip_acc32[1];
669 uip_conn->rcv_nxt[2] = uip_acc32[2];
670 uip_conn->rcv_nxt[3] = uip_acc32[3];
672 /*---------------------------------------------------------------------------*/
673 void
674 uip_process(u8_t flag)
676 register struct uip_conn *uip_connr = uip_conn;
678 #if UIP_UDP
679 if(flag == UIP_UDP_SEND_CONN) {
680 goto udp_send;
682 #endif /* UIP_UDP */
684 uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
686 /* Check if we were invoked because of a poll request for a
687 particular connection. */
688 if(flag == UIP_POLL_REQUEST) {
689 if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
690 !uip_outstanding(uip_connr)) {
691 uip_flags = UIP_POLL;
692 UIP_APPCALL();
693 goto appsend;
694 #if UIP_ACTIVE_OPEN
695 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
696 /* In the SYN_SENT state, we retransmit out SYN. */
697 BUF->flags = 0;
698 goto tcp_send_syn;
699 #endif /* UIP_ACTIVE_OPEN */
701 goto drop;
703 /* Check if we were invoked because of the perodic timer fireing. */
704 } else if(flag == UIP_TIMER) {
705 #if UIP_REASSEMBLY
706 if(uip_reasstmr != 0) {
707 --uip_reasstmr;
709 #endif /* UIP_REASSEMBLY */
710 /* Increase the initial sequence number. */
711 if(++iss[3] == 0) {
712 if(++iss[2] == 0) {
713 if(++iss[1] == 0) {
714 ++iss[0];
719 /* Reset the length variables. */
720 uip_len = 0;
721 uip_slen = 0;
723 /* Check if the connection is in a state in which we simply wait
724 for the connection to time out. If so, we increase the
725 connection's timer and remove the connection if it times
726 out. */
727 if(uip_connr->tcpstateflags == UIP_TIME_WAIT ||
728 uip_connr->tcpstateflags == UIP_FIN_WAIT_2) {
729 ++(uip_connr->timer);
730 if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
731 uip_connr->tcpstateflags = UIP_CLOSED;
733 } else if(uip_connr->tcpstateflags != UIP_CLOSED) {
734 /* If the connection has outstanding data, we increase the
735 connection's timer and see if it has reached the RTO value
736 in which case we retransmit. */
738 if(uip_outstanding(uip_connr)) {
739 if(uip_connr->timer-- == 0) {
740 if(uip_connr->nrtx == UIP_MAXRTX ||
741 ((uip_connr->tcpstateflags == UIP_SYN_SENT ||
742 uip_connr->tcpstateflags == UIP_SYN_RCVD) &&
743 uip_connr->nrtx == UIP_MAXSYNRTX)) {
744 uip_connr->tcpstateflags = UIP_CLOSED;
746 /* We call UIP_APPCALL() with uip_flags set to
747 UIP_TIMEDOUT to inform the application that the
748 connection has timed out. */
749 uip_flags = UIP_TIMEDOUT;
750 UIP_APPCALL();
752 /* We also send a reset packet to the remote host. */
753 BUF->flags = TCP_RST | TCP_ACK;
754 goto tcp_send_nodata;
757 /* Exponential backoff. */
758 uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
760 uip_connr->nrtx);
761 ++(uip_connr->nrtx);
763 /* Ok, so we need to retransmit. We do this differently
764 depending on which state we are in. In ESTABLISHED, we
765 call upon the application so that it may prepare the
766 data for the retransmit. In SYN_RCVD, we resend the
767 SYNACK that we sent earlier and in LAST_ACK we have to
768 retransmit our FINACK. */
769 UIP_STAT(++uip_stat.tcp.rexmit);
770 switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
771 case UIP_SYN_RCVD:
772 /* In the SYN_RCVD state, we should retransmit our
773 SYNACK. */
774 goto tcp_send_synack;
776 #if UIP_ACTIVE_OPEN
777 case UIP_SYN_SENT:
778 /* In the SYN_SENT state, we retransmit out SYN. */
779 BUF->flags = 0;
780 goto tcp_send_syn;
781 #endif /* UIP_ACTIVE_OPEN */
783 case UIP_ESTABLISHED:
784 /* In the ESTABLISHED state, we call upon the application
785 to do the actual retransmit after which we jump into
786 the code for sending out the packet (the apprexmit
787 label). */
788 uip_flags = UIP_REXMIT;
789 UIP_APPCALL();
790 goto apprexmit;
792 case UIP_FIN_WAIT_1:
793 case UIP_CLOSING:
794 case UIP_LAST_ACK:
795 /* In all these states we should retransmit a FINACK. */
796 goto tcp_send_finack;
800 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
801 /* If there was no need for a retransmission, we poll the
802 application for new data. */
803 uip_flags = UIP_POLL;
804 UIP_APPCALL();
805 goto appsend;
808 goto drop;
810 #if UIP_UDP
811 if(flag == UIP_UDP_TIMER) {
812 if(uip_udp_conn->lport != 0) {
813 uip_conn = NULL;
814 uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
815 uip_len = uip_slen = 0;
816 uip_flags = UIP_POLL;
817 UIP_UDP_APPCALL();
818 goto udp_send;
819 } else {
820 goto drop;
823 #endif
825 /* This is where the input processing starts. */
826 UIP_STAT(++uip_stat.ip.recv);
828 /* Start of IP input header processing code. */
830 #if UIP_CONF_IPV6
831 /* Check validity of the IP header. */
832 if((BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */
833 UIP_STAT(++uip_stat.ip.drop);
834 UIP_STAT(++uip_stat.ip.vhlerr);
835 UIP_LOG("ipv6: invalid version.");
836 goto drop;
838 #else /* UIP_CONF_IPV6 */
839 /* Check validity of the IP header. */
840 if(BUF->vhl != 0x45) { /* IP version and header length. */
841 UIP_STAT(++uip_stat.ip.drop);
842 UIP_STAT(++uip_stat.ip.vhlerr);
843 UIP_LOG("ip: invalid version or header length.");
844 goto drop;
846 #endif /* UIP_CONF_IPV6 */
848 /* Check the size of the packet. If the size reported to us in
849 uip_len is smaller the size reported in the IP header, we assume
850 that the packet has been corrupted in transit. If the size of
851 uip_len is larger than the size reported in the IP packet header,
852 the packet has been padded and we set uip_len to the correct
853 value.. */
855 if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) {
856 uip_len = (BUF->len[0] << 8) + BUF->len[1];
857 #if UIP_CONF_IPV6
858 uip_len += 40; /* The length reported in the IPv6 header is the
859 length of the payload that follows the
860 header. However, uIP uses the uip_len variable
861 for holding the size of the entire packet,
862 including the IP header. For IPv4 this is not a
863 problem as the length field in the IPv4 header
864 contains the length of the entire packet. But
865 for IPv6 we need to add the size of the IPv6
866 header (40 bytes). */
867 #endif /* UIP_CONF_IPV6 */
868 } else {
869 UIP_LOG("ip: packet shorter than reported in IP header.");
870 goto drop;
873 #if !UIP_CONF_IPV6
874 /* Check the fragment flag. */
875 if((BUF->ipoffset[0] & 0x3f) != 0 ||
876 BUF->ipoffset[1] != 0) {
877 #if UIP_REASSEMBLY
878 uip_len = uip_reass();
879 if(uip_len == 0) {
880 goto drop;
882 #else /* UIP_REASSEMBLY */
883 UIP_STAT(++uip_stat.ip.drop);
884 UIP_STAT(++uip_stat.ip.fragerr);
885 UIP_LOG("ip: fragment dropped.");
886 goto drop;
887 #endif /* UIP_REASSEMBLY */
889 #endif /* UIP_CONF_IPV6 */
891 if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) {
892 /* If we are configured to use ping IP address configuration and
893 hasn't been assigned an IP address yet, we accept all ICMP
894 packets. */
895 #if UIP_PINGADDRCONF && !UIP_CONF_IPV6
896 if(BUF->proto == UIP_PROTO_ICMP) {
897 UIP_LOG("ip: possible ping config packet received.");
898 goto icmp_input;
899 } else {
900 UIP_LOG("ip: packet dropped since no address assigned.");
901 goto drop;
903 #endif /* UIP_PINGADDRCONF */
905 } else {
906 /* If IP broadcast support is configured, we check for a broadcast
907 UDP packet, which may be destined to us. */
908 #if UIP_BROADCAST
909 DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum());
910 if(BUF->proto == UIP_PROTO_UDP &&
911 (uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr) ||
912 (BUF->destipaddr.u8[0] & 224) == 224)) { /* XXX this is a
913 hack to be able
914 to receive UDP
915 multicast
916 packets. We check
917 for the bit
918 pattern of the
919 multicast
920 prefix. */
921 goto udp_input;
923 #endif /* UIP_BROADCAST */
925 /* Check if the packet is destined for our IP address. */
926 #if !UIP_CONF_IPV6
927 if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr)) {
928 UIP_STAT(++uip_stat.ip.drop);
929 goto drop;
931 #else /* UIP_CONF_IPV6 */
932 /* For IPv6, packet reception is a little trickier as we need to
933 make sure that we listen to certain multicast addresses (all
934 hosts multicast address, and the solicited-node multicast
935 address) as well. However, we will cheat here and accept all
936 multicast packets that are sent to the ff02::/16 addresses. */
937 if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr) &&
938 BUF->destipaddr.u16[0] != UIP_HTONS(0xff02)) {
939 UIP_STAT(++uip_stat.ip.drop);
940 goto drop;
942 #endif /* UIP_CONF_IPV6 */
945 #if !UIP_CONF_IPV6
946 if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
947 checksum. */
948 UIP_STAT(++uip_stat.ip.drop);
949 UIP_STAT(++uip_stat.ip.chkerr);
950 UIP_LOG("ip: bad checksum.");
951 goto drop;
953 #endif /* UIP_CONF_IPV6 */
955 if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so,
956 proceed with TCP input
957 processing. */
958 goto tcp_input;
961 #if UIP_UDP
962 if(BUF->proto == UIP_PROTO_UDP) {
963 goto udp_input;
965 #endif /* UIP_UDP */
967 #if !UIP_CONF_IPV6
968 /* ICMPv4 processing code follows. */
969 if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
970 here. */
971 UIP_STAT(++uip_stat.ip.drop);
972 UIP_STAT(++uip_stat.ip.protoerr);
973 UIP_LOG("ip: neither tcp nor icmp.");
974 goto drop;
977 #if UIP_PINGADDRCONF
978 icmp_input:
979 #endif /* UIP_PINGADDRCONF */
980 UIP_STAT(++uip_stat.icmp.recv);
982 /* ICMP echo (i.e., ping) processing. This is simple, we only change
983 the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
984 checksum before we return the packet. */
985 if(ICMPBUF->type != ICMP_ECHO) {
986 UIP_STAT(++uip_stat.icmp.drop);
987 UIP_STAT(++uip_stat.icmp.typeerr);
988 UIP_LOG("icmp: not icmp echo.");
989 goto drop;
992 /* If we are configured to use ping IP address assignment, we use
993 the destination IP address of this ping packet and assign it to
994 ourself. */
995 #if UIP_PINGADDRCONF
996 if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) {
997 uip_hostaddr = BUF->destipaddr;
999 #endif /* UIP_PINGADDRCONF */
1001 ICMPBUF->type = ICMP_ECHO_REPLY;
1003 if(ICMPBUF->icmpchksum >= UIP_HTONS(0xffff - (ICMP_ECHO << 8))) {
1004 ICMPBUF->icmpchksum += UIP_HTONS(ICMP_ECHO << 8) + 1;
1005 } else {
1006 ICMPBUF->icmpchksum += UIP_HTONS(ICMP_ECHO << 8);
1009 /* Swap IP addresses. */
1010 uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
1011 uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
1013 UIP_STAT(++uip_stat.icmp.sent);
1014 BUF->ttl = UIP_TTL;
1015 goto ip_send_nolen;
1017 /* End of IPv4 input header processing code. */
1018 #else /* !UIP_CONF_IPV6 */
1020 /* This is IPv6 ICMPv6 processing code. */
1021 DEBUG_PRINTF("icmp6_input: length %d\n", uip_len);
1023 if(BUF->proto != UIP_PROTO_ICMP6) { /* We only allow ICMPv6 packets from
1024 here. */
1025 UIP_STAT(++uip_stat.ip.drop);
1026 UIP_STAT(++uip_stat.ip.protoerr);
1027 UIP_LOG("ip: neither tcp nor icmp6.");
1028 goto drop;
1031 UIP_STAT(++uip_stat.icmp.recv);
1033 /* If we get a neighbor solicitation for our address we should send
1034 a neighbor advertisement message back. */
1035 if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) {
1036 if(uip_ipaddr_cmp(&ICMPBUF->icmp6data, &uip_hostaddr)) {
1038 if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) {
1039 /* Save the sender's address in our neighbor list. */
1040 uip_neighbor_add(&ICMPBUF->srcipaddr, &(ICMPBUF->options[2]));
1043 /* We should now send a neighbor advertisement back to where the
1044 neighbor solicication came from. */
1045 ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
1046 ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */
1048 ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;
1050 uip_ipaddr_copy(&ICMPBUF->destipaddr, &ICMPBUF->srcipaddr);
1051 uip_ipaddr_copy(&ICMPBUF->srcipaddr, &uip_hostaddr);
1052 ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS;
1053 ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */
1054 memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr));
1055 ICMPBUF->icmpchksum = 0;
1056 ICMPBUF->icmpchksum = ~uip_icmp6chksum();
1058 goto send;
1061 goto drop;
1062 } else if(ICMPBUF->type == ICMP6_ECHO) {
1063 /* ICMP echo (i.e., ping) processing. This is simple, we only
1064 change the ICMP type from ECHO to ECHO_REPLY and update the
1065 ICMP checksum before we return the packet. */
1067 ICMPBUF->type = ICMP6_ECHO_REPLY;
1069 uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
1070 uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
1071 ICMPBUF->icmpchksum = 0;
1072 ICMPBUF->icmpchksum = ~uip_icmp6chksum();
1074 UIP_STAT(++uip_stat.icmp.sent);
1075 goto send;
1076 } else {
1077 DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type);
1078 UIP_STAT(++uip_stat.icmp.drop);
1079 UIP_STAT(++uip_stat.icmp.typeerr);
1080 UIP_LOG("icmp: unknown ICMP message.");
1081 goto drop;
1084 /* End of IPv6 ICMP processing. */
1086 #endif /* !UIP_CONF_IPV6 */
1088 #if UIP_UDP
1089 /* UDP input processing. */
1090 udp_input:
1091 /* UDP processing is really just a hack. We don't do anything to the
1092 UDP/IP headers, but let the UDP application do all the hard
1093 work. If the application sets uip_slen, it has a packet to
1094 send. */
1095 #if UIP_UDP_CHECKSUMS
1096 uip_len = uip_len - UIP_IPUDPH_LEN;
1097 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
1098 if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
1099 UIP_STAT(++uip_stat.udp.drop);
1100 UIP_STAT(++uip_stat.udp.chkerr);
1101 UIP_LOG("udp: bad checksum.");
1102 goto drop;
1104 #else /* UIP_UDP_CHECKSUMS */
1105 uip_len = uip_len - UIP_IPUDPH_LEN;
1106 #endif /* UIP_UDP_CHECKSUMS */
1108 /* Make sure that the UDP destination port number is not zero. */
1109 if(UDPBUF->destport == 0) {
1110 UIP_LOG("udp: zero port.");
1111 goto drop;
1114 /* Demultiplex this UDP packet between the UDP "connections". */
1115 for(uip_udp_conn = &uip_udp_conns[0];
1116 uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
1117 ++uip_udp_conn) {
1118 /* If the local UDP port is non-zero, the connection is considered
1119 to be used. If so, the local port number is checked against the
1120 destination port number in the received packet. If the two port
1121 numbers match, the remote port number is checked if the
1122 connection is bound to a remote port. Finally, if the
1123 connection is bound to a remote IP address, the source IP
1124 address of the packet is checked. */
1125 if(uip_udp_conn->lport != 0 &&
1126 UDPBUF->destport == uip_udp_conn->lport &&
1127 (uip_udp_conn->rport == 0 ||
1128 UDPBUF->srcport == uip_udp_conn->rport) &&
1129 (uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_all_zeroes_addr) ||
1130 uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_broadcast_addr) ||
1131 uip_ipaddr_cmp(&BUF->srcipaddr, &uip_udp_conn->ripaddr))) {
1132 goto udp_found;
1135 UIP_LOG("udp: no matching connection found");
1136 #if UIP_CONF_ICMP_DEST_UNREACH && !UIP_CONF_IPV6
1137 /* Copy fields from packet header into payload of this ICMP packet. */
1138 memcpy(&(ICMPBUF->payload[0]), ICMPBUF, UIP_IPH_LEN + 8);
1140 /* Set the ICMP type and code. */
1141 ICMPBUF->type = ICMP_DEST_UNREACHABLE;
1142 ICMPBUF->icode = ICMP_PORT_UNREACHABLE;
1144 /* Calculate the ICMP checksum. */
1145 ICMPBUF->icmpchksum = 0;
1146 ICMPBUF->icmpchksum = ~uip_chksum((u16_t *)&(ICMPBUF->type), 36);
1148 /* Set the IP destination address to be the source address of the
1149 original packet. */
1150 uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
1152 /* Set our IP address as the source address. */
1153 uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
1155 /* The size of the ICMP destination unreachable packet is 36 + the
1156 size of the IP header (20) = 56. */
1157 uip_len = 36 + UIP_IPH_LEN;
1158 ICMPBUF->len[0] = 0;
1159 ICMPBUF->len[1] = (u8_t)uip_len;
1160 ICMPBUF->ttl = UIP_TTL;
1161 ICMPBUF->proto = UIP_PROTO_ICMP;
1163 goto ip_send_nolen;
1164 #else /* UIP_CONF_ICMP_DEST_UNREACH */
1165 goto drop;
1166 #endif /* UIP_CONF_ICMP_DEST_UNREACH */
1168 udp_found:
1169 uip_conn = NULL;
1170 uip_flags = UIP_NEWDATA;
1171 uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
1172 uip_slen = 0;
1173 UIP_UDP_APPCALL();
1175 udp_send:
1176 if(uip_slen == 0) {
1177 goto drop;
1179 uip_len = uip_slen + UIP_IPUDPH_LEN;
1181 #if UIP_CONF_IPV6
1182 /* For IPv6, the IP length field does not include the IPv6 IP header
1183 length. */
1184 BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
1185 BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
1186 #else /* UIP_CONF_IPV6 */
1187 BUF->len[0] = (uip_len >> 8);
1188 BUF->len[1] = (uip_len & 0xff);
1189 #endif /* UIP_CONF_IPV6 */
1191 BUF->ttl = uip_udp_conn->ttl;
1192 BUF->proto = UIP_PROTO_UDP;
1194 UDPBUF->udplen = UIP_HTONS(uip_slen + UIP_UDPH_LEN);
1195 UDPBUF->udpchksum = 0;
1197 BUF->srcport = uip_udp_conn->lport;
1198 BUF->destport = uip_udp_conn->rport;
1200 uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
1201 uip_ipaddr_copy(&BUF->destipaddr, &uip_udp_conn->ripaddr);
1203 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
1205 #if UIP_UDP_CHECKSUMS
1206 /* Calculate UDP checksum. */
1207 UDPBUF->udpchksum = ~(uip_udpchksum());
1208 if(UDPBUF->udpchksum == 0) {
1209 UDPBUF->udpchksum = 0xffff;
1211 #endif /* UIP_UDP_CHECKSUMS */
1213 goto ip_send_nolen;
1214 #endif /* UIP_UDP */
1216 /* TCP input processing. */
1217 tcp_input:
1218 UIP_STAT(++uip_stat.tcp.recv);
1220 /* Start of TCP input header processing code. */
1222 if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
1223 checksum. */
1224 UIP_STAT(++uip_stat.tcp.drop);
1225 UIP_STAT(++uip_stat.tcp.chkerr);
1226 UIP_LOG("tcp: bad checksum.");
1227 goto drop;
1230 /* Make sure that the TCP port number is not zero. */
1231 if(BUF->destport == 0 || BUF->srcport == 0) {
1232 UIP_LOG("tcp: zero port.");
1233 goto drop;
1236 /* Demultiplex this segment. */
1237 /* First check any active connections. */
1238 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
1239 ++uip_connr) {
1240 if(uip_connr->tcpstateflags != UIP_CLOSED &&
1241 BUF->destport == uip_connr->lport &&
1242 BUF->srcport == uip_connr->rport &&
1243 uip_ipaddr_cmp(&BUF->srcipaddr, &uip_connr->ripaddr)) {
1244 goto found;
1248 /* If we didn't find and active connection that expected the packet,
1249 either this packet is an old duplicate, or this is a SYN packet
1250 destined for a connection in LISTEN. If the SYN flag isn't set,
1251 it is an old packet and we send a RST. */
1252 if((BUF->flags & TCP_CTL) != TCP_SYN) {
1253 goto reset;
1256 tmp16 = BUF->destport;
1257 /* Next, check listening connections. */
1258 for(c = 0; c < UIP_LISTENPORTS; ++c) {
1259 if(tmp16 == uip_listenports[c]) {
1260 goto found_listen;
1264 /* No matching connection found, so we send a RST packet. */
1265 UIP_STAT(++uip_stat.tcp.synrst);
1267 reset:
1268 /* We do not send resets in response to resets. */
1269 if(BUF->flags & TCP_RST) {
1270 goto drop;
1273 UIP_STAT(++uip_stat.tcp.rst);
1275 BUF->flags = TCP_RST | TCP_ACK;
1276 uip_len = UIP_IPTCPH_LEN;
1277 BUF->tcpoffset = 5 << 4;
1279 /* Flip the seqno and ackno fields in the TCP header. */
1280 c = BUF->seqno[3];
1281 BUF->seqno[3] = BUF->ackno[3];
1282 BUF->ackno[3] = c;
1284 c = BUF->seqno[2];
1285 BUF->seqno[2] = BUF->ackno[2];
1286 BUF->ackno[2] = c;
1288 c = BUF->seqno[1];
1289 BUF->seqno[1] = BUF->ackno[1];
1290 BUF->ackno[1] = c;
1292 c = BUF->seqno[0];
1293 BUF->seqno[0] = BUF->ackno[0];
1294 BUF->ackno[0] = c;
1296 /* We also have to increase the sequence number we are
1297 acknowledging. If the least significant byte overflowed, we need
1298 to propagate the carry to the other bytes as well. */
1299 if(++BUF->ackno[3] == 0) {
1300 if(++BUF->ackno[2] == 0) {
1301 if(++BUF->ackno[1] == 0) {
1302 ++BUF->ackno[0];
1307 /* Swap port numbers. */
1308 tmp16 = BUF->srcport;
1309 BUF->srcport = BUF->destport;
1310 BUF->destport = tmp16;
1312 /* Swap IP addresses. */
1313 uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
1314 uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
1316 /* And send out the RST packet! */
1317 goto tcp_send_noconn;
1319 /* This label will be jumped to if we matched the incoming packet
1320 with a connection in LISTEN. In that case, we should create a new
1321 connection and send a SYNACK in return. */
1322 found_listen:
1323 /* First we check if there are any connections avaliable. Unused
1324 connections are kept in the same table as used connections, but
1325 unused ones have the tcpstate set to CLOSED. Also, connections in
1326 TIME_WAIT are kept track of and we'll use the oldest one if no
1327 CLOSED connections are found. Thanks to Eddie C. Dost for a very
1328 nice algorithm for the TIME_WAIT search. */
1329 uip_connr = 0;
1330 for(c = 0; c < UIP_CONNS; ++c) {
1331 if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
1332 uip_connr = &uip_conns[c];
1333 break;
1335 if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
1336 if(uip_connr == 0 ||
1337 uip_conns[c].timer > uip_connr->timer) {
1338 uip_connr = &uip_conns[c];
1343 if(uip_connr == 0) {
1344 /* All connections are used already, we drop packet and hope that
1345 the remote end will retransmit the packet at a time when we
1346 have more spare connections. */
1347 UIP_STAT(++uip_stat.tcp.syndrop);
1348 UIP_LOG("tcp: found no unused connections.");
1349 goto drop;
1351 uip_conn = uip_connr;
1353 /* Fill in the necessary fields for the new connection. */
1354 uip_connr->rto = uip_connr->timer = UIP_RTO;
1355 uip_connr->sa = 0;
1356 uip_connr->sv = 4;
1357 uip_connr->nrtx = 0;
1358 uip_connr->lport = BUF->destport;
1359 uip_connr->rport = BUF->srcport;
1360 uip_ipaddr_copy(&uip_connr->ripaddr, &BUF->srcipaddr);
1361 uip_connr->tcpstateflags = UIP_SYN_RCVD;
1363 uip_connr->snd_nxt[0] = iss[0];
1364 uip_connr->snd_nxt[1] = iss[1];
1365 uip_connr->snd_nxt[2] = iss[2];
1366 uip_connr->snd_nxt[3] = iss[3];
1367 uip_connr->len = 1;
1369 /* rcv_nxt should be the seqno from the incoming packet + 1. */
1370 uip_connr->rcv_nxt[3] = BUF->seqno[3];
1371 uip_connr->rcv_nxt[2] = BUF->seqno[2];
1372 uip_connr->rcv_nxt[1] = BUF->seqno[1];
1373 uip_connr->rcv_nxt[0] = BUF->seqno[0];
1374 uip_add_rcv_nxt(1);
1376 /* Parse the TCP MSS option, if present. */
1377 if((BUF->tcpoffset & 0xf0) > 0x50) {
1378 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
1379 opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
1380 if(opt == TCP_OPT_END) {
1381 /* End of options. */
1382 break;
1383 } else if(opt == TCP_OPT_NOOP) {
1384 ++c;
1385 /* NOP option. */
1386 } else if(opt == TCP_OPT_MSS &&
1387 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
1388 /* An MSS option with the right option length. */
1389 tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
1390 (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
1391 uip_connr->initialmss = uip_connr->mss =
1392 tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
1394 /* And we are done processing options. */
1395 break;
1396 } else {
1397 /* All other options have a length field, so that we easily
1398 can skip past them. */
1399 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
1400 /* If the length field is zero, the options are malformed
1401 and we don't process them further. */
1402 break;
1404 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
1409 /* Our response will be a SYNACK. */
1410 #if UIP_ACTIVE_OPEN
1411 tcp_send_synack:
1412 BUF->flags = TCP_ACK;
1414 tcp_send_syn:
1415 BUF->flags |= TCP_SYN;
1416 #else /* UIP_ACTIVE_OPEN */
1417 tcp_send_synack:
1418 BUF->flags = TCP_SYN | TCP_ACK;
1419 #endif /* UIP_ACTIVE_OPEN */
1421 /* We send out the TCP Maximum Segment Size option with our
1422 SYNACK. */
1423 BUF->optdata[0] = TCP_OPT_MSS;
1424 BUF->optdata[1] = TCP_OPT_MSS_LEN;
1425 BUF->optdata[2] = (UIP_TCP_MSS) / 256;
1426 BUF->optdata[3] = (UIP_TCP_MSS) & 255;
1427 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
1428 BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
1429 goto tcp_send;
1431 /* This label will be jumped to if we found an active connection. */
1432 found:
1433 uip_conn = uip_connr;
1434 uip_flags = 0;
1435 /* We do a very naive form of TCP reset processing; we just accept
1436 any RST and kill our connection. We should in fact check if the
1437 sequence number of this reset is wihtin our advertised window
1438 before we accept the reset. */
1439 if(BUF->flags & TCP_RST) {
1440 uip_connr->tcpstateflags = UIP_CLOSED;
1441 UIP_LOG("tcp: got reset, aborting connection.");
1442 uip_flags = UIP_ABORT;
1443 UIP_APPCALL();
1444 goto drop;
1446 /* Calculate the length of the data, if the application has sent
1447 any data to us. */
1448 c = (BUF->tcpoffset >> 4) << 2;
1449 /* uip_len will contain the length of the actual TCP data. This is
1450 calculated by subtracing the length of the TCP header (in
1451 c) and the length of the IP header (20 bytes). */
1452 uip_len = uip_len - c - UIP_IPH_LEN;
1454 /* First, check if the sequence number of the incoming packet is
1455 what we're expecting next. If not, we send out an ACK with the
1456 correct numbers in, unless we are in the SYN_RCVD state and
1457 receive a SYN, in which case we should retransmit our SYNACK
1458 (which is done futher down). */
1459 if(!((((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
1460 ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
1461 (((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) &&
1462 ((BUF->flags & TCP_CTL) == TCP_SYN)))) {
1463 if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
1464 (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
1465 BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
1466 BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
1467 BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
1468 goto tcp_send_ack;
1472 /* Next, check if the incoming segment acknowledges any outstanding
1473 data. If so, we update the sequence number, reset the length of
1474 the outstanding data, calculate RTT estimations, and reset the
1475 retransmission timer. */
1476 if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
1477 uip_add32(uip_connr->snd_nxt, uip_connr->len);
1479 if(BUF->ackno[0] == uip_acc32[0] &&
1480 BUF->ackno[1] == uip_acc32[1] &&
1481 BUF->ackno[2] == uip_acc32[2] &&
1482 BUF->ackno[3] == uip_acc32[3]) {
1483 /* Update sequence number. */
1484 uip_connr->snd_nxt[0] = uip_acc32[0];
1485 uip_connr->snd_nxt[1] = uip_acc32[1];
1486 uip_connr->snd_nxt[2] = uip_acc32[2];
1487 uip_connr->snd_nxt[3] = uip_acc32[3];
1489 /* Do RTT estimation, unless we have done retransmissions. */
1490 if(uip_connr->nrtx == 0) {
1491 signed char m;
1492 m = uip_connr->rto - uip_connr->timer;
1493 /* This is taken directly from VJs original code in his paper */
1494 m = m - (uip_connr->sa >> 3);
1495 uip_connr->sa += m;
1496 if(m < 0) {
1497 m = -m;
1499 m = m - (uip_connr->sv >> 2);
1500 uip_connr->sv += m;
1501 uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
1504 /* Set the acknowledged flag. */
1505 uip_flags = UIP_ACKDATA;
1506 /* Reset the retransmission timer. */
1507 uip_connr->timer = uip_connr->rto;
1509 /* Reset length of outstanding data. */
1510 uip_connr->len = 0;
1515 /* Do different things depending on in what state the connection is. */
1516 switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
1517 /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
1518 implemented, since we force the application to close when the
1519 peer sends a FIN (hence the application goes directly from
1520 ESTABLISHED to LAST_ACK). */
1521 case UIP_SYN_RCVD:
1522 /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
1523 we are waiting for an ACK that acknowledges the data we sent
1524 out the last time. Therefore, we want to have the UIP_ACKDATA
1525 flag set. If so, we enter the ESTABLISHED state. */
1526 if(uip_flags & UIP_ACKDATA) {
1527 uip_connr->tcpstateflags = UIP_ESTABLISHED;
1528 uip_flags = UIP_CONNECTED;
1529 uip_connr->len = 0;
1530 if(uip_len > 0) {
1531 uip_flags |= UIP_NEWDATA;
1532 uip_add_rcv_nxt(uip_len);
1534 uip_slen = 0;
1535 UIP_APPCALL();
1536 goto appsend;
1538 /* We need to retransmit the SYNACK */
1539 if((BUF->flags & TCP_CTL) == TCP_SYN) {
1540 goto tcp_send_synack;
1542 goto drop;
1543 #if UIP_ACTIVE_OPEN
1544 case UIP_SYN_SENT:
1545 /* In SYN_SENT, we wait for a SYNACK that is sent in response to
1546 our SYN. The rcv_nxt is set to sequence number in the SYNACK
1547 plus one, and we send an ACK. We move into the ESTABLISHED
1548 state. */
1549 if((uip_flags & UIP_ACKDATA) &&
1550 (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
1552 /* Parse the TCP MSS option, if present. */
1553 if((BUF->tcpoffset & 0xf0) > 0x50) {
1554 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
1555 opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
1556 if(opt == TCP_OPT_END) {
1557 /* End of options. */
1558 break;
1559 } else if(opt == TCP_OPT_NOOP) {
1560 ++c;
1561 /* NOP option. */
1562 } else if(opt == TCP_OPT_MSS &&
1563 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
1564 /* An MSS option with the right option length. */
1565 tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
1566 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
1567 uip_connr->initialmss =
1568 uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
1570 /* And we are done processing options. */
1571 break;
1572 } else {
1573 /* All other options have a length field, so that we easily
1574 can skip past them. */
1575 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
1576 /* If the length field is zero, the options are malformed
1577 and we don't process them further. */
1578 break;
1580 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
1584 uip_connr->tcpstateflags = UIP_ESTABLISHED;
1585 uip_connr->rcv_nxt[0] = BUF->seqno[0];
1586 uip_connr->rcv_nxt[1] = BUF->seqno[1];
1587 uip_connr->rcv_nxt[2] = BUF->seqno[2];
1588 uip_connr->rcv_nxt[3] = BUF->seqno[3];
1589 uip_add_rcv_nxt(1);
1590 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
1591 uip_connr->len = 0;
1592 uip_len = 0;
1593 uip_slen = 0;
1594 UIP_APPCALL();
1595 goto appsend;
1597 /* Inform the application that the connection failed */
1598 uip_flags = UIP_ABORT;
1599 UIP_APPCALL();
1600 /* The connection is closed after we send the RST */
1601 uip_conn->tcpstateflags = UIP_CLOSED;
1602 goto reset;
1603 #endif /* UIP_ACTIVE_OPEN */
1605 case UIP_ESTABLISHED:
1606 /* In the ESTABLISHED state, we call upon the application to feed
1607 data into the uip_buf. If the UIP_ACKDATA flag is set, the
1608 application should put new data into the buffer, otherwise we are
1609 retransmitting an old segment, and the application should put that
1610 data into the buffer.
1612 If the incoming packet is a FIN, we should close the connection on
1613 this side as well, and we send out a FIN and enter the LAST_ACK
1614 state. We require that there is no outstanding data; otherwise the
1615 sequence numbers will be screwed up. */
1617 if(BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
1618 if(uip_outstanding(uip_connr)) {
1619 goto drop;
1621 uip_add_rcv_nxt(1 + uip_len);
1622 uip_flags |= UIP_CLOSE;
1623 if(uip_len > 0) {
1624 uip_flags |= UIP_NEWDATA;
1626 UIP_APPCALL();
1627 uip_connr->len = 1;
1628 uip_connr->tcpstateflags = UIP_LAST_ACK;
1629 uip_connr->nrtx = 0;
1630 tcp_send_finack:
1631 BUF->flags = TCP_FIN | TCP_ACK;
1632 goto tcp_send_nodata;
1635 /* Check the URG flag. If this is set, the segment carries urgent
1636 data that we must pass to the application. */
1637 if((BUF->flags & TCP_URG) != 0) {
1638 #if UIP_URGDATA > 0
1639 uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
1640 if(uip_urglen > uip_len) {
1641 /* There is more urgent data in the next segment to come. */
1642 uip_urglen = uip_len;
1644 uip_add_rcv_nxt(uip_urglen);
1645 uip_len -= uip_urglen;
1646 uip_urgdata = uip_appdata;
1647 uip_appdata += uip_urglen;
1648 } else {
1649 uip_urglen = 0;
1650 #else /* UIP_URGDATA > 0 */
1651 uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]);
1652 uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
1653 #endif /* UIP_URGDATA > 0 */
1656 /* If uip_len > 0 we have TCP data in the packet, and we flag this
1657 by setting the UIP_NEWDATA flag and update the sequence number
1658 we acknowledge. If the application has stopped the dataflow
1659 using uip_stop(), we must not accept any data packets from the
1660 remote host. */
1661 if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
1662 uip_flags |= UIP_NEWDATA;
1663 uip_add_rcv_nxt(uip_len);
1666 /* Check if the available buffer space advertised by the other end
1667 is smaller than the initial MSS for this connection. If so, we
1668 set the current MSS to the window size to ensure that the
1669 application does not send more data than the other end can
1670 handle.
1672 If the remote host advertises a zero window, we set the MSS to
1673 the initial MSS so that the application will send an entire MSS
1674 of data. This data will not be acknowledged by the receiver,
1675 and the application will retransmit it. This is called the
1676 "persistent timer" and uses the retransmission mechanim.
1678 tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1];
1679 if(tmp16 > uip_connr->initialmss ||
1680 tmp16 == 0) {
1681 tmp16 = uip_connr->initialmss;
1683 uip_connr->mss = tmp16;
1685 /* If this packet constitutes an ACK for outstanding data (flagged
1686 by the UIP_ACKDATA flag, we should call the application since it
1687 might want to send more data. If the incoming packet had data
1688 from the peer (as flagged by the UIP_NEWDATA flag), the
1689 application must also be notified.
1691 When the application is called, the global variable uip_len
1692 contains the length of the incoming data. The application can
1693 access the incoming data through the global pointer
1694 uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN
1695 bytes into the uip_buf array.
1697 If the application wishes to send any data, this data should be
1698 put into the uip_appdata and the length of the data should be
1699 put into uip_len. If the application don't have any data to
1700 send, uip_len must be set to 0. */
1701 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
1702 uip_slen = 0;
1703 UIP_APPCALL();
1705 appsend:
1707 if(uip_flags & UIP_ABORT) {
1708 uip_slen = 0;
1709 uip_connr->tcpstateflags = UIP_CLOSED;
1710 BUF->flags = TCP_RST | TCP_ACK;
1711 goto tcp_send_nodata;
1714 if(uip_flags & UIP_CLOSE) {
1715 uip_slen = 0;
1716 uip_connr->len = 1;
1717 uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
1718 uip_connr->nrtx = 0;
1719 BUF->flags = TCP_FIN | TCP_ACK;
1720 goto tcp_send_nodata;
1723 /* If uip_slen > 0, the application has data to be sent. */
1724 if(uip_slen > 0) {
1726 /* If the connection has acknowledged data, the contents of
1727 the ->len variable should be discarded. */
1728 if((uip_flags & UIP_ACKDATA) != 0) {
1729 uip_connr->len = 0;
1732 /* If the ->len variable is non-zero the connection has
1733 already data in transit and cannot send anymore right
1734 now. */
1735 if(uip_connr->len == 0) {
1737 /* The application cannot send more than what is allowed by
1738 the mss (the minumum of the MSS and the available
1739 window). */
1740 if(uip_slen > uip_connr->mss) {
1741 uip_slen = uip_connr->mss;
1744 /* Remember how much data we send out now so that we know
1745 when everything has been acknowledged. */
1746 uip_connr->len = uip_slen;
1747 } else {
1749 /* If the application already had unacknowledged data, we
1750 make sure that the application does not send (i.e.,
1751 retransmit) out more than it previously sent out. */
1752 uip_slen = uip_connr->len;
1755 uip_connr->nrtx = 0;
1756 apprexmit:
1757 uip_appdata = uip_sappdata;
1759 /* If the application has data to be sent, or if the incoming
1760 packet had new data in it, we must send out a packet. */
1761 if(uip_slen > 0 && uip_connr->len > 0) {
1762 /* Add the length of the IP and TCP headers. */
1763 uip_len = uip_connr->len + UIP_TCPIP_HLEN;
1764 /* We always set the ACK flag in response packets. */
1765 BUF->flags = TCP_ACK | TCP_PSH;
1766 /* Send the packet. */
1767 goto tcp_send_noopts;
1769 /* If there is no data to send, just send out a pure ACK if
1770 there is newdata. */
1771 if(uip_flags & UIP_NEWDATA) {
1772 uip_len = UIP_TCPIP_HLEN;
1773 BUF->flags = TCP_ACK;
1774 goto tcp_send_noopts;
1777 goto drop;
1778 case UIP_LAST_ACK:
1779 /* We can close this connection if the peer has acknowledged our
1780 FIN. This is indicated by the UIP_ACKDATA flag. */
1781 if(uip_flags & UIP_ACKDATA) {
1782 uip_connr->tcpstateflags = UIP_CLOSED;
1783 uip_flags = UIP_CLOSE;
1784 UIP_APPCALL();
1786 break;
1788 case UIP_FIN_WAIT_1:
1789 /* The application has closed the connection, but the remote host
1790 hasn't closed its end yet. Thus we do nothing but wait for a
1791 FIN from the other side. */
1792 if(uip_len > 0) {
1793 uip_add_rcv_nxt(uip_len);
1795 if(BUF->flags & TCP_FIN) {
1796 if(uip_flags & UIP_ACKDATA) {
1797 uip_connr->tcpstateflags = UIP_TIME_WAIT;
1798 uip_connr->timer = 0;
1799 uip_connr->len = 0;
1800 } else {
1801 uip_connr->tcpstateflags = UIP_CLOSING;
1803 uip_add_rcv_nxt(1);
1804 uip_flags = UIP_CLOSE;
1805 UIP_APPCALL();
1806 goto tcp_send_ack;
1807 } else if(uip_flags & UIP_ACKDATA) {
1808 uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
1809 uip_connr->len = 0;
1810 goto drop;
1812 if(uip_len > 0) {
1813 goto tcp_send_ack;
1815 goto drop;
1817 case UIP_FIN_WAIT_2:
1818 if(uip_len > 0) {
1819 uip_add_rcv_nxt(uip_len);
1821 if(BUF->flags & TCP_FIN) {
1822 uip_connr->tcpstateflags = UIP_TIME_WAIT;
1823 uip_connr->timer = 0;
1824 uip_add_rcv_nxt(1);
1825 uip_flags = UIP_CLOSE;
1826 UIP_APPCALL();
1827 goto tcp_send_ack;
1829 if(uip_len > 0) {
1830 goto tcp_send_ack;
1832 goto drop;
1834 case UIP_TIME_WAIT:
1835 goto tcp_send_ack;
1837 case UIP_CLOSING:
1838 if(uip_flags & UIP_ACKDATA) {
1839 uip_connr->tcpstateflags = UIP_TIME_WAIT;
1840 uip_connr->timer = 0;
1843 goto drop;
1845 /* We jump here when we are ready to send the packet, and just want
1846 to set the appropriate TCP sequence numbers in the TCP header. */
1847 tcp_send_ack:
1848 BUF->flags = TCP_ACK;
1850 tcp_send_nodata:
1851 uip_len = UIP_IPTCPH_LEN;
1853 tcp_send_noopts:
1854 BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
1856 /* We're done with the input processing. We are now ready to send a
1857 reply. Our job is to fill in all the fields of the TCP and IP
1858 headers before calculating the checksum and finally send the
1859 packet. */
1860 tcp_send:
1861 BUF->ackno[0] = uip_connr->rcv_nxt[0];
1862 BUF->ackno[1] = uip_connr->rcv_nxt[1];
1863 BUF->ackno[2] = uip_connr->rcv_nxt[2];
1864 BUF->ackno[3] = uip_connr->rcv_nxt[3];
1866 BUF->seqno[0] = uip_connr->snd_nxt[0];
1867 BUF->seqno[1] = uip_connr->snd_nxt[1];
1868 BUF->seqno[2] = uip_connr->snd_nxt[2];
1869 BUF->seqno[3] = uip_connr->snd_nxt[3];
1871 BUF->proto = UIP_PROTO_TCP;
1873 BUF->srcport = uip_connr->lport;
1874 BUF->destport = uip_connr->rport;
1876 uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
1877 uip_ipaddr_copy(&BUF->destipaddr, &uip_connr->ripaddr);
1879 if(uip_connr->tcpstateflags & UIP_STOPPED) {
1880 /* If the connection has issued uip_stop(), we advertise a zero
1881 window so that the remote host will stop sending data. */
1882 BUF->wnd[0] = BUF->wnd[1] = 0;
1883 } else {
1884 BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
1885 BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
1888 tcp_send_noconn:
1889 BUF->ttl = UIP_TTL;
1890 #if UIP_CONF_IPV6
1891 /* For IPv6, the IP length field does not include the IPv6 IP header
1892 length. */
1893 BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
1894 BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
1895 #else /* UIP_CONF_IPV6 */
1896 BUF->len[0] = (uip_len >> 8);
1897 BUF->len[1] = (uip_len & 0xff);
1898 #endif /* UIP_CONF_IPV6 */
1900 BUF->urgp[0] = BUF->urgp[1] = 0;
1902 /* Calculate TCP checksum. */
1903 BUF->tcpchksum = 0;
1904 BUF->tcpchksum = ~(uip_tcpchksum());
1906 ip_send_nolen:
1907 #if UIP_CONF_IPV6
1908 BUF->vtc = 0x60;
1909 BUF->tcflow = 0x00;
1910 BUF->flow = 0x00;
1911 #else /* UIP_CONF_IPV6 */
1912 BUF->vhl = 0x45;
1913 BUF->tos = 0;
1914 BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
1915 ++ipid;
1916 BUF->ipid[0] = ipid >> 8;
1917 BUF->ipid[1] = ipid & 0xff;
1918 /* Calculate IP checksum. */
1919 BUF->ipchksum = 0;
1920 BUF->ipchksum = ~(uip_ipchksum());
1921 DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum());
1922 #endif /* UIP_CONF_IPV6 */
1923 UIP_STAT(++uip_stat.tcp.sent);
1924 #if UIP_CONF_IPV6
1925 send:
1926 #endif /* UIP_CONF_IPV6 */
1927 DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len,
1928 (BUF->len[0] << 8) | BUF->len[1]);
1930 UIP_STAT(++uip_stat.ip.sent);
1931 /* Return and let the caller do the actual transmission. */
1932 uip_flags = 0;
1933 return;
1935 drop:
1936 uip_len = 0;
1937 uip_flags = 0;
1938 return;
1940 /*---------------------------------------------------------------------------*/
1941 u16_t
1942 uip_htons(u16_t val)
1944 return UIP_HTONS(val);
1947 u32_t
1948 uip_htonl(u32_t val)
1950 return UIP_HTONL(val);
1952 /*---------------------------------------------------------------------------*/
1953 void
1954 uip_send(const void *data, int len)
1956 int copylen;
1957 #define MIN(a,b) ((a) < (b)? (a): (b))
1958 copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN -
1959 (int)((char *)uip_sappdata - (char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]));
1960 if(copylen > 0) {
1961 uip_slen = copylen;
1962 if(data != uip_sappdata) {
1963 memcpy(uip_sappdata, (data), uip_slen);
1967 /*---------------------------------------------------------------------------*/
1968 /** @} */
1969 #endif /* UIP_CONF_IPV6 */