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

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

フォルダ構成をContikiに合わせて変更

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