source: uKadecot/trunk/uip/net/ipv4/uip.c@ 262

Last change on this file since 262 was 262, checked in by coas-nagasima, 7 years ago

uIPを更新
プロジェクトファイルを更新

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