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