1 #define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/
4 * \defgroup uip The uIP TCP/IP stack
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.
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
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
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.1 2008/08/06 23:21:19 andrewlxia 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.
83 #include <uip/uipopt.h>
84 #include <uip/uip_arch.h>
87 #include <uip/uip-neighbor.h>
88 #endif /* UIP_CONF_IPV6 */
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 */
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)};
110 uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
111 #endif /* UIP_FIXEDADDR */
113 static const uip_ipaddr_t all_ones_addr =
115 {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff};
116 #else /* UIP_CONF_IPV6 */
118 #endif /* UIP_CONF_IPV6 */
119 static const uip_ipaddr_t all_zeroes_addr =
121 {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
122 #else /* UIP_CONF_IPV6 */
124 #endif /* UIP_CONF_IPV6 */
128 const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
135 struct uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}};
138 #ifndef UIP_CONF_EXTERNAL_BUFFER
139 u8_t uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains
141 #endif /* UIP_CONF_EXTERNAL_BUFFER */
143 void *uip_appdata; /* The uip_appdata pointer points to
145 void *uip_sappdata; /* The uip_appdata pointer points to
146 the application data which is to
149 void *uip_urgdata; /* The uip_urgdata pointer points to
150 urgent data (out-of-band data), if
152 u16_t uip_urglen, uip_surglen;
153 #endif /* UIP_URGDATA > 0 */
155 u16_t uip_len, uip_slen;
156 /* The uip_len is either 8 or 16 bits,
157 depending on the maximum packet
160 u8_t uip_flags; /* The uip_flags variable is used for
161 communication between the TCP/IP stack
162 and the application program. */
163 struct uip_conn *uip_conn; /* uip_conn always points to the current
166 struct uip_conn uip_conns[UIP_CONNS];
167 /* The uip_conns array holds all TCP
169 u16_t uip_listenports[UIP_LISTENPORTS];
170 /* The uip_listenports list all currently
173 struct uip_udp_conn *uip_udp_conn;
174 struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
177 static u16_t ipid; /* Ths ipid variable is an increasing
178 number that is used for the IP ID
181 void uip_setipid(u16_t id) { ipid = id; }
183 static u8_t iss[4]; /* The iss variable is used for the TCP
184 initial sequence number. */
187 static u16_t lastport; /* Keeps track of the last port used for
189 #endif /* UIP_ACTIVE_OPEN */
191 /* Temporary variables. */
196 /* Structures and definitions. */
205 #define TCP_OPT_END 0 /* End of TCP options list */
206 #define TCP_OPT_NOOP 1 /* "No-operation" TCP option */
207 #define TCP_OPT_MSS 2 /* Maximum segment size TCP option */
209 #define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */
211 #define ICMP_ECHO_REPLY 0
214 #define ICMP6_ECHO_REPLY 129
215 #define ICMP6_ECHO 128
216 #define ICMP6_NEIGHBOR_SOLICITATION 135
217 #define ICMP6_NEIGHBOR_ADVERTISEMENT 136
219 #define ICMP6_FLAG_S (1 << 6)
221 #define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1
222 #define ICMP6_OPTION_TARGET_LINK_ADDRESS 2
226 #define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
227 #define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
228 #define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
229 #define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
232 #if UIP_STATISTICS == 1
233 struct uip_stats uip_stat;
234 #define UIP_STAT(s) s
237 #endif /* UIP_STATISTICS == 1 */
241 void uip_log(char *msg);
242 #define UIP_LOG(m) uip_log(m)
245 #endif /* UIP_LOGGING == 1 */
249 uip_add32(u8_t *op32, u16_t op16)
251 uip_acc32[3] = op32[3] + (op16 & 0xff);
252 uip_acc32[2] = op32[2] + (op16 >> 8);
253 uip_acc32[1] = op32[1];
254 uip_acc32[0] = op32[0];
256 if(uip_acc32[2] < (op16 >> 8)) {
258 if(uip_acc32[1] == 0) {
264 if(uip_acc32[3] < (op16 & 0xff)) {
266 if(uip_acc32[2] == 0) {
268 if(uip_acc32[1] == 0) {
275 #endif /* UIP_ARCH_ADD32 */
277 #if ! UIP_ARCH_CHKSUM
278 /*---------------------------------------------------------------------------*/
280 chksum(u16_t sum, const u8_t *data, u16_t len)
284 const u8_t *last_byte;
287 last_byte = data + len - 1;
289 while(dataptr < last_byte) { /* At least two more bytes */
290 t = (dataptr[0] << 8) + dataptr[1];
298 if(dataptr == last_byte) {
299 t = (dataptr[0] << 8) + 0;
306 /* Return sum in host byte order. */
309 /*---------------------------------------------------------------------------*/
311 uip_chksum(u16_t *data, u16_t len)
313 return htons(chksum(0, (u8_t *)data, len));
315 /*---------------------------------------------------------------------------*/
316 #ifndef UIP_ARCH_IPCHKSUM
322 sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
323 DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum);
324 return (sum == 0) ? 0xffff : htons(sum);
327 /*---------------------------------------------------------------------------*/
329 upper_layer_chksum(u8_t proto)
331 u16_t upper_layer_len;
335 upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]);
336 #else /* UIP_CONF_IPV6 */
337 upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;
338 #endif /* UIP_CONF_IPV6 */
340 /* First sum pseudoheader. */
342 /* IP protocol and length fields. This addition cannot carry. */
343 sum = upper_layer_len + proto;
344 /* Sum IP source and destination addresses. */
345 sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t));
347 /* Sum TCP header and data. */
348 sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN],
351 return (sum == 0) ? 0xffff : htons(sum);
353 /*---------------------------------------------------------------------------*/
356 uip_icmp6chksum(void)
358 return upper_layer_chksum(UIP_PROTO_ICMP6);
361 #endif /* UIP_CONF_IPV6 */
362 /*---------------------------------------------------------------------------*/
366 return upper_layer_chksum(UIP_PROTO_TCP);
368 /*---------------------------------------------------------------------------*/
369 #if UIP_UDP_CHECKSUMS
373 return upper_layer_chksum(UIP_PROTO_UDP);
375 #endif /* UIP_UDP_CHECKSUMS */
376 #endif /* UIP_ARCH_CHKSUM */
377 /*---------------------------------------------------------------------------*/
381 for(c = 0; c < UIP_LISTENPORTS; ++c) {
382 uip_listenports[c] = 0;
384 for(c = 0; c < UIP_CONNS; ++c) {
385 uip_conns[c].tcpstateflags = UIP_CLOSED;
389 #endif /* UIP_ACTIVE_OPEN */
392 for(c = 0; c < UIP_UDP_CONNS; ++c) {
393 uip_udp_conns[c].lport = 0;
398 /* IPv4 initialization. */
399 #if UIP_FIXEDADDR == 0
400 /* uip_hostaddr[0] = uip_hostaddr[1] = 0;*/
401 #endif /* UIP_FIXEDADDR */
404 /*---------------------------------------------------------------------------*/
407 uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
409 register struct uip_conn *conn, *cconn;
411 /* Find an unused local port. */
415 if(lastport >= 32000) {
419 /* Check if this port is already in use, and if so try to find
421 for(c = 0; c < UIP_CONNS; ++c) {
422 conn = &uip_conns[c];
423 if(conn->tcpstateflags != UIP_CLOSED &&
424 conn->lport == htons(lastport)) {
430 for(c = 0; c < UIP_CONNS; ++c) {
431 cconn = &uip_conns[c];
432 if(cconn->tcpstateflags == UIP_CLOSED) {
436 if(cconn->tcpstateflags == UIP_TIME_WAIT) {
438 cconn->timer > conn->timer) {
448 conn->tcpstateflags = UIP_SYN_SENT;
450 conn->snd_nxt[0] = iss[0];
451 conn->snd_nxt[1] = iss[1];
452 conn->snd_nxt[2] = iss[2];
453 conn->snd_nxt[3] = iss[3];
455 conn->initialmss = conn->mss = UIP_TCP_MSS;
457 conn->len = 1; /* TCP length of the SYN is one. */
459 conn->timer = 1; /* Send the SYN next time around. */
462 conn->sv = 16; /* Initial value of the RTT variance. */
463 conn->lport = htons(lastport);
465 uip_ipaddr_copy(&conn->ripaddr, ripaddr);
469 #endif /* UIP_ACTIVE_OPEN */
470 /*---------------------------------------------------------------------------*/
472 struct uip_udp_conn *
473 uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport)
475 register struct uip_udp_conn *conn;
477 /* Find an unused local port. */
481 if(lastport >= 32000) {
485 for(c = 0; c < UIP_UDP_CONNS; ++c) {
486 if(uip_udp_conns[c].lport == htons(lastport)) {
493 for(c = 0; c < UIP_UDP_CONNS; ++c) {
494 if(uip_udp_conns[c].lport == 0) {
495 conn = &uip_udp_conns[c];
504 conn->lport = HTONS(lastport);
506 if(ripaddr == NULL) {
507 memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t));
509 uip_ipaddr_copy(&conn->ripaddr, ripaddr);
516 /*---------------------------------------------------------------------------*/
518 uip_unlisten(u16_t port)
520 for(c = 0; c < UIP_LISTENPORTS; ++c) {
521 if(uip_listenports[c] == port) {
522 uip_listenports[c] = 0;
527 /*---------------------------------------------------------------------------*/
529 uip_listen(u16_t port)
531 for(c = 0; c < UIP_LISTENPORTS; ++c) {
532 if(uip_listenports[c] == 0) {
533 uip_listenports[c] = port;
538 /*---------------------------------------------------------------------------*/
539 /* XXX: IP fragment reassembly: not well-tested. */
541 #if UIP_REASSEMBLY && !UIP_CONF_IPV6
542 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
543 static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
544 static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
545 static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
546 0x0f, 0x07, 0x03, 0x01};
547 static u16_t uip_reasslen;
548 static u8_t uip_reassflags;
549 #define UIP_REASS_FLAG_LASTFRAG 0x01
550 static u8_t uip_reasstmr;
560 /* If ip_reasstmr is zero, no packet is present in the buffer, so we
561 write the IP header of the fragment into the reassembly
562 buffer. The timer is updated with the maximum age. */
563 if(uip_reasstmr == 0) {
564 memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN);
565 uip_reasstmr = UIP_REASS_MAXAGE;
567 /* Clear the bitmap. */
568 memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap));
571 /* Check if the incoming fragment matches the one currently present
572 in the reasembly buffer. If so, we proceed with copying the
573 fragment into the buffer. */
574 if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
575 BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
576 BUF->destipaddr[0] == FBUF->destipaddr[0] &&
577 BUF->destipaddr[1] == FBUF->destipaddr[1] &&
578 BUF->ipid[0] == FBUF->ipid[0] &&
579 BUF->ipid[1] == FBUF->ipid[1]) {
581 len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
582 offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
584 /* If the offset or the offset + fragment length overflows the
585 reassembly buffer, we discard the entire packet. */
586 if(offset > UIP_REASS_BUFSIZE ||
587 offset + len > UIP_REASS_BUFSIZE) {
592 /* Copy the fragment into the reassembly buffer, at the right
594 memcpy(&uip_reassbuf[UIP_IPH_LEN + offset],
595 (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
598 /* Update the bitmap. */
599 if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
600 /* If the two endpoints are in the same byte, we only update
603 uip_reassbitmap[offset / (8 * 8)] |=
604 bitmap_bits[(offset / 8 ) & 7] &
605 ~bitmap_bits[((offset + len) / 8 ) & 7];
607 /* If the two endpoints are in different bytes, we update the
608 bytes in the endpoints and fill the stuff inbetween with
610 uip_reassbitmap[offset / (8 * 8)] |=
611 bitmap_bits[(offset / 8 ) & 7];
612 for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
613 uip_reassbitmap[i] = 0xff;
615 uip_reassbitmap[(offset + len) / (8 * 8)] |=
616 ~bitmap_bits[((offset + len) / 8 ) & 7];
619 /* If this fragment has the More Fragments flag set to zero, we
620 know that this is the last fragment, so we can calculate the
621 size of the entire packet. We also set the
622 IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
623 the final fragment. */
625 if((BUF->ipoffset[0] & IP_MF) == 0) {
626 uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
627 uip_reasslen = offset + len;
630 /* Finally, we check if we have a full packet in the buffer. We do
631 this by checking if we have the last fragment and if all bits
632 in the bitmap are set. */
633 if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
634 /* Check all bytes up to and including all but the last byte in
636 for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
637 if(uip_reassbitmap[i] != 0xff) {
641 /* Check the last byte in the bitmap. It should contain just the
642 right amount of bits. */
643 if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
644 (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
648 /* If we have come this far, we have a full packet in the
649 buffer, so we allocate a pbuf and copy the packet into it. We
650 also reset the timer. */
652 memcpy(BUF, FBUF, uip_reasslen);
654 /* Pretend to be a "normal" (i.e., not fragmented) IP packet
656 BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
657 BUF->len[0] = uip_reasslen >> 8;
658 BUF->len[1] = uip_reasslen & 0xff;
660 BUF->ipchksum = ~(uip_ipchksum());
669 #endif /* UIP_REASSEMBLY */
670 /*---------------------------------------------------------------------------*/
672 uip_add_rcv_nxt(u16_t n)
674 uip_add32(uip_conn->rcv_nxt, n);
675 uip_conn->rcv_nxt[0] = uip_acc32[0];
676 uip_conn->rcv_nxt[1] = uip_acc32[1];
677 uip_conn->rcv_nxt[2] = uip_acc32[2];
678 uip_conn->rcv_nxt[3] = uip_acc32[3];
680 /*---------------------------------------------------------------------------*/
682 uip_process(u8_t flag)
684 register struct uip_conn *uip_connr = uip_conn;
687 if(flag == UIP_UDP_SEND_CONN) {
692 uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
694 /* Check if we were invoked because of a poll request for a
695 particular connection. */
696 if(flag == UIP_POLL_REQUEST) {
697 if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
698 !uip_outstanding(uip_connr)) {
699 uip_flags = UIP_POLL;
705 /* Check if we were invoked because of the perodic timer fireing. */
706 } else if(flag == UIP_TIMER) {
708 if(uip_reasstmr != 0) {
711 #endif /* UIP_REASSEMBLY */
712 /* Increase the initial sequence number. */
721 /* Reset the length variables. */
725 /* Check if the connection is in a state in which we simply wait
726 for the connection to time out. If so, we increase the
727 connection's timer and remove the connection if it times
729 if(uip_connr->tcpstateflags == UIP_TIME_WAIT ||
730 uip_connr->tcpstateflags == UIP_FIN_WAIT_2) {
731 ++(uip_connr->timer);
732 if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
733 uip_connr->tcpstateflags = UIP_CLOSED;
735 } else if(uip_connr->tcpstateflags != UIP_CLOSED) {
736 /* If the connection has outstanding data, we increase the
737 connection's timer and see if it has reached the RTO value
738 in which case we retransmit. */
739 if(uip_outstanding(uip_connr)) {
740 if(uip_connr->timer-- == 0) {
741 if(uip_connr->nrtx == UIP_MAXRTX ||
742 ((uip_connr->tcpstateflags == UIP_SYN_SENT ||
743 uip_connr->tcpstateflags == UIP_SYN_RCVD) &&
744 uip_connr->nrtx == UIP_MAXSYNRTX)) {
745 uip_connr->tcpstateflags = UIP_CLOSED;
747 /* We call UIP_APPCALL() with uip_flags set to
748 UIP_TIMEDOUT to inform the application that the
749 connection has timed out. */
750 uip_flags = UIP_TIMEDOUT;
753 /* We also send a reset packet to the remote host. */
754 BUF->flags = TCP_RST | TCP_ACK;
755 goto tcp_send_nodata;
758 /* Exponential backoff. */
759 uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
764 /* Ok, so we need to retransmit. We do this differently
765 depending on which state we are in. In ESTABLISHED, we
766 call upon the application so that it may prepare the
767 data for the retransmit. In SYN_RCVD, we resend the
768 SYNACK that we sent earlier and in LAST_ACK we have to
769 retransmit our FINACK. */
770 UIP_STAT(++uip_stat.tcp.rexmit);
771 switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
773 /* In the SYN_RCVD state, we should retransmit our
775 goto tcp_send_synack;
779 /* In the SYN_SENT state, we retransmit out SYN. */
782 #endif /* UIP_ACTIVE_OPEN */
784 case UIP_ESTABLISHED:
785 /* In the ESTABLISHED state, we call upon the application
786 to do the actual retransmit after which we jump into
787 the code for sending out the packet (the apprexmit
789 uip_flags = UIP_REXMIT;
796 /* In all these states we should retransmit a FINACK. */
797 goto tcp_send_finack;
801 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
802 /* If there was no need for a retransmission, we poll the
803 application for new data. */
804 uip_flags = UIP_POLL;
812 if(flag == UIP_UDP_TIMER) {
813 if(uip_udp_conn->lport != 0) {
815 uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
816 uip_len = uip_slen = 0;
817 uip_flags = UIP_POLL;
826 /* This is where the input processing starts. */
827 UIP_STAT(++uip_stat.ip.recv);
829 /* Start of IP input header processing code. */
832 /* Check validity of the IP header. */
833 if((BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */
834 UIP_STAT(++uip_stat.ip.drop);
835 UIP_STAT(++uip_stat.ip.vhlerr);
836 UIP_LOG("ipv6: invalid version.");
839 #else /* UIP_CONF_IPV6 */
840 /* Check validity of the IP header. */
841 if(BUF->vhl != 0x45) { /* IP version and header length. */
842 UIP_STAT(++uip_stat.ip.drop);
843 UIP_STAT(++uip_stat.ip.vhlerr);
844 UIP_LOG("ip: invalid version or header length.");
847 #endif /* UIP_CONF_IPV6 */
849 /* Check the size of the packet. If the size reported to us in
850 uip_len is smaller the size reported in the IP header, we assume
851 that the packet has been corrupted in transit. If the size of
852 uip_len is larger than the size reported in the IP packet header,
853 the packet has been padded and we set uip_len to the correct
856 if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) {
857 uip_len = (BUF->len[0] << 8) + BUF->len[1];
859 uip_len += 40; /* The length reported in the IPv6 header is the
860 length of the payload that follows the
861 header. However, uIP uses the uip_len variable
862 for holding the size of the entire packet,
863 including the IP header. For IPv4 this is not a
864 problem as the length field in the IPv4 header
865 contains the length of the entire packet. But
866 for IPv6 we need to add the size of the IPv6
867 header (40 bytes). */
868 #endif /* UIP_CONF_IPV6 */
870 UIP_LOG("ip: packet shorter than reported in IP header.");
875 /* Check the fragment flag. */
876 if((BUF->ipoffset[0] & 0x3f) != 0 ||
877 BUF->ipoffset[1] != 0) {
879 uip_len = uip_reass();
883 #else /* UIP_REASSEMBLY */
884 UIP_STAT(++uip_stat.ip.drop);
885 UIP_STAT(++uip_stat.ip.fragerr);
886 UIP_LOG("ip: fragment dropped.");
888 #endif /* UIP_REASSEMBLY */
890 #endif /* UIP_CONF_IPV6 */
892 if(uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) {
893 /* If we are configured to use ping IP address configuration and
894 hasn't been assigned an IP address yet, we accept all ICMP
896 #if UIP_PINGADDRCONF && !UIP_CONF_IPV6
897 if(BUF->proto == UIP_PROTO_ICMP) {
898 UIP_LOG("ip: possible ping config packet received.");
901 UIP_LOG("ip: packet dropped since no address assigned.");
904 #endif /* UIP_PINGADDRCONF */
907 /* If IP broadcast support is configured, we check for a broadcast
908 UDP packet, which may be destined to us. */
910 DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum());
911 if(BUF->proto == UIP_PROTO_UDP &&
912 uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr)
914 uip_ipchksum() == 0xffff*/) {
917 #endif /* UIP_BROADCAST */
919 /* Check if the packet is destined for our IP address. */
921 if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr)) {
922 UIP_STAT(++uip_stat.ip.drop);
925 #else /* UIP_CONF_IPV6 */
926 /* For IPv6, packet reception is a little trickier as we need to
927 make sure that we listen to certain multicast addresses (all
928 hosts multicast address, and the solicited-node multicast
929 address) as well. However, we will cheat here and accept all
930 multicast packets that are sent to the ff02::/16 addresses. */
931 if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) &&
932 BUF->destipaddr[0] != HTONS(0xff02)) {
933 UIP_STAT(++uip_stat.ip.drop);
936 #endif /* UIP_CONF_IPV6 */
940 if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
942 UIP_STAT(++uip_stat.ip.drop);
943 UIP_STAT(++uip_stat.ip.chkerr);
944 UIP_LOG("ip: bad checksum.");
947 #endif /* UIP_CONF_IPV6 */
949 if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so,
950 proceed with TCP input
956 if(BUF->proto == UIP_PROTO_UDP) {
962 /* ICMPv4 processing code follows. */
963 if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
965 UIP_STAT(++uip_stat.ip.drop);
966 UIP_STAT(++uip_stat.ip.protoerr);
967 UIP_LOG("ip: neither tcp nor icmp.");
973 #endif /* UIP_PINGADDRCONF */
974 UIP_STAT(++uip_stat.icmp.recv);
976 /* ICMP echo (i.e., ping) processing. This is simple, we only change
977 the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
978 checksum before we return the packet. */
979 if(ICMPBUF->type != ICMP_ECHO) {
980 UIP_STAT(++uip_stat.icmp.drop);
981 UIP_STAT(++uip_stat.icmp.typeerr);
982 UIP_LOG("icmp: not icmp echo.");
986 /* If we are configured to use ping IP address assignment, we use
987 the destination IP address of this ping packet and assign it to
990 if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
991 uip_hostaddr[0] = BUF->destipaddr[0];
992 uip_hostaddr[1] = BUF->destipaddr[1];
994 #endif /* UIP_PINGADDRCONF */
996 ICMPBUF->type = ICMP_ECHO_REPLY;
998 if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
999 ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
1001 ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
1004 /* Swap IP addresses. */
1005 uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
1006 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
1008 UIP_STAT(++uip_stat.icmp.sent);
1011 /* End of IPv4 input header processing code. */
1012 #else /* !UIP_CONF_IPV6 */
1014 /* This is IPv6 ICMPv6 processing code. */
1015 DEBUG_PRINTF("icmp6_input: length %d\n", uip_len);
1017 if(BUF->proto != UIP_PROTO_ICMP6) { /* We only allow ICMPv6 packets from
1019 UIP_STAT(++uip_stat.ip.drop);
1020 UIP_STAT(++uip_stat.ip.protoerr);
1021 UIP_LOG("ip: neither tcp nor icmp6.");
1025 UIP_STAT(++uip_stat.icmp.recv);
1027 /* If we get a neighbor solicitation for our address we should send
1028 a neighbor advertisement message back. */
1029 if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) {
1030 if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) {
1032 if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) {
1033 /* Save the sender's address in our neighbor list. */
1034 uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2]));
1037 /* We should now send a neighbor advertisement back to where the
1038 neighbor solicication came from. */
1039 ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
1040 ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */
1042 ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;
1044 uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr);
1045 uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr);
1046 ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS;
1047 ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */
1048 memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr));
1049 ICMPBUF->icmpchksum = 0;
1050 ICMPBUF->icmpchksum = ~uip_icmp6chksum();
1055 } else if(ICMPBUF->type == ICMP6_ECHO) {
1056 /* ICMP echo (i.e., ping) processing. This is simple, we only
1057 change the ICMP type from ECHO to ECHO_REPLY and update the
1058 ICMP checksum before we return the packet. */
1060 ICMPBUF->type = ICMP6_ECHO_REPLY;
1062 uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
1063 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
1064 ICMPBUF->icmpchksum = 0;
1065 ICMPBUF->icmpchksum = ~uip_icmp6chksum();
1067 UIP_STAT(++uip_stat.icmp.sent);
1070 DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type);
1071 UIP_STAT(++uip_stat.icmp.drop);
1072 UIP_STAT(++uip_stat.icmp.typeerr);
1073 UIP_LOG("icmp: unknown ICMP message.");
1077 /* End of IPv6 ICMP processing. */
1079 #endif /* !UIP_CONF_IPV6 */
1082 /* UDP input processing. */
1084 /* UDP processing is really just a hack. We don't do anything to the
1085 UDP/IP headers, but let the UDP application do all the hard
1086 work. If the application sets uip_slen, it has a packet to
1088 #if UIP_UDP_CHECKSUMS
1089 uip_len = uip_len - UIP_IPUDPH_LEN;
1090 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
1091 if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
1092 UIP_STAT(++uip_stat.udp.drop);
1093 UIP_STAT(++uip_stat.udp.chkerr);
1094 UIP_LOG("udp: bad checksum.");
1097 #else /* UIP_UDP_CHECKSUMS */
1098 uip_len = uip_len - UIP_IPUDPH_LEN;
1099 #endif /* UIP_UDP_CHECKSUMS */
1101 /* Demultiplex this UDP packet between the UDP "connections". */
1102 for(uip_udp_conn = &uip_udp_conns[0];
1103 uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
1105 /* If the local UDP port is non-zero, the connection is considered
1106 to be used. If so, the local port number is checked against the
1107 destination port number in the received packet. If the two port
1108 numbers match, the remote port number is checked if the
1109 connection is bound to a remote port. Finally, if the
1110 connection is bound to a remote IP address, the source IP
1111 address of the packet is checked. */
1112 if(uip_udp_conn->lport != 0 &&
1113 UDPBUF->destport == uip_udp_conn->lport &&
1114 (uip_udp_conn->rport == 0 ||
1115 UDPBUF->srcport == uip_udp_conn->rport) &&
1116 (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) ||
1117 uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) ||
1118 uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) {
1122 UIP_LOG("udp: no matching connection found");
1127 uip_flags = UIP_NEWDATA;
1128 uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
1135 uip_len = uip_slen + UIP_IPUDPH_LEN;
1138 /* For IPv6, the IP length field does not include the IPv6 IP header
1140 BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
1141 BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
1142 #else /* UIP_CONF_IPV6 */
1143 BUF->len[0] = (uip_len >> 8);
1144 BUF->len[1] = (uip_len & 0xff);
1145 #endif /* UIP_CONF_IPV6 */
1147 BUF->ttl = uip_udp_conn->ttl;
1148 BUF->proto = UIP_PROTO_UDP;
1150 UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN);
1151 UDPBUF->udpchksum = 0;
1153 BUF->srcport = uip_udp_conn->lport;
1154 BUF->destport = uip_udp_conn->rport;
1156 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
1157 uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr);
1159 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
1161 #if UIP_UDP_CHECKSUMS
1162 /* Calculate UDP checksum. */
1163 UDPBUF->udpchksum = ~(uip_udpchksum());
1164 if(UDPBUF->udpchksum == 0) {
1165 UDPBUF->udpchksum = 0xffff;
1167 #endif /* UIP_UDP_CHECKSUMS */
1170 #endif /* UIP_UDP */
1172 /* TCP input processing. */
1174 UIP_STAT(++uip_stat.tcp.recv);
1176 /* Start of TCP input header processing code. */
1178 if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
1180 UIP_STAT(++uip_stat.tcp.drop);
1181 UIP_STAT(++uip_stat.tcp.chkerr);
1182 UIP_LOG("tcp: bad checksum.");
1187 /* Demultiplex this segment. */
1188 /* First check any active connections. */
1189 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
1191 if(uip_connr->tcpstateflags != UIP_CLOSED &&
1192 BUF->destport == uip_connr->lport &&
1193 BUF->srcport == uip_connr->rport &&
1194 uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) {
1199 /* If we didn't find and active connection that expected the packet,
1200 either this packet is an old duplicate, or this is a SYN packet
1201 destined for a connection in LISTEN. If the SYN flag isn't set,
1202 it is an old packet and we send a RST. */
1203 if((BUF->flags & TCP_CTL) != TCP_SYN) {
1207 tmp16 = BUF->destport;
1208 /* Next, check listening connections. */
1209 for(c = 0; c < UIP_LISTENPORTS; ++c) {
1210 if(tmp16 == uip_listenports[c])
1214 /* No matching connection found, so we send a RST packet. */
1215 UIP_STAT(++uip_stat.tcp.synrst);
1218 /* We do not send resets in response to resets. */
1219 if(BUF->flags & TCP_RST) {
1223 UIP_STAT(++uip_stat.tcp.rst);
1225 BUF->flags = TCP_RST | TCP_ACK;
1226 uip_len = UIP_IPTCPH_LEN;
1227 BUF->tcpoffset = 5 << 4;
1229 /* Flip the seqno and ackno fields in the TCP header. */
1231 BUF->seqno[3] = BUF->ackno[3];
1235 BUF->seqno[2] = BUF->ackno[2];
1239 BUF->seqno[1] = BUF->ackno[1];
1243 BUF->seqno[0] = BUF->ackno[0];
1246 /* We also have to increase the sequence number we are
1247 acknowledging. If the least significant byte overflowed, we need
1248 to propagate the carry to the other bytes as well. */
1249 if(++BUF->ackno[3] == 0) {
1250 if(++BUF->ackno[2] == 0) {
1251 if(++BUF->ackno[1] == 0) {
1257 /* Swap port numbers. */
1258 tmp16 = BUF->srcport;
1259 BUF->srcport = BUF->destport;
1260 BUF->destport = tmp16;
1262 /* Swap IP addresses. */
1263 uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
1264 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
1266 /* And send out the RST packet! */
1267 goto tcp_send_noconn;
1269 /* This label will be jumped to if we matched the incoming packet
1270 with a connection in LISTEN. In that case, we should create a new
1271 connection and send a SYNACK in return. */
1273 /* First we check if there are any connections avaliable. Unused
1274 connections are kept in the same table as used connections, but
1275 unused ones have the tcpstate set to CLOSED. Also, connections in
1276 TIME_WAIT are kept track of and we'll use the oldest one if no
1277 CLOSED connections are found. Thanks to Eddie C. Dost for a very
1278 nice algorithm for the TIME_WAIT search. */
1280 for(c = 0; c < UIP_CONNS; ++c) {
1281 if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
1282 uip_connr = &uip_conns[c];
1285 if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
1286 if(uip_connr == 0 ||
1287 uip_conns[c].timer > uip_connr->timer) {
1288 uip_connr = &uip_conns[c];
1293 if(uip_connr == 0) {
1294 /* All connections are used already, we drop packet and hope that
1295 the remote end will retransmit the packet at a time when we
1296 have more spare connections. */
1297 UIP_STAT(++uip_stat.tcp.syndrop);
1298 UIP_LOG("tcp: found no unused connections.");
1301 uip_conn = uip_connr;
1303 /* Fill in the necessary fields for the new connection. */
1304 uip_connr->rto = uip_connr->timer = UIP_RTO;
1307 uip_connr->nrtx = 0;
1308 uip_connr->lport = BUF->destport;
1309 uip_connr->rport = BUF->srcport;
1310 uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr);
1311 uip_connr->tcpstateflags = UIP_SYN_RCVD;
1313 uip_connr->snd_nxt[0] = iss[0];
1314 uip_connr->snd_nxt[1] = iss[1];
1315 uip_connr->snd_nxt[2] = iss[2];
1316 uip_connr->snd_nxt[3] = iss[3];
1319 /* rcv_nxt should be the seqno from the incoming packet + 1. */
1320 uip_connr->rcv_nxt[3] = BUF->seqno[3];
1321 uip_connr->rcv_nxt[2] = BUF->seqno[2];
1322 uip_connr->rcv_nxt[1] = BUF->seqno[1];
1323 uip_connr->rcv_nxt[0] = BUF->seqno[0];
1326 /* Parse the TCP MSS option, if present. */
1327 if((BUF->tcpoffset & 0xf0) > 0x50) {
1328 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
1329 opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
1330 if(opt == TCP_OPT_END) {
1331 /* End of options. */
1333 } else if(opt == TCP_OPT_NOOP) {
1336 } else if(opt == TCP_OPT_MSS &&
1337 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
1338 /* An MSS option with the right option length. */
1339 tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
1340 (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
1341 uip_connr->initialmss = uip_connr->mss =
1342 tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
1344 /* And we are done processing options. */
1347 /* All other options have a length field, so that we easily
1348 can skip past them. */
1349 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
1350 /* If the length field is zero, the options are malformed
1351 and we don't process them further. */
1354 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
1359 /* Our response will be a SYNACK. */
1362 BUF->flags = TCP_ACK;
1365 BUF->flags |= TCP_SYN;
1366 #else /* UIP_ACTIVE_OPEN */
1368 BUF->flags = TCP_SYN | TCP_ACK;
1369 #endif /* UIP_ACTIVE_OPEN */
1371 /* We send out the TCP Maximum Segment Size option with our
1373 BUF->optdata[0] = TCP_OPT_MSS;
1374 BUF->optdata[1] = TCP_OPT_MSS_LEN;
1375 BUF->optdata[2] = (UIP_TCP_MSS) / 256;
1376 BUF->optdata[3] = (UIP_TCP_MSS) & 255;
1377 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
1378 BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
1381 /* This label will be jumped to if we found an active connection. */
1383 uip_conn = uip_connr;
1385 /* We do a very naive form of TCP reset processing; we just accept
1386 any RST and kill our connection. We should in fact check if the
1387 sequence number of this reset is wihtin our advertised window
1388 before we accept the reset. */
1389 if(BUF->flags & TCP_RST) {
1390 uip_connr->tcpstateflags = UIP_CLOSED;
1391 UIP_LOG("tcp: got reset, aborting connection.");
1392 uip_flags = UIP_ABORT;
1396 /* Calculated the length of the data, if the application has sent
1398 c = (BUF->tcpoffset >> 4) << 2;
1399 /* uip_len will contain the length of the actual TCP data. This is
1400 calculated by subtracing the length of the TCP header (in
1401 c) and the length of the IP header (20 bytes). */
1402 uip_len = uip_len - c - UIP_IPH_LEN;
1404 /* First, check if the sequence number of the incoming packet is
1405 what we're expecting next. If not, we send out an ACK with the
1406 correct numbers in. */
1407 if(!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
1408 ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) {
1409 if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
1410 (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
1411 BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
1412 BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
1413 BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
1418 /* Next, check if the incoming segment acknowledges any outstanding
1419 data. If so, we update the sequence number, reset the length of
1420 the outstanding data, calculate RTT estimations, and reset the
1421 retransmission timer. */
1422 if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
1423 uip_add32(uip_connr->snd_nxt, uip_connr->len);
1425 if(BUF->ackno[0] == uip_acc32[0] &&
1426 BUF->ackno[1] == uip_acc32[1] &&
1427 BUF->ackno[2] == uip_acc32[2] &&
1428 BUF->ackno[3] == uip_acc32[3]) {
1429 /* Update sequence number. */
1430 uip_connr->snd_nxt[0] = uip_acc32[0];
1431 uip_connr->snd_nxt[1] = uip_acc32[1];
1432 uip_connr->snd_nxt[2] = uip_acc32[2];
1433 uip_connr->snd_nxt[3] = uip_acc32[3];
1436 /* Do RTT estimation, unless we have done retransmissions. */
1437 if(uip_connr->nrtx == 0) {
1439 m = uip_connr->rto - uip_connr->timer;
1440 /* This is taken directly from VJs original code in his paper */
1441 m = m - (uip_connr->sa >> 3);
1446 m = m - (uip_connr->sv >> 2);
1448 uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
1451 /* Set the acknowledged flag. */
1452 uip_flags = UIP_ACKDATA;
1453 /* Reset the retransmission timer. */
1454 uip_connr->timer = uip_connr->rto;
1456 /* Reset length of outstanding data. */
1462 /* Do different things depending on in what state the connection is. */
1463 switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
1464 /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
1465 implemented, since we force the application to close when the
1466 peer sends a FIN (hence the application goes directly from
1467 ESTABLISHED to LAST_ACK). */
1469 /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
1470 we are waiting for an ACK that acknowledges the data we sent
1471 out the last time. Therefore, we want to have the UIP_ACKDATA
1472 flag set. If so, we enter the ESTABLISHED state. */
1473 if(uip_flags & UIP_ACKDATA) {
1474 uip_connr->tcpstateflags = UIP_ESTABLISHED;
1475 uip_flags = UIP_CONNECTED;
1478 uip_flags |= UIP_NEWDATA;
1479 uip_add_rcv_nxt(uip_len);
1488 /* In SYN_SENT, we wait for a SYNACK that is sent in response to
1489 our SYN. The rcv_nxt is set to sequence number in the SYNACK
1490 plus one, and we send an ACK. We move into the ESTABLISHED
1492 if((uip_flags & UIP_ACKDATA) &&
1493 (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
1495 /* Parse the TCP MSS option, if present. */
1496 if((BUF->tcpoffset & 0xf0) > 0x50) {
1497 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
1498 opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
1499 if(opt == TCP_OPT_END) {
1500 /* End of options. */
1502 } else if(opt == TCP_OPT_NOOP) {
1505 } else if(opt == TCP_OPT_MSS &&
1506 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
1507 /* An MSS option with the right option length. */
1508 tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
1509 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
1510 uip_connr->initialmss =
1511 uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
1513 /* And we are done processing options. */
1516 /* All other options have a length field, so that we easily
1517 can skip past them. */
1518 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
1519 /* If the length field is zero, the options are malformed
1520 and we don't process them further. */
1523 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
1527 uip_connr->tcpstateflags = UIP_ESTABLISHED;
1528 uip_connr->rcv_nxt[0] = BUF->seqno[0];
1529 uip_connr->rcv_nxt[1] = BUF->seqno[1];
1530 uip_connr->rcv_nxt[2] = BUF->seqno[2];
1531 uip_connr->rcv_nxt[3] = BUF->seqno[3];
1533 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
1540 /* Inform the application that the connection failed */
1541 uip_flags = UIP_ABORT;
1543 /* The connection is closed after we send the RST */
1544 uip_conn->tcpstateflags = UIP_CLOSED;
1546 #endif /* UIP_ACTIVE_OPEN */
1548 case UIP_ESTABLISHED:
1549 /* In the ESTABLISHED state, we call upon the application to feed
1550 data into the uip_buf. If the UIP_ACKDATA flag is set, the
1551 application should put new data into the buffer, otherwise we are
1552 retransmitting an old segment, and the application should put that
1553 data into the buffer.
1555 If the incoming packet is a FIN, we should close the connection on
1556 this side as well, and we send out a FIN and enter the LAST_ACK
1557 state. We require that there is no outstanding data; otherwise the
1558 sequence numbers will be screwed up. */
1560 if(BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
1561 if(uip_outstanding(uip_connr)) {
1564 uip_add_rcv_nxt(1 + uip_len);
1565 uip_flags |= UIP_CLOSE;
1567 uip_flags |= UIP_NEWDATA;
1571 uip_connr->tcpstateflags = UIP_LAST_ACK;
1572 uip_connr->nrtx = 0;
1574 BUF->flags = TCP_FIN | TCP_ACK;
1575 goto tcp_send_nodata;
1578 /* Check the URG flag. If this is set, the segment carries urgent
1579 data that we must pass to the application. */
1580 if((BUF->flags & TCP_URG) != 0) {
1582 uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
1583 if(uip_urglen > uip_len) {
1584 /* There is more urgent data in the next segment to come. */
1585 uip_urglen = uip_len;
1587 uip_add_rcv_nxt(uip_urglen);
1588 uip_len -= uip_urglen;
1589 uip_urgdata = uip_appdata;
1590 uip_appdata += uip_urglen;
1593 #else /* UIP_URGDATA > 0 */
1594 uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]);
1595 uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
1596 #endif /* UIP_URGDATA > 0 */
1599 /* If uip_len > 0 we have TCP data in the packet, and we flag this
1600 by setting the UIP_NEWDATA flag and update the sequence number
1601 we acknowledge. If the application has stopped the dataflow
1602 using uip_stop(), we must not accept any data packets from the
1604 if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
1605 uip_flags |= UIP_NEWDATA;
1606 uip_add_rcv_nxt(uip_len);
1609 /* Check if the available buffer space advertised by the other end
1610 is smaller than the initial MSS for this connection. If so, we
1611 set the current MSS to the window size to ensure that the
1612 application does not send more data than the other end can
1615 If the remote host advertises a zero window, we set the MSS to
1616 the initial MSS so that the application will send an entire MSS
1617 of data. This data will not be acknowledged by the receiver,
1618 and the application will retransmit it. This is called the
1619 "persistent timer" and uses the retransmission mechanim.
1621 tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1];
1622 if(tmp16 > uip_connr->initialmss ||
1624 tmp16 = uip_connr->initialmss;
1626 uip_connr->mss = tmp16;
1628 /* If this packet constitutes an ACK for outstanding data (flagged
1629 by the UIP_ACKDATA flag, we should call the application since it
1630 might want to send more data. If the incoming packet had data
1631 from the peer (as flagged by the UIP_NEWDATA flag), the
1632 application must also be notified.
1634 When the application is called, the global variable uip_len
1635 contains the length of the incoming data. The application can
1636 access the incoming data through the global pointer
1637 uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN
1638 bytes into the uip_buf array.
1640 If the application wishes to send any data, this data should be
1641 put into the uip_appdata and the length of the data should be
1642 put into uip_len. If the application don't have any data to
1643 send, uip_len must be set to 0. */
1644 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
1650 if(uip_flags & UIP_ABORT) {
1652 uip_connr->tcpstateflags = UIP_CLOSED;
1653 BUF->flags = TCP_RST | TCP_ACK;
1654 goto tcp_send_nodata;
1657 if(uip_flags & UIP_CLOSE) {
1660 uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
1661 uip_connr->nrtx = 0;
1662 BUF->flags = TCP_FIN | TCP_ACK;
1663 goto tcp_send_nodata;
1666 /* If uip_slen > 0, the application has data to be sent. */
1669 /* If the connection has acknowledged data, the contents of
1670 the ->len variable should be discarded. */
1671 if((uip_flags & UIP_ACKDATA) != 0) {
1675 /* If the ->len variable is non-zero the connection has
1676 already data in transit and cannot send anymore right
1678 if(uip_connr->len == 0) {
1680 /* The application cannot send more than what is allowed by
1681 the mss (the minumum of the MSS and the available
1683 if(uip_slen > uip_connr->mss) {
1684 uip_slen = uip_connr->mss;
1687 /* Remember how much data we send out now so that we know
1688 when everything has been acknowledged. */
1689 uip_connr->len = uip_slen;
1692 /* If the application already had unacknowledged data, we
1693 make sure that the application does not send (i.e.,
1694 retransmit) out more than it previously sent out. */
1695 uip_slen = uip_connr->len;
1698 uip_connr->nrtx = 0;
1700 uip_appdata = uip_sappdata;
1702 /* If the application has data to be sent, or if the incoming
1703 packet had new data in it, we must send out a packet. */
1704 if(uip_slen > 0 && uip_connr->len > 0) {
1705 /* Add the length of the IP and TCP headers. */
1706 uip_len = uip_connr->len + UIP_TCPIP_HLEN;
1707 /* We always set the ACK flag in response packets. */
1708 BUF->flags = TCP_ACK | TCP_PSH;
1709 /* Send the packet. */
1710 goto tcp_send_noopts;
1712 /* If there is no data to send, just send out a pure ACK if
1713 there is newdata. */
1714 if(uip_flags & UIP_NEWDATA) {
1715 uip_len = UIP_TCPIP_HLEN;
1716 BUF->flags = TCP_ACK;
1717 goto tcp_send_noopts;
1722 /* We can close this connection if the peer has acknowledged our
1723 FIN. This is indicated by the UIP_ACKDATA flag. */
1724 if(uip_flags & UIP_ACKDATA) {
1725 uip_connr->tcpstateflags = UIP_CLOSED;
1726 uip_flags = UIP_CLOSE;
1731 case UIP_FIN_WAIT_1:
1732 /* The application has closed the connection, but the remote host
1733 hasn't closed its end yet. Thus we do nothing but wait for a
1734 FIN from the other side. */
1736 uip_add_rcv_nxt(uip_len);
1738 if(BUF->flags & TCP_FIN) {
1739 if(uip_flags & UIP_ACKDATA) {
1740 uip_connr->tcpstateflags = UIP_TIME_WAIT;
1741 uip_connr->timer = 0;
1744 uip_connr->tcpstateflags = UIP_CLOSING;
1747 uip_flags = UIP_CLOSE;
1750 } else if(uip_flags & UIP_ACKDATA) {
1751 uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
1760 case UIP_FIN_WAIT_2:
1762 uip_add_rcv_nxt(uip_len);
1764 if(BUF->flags & TCP_FIN) {
1765 uip_connr->tcpstateflags = UIP_TIME_WAIT;
1766 uip_connr->timer = 0;
1768 uip_flags = UIP_CLOSE;
1781 if(uip_flags & UIP_ACKDATA) {
1782 uip_connr->tcpstateflags = UIP_TIME_WAIT;
1783 uip_connr->timer = 0;
1789 /* We jump here when we are ready to send the packet, and just want
1790 to set the appropriate TCP sequence numbers in the TCP header. */
1792 BUF->flags = TCP_ACK;
1794 uip_len = UIP_IPTCPH_LEN;
1796 BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
1798 /* We're done with the input processing. We are now ready to send a
1799 reply. Our job is to fill in all the fields of the TCP and IP
1800 headers before calculating the checksum and finally send the
1802 BUF->ackno[0] = uip_connr->rcv_nxt[0];
1803 BUF->ackno[1] = uip_connr->rcv_nxt[1];
1804 BUF->ackno[2] = uip_connr->rcv_nxt[2];
1805 BUF->ackno[3] = uip_connr->rcv_nxt[3];
1807 BUF->seqno[0] = uip_connr->snd_nxt[0];
1808 BUF->seqno[1] = uip_connr->snd_nxt[1];
1809 BUF->seqno[2] = uip_connr->snd_nxt[2];
1810 BUF->seqno[3] = uip_connr->snd_nxt[3];
1812 BUF->proto = UIP_PROTO_TCP;
1814 BUF->srcport = uip_connr->lport;
1815 BUF->destport = uip_connr->rport;
1817 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
1818 uip_ipaddr_copy(BUF->destipaddr, uip_connr->ripaddr);
1820 if(uip_connr->tcpstateflags & UIP_STOPPED) {
1821 /* If the connection has issued uip_stop(), we advertise a zero
1822 window so that the remote host will stop sending data. */
1823 BUF->wnd[0] = BUF->wnd[1] = 0;
1825 BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
1826 BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
1832 /* For IPv6, the IP length field does not include the IPv6 IP header
1834 BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
1835 BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
1836 #else /* UIP_CONF_IPV6 */
1837 BUF->len[0] = (uip_len >> 8);
1838 BUF->len[1] = (uip_len & 0xff);
1839 #endif /* UIP_CONF_IPV6 */
1841 BUF->urgp[0] = BUF->urgp[1] = 0;
1843 /* Calculate TCP checksum. */
1845 BUF->tcpchksum = ~(uip_tcpchksum());
1853 #else /* UIP_CONF_IPV6 */
1856 BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
1858 BUF->ipid[0] = ipid >> 8;
1859 BUF->ipid[1] = ipid & 0xff;
1860 /* Calculate IP checksum. */
1862 BUF->ipchksum = ~(uip_ipchksum());
1863 DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum());
1864 #endif /* UIP_CONF_IPV6 */
1866 UIP_STAT(++uip_stat.tcp.sent);
1868 DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len,
1869 (BUF->len[0] << 8) | BUF->len[1]);
1871 UIP_STAT(++uip_stat.ip.sent);
1872 /* Return and let the caller do the actual transmission. */
1881 /*---------------------------------------------------------------------------*/
1882 /* replicate defined in lwip.c,
1890 /*---------------------------------------------------------------------------*/
1892 uip_send(const void *data, int len)
1896 if(data != uip_sappdata) {
1897 memcpy(uip_sappdata, (data), uip_slen);