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