Contiki-NG
Loading...
Searching...
No Matches
uip6.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2001-2003, Adam Dunkels.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote
14 * products derived from this software without specific prior
15 * written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * This file is part of the uIP TCP/IP stack.
30 *
31 *
32 */
33
34/**
35 * \addtogroup uip
36 * @{
37 */
38
39/**
40 * \file
41 * The uIP TCP/IPv6 stack code.
42 *
43 * \author Adam Dunkels <adam@sics.se>
44 * \author Julien Abeille <jabeille@cisco.com> (IPv6 related code)
45 * \author Mathilde Durvy <mdurvy@cisco.com> (IPv6 related code)
46 */
47
48/*
49 * uIP is a small implementation of the IP, UDP and TCP protocols (as
50 * well as some basic ICMP stuff). The implementation couples the IP,
51 * UDP, TCP and the application layers very tightly. To keep the size
52 * of the compiled code down, this code frequently uses the goto
53 * statement. While it would be possible to break the uip_process()
54 * function into many smaller functions, this would increase the code
55 * size because of the overhead of parameter passing and the fact that
56 * the optimizer would not be as efficient.
57 *
58 * The principle is that we have a small buffer, called the uip_buf,
59 * in which the device driver puts an incoming packet. The TCP/IP
60 * stack parses the headers in the packet, and calls the
61 * application. If the remote host has sent data to the application,
62 * this data is present in the uip_buf and the application read the
63 * data from there. It is up to the application to put this data into
64 * a byte stream if needed. The application will not be fed with data
65 * that is out of sequence.
66 *
67 * If the application wishes to send data to the peer, it should put
68 * its data into the uip_buf. The uip_appdata pointer points to the
69 * first available byte. The TCP/IP stack will calculate the
70 * checksums, and fill in the necessary header fields and finally send
71 * the packet back to the peer.
72 */
73
74#include "sys/cc.h"
75#include "net/ipv6/uip.h"
76#include "net/ipv6/uip-arch.h"
77#include "net/ipv6/uipopt.h"
78#include "net/ipv6/uip-icmp6.h"
79#include "net/ipv6/uip-nd6.h"
80#include "net/ipv6/uip-ds6.h"
82#include "net/routing/routing.h"
83
84#if UIP_ND6_SEND_NS
86#endif /* UIP_ND6_SEND_NS */
87
88/* Log configuration */
89#include "sys/log.h"
90#define LOG_MODULE "IPv6"
91#define LOG_LEVEL LOG_LEVEL_IPV6
92
93#if UIP_STATISTICS == 1
94struct uip_stats uip_stat;
95#endif /* UIP_STATISTICS == 1 */
96
97/*---------------------------------------------------------------------------*/
98/**
99 * \name Layer 2 variables
100 * @{
101 */
102/*---------------------------------------------------------------------------*/
103/** Host L2 address */
104#if UIP_CONF_LL_802154
105uip_lladdr_t uip_lladdr;
106#else /*UIP_CONF_LL_802154*/
107uip_lladdr_t uip_lladdr = {{0x00,0x06,0x98,0x00,0x02,0x32}};
108#endif /*UIP_CONF_LL_802154*/
109/** @} */
110
111/*---------------------------------------------------------------------------*/
112/**
113 * \name Layer 3 variables
114 * @{
115 */
116/*---------------------------------------------------------------------------*/
117/** \brief bitmap we use to record which IPv6 headers we have already seen */
118uint8_t uip_ext_bitmap = 0;
119/**
120 * \brief Total length of all IPv6 extension headers
121 */
122uint16_t uip_ext_len = 0;
123/** \brief The final protocol after IPv6 extension headers:
124 * UIP_PROTO_TCP, UIP_PROTO_UDP or UIP_PROTO_ICMP6 */
125uint8_t uip_last_proto = 0;
126/** @} */
127
128/*---------------------------------------------------------------------------*/
129/* Buffers */
130/*---------------------------------------------------------------------------*/
131/**
132 * \name Reassembly buffer definition
133 * @{
134 */
135#define FBUF ((struct uip_ip_hdr *)&uip_reassbuf[0])
136
137/** @} */
138/**
139 * \name Buffer variables
140 * @{
141 */
142/** Packet buffer for incoming and outgoing packets */
143#ifndef UIP_CONF_EXTERNAL_BUFFER
145#endif /* UIP_CONF_EXTERNAL_BUFFER */
146
147/* The uip_appdata pointer points to application data. */
149/* The uip_appdata pointer points to the application data which is to be sent*/
150void *uip_sappdata;
151
152#if UIP_URGDATA > 0
153/* The uip_urgdata pointer points to urgent data (out-of-band data), if present */
154void *uip_urgdata;
155uint16_t uip_urglen, uip_surglen;
156#endif /* UIP_URGDATA > 0 */
157
158/* The uip_len is either 8 or 16 bits, depending on the maximum packet size.*/
159uint16_t uip_len, uip_slen;
160/** @} */
161
162/*---------------------------------------------------------------------------*/
163/**
164 * \name General variables
165 * @{
166 */
167/*---------------------------------------------------------------------------*/
168
169/* The uip_flags variable is used for communication between the TCP/IP stack
170and the application program. */
171uint8_t uip_flags;
172
173/* uip_conn always points to the current connection (set to NULL for UDP). */
175
176#if UIP_ACTIVE_OPEN || UIP_UDP
177/* Keeps track of the last port used for a new connection. */
178static uint16_t lastport;
179#endif /* UIP_ACTIVE_OPEN || UIP_UDP */
180/** @} */
181
182/*---------------------------------------------------------------------------*/
183/* TCP */
184/*---------------------------------------------------------------------------*/
185/**
186 * \name TCP defines
187 *@{
188 */
189/* Structures and definitions. */
190#define TCP_FIN 0x01
191#define TCP_SYN 0x02
192#define TCP_RST 0x04
193#define TCP_PSH 0x08
194#define TCP_ACK 0x10
195#define TCP_URG 0x20
196#define TCP_CTL 0x3f
197
198#define TCP_OPT_END 0 /* End of TCP options list */
199#define TCP_OPT_NOOP 1 /* "No-operation" TCP option */
200#define TCP_OPT_MSS 2 /* Maximum segment size TCP option */
201
202#define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */
203/** @} */
204/**
205 * \name TCP variables
206 *@{
207 */
208#if UIP_TCP
209/* The uip_conns array holds all TCP connections. */
210struct uip_conn uip_conns[UIP_TCP_CONNS];
211
212/* The uip_listenports list all currently listning ports. */
213uint16_t uip_listenports[UIP_LISTENPORTS];
214
215/* The iss variable is used for the TCP initial sequence number. */
216static uint8_t iss[4];
217
218/* Temporary variables. */
219uint8_t uip_acc32[4];
220#endif /* UIP_TCP */
221/** @} */
222
223/*---------------------------------------------------------------------------*/
224/**
225 * \name UDP variables
226 * @{
227 */
228/*---------------------------------------------------------------------------*/
229#if UIP_UDP
231struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
232#endif /* UIP_UDP */
233/** @} */
234
235/*---------------------------------------------------------------------------*/
236/**
237 * \name ICMPv6 variables
238 * @{
239 */
240/*---------------------------------------------------------------------------*/
241#if UIP_CONF_ICMP6
242/** single possible icmpv6 "connection" */
243struct uip_icmp6_conn uip_icmp6_conns;
244#endif /*UIP_CONF_ICMP6*/
245/** @} */
246
247/*---------------------------------------------------------------------------*/
248/* Functions */
249/*---------------------------------------------------------------------------*/
250#if UIP_TCP
251void
252uip_add32(uint8_t *op32, uint16_t op16)
253{
254 uip_acc32[3] = op32[3] + (op16 & 0xff);
255 uip_acc32[2] = op32[2] + (op16 >> 8);
256 uip_acc32[1] = op32[1];
257 uip_acc32[0] = op32[0];
258
259 if(uip_acc32[2] < (op16 >> 8)) {
260 ++uip_acc32[1];
261 if(uip_acc32[1] == 0) {
262 ++uip_acc32[0];
263 }
264 }
265
266
267 if(uip_acc32[3] < (op16 & 0xff)) {
268 ++uip_acc32[2];
269 if(uip_acc32[2] == 0) {
270 ++uip_acc32[1];
271 if(uip_acc32[1] == 0) {
272 ++uip_acc32[0];
273 }
274 }
275 }
276}
277
278/*---------------------------------------------------------------------------*/
279/* TCP sequence number and window validation functions */
280static inline uint32_t
281seq_to_uint32(uint8_t *seq)
282{
283 return ((uint32_t)seq[0] << 24) | ((uint32_t)seq[1] << 16) |
284 ((uint32_t)seq[2] << 8) | seq[3];
285}
286
287/*
288 * Segment acceptability test per RFC 9293 Section 3.10.7.4, Table 6.
289 *
290 * A segment is acceptable if any part of it falls within the receive
291 * window. For segments with data, this means either the beginning or
292 * end of the segment must be in [RCV.NXT, RCV.NXT + RCV.WND).
293 */
294static inline int
295seg_in_window(uint8_t *seq, uint16_t seg_len, uint8_t *rcv_nxt,
296 uint16_t window)
297{
298 int32_t start_diff = (int32_t)(seq_to_uint32(seq) - seq_to_uint32(rcv_nxt));
299
300 if(seg_len == 0) {
301 if(window == 0) {
302 return start_diff == 0;
303 }
304 return start_diff >= 0 && start_diff < (int32_t)window;
305 }
306
307 if(window == 0) {
308 return 0;
309 }
310
311 /* SEG.LEN > 0, RCV.WND > 0: accept if beginning OR end is in window */
312 if(start_diff >= 0 && start_diff < (int32_t)window) {
313 return 1;
314 }
315 int32_t end_diff = start_diff + (int32_t)(seg_len - 1);
316 return end_diff >= 0 && end_diff < (int32_t)window;
317}
318#endif /* UIP_TCP */
319
320#if ! UIP_ARCH_CHKSUM
321/*---------------------------------------------------------------------------*/
322static uint16_t
323chksum(uint16_t sum, const uint8_t *data, uint16_t len)
324{
325 uint16_t t;
326 const uint8_t *dataptr;
327 const uint8_t *last_byte;
328
329 dataptr = data;
330 last_byte = data + len - 1;
331
332 while(dataptr < last_byte) { /* At least two more bytes */
333 t = (dataptr[0] << 8) + dataptr[1];
334 sum += t;
335 if(sum < t) {
336 sum++; /* carry */
337 }
338 dataptr += 2;
339 }
340
341 if(dataptr == last_byte) {
342 t = (dataptr[0] << 8) + 0;
343 sum += t;
344 if(sum < t) {
345 sum++; /* carry */
346 }
347 }
348
349 /* Return sum in host byte order. */
350 return sum;
351}
352/*---------------------------------------------------------------------------*/
353uint16_t
354uip_chksum(uint16_t *data, uint16_t len)
355{
356 return uip_htons(chksum(0, (uint8_t *)data, len));
357}
358/*---------------------------------------------------------------------------*/
359#ifndef UIP_ARCH_IPCHKSUM
360uint16_t
362{
363 uint16_t sum;
364
365 sum = chksum(0, uip_buf, UIP_IPH_LEN);
366 LOG_DBG("uip_ipchksum: sum 0x%04x\n", sum);
367 return (sum == 0) ? 0xffff : uip_htons(sum);
368}
369#endif
370/*---------------------------------------------------------------------------*/
371static uint16_t
372upper_layer_chksum(uint8_t proto)
373{
374/* gcc 4.4.0 - 4.6.1 (maybe 4.3...) with -Os on 8 bit CPUS incorrectly compiles:
375 * int bar (int);
376 * int foo (unsigned char a, unsigned char b) {
377 * int len = (a << 8) + b; //len becomes 0xff00&<random>+b
378 * return len + bar (len);
379 * }
380 * upper_layer_len triggers this bug unless it is declared volatile.
381 * See https://sourceforge.net/apps/mantisbt/contiki/view.php?id=3
382 */
383 volatile uint16_t upper_layer_len;
384 uint16_t sum;
385
386 upper_layer_len = uipbuf_get_len_field(UIP_IP_BUF) - uip_ext_len;
387
388 LOG_DBG("Upper layer checksum len: %d from: %d\n", upper_layer_len,
389 (int)(UIP_IP_PAYLOAD(uip_ext_len) - uip_buf));
390
391 /* First sum pseudoheader. */
392 /* IP protocol and length fields. This addition cannot carry. */
393 sum = upper_layer_len + proto;
394 /* Sum IP source and destination addresses. */
395 sum = chksum(sum, (uint8_t *)&UIP_IP_BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t));
396
397 /* Sum upper-layer header and data. */
398 sum = chksum(sum, UIP_IP_PAYLOAD(uip_ext_len), upper_layer_len);
399
400 return (sum == 0) ? 0xffff : uip_htons(sum);
401}
402/*---------------------------------------------------------------------------*/
403uint16_t
405{
406 return upper_layer_chksum(UIP_PROTO_ICMP6);
407
408}
409/*---------------------------------------------------------------------------*/
410#if UIP_TCP
411uint16_t
413{
414 return upper_layer_chksum(UIP_PROTO_TCP);
415}
416#endif /* UIP_TCP */
417/*---------------------------------------------------------------------------*/
418#if UIP_UDP && UIP_UDP_CHECKSUMS
419uint16_t
420uip_udpchksum(void)
421{
422 return upper_layer_chksum(UIP_PROTO_UDP);
423}
424#endif /* UIP_UDP && UIP_UDP_CHECKSUMS */
425#endif /* UIP_ARCH_CHKSUM */
426/*---------------------------------------------------------------------------*/
427void
429{
430 uipbuf_init();
431 uip_ds6_init();
433 uip_nd6_init();
434
435#if UIP_TCP
436 for(int c = 0; c < UIP_LISTENPORTS; ++c) {
437 uip_listenports[c] = 0;
438 }
439 for(int c = 0; c < UIP_TCP_CONNS; ++c) {
440 uip_conns[c].tcpstateflags = UIP_CLOSED;
441 }
442#endif /* UIP_TCP */
443
444#if UIP_ACTIVE_OPEN || UIP_UDP
445 lastport = 1024;
446#endif /* UIP_ACTIVE_OPEN || UIP_UDP */
447
448#if UIP_UDP
449 for(int c = 0; c < UIP_UDP_CONNS; ++c) {
450 uip_udp_conns[c].lport = 0;
451 }
452#endif /* UIP_UDP */
453
454#if UIP_IPV6_MULTICAST
455 UIP_MCAST6.init();
456#endif
457}
458/*---------------------------------------------------------------------------*/
459#if UIP_TCP && UIP_ACTIVE_OPEN
460struct uip_conn *
461uip_connect(const uip_ipaddr_t *ripaddr, uint16_t rport)
462{
463 register struct uip_conn *conn, *cconn;
464 int c;
465
466 /* Find an unused local port. */
467 again:
468 ++lastport;
469
470 if(lastport >= 32000) {
471 lastport = 4096;
472 }
473
474 /* Check if this port is already in use, and if so try to find
475 another one. */
476 for(c = 0; c < UIP_TCP_CONNS; ++c) {
477 conn = &uip_conns[c];
478 if(conn->tcpstateflags != UIP_CLOSED &&
479 conn->lport == uip_htons(lastport)) {
480 goto again;
481 }
482 }
483
484 conn = 0;
485 for(c = 0; c < UIP_TCP_CONNS; ++c) {
486 cconn = &uip_conns[c];
487 if(cconn->tcpstateflags == UIP_CLOSED) {
488 conn = cconn;
489 break;
490 }
491 if(cconn->tcpstateflags == UIP_TIME_WAIT) {
492 if(conn == 0 ||
493 cconn->timer > conn->timer) {
494 conn = cconn;
495 }
496 }
497 }
498
499 if(conn == 0) {
500 return 0;
501 }
502
503 conn->tcpstateflags = UIP_SYN_SENT;
504
505 conn->snd_nxt[0] = iss[0];
506 conn->snd_nxt[1] = iss[1];
507 conn->snd_nxt[2] = iss[2];
508 conn->snd_nxt[3] = iss[3];
509
510 conn->rcv_nxt[0] = 0;
511 conn->rcv_nxt[1] = 0;
512 conn->rcv_nxt[2] = 0;
513 conn->rcv_nxt[3] = 0;
514
515 conn->initialmss = conn->mss = UIP_TCP_MSS;
516
517 conn->len = 1; /* TCP length of the SYN is one. */
518 conn->nrtx = 0;
519 conn->timer = 1; /* Send the SYN next time around. */
520 conn->rto = UIP_RTO;
521 conn->sa = 0;
522 conn->sv = 16; /* Initial value of the RTT variance. */
523 conn->lport = uip_htons(lastport);
524 conn->rport = rport;
526
527 return conn;
528}
529#endif /* UIP_TCP && UIP_ACTIVE_OPEN */
530/*---------------------------------------------------------------------------*/
531bool
533{
534 /* Remove ext header before TCP/UDP processing. */
535 if(uip_ext_len > 0) {
536 LOG_DBG("Removing IPv6 extension headers (extlen: %d, uiplen: %d)\n",
538 if(uip_len < UIP_IPH_LEN + uip_ext_len) {
539 LOG_ERR("uip_len too short compared to ext len\n");
540 uipbuf_clear();
541 return false;
542 }
543
544 /* Set proto */
545 UIP_IP_BUF->proto = uip_last_proto;
546 /* Move IP payload to the "left"*/
547 memmove(UIP_IP_PAYLOAD(0), UIP_IP_PAYLOAD(uip_ext_len),
548 uip_len - UIP_IPH_LEN - uip_ext_len);
549
550 /* Update the IP length. */
551 if(uipbuf_add_ext_hdr(-uip_ext_len) == false) {
552 return false;
553 }
554 uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
555 }
556 return true;
557}
558/*---------------------------------------------------------------------------*/
559#if UIP_UDP
560struct uip_udp_conn *
561uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport)
562{
563 int c;
564 register struct uip_udp_conn *conn;
565
566 /* Find an unused local port. */
567 again:
568 ++lastport;
569
570 if(lastport >= 32000) {
571 lastport = 4096;
572 }
573
574 for(c = 0; c < UIP_UDP_CONNS; ++c) {
575 if(uip_udp_conns[c].lport == uip_htons(lastport)) {
576 goto again;
577 }
578 }
579
580 conn = 0;
581 for(c = 0; c < UIP_UDP_CONNS; ++c) {
582 if(uip_udp_conns[c].lport == 0) {
583 conn = &uip_udp_conns[c];
584 break;
585 }
586 }
587
588 if(conn == 0) {
589 return 0;
590 }
591
592 conn->lport = UIP_HTONS(lastport);
593 conn->rport = rport;
594 if(ripaddr == NULL) {
595 memset(&conn->ripaddr, 0, sizeof(uip_ipaddr_t));
596 } else {
598 }
599 conn->ttl = uip_ds6_if.cur_hop_limit;
600
601 return conn;
602}
603#endif /* UIP_UDP */
604/*---------------------------------------------------------------------------*/
605#if UIP_TCP
606void
607uip_unlisten(uint16_t port)
608{
609 int c;
610 for(c = 0; c < UIP_LISTENPORTS; ++c) {
611 if(uip_listenports[c] == port) {
612 uip_listenports[c] = 0;
613 return;
614 }
615 }
616}
617/*---------------------------------------------------------------------------*/
618void
619uip_listen(uint16_t port)
620{
621 int c;
622 for(c = 0; c < UIP_LISTENPORTS; ++c) {
623 if(uip_listenports[c] == 0) {
624 uip_listenports[c] = port;
625 return;
626 }
627 }
628}
629#endif
630/*---------------------------------------------------------------------------*/
631
632#if UIP_CONF_IPV6_REASSEMBLY
633#define UIP_REASS_BUFSIZE (UIP_BUFSIZE)
634
635static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE];
636
637/* One bit per 8 bytes, i.e. one byte per 64 bytes of the reassembly
638 buffer. Round the element count up so the bitmap covers the whole
639 buffer even when UIP_REASS_BUFSIZE is not a multiple of 64; otherwise
640 integer division would truncate the last partial block and let
641 (offset + len) >> 6 index one element past the end. */
642static uint8_t uip_reassbitmap[(UIP_REASS_BUFSIZE + (8 * 8) - 1) / (8 * 8)];
643/*the first byte of an IP fragment is aligned on an 8-byte boundary */
644
645static const uint8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
646 0x0f, 0x07, 0x03, 0x01};
647static uint16_t uip_reasslen;
648static uint8_t uip_reassflags;
649
650#define UIP_REASS_FLAG_LASTFRAG 0x01
651#define UIP_REASS_FLAG_FIRSTFRAG 0x02
652#define UIP_REASS_FLAG_ERROR_MSG 0x04
653
654
655/*
656 * See RFC 2460 for a description of fragmentation in IPv6
657 * A typical Ipv6 fragment
658 * +------------------+--------+--------------+
659 * | Unfragmentable |Fragment| first |
660 * | Part | Header | fragment |
661 * +------------------+--------+--------------+
662 */
663
664
665struct etimer uip_reass_timer; /**< Timer for reassembly */
666uint8_t uip_reass_on; /* equal to 1 if we are currently reassembling a packet */
667
668static uint32_t uip_id; /* For every packet that is to be fragmented, the source
669 node generates an Identification value that is present
670 in all the fragments */
671#define IP_MF 0x0001
672
673static uint16_t
674uip_reass(uint8_t *prev_proto_ptr)
675{
676 uint16_t offset=0;
677 uint16_t len;
678 uint16_t i;
679 struct uip_frag_hdr *frag_buf = (struct uip_frag_hdr *)UIP_IP_PAYLOAD(uip_ext_len);
680
681 /* If ip_reasstmr is zero, no packet is present in the buffer */
682 /* We first write the unfragmentable part of IP header into the reassembly
683 buffer. The reset the other reassembly variables. */
684 if(uip_reass_on == 0) {
685 LOG_INFO("Starting reassembly\n");
686 memcpy(FBUF, UIP_IP_BUF, uip_ext_len + UIP_IPH_LEN);
687 /* temporary in case we do not receive the fragment with offset 0 first */
689 uip_reass_on = 1;
690 uip_reassflags = 0;
691 uip_id = frag_buf->id;
692 /* Clear the bitmap. */
693 memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap));
694 }
695 /*
696 * Check if the incoming fragment matches the one currently present
697 * in the reasembly buffer. If so, we proceed with copying the fragment
698 * into the buffer.
699 */
700 if(uip_ipaddr_cmp(&FBUF->srcipaddr, &UIP_IP_BUF->srcipaddr) &&
701 uip_ipaddr_cmp(&FBUF->destipaddr, &UIP_IP_BUF->destipaddr) &&
702 frag_buf->id == uip_id) {
703 len = uip_len - uip_ext_len - UIP_IPH_LEN - UIP_FRAGH_LEN;
704 offset = (uip_ntohs(frag_buf->offsetresmore) & 0xfff8);
705 /* in byte, originaly in multiple of 8 bytes*/
706 LOG_INFO("len %d\n", len);
707 LOG_INFO("offset %d\n", offset);
708 if(offset == 0){
709 uip_reassflags |= UIP_REASS_FLAG_FIRSTFRAG;
710 /*
711 * The Next Header field of the last header of the Unfragmentable
712 * Part is obtained from the Next Header field of the first
713 * fragment's Fragment header.
714 */
715 *prev_proto_ptr = frag_buf->next;
716 memcpy(FBUF, UIP_IP_BUF, uip_ext_len + UIP_IPH_LEN);
717 LOG_INFO("src ");
718 LOG_INFO_6ADDR(&FBUF->srcipaddr);
719 LOG_INFO_("dest ");
720 LOG_INFO_6ADDR(&FBUF->destipaddr);
721 LOG_INFO_("next %d\n", UIP_IP_BUF->proto);
722
723 }
724
725 /* If the offset or the offset + fragment length overflows the
726 reassembly buffer, we discard the entire packet. The fragment is
727 copied to FBUF + UIP_IPH_LEN + uip_ext_len + offset, so the
728 unfragmentable part (UIP_IPH_LEN + uip_ext_len) must be included in
729 the bound; otherwise a fragment with offset + len close to
730 UIP_REASS_BUFSIZE would write up to UIP_IPH_LEN + uip_ext_len bytes
731 past the end of uip_reassbuf[]. */
732 if(offset > UIP_REASS_BUFSIZE ||
733 UIP_IPH_LEN + uip_ext_len + offset + len > UIP_REASS_BUFSIZE) {
734 uip_reass_on = 0;
736 return 0;
737 }
738
739 /* If this fragment has the More Fragments flag set to zero, it is the
740 last fragment*/
741 if((uip_ntohs(frag_buf->offsetresmore) & IP_MF) == 0) {
742 uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
743 /*calculate the size of the entire packet*/
744 uip_reasslen = offset + len;
745 LOG_INFO("last fragment reasslen %d\n", uip_reasslen);
746 } else {
747 /* If len is not a multiple of 8 octets and the M flag of that fragment
748 is 1, then that fragment must be discarded and an ICMP Parameter
749 Problem, Code 0, message should be sent to the source of the fragment,
750 pointing to the Payload Length field of the fragment packet. */
751 if(len % 8 != 0){
753 uip_reassflags |= UIP_REASS_FLAG_ERROR_MSG;
754 /* not clear if we should interrupt reassembly, but it seems so from
755 the conformance tests */
756 uip_reass_on = 0;
758 return uip_len;
759 }
760 }
761
762 /* Copy the fragment into the reassembly buffer, at the right
763 offset. */
764 memcpy((uint8_t *)FBUF + UIP_IPH_LEN + uip_ext_len + offset,
765 (uint8_t *)frag_buf + UIP_FRAGH_LEN, len);
766
767 /* Update the bitmap. */
768 if(offset >> 6 == (offset + len) >> 6) {
769 uip_reassbitmap[offset >> 6] |=
770 bitmap_bits[(offset >> 3) & 7] &
771 ~bitmap_bits[((offset + len) >> 3) & 7];
772 } else {
773 /* If the two endpoints are in different bytes, we update the
774 bytes in the endpoints and fill the stuff inbetween with
775 0xff. */
776 uip_reassbitmap[offset >> 6] |= bitmap_bits[(offset >> 3) & 7];
777
778 for(i = (1 + (offset >> 6)); i < ((offset + len) >> 6); ++i) {
779 uip_reassbitmap[i] = 0xff;
780 }
781 uip_reassbitmap[(offset + len) >> 6] |=
782 ~bitmap_bits[((offset + len) >> 3) & 7];
783 }
784
785 /* Finally, we check if we have a full packet in the buffer. We do
786 this by checking if we have the last fragment and if all bits
787 in the bitmap are set. */
788
789 if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
790 /* Check all bytes up to and including all but the last byte in
791 the bitmap. */
792 for(i = 0; i < (uip_reasslen >> 6); ++i) {
793 if(uip_reassbitmap[i] != 0xff) {
794 return 0;
795 }
796 }
797 /* Check the last byte in the bitmap. It should contain just the
798 right amount of bits. */
799 if(uip_reassbitmap[uip_reasslen >> 6] !=
800 (uint8_t)~bitmap_bits[(uip_reasslen >> 3) & 7]) {
801 return 0;
802 }
803
804 /* If we have come this far, we have a full packet in the
805 buffer, so we copy it to uip_buf. We also reset the timer. */
806 uip_reass_on = 0;
808
809 uip_reasslen += UIP_IPH_LEN + uip_ext_len;
810 memcpy(UIP_IP_BUF, FBUF, uip_reasslen);
811 uipbuf_set_len_field(UIP_IP_BUF, uip_reasslen - UIP_IPH_LEN);
812 LOG_INFO("reassembled packet %d (%d)\n", uip_reasslen, uipbuf_get_len_field(UIP_IP_BUF));
813
814 return uip_reasslen;
815
816 }
817 } else {
818 LOG_WARN("Already reassembling another paquet\n");
819 }
820 return 0;
821}
822
823void
825{
826 /* to late, we abandon the reassembly of the packet */
827
828 uip_reass_on = 0;
830
831 if(uip_reassflags & UIP_REASS_FLAG_FIRSTFRAG){
832 LOG_ERR("fragmentation timeout\n");
833 /* If the first fragment has been received, an ICMP Time Exceeded
834 -- Fragment Reassembly Time Exceeded message should be sent to the
835 source of that fragment. */
836 /** \note
837 * We don't have a complete packet to put in the error message.
838 * We could include the first fragment but since its not mandated by
839 * any RFC, we decided not to include it as it reduces the size of
840 * the packet.
841 */
842 uipbuf_clear();
843 memcpy(UIP_IP_BUF, FBUF, UIP_IPH_LEN); /* copy the header for src
844 and dest address*/
846
847 UIP_STAT(++uip_stat.ip.sent);
848 uip_flags = 0;
849 }
850}
851
852#endif /* UIP_CONF_IPV6_REASSEMBLY */
853
854/*---------------------------------------------------------------------------*/
855#if UIP_TCP
856static void
857uip_add_rcv_nxt(uint16_t n)
858{
860 uip_conn->rcv_nxt[0] = uip_acc32[0];
861 uip_conn->rcv_nxt[1] = uip_acc32[1];
862 uip_conn->rcv_nxt[2] = uip_acc32[2];
863 uip_conn->rcv_nxt[3] = uip_acc32[3];
864}
865#endif
866/*---------------------------------------------------------------------------*/
867
868/**
869 * \brief Process the options in Destination and Hop By Hop extension headers
870 */
871static uint8_t
872ext_hdr_options_process(uint8_t *ext_buf)
873{
874 /*
875 * Length field in the extension header: length of the header in units of
876 * 8 bytes, excluding the first 8 bytes
877 * length field in an option : the length of data in the option
878 */
879 uint16_t opt_offset = 2; /* 2 first bytes in ext header */
880 struct uip_hbho_hdr *ext_hdr = (struct uip_hbho_hdr *)ext_buf;
881 uint16_t ext_hdr_len = (ext_hdr->len << 3) + 8;
882
883 while(opt_offset + 2 <= ext_hdr_len) { /* + 2 for opt header */
884 struct uip_ext_hdr_opt *opt_hdr = (struct uip_ext_hdr_opt *)(ext_buf + opt_offset);
885 uint16_t opt_len = opt_hdr->len + 2;
886
887 if(opt_offset + opt_len > ext_hdr_len) {
888 LOG_ERR("Extension header option too long: dropping packet\n");
890 (ext_buf + opt_offset) - uip_buf);
891 return 2;
892 }
893
894 switch(opt_hdr->type) {
896 LOG_DBG("Processing PAD1 option\n");
897 opt_offset += 1;
898 break;
899 case UIP_EXT_HDR_OPT_PADN:
900 LOG_DBG("Processing PADN option\n");
901 opt_offset += opt_len;
902 break;
903 case UIP_EXT_HDR_OPT_RPL:
904 /* Fixes situation when a node that is not using RPL
905 * joins a network which does. The received packages will include the
906 * RPL header and processed by the "default" case of the switch
907 * (0x63 & 0xC0 = 0x40). Hence, the packet is discarded as the header
908 * is considered invalid.
909 * Using this fix, the header is ignored, and the next header (if
910 * present) is processed.
911 */
912 LOG_DBG("Processing RPL option\n");
913 if(!NETSTACK_ROUTING.ext_header_hbh_update(ext_buf, opt_offset)) {
914 LOG_ERR("RPL Option Error: Dropping Packet\n");
915 return 1;
916 }
917 opt_offset += opt_len;
918 break;
919#if UIP_MCAST6_ENGINE == UIP_MCAST6_ENGINE_MPL
920 case UIP_EXT_HDR_OPT_MPL:
921 /* MPL (RFC7731) Introduces the 0x6D hop by hop option. Hosts that do not
922 * recognise the option should drop the packet. Since we want to keep the packet,
923 * we want to process the option and not revert to the default case.
924 */
925 LOG_DBG("Processing MPL option\n");
926 opt_offset += opt_len;
927 break;
928#endif
929 default:
930 /*
931 * check the two highest order bits of the option
932 * - 00 skip over this option and continue processing the header.
933 * - 01 discard the packet.
934 * - 10 discard the packet and, regardless of whether or not the
935 * packet's Destination Address was a multicast address, send an
936 * ICMP Parameter Problem, Code 2, message to the packet's
937 * Source Address, pointing to the unrecognized Option Type.
938 * - 11 discard the packet and, only if the packet's Destination
939 * Address was not a multicast address, send an ICMP Parameter
940 * Problem, Code 2, message to the packet's Source Address,
941 * pointing to the unrecognized Option Type.
942 */
943 LOG_DBG("Unrecognized option, MSB 0x%x\n", opt_hdr->type);
944 switch(opt_hdr->type & 0xC0) {
945 case 0:
946 break;
947 case 0x40:
948 return 1;
949 case 0xC0:
950 if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
951 return 1;
952 }
953 case 0x80:
955 (ext_buf + opt_offset) - uip_buf);
956 return 2;
957 }
958 /* in the cases were we did not discard, update ext_opt* */
959 opt_offset += opt_len;
960 break;
961 }
962 }
963 return 0;
964}
965/*---------------------------------------------------------------------------*/
966#if UIP_TCP
967static void
968process_tcp_options(struct uip_conn *conn)
969{
970 if((UIP_TCP_BUF->tcpoffset & 0xf0) <= 0x50) {
971 return;
972 }
973
974 /* Parse the TCP MSS option, if present. */
975 for(unsigned c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
976 if(UIP_IPTCPH_LEN + c >= UIP_BUFSIZE) {
977 /* TCP option data out of bounds. */
978 return;
979 }
980 uint8_t opt = uip_buf[UIP_IPTCPH_LEN + c];
981 switch(opt) {
982 case TCP_OPT_END:
983 /* Stop processing options. */
984 return;
985 case TCP_OPT_NOOP:
986 c++;
987 break;
988 case TCP_OPT_MSS:
989 if(UIP_IPTCPH_LEN + 3 + c >= UIP_BUFSIZE ||
990 uip_buf[UIP_IPTCPH_LEN + 1 + c] != TCP_OPT_MSS_LEN) {
991 /* TCP option data out of bounds or invalid MSS option length. */
992 return;
993 }
994
995 /* An MSS option with the right option length. */
996 uint16_t tmp16 = (uip_buf[UIP_IPTCPH_LEN + 2 + c] << 8) |
997 uip_buf[UIP_IPTCPH_LEN + 3 + c];
998 conn->initialmss = conn->mss =
999 tmp16 > UIP_TCP_MSS ? UIP_TCP_MSS : tmp16;
1000 /* Stop processing options. */
1001 return;
1002 default:
1003 if(UIP_IPTCPH_LEN + 1 + c >= UIP_BUFSIZE) {
1004 /* TCP option data out of bounds. */
1005 return;
1006 }
1007 /* All other options have a length field, so that we easily
1008 can skip past them. */
1009 if(uip_buf[UIP_IPTCPH_LEN + 1 + c] == 0) {
1010 /* If the length field is zero, the options are malformed
1011 and we don't process them further. */
1012 return;
1013 }
1014 c += uip_buf[UIP_IPTCPH_LEN + 1 + c];
1015 break;
1016 }
1017 }
1018}
1019#endif /* UIP_TCP */
1020/*---------------------------------------------------------------------------*/
1021static bool
1022uip_check_mtu(void)
1023{
1024 if(uip_len > UIP_LINK_MTU) {
1026 UIP_STAT(++uip_stat.ip.drop);
1027 return false;
1028 } else {
1029 return true;
1030 }
1031}
1032/*---------------------------------------------------------------------------*/
1033static bool
1034uip_update_ttl(void)
1035{
1036 if(UIP_IP_BUF->ttl <= 1) {
1038 UIP_STAT(++uip_stat.ip.drop);
1039 return false;
1040 } else {
1041 UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1;
1042 return true;
1043 }
1044}
1045/*---------------------------------------------------------------------------*/
1046void
1047uip_process(uint8_t flag)
1048{
1049 uint8_t *last_header;
1050 uint8_t protocol;
1051 uint8_t *next_header;
1052 struct uip_ext_hdr *ext_ptr;
1053#if UIP_TCP
1054 int c;
1055 register struct uip_conn *uip_connr = uip_conn;
1056#endif /* UIP_TCP */
1057#if UIP_UDP
1058 if(flag == UIP_UDP_SEND_CONN) {
1059 goto udp_send;
1060 }
1061#endif /* UIP_UDP */
1062 uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN];
1063
1064 /* Check if we were invoked because of a poll request for a
1065 particular connection. */
1066 if(flag == UIP_POLL_REQUEST) {
1067#if UIP_TCP
1068 if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
1069 !uip_outstanding(uip_connr)) {
1070 uip_flags = UIP_POLL;
1071 UIP_APPCALL();
1072 goto appsend;
1073#if UIP_ACTIVE_OPEN
1074 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
1075 /* In the SYN_SENT state, we retransmit out SYN. */
1076 UIP_TCP_BUF->flags = 0;
1077 goto tcp_send_syn;
1078#endif /* UIP_ACTIVE_OPEN */
1079 }
1080 goto drop;
1081#endif /* UIP_TCP */
1082 /* Check if we were invoked because of the perodic timer fireing. */
1083 } else if(flag == UIP_TIMER) {
1084 /* Reset the length variables. */
1085#if UIP_TCP
1086 uipbuf_clear();
1087 uip_slen = 0;
1088
1089 /* Increase the initial sequence number. */
1090 if(++iss[3] == 0) {
1091 if(++iss[2] == 0) {
1092 if(++iss[1] == 0) {
1093 ++iss[0];
1094 }
1095 }
1096 }
1097
1098 /*
1099 * Check if the connection is in a state in which we simply wait
1100 * for the connection to time out. If so, we increase the
1101 * connection's timer and remove the connection if it times
1102 * out.
1103 */
1104 if(uip_connr->tcpstateflags == UIP_TIME_WAIT ||
1105 uip_connr->tcpstateflags == UIP_FIN_WAIT_2) {
1106 ++(uip_connr->timer);
1107 if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
1108 uip_connr->tcpstateflags = UIP_CLOSED;
1109 }
1110 } else if(uip_connr->tcpstateflags != UIP_CLOSED) {
1111 /*
1112 * If the connection has outstanding data, we increase the
1113 * connection's timer and see if it has reached the RTO value
1114 * in which case we retransmit.
1115 */
1116 if(uip_outstanding(uip_connr)) {
1117 if(uip_connr->timer-- == 0) {
1118 if(uip_connr->nrtx == UIP_MAXRTX ||
1119 ((uip_connr->tcpstateflags == UIP_SYN_SENT ||
1120 uip_connr->tcpstateflags == UIP_SYN_RCVD) &&
1121 uip_connr->nrtx == UIP_MAXSYNRTX)) {
1122 uip_connr->tcpstateflags = UIP_CLOSED;
1123
1124 /*
1125 * We call UIP_APPCALL() with uip_flags set to
1126 * UIP_TIMEDOUT to inform the application that the
1127 * connection has timed out.
1128 */
1129 uip_flags = UIP_TIMEDOUT;
1130 UIP_APPCALL();
1131
1132 /* We also send a reset packet to the remote host. */
1133 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1134 goto tcp_send_nodata;
1135 }
1136
1137 /* Exponential backoff. */
1138 uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
1139 4:
1140 uip_connr->nrtx);
1141 ++(uip_connr->nrtx);
1142
1143 /*
1144 * Ok, so we need to retransmit. We do this differently
1145 * depending on which state we are in. In ESTABLISHED, we
1146 * call upon the application so that it may prepare the
1147 * data for the retransmit. In SYN_RCVD, we resend the
1148 * SYNACK that we sent earlier and in LAST_ACK we have to
1149 * retransmit our FINACK.
1150 */
1151 UIP_STAT(++uip_stat.tcp.rexmit);
1152 switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
1153 case UIP_SYN_RCVD:
1154 /* In the SYN_RCVD state, we should retransmit our SYNACK. */
1155 goto tcp_send_synack;
1156
1157#if UIP_ACTIVE_OPEN
1158 case UIP_SYN_SENT:
1159 /* In the SYN_SENT state, we retransmit out SYN. */
1160 UIP_TCP_BUF->flags = 0;
1161 goto tcp_send_syn;
1162#endif /* UIP_ACTIVE_OPEN */
1163
1164 case UIP_ESTABLISHED:
1165 /*
1166 * In the ESTABLISHED state, we call upon the application
1167 * to do the actual retransmit after which we jump into
1168 * the code for sending out the packet (the apprexmit
1169 * label).
1170 */
1171 uip_flags = UIP_REXMIT;
1172 UIP_APPCALL();
1173 goto apprexmit;
1174
1175 case UIP_FIN_WAIT_1:
1176 case UIP_CLOSING:
1177 case UIP_LAST_ACK:
1178 /* In all these states we should retransmit a FINACK. */
1179 goto tcp_send_finack;
1180 }
1181 }
1182 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
1183 /*
1184 * If there was no need for a retransmission, we poll the
1185 * application for new data.
1186 */
1187 uip_flags = UIP_POLL;
1188 UIP_APPCALL();
1189 goto appsend;
1190 }
1191 }
1192 goto drop;
1193#endif /* UIP_TCP */
1194 }
1195#if UIP_UDP
1196 if(flag == UIP_UDP_TIMER) {
1197 if(uip_udp_conn->lport != 0) {
1198 uip_conn = NULL;
1199 uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN];
1200 uip_len = uip_slen = 0;
1201 uip_flags = UIP_POLL;
1202 UIP_UDP_APPCALL();
1203 goto udp_send;
1204 } else {
1205 goto drop;
1206 }
1207 }
1208#endif /* UIP_UDP */
1209
1210
1211 /* This is where the input processing starts. */
1212 UIP_STAT(++uip_stat.ip.recv);
1213
1214 /* Start of IP input header processing code. */
1215
1216 /* First check that we have received a full IPv6 header. */
1217 if(uip_len < UIP_IPH_LEN) {
1218 UIP_STAT(++uip_stat.ip.drop);
1219 LOG_WARN("incomplete IPv6 header received (%d bytes)\n", (int)uip_len);
1220 goto drop;
1221 }
1222
1223 /* Check validity of the IP header. */
1224 if((UIP_IP_BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */
1225 UIP_STAT(++uip_stat.ip.drop);
1226 UIP_STAT(++uip_stat.ip.vhlerr);
1227 LOG_ERR("invalid version\n");
1228 goto drop;
1229 }
1230
1231 /*
1232 * Check the size of the packet. If the size reported to us in
1233 * uip_len is smaller the size reported in the IP header, we assume
1234 * that the packet has been corrupted in transit.
1235 *
1236 * If the size of uip_len is larger than the size reported in the IP
1237 * packet header, the packet has been padded, and we set uip_len to
1238 * the correct value.
1239 */
1240 if(uipbuf_get_len_field(UIP_IP_BUF) > uip_len - UIP_IPH_LEN) {
1241 UIP_STAT(++uip_stat.ip.drop);
1242 LOG_ERR("packet shorter than reported in IP header\n");
1243 goto drop;
1244 }
1245
1246 /*
1247 * The length reported in the IPv6 header is the length of the
1248 * payload that follows the header. However, uIP uses the uip_len
1249 * variable for holding the size of the entire packet, including the
1250 * IP header. For IPv4 this is not a problem as the length field in
1251 * the IPv4 header contains the length of the entire packet. But for
1252 * IPv6 we need to add the size of the IPv6 header (40 bytes).
1253 */
1254 uip_len = uipbuf_get_len_field(UIP_IP_BUF) + UIP_IPH_LEN;
1255
1256 /* Check that the packet length is acceptable given our IP buffer size. */
1257 if(uip_len > sizeof(uip_buf)) {
1258 UIP_STAT(++uip_stat.ip.drop);
1259 LOG_WARN("dropping packet with length %d > %d\n",
1260 (int)uip_len, (int)sizeof(uip_buf));
1261 goto drop;
1262 }
1263
1264 /* Check sanity of extension headers, and compute the total extension header
1265 * length (uip_ext_len) as well as the final protocol (uip_last_proto) */
1266 uip_last_proto = 0;
1267 last_header = uipbuf_get_last_header(uip_buf, uip_len, &uip_last_proto);
1268 if(last_header == NULL) {
1269 LOG_ERR("invalid extension header chain\n");
1270 goto drop;
1271 }
1272 /* Set uip_ext_len */
1273 uip_ext_len = last_header - UIP_IP_PAYLOAD(0);
1274
1275 LOG_INFO("packet received from ");
1276 LOG_INFO_6ADDR(&UIP_IP_BUF->srcipaddr);
1277 LOG_INFO_(" to ");
1278 LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
1279 LOG_INFO_("\n");
1280
1281 if(uip_is_addr_mcast(&UIP_IP_BUF->srcipaddr)){
1282 UIP_STAT(++uip_stat.ip.drop);
1283 LOG_ERR("Dropping packet, src is mcast\n");
1284 goto drop;
1285 }
1286
1287 /* Refresh neighbor state after receiving a unicast message */
1288#if UIP_ND6_SEND_NS
1289 if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
1290 uip_ds6_nbr_refresh_reachable_state(&UIP_IP_BUF->srcipaddr);
1291 }
1292#endif /* UIP_ND6_SEND_NS */
1293
1294#if UIP_CONF_ROUTER
1295 /*
1296 * If present, the Hop-by-Hop Option must be processed before forwarding
1297 * the packet.
1298 */
1299
1300 next_header = uipbuf_get_next_header(uip_buf, uip_len, &protocol, true);
1301 if(next_header != NULL && protocol == UIP_PROTO_HBHO) {
1302 switch(ext_hdr_options_process(next_header)) {
1303 case 0:
1304 break; /* done */
1305 case 1:
1306 goto drop; /* silently discard */
1307 case 2:
1308 goto send; /* send icmp error message (created in
1309 ext_hdr_options_process) and discard */
1310 }
1311 }
1312
1313 /*
1314 * Process Packets with a routable multicast destination:
1315 * - We invoke the multicast engine and let it do its thing
1316 * (cache, forward etc).
1317 * - We never execute the datagram forwarding logic in this file here. When
1318 * the engine returns, forwarding has been handled if and as required.
1319 * - Depending on the return value, we either discard or deliver up the stack
1320 *
1321 * All multicast engines must hook in here. After this function returns, we
1322 * expect UIP_BUF to be unmodified
1323 */
1324#if UIP_IPV6_MULTICAST
1325 if(uip_is_addr_mcast_routable(&UIP_IP_BUF->destipaddr)) {
1326 if(UIP_MCAST6.in() == UIP_MCAST6_ACCEPT) {
1327 /* Deliver up the stack */
1328 goto process;
1329 } else {
1330 /* Don't deliver up the stack */
1331 goto drop;
1332 }
1333 }
1334#endif /* UIP_IPV6_MULTICAST */
1335
1336 /* TBD Some Parameter problem messages */
1337 if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) &&
1338 !uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr)) {
1339 if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr) &&
1340 !uip_is_addr_linklocal(&UIP_IP_BUF->destipaddr) &&
1341 !uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr) &&
1342 !uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr) &&
1343 !uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) {
1344
1345 if(!uip_check_mtu() || !uip_update_ttl()) {
1346 /* Send ICMPv6 error, prepared by the function that just returned false */
1347 goto send;
1348 }
1349
1350 LOG_INFO("Forwarding packet to next hop, dest: ");
1351 LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
1352 LOG_INFO_("\n");
1353 UIP_STAT(++uip_stat.ip.forwarded);
1354 goto send;
1355 } else {
1356 if((uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr)) &&
1357 (!uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) &&
1358 (!uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) &&
1359 (!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) &&
1360 (!uip_ds6_is_addr_onlink((&UIP_IP_BUF->destipaddr)))) {
1361 LOG_ERR("LL source address with off link destination, dropping\n");
1364 goto send;
1365 }
1366 LOG_ERR("Dropping packet, not for me and link local or multicast\n");
1367 UIP_STAT(++uip_stat.ip.drop);
1368 goto drop;
1369 }
1370 }
1371#else /* UIP_CONF_ROUTER */
1372 if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) &&
1373 !uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr) &&
1374 !uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
1375 LOG_ERR("Dropping packet, not for me\n");
1376 UIP_STAT(++uip_stat.ip.drop);
1377 goto drop;
1378 }
1379#endif /* UIP_CONF_ROUTER */
1380
1381#if UIP_IPV6_MULTICAST && UIP_CONF_ROUTER
1382 process:
1383#endif /* UIP_IPV6_MULTICAST && UIP_CONF_ROUTER */
1384
1385 /* IPv6 extension header processing: loop until reaching upper-layer protocol */
1386 uip_ext_bitmap = 0;
1387 for(next_header = uipbuf_get_next_header(uip_buf, uip_len, &protocol, true);
1388 next_header != NULL && uip_is_proto_ext_hdr(protocol);
1389 next_header = uipbuf_get_next_header(next_header, uip_len - (next_header - uip_buf), &protocol, false)) {
1390
1391 ext_ptr = (struct uip_ext_hdr *)next_header;
1392 switch(protocol) {
1393 case UIP_PROTO_HBHO:
1394 LOG_DBG("Processing hbh header\n");
1395 /* Hop by hop option header */
1396#if UIP_CONF_IPV6_CHECKS
1397 /* Hop by hop option header. If we saw one HBH already, drop */
1399 goto bad_hdr;
1400 } else {
1402 }
1403#endif /*UIP_CONF_IPV6_CHECKS*/
1404 /* HBH options should have been processed already if
1405 UIP_CONF_ROUTER != 0. */
1406 if(!UIP_CONF_ROUTER) {
1407 switch(ext_hdr_options_process(next_header)) {
1408 case 0:
1409 break; /* done */
1410 case 1:
1411 goto drop; /* silently discard */
1412 case 2:
1413 goto send; /* send icmp error message (created in
1414 ext_hdr_options_process) and discard */
1415 }
1416 }
1417 break;
1418 case UIP_PROTO_DESTO:
1419#if UIP_CONF_IPV6_CHECKS
1420 /* Destination option header. if we saw two already, drop */
1421 LOG_DBG("Processing desto header\n");
1422 if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO1) {
1423 if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO2) {
1424 goto bad_hdr;
1425 } else{
1426 uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO2;
1427 }
1428 } else {
1429 uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO1;
1430 }
1431#endif /*UIP_CONF_IPV6_CHECKS*/
1432 switch(ext_hdr_options_process(next_header)) {
1433 case 0:
1434 break; /* done */
1435 case 1:
1436 goto drop; /* silently discard */
1437 case 2:
1438 goto send; /* send icmp error message (created in
1439 ext_hdr_options_process) and discard */
1440 }
1441 break;
1442 case UIP_PROTO_ROUTING:
1443#if UIP_CONF_IPV6_CHECKS
1444 /* Routing header. If we saw one already, drop */
1445 if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_ROUTING) {
1446 goto bad_hdr;
1447 } else {
1448 uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_ROUTING;
1449 }
1450#endif /*UIP_CONF_IPV6_CHECKS*/
1451 /*
1452 * Routing Header length field is in units of 8 bytes, excluding
1453 * As per RFC2460 section 4.4, if routing type is unrecognized:
1454 * if segments left = 0, ignore the header
1455 * if segments left > 0, discard packet and send icmp error pointing
1456 * to the routing type
1457 */
1458
1459 LOG_DBG("Processing Routing header\n");
1460 if(((struct uip_routing_hdr *)ext_ptr)->seg_left > 0) {
1461 /* Process source routing header */
1462 if(NETSTACK_ROUTING.ext_header_srh_update()) {
1463
1464 /* The MTU and TTL were not checked and updated yet, because with
1465 * a routing header, the IPv6 destination address was set to us
1466 * even though we act only as forwarder. Check MTU and TTL now */
1467 if(!uip_check_mtu() || !uip_update_ttl()) {
1468 /* Send ICMPv6 error, prepared by the function that just returned false */
1469 goto send;
1470 }
1471
1472 if(uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) ||
1473 uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr) ||
1474 uip_is_addr_mcast(&UIP_IP_BUF->destipaddr) ||
1475 uip_is_addr_unspecified(&UIP_IP_BUF->destipaddr) ||
1476 uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) {
1477 LOG_ERR("SRH next hop address is unacceptable; drop the packet\n");
1478 goto bad_hdr;
1479 }
1480
1481 LOG_INFO("Forwarding packet to next hop ");
1482 LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
1483 LOG_INFO_("\n");
1484 UIP_STAT(++uip_stat.ip.forwarded);
1485
1486 goto send; /* Proceed to forwarding */
1487 } else {
1488 LOG_ERR("Unrecognized routing type\n");
1489 goto bad_hdr;
1490 }
1491 }
1492 break;
1493 case UIP_PROTO_FRAG:
1494 /* Fragmentation header:call the reassembly function, then leave */
1495#if UIP_CONF_IPV6_REASSEMBLY
1496 LOG_INFO("Processing fragmentation header\n");
1497 uip_len = uip_reass(&ext_ptr->next);
1498 if(uip_len == 0) {
1499 goto drop;
1500 }
1501 if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG) {
1502 /* we are not done with reassembly, this is an error message */
1503 goto send;
1504 }
1505 /* packet is reassembled. Restart the parsing of the reassembled pkt */
1506 LOG_INFO("Processing reassembled packet\n");
1507 uip_ext_bitmap = 0;
1508 next_header = uipbuf_get_next_header(uip_buf, uip_len, &protocol, true);
1509 break;
1510#else /* UIP_CONF_IPV6_REASSEMBLY */
1511 UIP_STAT(++uip_stat.ip.drop);
1512 UIP_STAT(++uip_stat.ip.fragerr);
1513 LOG_ERR("fragment dropped.");
1514 goto drop;
1515#endif /* UIP_CONF_IPV6_REASSEMBLY */
1516 case UIP_PROTO_NONE:
1517 goto drop;
1518 default:
1519 goto bad_hdr;
1520 }
1521 }
1522
1523 /* Process upper-layer input */
1524 if(next_header != NULL) {
1525 switch(protocol) {
1526#if UIP_TCP
1527 case UIP_PROTO_TCP:
1528 /* TCP, for both IPv4 and IPv6 */
1529 goto tcp_input;
1530#endif
1531#if UIP_UDP
1532 case UIP_PROTO_UDP:
1533 /* UDP, for both IPv4 and IPv6 */
1534 goto udp_input;
1535#endif
1536 case UIP_PROTO_ICMP6:
1537 /* ICMPv6 */
1538 goto icmp6_input;
1539 }
1540 }
1541
1542 bad_hdr:
1543 /*
1544 * RFC 2460 send error message parameterr problem, code unrecognized
1545 * next header, pointing to the next header field
1546 */
1548 UIP_STAT(++uip_stat.ip.drop);
1549 UIP_STAT(++uip_stat.ip.protoerr);
1550 LOG_ERR("unrecognized header\n");
1551 goto send;
1552 /* End of headers processing */
1553
1554 icmp6_input:
1555 /* This is IPv6 ICMPv6 processing code. */
1556 LOG_INFO("icmpv6 input length %d type: %d \n", uip_len, UIP_ICMP_BUF->type);
1557
1558#if UIP_CONF_IPV6_CHECKS
1559 /* Compute and check the ICMP header checksum */
1560 if(uip_icmp6chksum() != 0xffff) {
1561 UIP_STAT(++uip_stat.icmp.drop);
1562 UIP_STAT(++uip_stat.icmp.chkerr);
1563 LOG_ERR("icmpv6 bad checksum\n");
1564 goto drop;
1565 }
1566#endif /*UIP_CONF_IPV6_CHECKS*/
1567
1568 UIP_STAT(++uip_stat.icmp.recv);
1569 /*
1570 * Here we process incoming ICMPv6 packets
1571 * For echo request, we send echo reply
1572 * For ND pkts, we call the appropriate function in uip-nd6.c
1573 * We do not treat Error messages for now
1574 * If no pkt is to be sent as an answer to the incoming one, we
1575 * "goto drop". Else we just break; then at the after the "switch"
1576 * we "goto send"
1577 */
1578#if UIP_CONF_ICMP6
1579 UIP_ICMP6_APPCALL(UIP_ICMP_BUF->type);
1580#endif /*UIP_CONF_ICMP6*/
1581
1582 /*
1583 * Search generic input handlers.
1584 * The handler is in charge of setting uip_len to 0
1585 */
1587 UIP_ICMP_BUF->icode) == UIP_ICMP6_INPUT_ERROR) {
1588 LOG_ERR("Unknown ICMPv6 message type/code %d\n", UIP_ICMP_BUF->type);
1589 UIP_STAT(++uip_stat.icmp.drop);
1590 UIP_STAT(++uip_stat.icmp.typeerr);
1591 uipbuf_clear();
1592 }
1593
1594 if(uip_len > 0) {
1595 goto send;
1596 } else {
1597 goto drop;
1598 }
1599 /* End of IPv6 ICMP processing. */
1600
1601
1602#if UIP_UDP
1603 /* UDP input processing. */
1604 udp_input:
1605
1607
1608 LOG_INFO("Receiving UDP packet\n");
1609
1610 /* UDP processing is really just a hack. We don't do anything to the
1611 UDP/IP headers, but let the UDP application do all the hard
1612 work. If the application sets uip_slen, it has a packet to
1613 send. */
1614#if UIP_UDP_CHECKSUMS
1615 /* XXX hack: UDP/IPv6 receivers should drop packets with UDP
1616 checksum 0. Here, we explicitly receive UDP packets with checksum
1617 0. This is to be able to debug code that for one reason or
1618 another miscomputes UDP checksums. The reception of zero UDP
1619 checksums should be turned into a configration option. */
1620 if(UIP_UDP_BUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
1621 UIP_STAT(++uip_stat.udp.drop);
1622 UIP_STAT(++uip_stat.udp.chkerr);
1623 LOG_ERR("udp: bad checksum 0x%04x 0x%04x\n", UIP_UDP_BUF->udpchksum,
1624 uip_udpchksum());
1625 goto drop;
1626 }
1627#endif /* UIP_UDP_CHECKSUMS */
1628
1629 /* Make sure that the UDP destination port number is not zero. */
1630 if(UIP_UDP_BUF->destport == 0) {
1631 LOG_ERR("udp: zero port.\n");
1632 goto drop;
1633 }
1634
1635 /* Demultiplex this UDP packet between the UDP "connections". */
1636 for(uip_udp_conn = &uip_udp_conns[0];
1637 uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
1638 ++uip_udp_conn) {
1639 /* If the local UDP port is non-zero, the connection is considered
1640 to be used. If so, the local port number is checked against the
1641 destination port number in the received packet. If the two port
1642 numbers match, the remote port number is checked if the
1643 connection is bound to a remote port. Finally, if the
1644 connection is bound to a remote IP address, the source IP
1645 address of the packet is checked. */
1646 if(uip_udp_conn->lport != 0 &&
1647 UIP_UDP_BUF->destport == uip_udp_conn->lport &&
1648 (uip_udp_conn->rport == 0 ||
1649 UIP_UDP_BUF->srcport == uip_udp_conn->rport) &&
1651 uip_ipaddr_cmp(&UIP_IP_BUF->srcipaddr, &uip_udp_conn->ripaddr))) {
1652 goto udp_found;
1653 }
1654 }
1655 LOG_ERR("udp: no matching connection found\n");
1656 UIP_STAT(++uip_stat.udp.drop);
1657
1659 goto send;
1660
1661 udp_found:
1662 LOG_DBG("In udp_found\n");
1663 UIP_STAT(++uip_stat.udp.recv);
1664
1665 uip_len = uip_len - UIP_IPUDPH_LEN;
1666 uip_appdata = &uip_buf[UIP_IPUDPH_LEN];
1667 uip_conn = NULL;
1668 uip_flags = UIP_NEWDATA;
1669 uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN];
1670 uip_slen = 0;
1671 UIP_UDP_APPCALL();
1672
1673 udp_send:
1674 LOG_DBG("In udp_send\n");
1675
1676 if(uip_slen == 0) {
1677 goto drop;
1678 }
1679 uip_len = uip_slen + UIP_IPUDPH_LEN;
1680
1681 /* For IPv6, the IP length field does not include the IPv6 IP header
1682 length. */
1683 uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
1684
1685 UIP_IP_BUF->vtc = 0x60;
1686 UIP_IP_BUF->tcflow = 0x00;
1687 UIP_IP_BUF->ttl = uip_udp_conn->ttl;
1688 UIP_IP_BUF->proto = UIP_PROTO_UDP;
1689
1690 UIP_UDP_BUF->udplen = UIP_HTONS(uip_slen + UIP_UDPH_LEN);
1691 UIP_UDP_BUF->udpchksum = 0;
1692
1693 UIP_UDP_BUF->srcport = uip_udp_conn->lport;
1694 UIP_UDP_BUF->destport = uip_udp_conn->rport;
1695
1697 uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
1698
1699 uip_appdata = &uip_buf[UIP_IPTCPH_LEN];
1700
1701#if UIP_UDP_CHECKSUMS
1702 /* Calculate UDP checksum. */
1703 UIP_UDP_BUF->udpchksum = ~(uip_udpchksum());
1704 if(UIP_UDP_BUF->udpchksum == 0) {
1705 UIP_UDP_BUF->udpchksum = 0xffff;
1706 }
1707#endif /* UIP_UDP_CHECKSUMS */
1708
1709 UIP_STAT(++uip_stat.udp.sent);
1710 goto ip_send_nolen;
1711#endif /* UIP_UDP */
1712
1713#if UIP_TCP
1714 /* TCP input processing. */
1715 tcp_input:
1716
1718
1719 UIP_STAT(++uip_stat.tcp.recv);
1720 LOG_INFO("Receiving TCP packet\n");
1721 /* Start of TCP input header processing code. */
1722
1723 if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
1724 checksum. */
1725 UIP_STAT(++uip_stat.tcp.drop);
1726 UIP_STAT(++uip_stat.tcp.chkerr);
1727 LOG_ERR("tcp: bad checksum 0x%04x 0x%04x\n", UIP_TCP_BUF->tcpchksum,
1728 uip_tcpchksum());
1729 goto drop;
1730 }
1731
1732 /* Make sure that the TCP port number is not zero. */
1733 if(UIP_TCP_BUF->destport == 0 || UIP_TCP_BUF->srcport == 0) {
1734 LOG_ERR("tcp: zero port\n");
1735 goto drop;
1736 }
1737
1738 /* Demultiplex this segment. */
1739 /* First check any active connections. */
1740 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_TCP_CONNS - 1];
1741 ++uip_connr) {
1742 if(uip_connr->tcpstateflags != UIP_CLOSED &&
1743 UIP_TCP_BUF->destport == uip_connr->lport &&
1744 UIP_TCP_BUF->srcport == uip_connr->rport &&
1745 uip_ipaddr_cmp(&UIP_IP_BUF->srcipaddr, &uip_connr->ripaddr)) {
1746 goto found;
1747 }
1748 }
1749
1750 /* If we didn't find and active connection that expected the packet,
1751 either this packet is an old duplicate, or this is a SYN packet
1752 destined for a connection in LISTEN. If the SYN flag isn't set,
1753 it is an old packet and we send a RST. */
1754 if((UIP_TCP_BUF->flags & TCP_CTL) != TCP_SYN) {
1755 goto reset;
1756 }
1757
1758 uint16_t tmp16 = UIP_TCP_BUF->destport;
1759 /* Next, check listening connections. */
1760 for(c = 0; c < UIP_LISTENPORTS; ++c) {
1761 if(tmp16 == uip_listenports[c]) {
1762 goto found_listen;
1763 }
1764 }
1765
1766 /* No matching connection found, so we send a RST packet. */
1767 UIP_STAT(++uip_stat.tcp.synrst);
1768
1769 reset:
1770 LOG_WARN("In reset\n");
1771 /* We do not send resets in response to resets. */
1772 if(UIP_TCP_BUF->flags & TCP_RST) {
1773 goto drop;
1774 }
1775
1776 UIP_STAT(++uip_stat.tcp.rst);
1777
1778 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1779 uip_len = UIP_IPTCPH_LEN;
1780 UIP_TCP_BUF->tcpoffset = 5 << 4;
1781
1782 /* Flip the seqno and ackno fields in the TCP header. */
1783 c = UIP_TCP_BUF->seqno[3];
1784 UIP_TCP_BUF->seqno[3] = UIP_TCP_BUF->ackno[3];
1785 UIP_TCP_BUF->ackno[3] = c;
1786
1787 c = UIP_TCP_BUF->seqno[2];
1788 UIP_TCP_BUF->seqno[2] = UIP_TCP_BUF->ackno[2];
1789 UIP_TCP_BUF->ackno[2] = c;
1790
1791 c = UIP_TCP_BUF->seqno[1];
1792 UIP_TCP_BUF->seqno[1] = UIP_TCP_BUF->ackno[1];
1793 UIP_TCP_BUF->ackno[1] = c;
1794
1795 c = UIP_TCP_BUF->seqno[0];
1796 UIP_TCP_BUF->seqno[0] = UIP_TCP_BUF->ackno[0];
1797 UIP_TCP_BUF->ackno[0] = c;
1798
1799 /* We also have to increase the sequence number we are
1800 acknowledging. If the least significant byte overflowed, we need
1801 to propagate the carry to the other bytes as well. */
1802 if(++UIP_TCP_BUF->ackno[3] == 0) {
1803 if(++UIP_TCP_BUF->ackno[2] == 0) {
1804 if(++UIP_TCP_BUF->ackno[1] == 0) {
1805 ++UIP_TCP_BUF->ackno[0];
1806 }
1807 }
1808 }
1809
1810 /* Swap port numbers. */
1811 tmp16 = UIP_TCP_BUF->srcport;
1812 UIP_TCP_BUF->srcport = UIP_TCP_BUF->destport;
1813 UIP_TCP_BUF->destport = tmp16;
1814
1815 /* Swap IP addresses. */
1816 uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr);
1817 uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
1818 /* And send out the RST packet! */
1819 goto tcp_send_noconn;
1820
1821 /* This label will be jumped to if we matched the incoming packet
1822 with a connection in LISTEN. In that case, we should create a new
1823 connection and send a SYNACK in return. */
1824 found_listen:
1825 LOG_DBG("In found listen\n");
1826 /* First we check if there are any connections avaliable. Unused
1827 connections are kept in the same table as used connections, but
1828 unused ones have the tcpstate set to CLOSED. Also, connections in
1829 TIME_WAIT are kept track of and we'll use the oldest one if no
1830 CLOSED connections are found. Thanks to Eddie C. Dost for a very
1831 nice algorithm for the TIME_WAIT search. */
1832 uip_connr = 0;
1833 for(c = 0; c < UIP_TCP_CONNS; ++c) {
1834 if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
1835 uip_connr = &uip_conns[c];
1836 break;
1837 }
1838 if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
1839 if(uip_connr == 0 ||
1840 uip_conns[c].timer > uip_connr->timer) {
1841 uip_connr = &uip_conns[c];
1842 }
1843 }
1844 }
1845
1846 if(uip_connr == 0) {
1847 /* All connections are used already, we drop packet and hope that
1848 the remote end will retransmit the packet at a time when we
1849 have more spare connections. */
1850 UIP_STAT(++uip_stat.tcp.syndrop);
1851 LOG_ERR("tcp: found no unused connections\n");
1852 goto drop;
1853 }
1854 uip_conn = uip_connr;
1855
1856 /* Fill in the necessary fields for the new connection. */
1857 uip_connr->rto = uip_connr->timer = UIP_RTO;
1858 uip_connr->sa = 0;
1859 uip_connr->sv = 4;
1860 uip_connr->nrtx = 0;
1861 uip_connr->lport = UIP_TCP_BUF->destport;
1862 uip_connr->rport = UIP_TCP_BUF->srcport;
1863 uip_ipaddr_copy(&uip_connr->ripaddr, &UIP_IP_BUF->srcipaddr);
1864 uip_connr->tcpstateflags = UIP_SYN_RCVD;
1865
1866 uip_connr->snd_nxt[0] = iss[0];
1867 uip_connr->snd_nxt[1] = iss[1];
1868 uip_connr->snd_nxt[2] = iss[2];
1869 uip_connr->snd_nxt[3] = iss[3];
1870 uip_connr->len = 1;
1871
1872 /* rcv_nxt should be the seqno from the incoming packet + 1. */
1873 uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
1874 uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
1875 uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
1876 uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
1877 uip_add_rcv_nxt(1);
1878
1879 process_tcp_options(uip_connr);
1880
1881 /* Our response will be a SYNACK. */
1882#if UIP_ACTIVE_OPEN
1883 tcp_send_synack:
1884 UIP_TCP_BUF->flags = TCP_ACK;
1885
1886 tcp_send_syn:
1887 UIP_TCP_BUF->flags |= TCP_SYN;
1888#else /* UIP_ACTIVE_OPEN */
1889 tcp_send_synack:
1890 UIP_TCP_BUF->flags = TCP_SYN | TCP_ACK;
1891#endif /* UIP_ACTIVE_OPEN */
1892
1893 /* We send out the TCP Maximum Segment Size option with our
1894 SYNACK. */
1895 UIP_TCP_BUF->optdata[0] = TCP_OPT_MSS;
1896 UIP_TCP_BUF->optdata[1] = TCP_OPT_MSS_LEN;
1897 UIP_TCP_BUF->optdata[2] = (UIP_TCP_MSS) / 256;
1898 UIP_TCP_BUF->optdata[3] = (UIP_TCP_MSS) & 255;
1899 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
1900 UIP_TCP_BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
1901 goto tcp_send;
1902
1903 /* This label will be jumped to if we found an active connection. */
1904 found:
1905 LOG_DBG("In found\n");
1906 uip_conn = uip_connr;
1907 uip_flags = 0;
1908 /* We do a very naive form of TCP reset processing; we just accept
1909 any RST and kill our connection. We should in fact check if the
1910 sequence number of this reset is wihtin our advertised window
1911 before we accept the reset. */
1912 if(UIP_TCP_BUF->flags & TCP_RST) {
1913 uip_connr->tcpstateflags = UIP_CLOSED;
1914 LOG_WARN("tcp: got reset, aborting connection.");
1915 uip_flags = UIP_ABORT;
1916 UIP_APPCALL();
1917 goto drop;
1918 }
1919 /* Calculate the length of the data, if the application has sent
1920 any data to us. */
1921 c = (UIP_TCP_BUF->tcpoffset >> 4) << 2;
1922
1923 /* Check that the indicated length of the TCP header is not too large
1924 for the total packet length. */
1925 if(uip_len < c + UIP_IPH_LEN) {
1926 LOG_WARN("Dropping TCP packet with too large data offset (%u bytes)\n",
1927 (unsigned)c);
1928 goto drop;
1929 }
1930
1931 /* uip_len will contain the length of the actual TCP data. This is
1932 calculated by subtracing the length of the TCP header (in
1933 c) and the length of the IP header (20 bytes). */
1934 uip_len = uip_len - c - UIP_IPH_LEN;
1935
1936 /*
1937 * Accept segments within the receive window and handle overlapping data.
1938 *
1939 * Out-of-order segments are dropped and an ACK is sent to trigger
1940 * retransmission.
1941 */
1942 if(!((((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
1943 ((UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
1944 (((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) &&
1945 ((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN)))) {
1946 if((uip_len > 0 || ((UIP_TCP_BUF->flags & (TCP_SYN | TCP_FIN)) != 0))) {
1947
1948 /* Compute effective segment length: FIN occupies one sequence number */
1949 uint16_t eff_seg_len = uip_len;
1950 if(UIP_TCP_BUF->flags & TCP_FIN) {
1951 eff_seg_len++;
1952 }
1953
1954 /* Check segment acceptability per RFC 9293 Table 6 */
1955 if(!seg_in_window(UIP_TCP_BUF->seqno, eff_seg_len,
1956 uip_connr->rcv_nxt, UIP_RECEIVE_WINDOW)) {
1957 /* Segment outside receive window - send ACK and drop */
1958 if((UIP_TCP_BUF->flags & TCP_SYN)) {
1959 if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) {
1960 goto tcp_send_synack;
1961#if UIP_ACTIVE_OPEN
1962 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
1963 goto tcp_send_syn;
1964#endif
1965 }
1966 }
1967 goto tcp_send_ack;
1968 }
1969
1970 /* Handle overlapping segments by trimming to new data only.
1971 Use signed comparison for correct wraparound handling. */
1972 uint32_t seg_seq = seq_to_uint32(UIP_TCP_BUF->seqno);
1973 uint32_t expected_seq = seq_to_uint32(uip_connr->rcv_nxt);
1974 int32_t seq_diff = (int32_t)(seg_seq - expected_seq);
1975
1976 if(seq_diff < 0) {
1977 /* Overlapping segment - trim already received data */
1978 uint32_t overlap = (uint32_t)(-seq_diff);
1979 if(overlap >= uip_len) {
1980 /* Entire segment is old data - just ACK */
1981 goto tcp_send_ack;
1982 }
1983
1984 LOG_DBG("TCP: trimming %lu bytes of overlap from segment\n",
1985 (unsigned long)overlap);
1986
1987 /* Trim the overlapping portion */
1988 uip_len -= overlap;
1989 uip_appdata += overlap;
1990 /* Update packet sequence number to reflect trimmed segment */
1991 UIP_TCP_BUF->seqno[0] = (expected_seq >> 24) & 0xff;
1992 UIP_TCP_BUF->seqno[1] = (expected_seq >> 16) & 0xff;
1993 UIP_TCP_BUF->seqno[2] = (expected_seq >> 8) & 0xff;
1994 UIP_TCP_BUF->seqno[3] = expected_seq & 0xff;
1995 } else if(seq_diff > 0) {
1996 /* Out-of-order segment: send ACK to trigger retransmission */
1997 LOG_DBG("TCP: out-of-order segment (gap of %lu bytes), sending ACK\n",
1998 (unsigned long)(uint32_t)seq_diff);
1999 goto tcp_send_ack;
2000 }
2001 /* If seg_seq == expected_seq, process normally */
2002 }
2003 }
2004
2005 /* Next, check if the incoming segment acknowledges any outstanding
2006 data. If so, we update the sequence number, reset the length of
2007 the outstanding data, calculate RTT estimations, and reset the
2008 retransmission timer. */
2009 if((UIP_TCP_BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
2010 uip_add32(uip_connr->snd_nxt, uip_connr->len);
2011
2012 if(UIP_TCP_BUF->ackno[0] == uip_acc32[0] &&
2013 UIP_TCP_BUF->ackno[1] == uip_acc32[1] &&
2014 UIP_TCP_BUF->ackno[2] == uip_acc32[2] &&
2015 UIP_TCP_BUF->ackno[3] == uip_acc32[3]) {
2016 /* Update sequence number. */
2017 uip_connr->snd_nxt[0] = uip_acc32[0];
2018 uip_connr->snd_nxt[1] = uip_acc32[1];
2019 uip_connr->snd_nxt[2] = uip_acc32[2];
2020 uip_connr->snd_nxt[3] = uip_acc32[3];
2021
2022 /* Do RTT estimation, unless we have done retransmissions. */
2023 if(uip_connr->nrtx == 0) {
2024 signed char m;
2025 m = uip_connr->rto - uip_connr->timer;
2026 /* This is taken directly from VJs original code in his paper */
2027 m = m - (uip_connr->sa >> 3);
2028 uip_connr->sa += m;
2029 if(m < 0) {
2030 m = -m;
2031 }
2032 m = m - (uip_connr->sv >> 2);
2033 uip_connr->sv += m;
2034 uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
2035
2036 }
2037 /* Set the acknowledged flag. */
2038 uip_flags = UIP_ACKDATA;
2039 /* Reset the retransmission timer. */
2040 uip_connr->timer = uip_connr->rto;
2041
2042 /* Reset length of outstanding data. */
2043 uip_connr->len = 0;
2044 }
2045
2046 }
2047
2048 /* Do different things depending on in what state the connection is. */
2049 switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
2050 /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
2051 implemented, since we force the application to close when the
2052 peer sends a FIN (hence the application goes directly from
2053 ESTABLISHED to LAST_ACK). */
2054 case UIP_SYN_RCVD:
2055 /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
2056 we are waiting for an ACK that acknowledges the data we sent
2057 out the last time. Therefore, we want to have the UIP_ACKDATA
2058 flag set. If so, we enter the ESTABLISHED state. */
2059 if(uip_flags & UIP_ACKDATA) {
2060 uip_connr->tcpstateflags = UIP_ESTABLISHED;
2061 uip_flags = UIP_CONNECTED;
2062 uip_connr->len = 0;
2063 if(uip_len > 0) {
2064 uip_flags |= UIP_NEWDATA;
2065 uip_add_rcv_nxt(uip_len);
2066 }
2067 uip_slen = 0;
2068 UIP_APPCALL();
2069 goto appsend;
2070 }
2071 /* We need to retransmit the SYNACK */
2072 if((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN) {
2073 goto tcp_send_synack;
2074 }
2075 goto drop;
2076#if UIP_ACTIVE_OPEN
2077 case UIP_SYN_SENT:
2078 /* In SYN_SENT, we wait for a SYNACK that is sent in response to
2079 our SYN. The rcv_nxt is set to sequence number in the SYNACK
2080 plus one, and we send an ACK. We move into the ESTABLISHED
2081 state. */
2082 if((uip_flags & UIP_ACKDATA) &&
2083 (UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
2084
2085 process_tcp_options(uip_connr);
2086
2087 uip_connr->tcpstateflags = UIP_ESTABLISHED;
2088 uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
2089 uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
2090 uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
2091 uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
2092 uip_add_rcv_nxt(1);
2093 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
2094 uip_connr->len = 0;
2095 uipbuf_clear();
2096 uip_slen = 0;
2097 UIP_APPCALL();
2098 goto appsend;
2099 }
2100 /* Inform the application that the connection failed */
2101 uip_flags = UIP_ABORT;
2102 UIP_APPCALL();
2103 /* The connection is closed after we send the RST */
2104 uip_conn->tcpstateflags = UIP_CLOSED;
2105 goto reset;
2106#endif /* UIP_ACTIVE_OPEN */
2107
2108 case UIP_ESTABLISHED:
2109 /* In the ESTABLISHED state, we call upon the application to feed
2110 data into the uip_buf. If the UIP_ACKDATA flag is set, the
2111 application should put new data into the buffer, otherwise we are
2112 retransmitting an old segment, and the application should put that
2113 data into the buffer.
2114
2115 If the incoming packet is a FIN, we should close the connection on
2116 this side as well, and we send out a FIN and enter the LAST_ACK
2117 state. We require that there is no outstanding data; otherwise the
2118 sequence numbers will be screwed up. */
2119
2120 if(UIP_TCP_BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
2121 if(uip_outstanding(uip_connr)) {
2122 goto drop;
2123 }
2124 uip_add_rcv_nxt(1 + uip_len);
2125 uip_flags |= UIP_CLOSE;
2126 if(uip_len > 0) {
2127 uip_flags |= UIP_NEWDATA;
2128 }
2129 UIP_APPCALL();
2130 uip_connr->len = 1;
2131 uip_connr->tcpstateflags = UIP_LAST_ACK;
2132 uip_connr->nrtx = 0;
2133 tcp_send_finack:
2134 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2135 goto tcp_send_nodata;
2136 }
2137
2138 /* Check the URG flag. If this is set, the segment carries urgent
2139 data that we must pass to the application. */
2140 if((UIP_TCP_BUF->flags & TCP_URG) != 0) {
2141 tmp16 = (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1];
2142 if(tmp16 > uip_len) {
2143 /* There is more urgent data in the next segment to come.
2144 Cap the urgent data length at the segment length for
2145 further processing. */
2146 tmp16 = uip_len;
2147 }
2148#if UIP_URGDATA > 0
2149 uip_urglen = tmp16;
2150 uip_add_rcv_nxt(uip_urglen);
2151 uip_len -= uip_urglen;
2152 uip_urgdata = uip_appdata;
2153 uip_appdata += uip_urglen;
2154 } else {
2155 uip_urglen = 0;
2156#else /* UIP_URGDATA > 0 */
2157 /* Ignore and discard any urgent data in this segment. */
2158 uip_appdata = ((char *)uip_appdata) + tmp16;
2159 uip_len -= tmp16;
2160#endif /* UIP_URGDATA > 0 */
2161 }
2162
2163 /* If uip_len > 0 we have TCP data in the packet, and we flag this
2164 by setting the UIP_NEWDATA flag and update the sequence number
2165 we acknowledge. If the application has stopped the dataflow
2166 using uip_stop(), we must not accept any data packets from the
2167 remote host. */
2168 if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
2169 uip_flags |= UIP_NEWDATA;
2170 uip_add_rcv_nxt(uip_len);
2171 }
2172
2173 /* Check if the available buffer space advertised by the other end
2174 is smaller than the initial MSS for this connection. If so, we
2175 set the current MSS to the window size to ensure that the
2176 application does not send more data than the other end can
2177 handle.
2178
2179 If the remote host advertises a zero window, we set the MSS to
2180 the initial MSS so that the application will send an entire MSS
2181 of data. This data will not be acknowledged by the receiver,
2182 and the application will retransmit it. This is called the
2183 "persistent timer" and uses the retransmission mechanim.
2184 */
2185 tmp16 = ((uint16_t)UIP_TCP_BUF->wnd[0] << 8) + (uint16_t)UIP_TCP_BUF->wnd[1];
2186 if(tmp16 > uip_connr->initialmss ||
2187 tmp16 == 0) {
2188 tmp16 = uip_connr->initialmss;
2189 }
2190 uip_connr->mss = tmp16;
2191
2192 /* If this packet constitutes an ACK for outstanding data (flagged
2193 by the UIP_ACKDATA flag, we should call the application since it
2194 might want to send more data. If the incoming packet had data
2195 from the peer (as flagged by the UIP_NEWDATA flag), the
2196 application must also be notified.
2197
2198 When the application is called, the global variable uip_len
2199 contains the length of the incoming data. The application can
2200 access the incoming data through the global pointer
2201 uip_appdata, which usually points UIP_IPTCPH_LEN
2202 bytes into the uip_buf array.
2203
2204 If the application wishes to send any data, this data should be
2205 put into the uip_appdata and the length of the data should be
2206 put into uip_len. If the application don't have any data to
2207 send, uip_len must be set to 0. */
2208 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
2209 uip_slen = 0;
2210 UIP_APPCALL();
2211
2212 appsend:
2213
2214 if(uip_flags & UIP_ABORT) {
2215 uip_slen = 0;
2216 uip_connr->tcpstateflags = UIP_CLOSED;
2217 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
2218 goto tcp_send_nodata;
2219 }
2220
2221 if(uip_flags & UIP_CLOSE) {
2222 uip_slen = 0;
2223 uip_connr->len = 1;
2224 uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
2225 uip_connr->nrtx = 0;
2226 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2227 goto tcp_send_nodata;
2228 }
2229
2230 /* If uip_slen > 0, the application has data to be sent. */
2231 if(uip_slen > 0) {
2232
2233 /* If the connection has acknowledged data, the contents of
2234 the ->len variable should be discarded. */
2235 if((uip_flags & UIP_ACKDATA) != 0) {
2236 uip_connr->len = 0;
2237 }
2238
2239 /* If the ->len variable is non-zero the connection has
2240 already data in transit and cannot send anymore right
2241 now. */
2242 if(uip_connr->len == 0) {
2243
2244 /* The application cannot send more than what is allowed by
2245 the mss (the minumum of the MSS and the available
2246 window). */
2247 if(uip_slen > uip_connr->mss) {
2248 uip_slen = uip_connr->mss;
2249 }
2250
2251 /* Remember how much data we send out now so that we know
2252 when everything has been acknowledged. */
2253 uip_connr->len = uip_slen;
2254 } else {
2255
2256 /* If the application already had unacknowledged data, we
2257 make sure that the application does not send (i.e.,
2258 retransmit) out more than it previously sent out. */
2259 uip_slen = uip_connr->len;
2260 }
2261 }
2262 uip_connr->nrtx = 0;
2263 apprexmit:
2264 uip_appdata = uip_sappdata;
2265
2266 /* If the application has data to be sent, or if the incoming
2267 packet had new data in it, we must send out a packet. */
2268 if(uip_slen > 0 && uip_connr->len > 0) {
2269 /* Add the length of the IP and TCP headers. */
2270 uip_len = uip_connr->len + UIP_IPTCPH_LEN;
2271 /* We always set the ACK flag in response packets. */
2272 UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH;
2273 /* Send the packet. */
2274 goto tcp_send_noopts;
2275 }
2276 /* If there is no data to send, just send out a pure ACK if
2277 there is newdata. */
2278 if(uip_flags & UIP_NEWDATA) {
2279 uip_len = UIP_IPTCPH_LEN;
2280 UIP_TCP_BUF->flags = TCP_ACK;
2281 goto tcp_send_noopts;
2282 }
2283 }
2284 goto drop;
2285 case UIP_LAST_ACK:
2286 /* We can close this connection if the peer has acknowledged our
2287 FIN. This is indicated by the UIP_ACKDATA flag. */
2288 if(uip_flags & UIP_ACKDATA) {
2289 uip_connr->tcpstateflags = UIP_CLOSED;
2290 uip_flags = UIP_CLOSE;
2291 UIP_APPCALL();
2292 }
2293 break;
2294
2295 case UIP_FIN_WAIT_1:
2296 /* The application has closed the connection, but the remote host
2297 hasn't closed its end yet. Thus we do nothing but wait for a
2298 FIN from the other side. */
2299 if(uip_len > 0) {
2300 uip_add_rcv_nxt(uip_len);
2301 }
2302 if(UIP_TCP_BUF->flags & TCP_FIN) {
2303 if(uip_flags & UIP_ACKDATA) {
2304 uip_connr->tcpstateflags = UIP_TIME_WAIT;
2305 uip_connr->timer = 0;
2306 uip_connr->len = 0;
2307 } else {
2308 uip_connr->tcpstateflags = UIP_CLOSING;
2309 }
2310 uip_add_rcv_nxt(1);
2311 uip_flags = UIP_CLOSE;
2312 UIP_APPCALL();
2313 goto tcp_send_ack;
2314 } else if(uip_flags & UIP_ACKDATA) {
2315 uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
2316 uip_connr->len = 0;
2317 goto drop;
2318 }
2319 if(uip_len > 0) {
2320 goto tcp_send_ack;
2321 }
2322 goto drop;
2323
2324 case UIP_FIN_WAIT_2:
2325 if(uip_len > 0) {
2326 uip_add_rcv_nxt(uip_len);
2327 }
2328 if(UIP_TCP_BUF->flags & TCP_FIN) {
2329 uip_connr->tcpstateflags = UIP_TIME_WAIT;
2330 uip_connr->timer = 0;
2331 uip_add_rcv_nxt(1);
2332 uip_flags = UIP_CLOSE;
2333 UIP_APPCALL();
2334 goto tcp_send_ack;
2335 }
2336 if(uip_len > 0) {
2337 goto tcp_send_ack;
2338 }
2339 goto drop;
2340
2341 case UIP_TIME_WAIT:
2342 goto tcp_send_ack;
2343
2344 case UIP_CLOSING:
2345 if(uip_flags & UIP_ACKDATA) {
2346 uip_connr->tcpstateflags = UIP_TIME_WAIT;
2347 uip_connr->timer = 0;
2348 }
2349 }
2350 goto drop;
2351
2352 /* We jump here when we are ready to send the packet, and just want
2353 to set the appropriate TCP sequence numbers in the TCP header. */
2354 tcp_send_ack:
2355 UIP_TCP_BUF->flags = TCP_ACK;
2356
2357 tcp_send_nodata:
2358 uip_len = UIP_IPTCPH_LEN;
2359
2360 tcp_send_noopts:
2361 UIP_TCP_BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
2362
2363 /* We're done with the input processing. We are now ready to send a
2364 reply. Our job is to fill in all the fields of the TCP and IP
2365 headers before calculating the checksum and finally send the
2366 packet. */
2367 tcp_send:
2368 LOG_DBG("In tcp_send\n");
2369
2370 UIP_TCP_BUF->ackno[0] = uip_connr->rcv_nxt[0];
2371 UIP_TCP_BUF->ackno[1] = uip_connr->rcv_nxt[1];
2372 UIP_TCP_BUF->ackno[2] = uip_connr->rcv_nxt[2];
2373 UIP_TCP_BUF->ackno[3] = uip_connr->rcv_nxt[3];
2374
2375 UIP_TCP_BUF->seqno[0] = uip_connr->snd_nxt[0];
2376 UIP_TCP_BUF->seqno[1] = uip_connr->snd_nxt[1];
2377 UIP_TCP_BUF->seqno[2] = uip_connr->snd_nxt[2];
2378 UIP_TCP_BUF->seqno[3] = uip_connr->snd_nxt[3];
2379
2380 UIP_TCP_BUF->srcport = uip_connr->lport;
2381 UIP_TCP_BUF->destport = uip_connr->rport;
2382
2383 UIP_IP_BUF->vtc = 0x60;
2384 UIP_IP_BUF->tcflow = 0x00;
2385
2386 uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_connr->ripaddr);
2387 uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
2388 LOG_INFO("Sending TCP packet to ");
2389 LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
2390 LOG_INFO_(" from ");
2391 LOG_INFO_6ADDR(&UIP_IP_BUF->srcipaddr);
2392 LOG_INFO_("\n");
2393
2394 if(uip_connr->tcpstateflags & UIP_STOPPED) {
2395 /* If the connection has issued uip_stop(), we advertise a zero
2396 window so that the remote host will stop sending data. */
2397 UIP_TCP_BUF->wnd[0] = UIP_TCP_BUF->wnd[1] = 0;
2398 } else {
2399 UIP_TCP_BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
2400 UIP_TCP_BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
2401 }
2402
2403 tcp_send_noconn:
2404 UIP_IP_BUF->proto = UIP_PROTO_TCP;
2405
2406 UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit;
2407 uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
2408
2409 UIP_TCP_BUF->urgp[0] = UIP_TCP_BUF->urgp[1] = 0;
2410
2411 /* Calculate TCP checksum. */
2412 UIP_TCP_BUF->tcpchksum = 0;
2413 UIP_TCP_BUF->tcpchksum = ~(uip_tcpchksum());
2414 UIP_STAT(++uip_stat.tcp.sent);
2415
2416#endif /* UIP_TCP */
2417#if UIP_UDP
2418 ip_send_nolen:
2419#endif
2420 UIP_IP_BUF->flow = 0x00;
2421 send:
2422 LOG_INFO("Sending packet with length %d (%d)\n", uip_len, uipbuf_get_len_field(UIP_IP_BUF));
2423
2424 UIP_STAT(++uip_stat.ip.sent);
2425 /* Return and let the caller do the actual transmission. */
2426 uip_flags = 0;
2427 return;
2428
2429 drop:
2430 uipbuf_clear();
2431 uip_ext_bitmap = 0;
2432 uip_flags = 0;
2433 return;
2434}
2435/*---------------------------------------------------------------------------*/
2436uint16_t
2437uip_htons(uint16_t val)
2438{
2439 return UIP_HTONS(val);
2440}
2441
2442uint32_t
2443uip_htonl(uint32_t val)
2444{
2445 return UIP_HTONL(val);
2446}
2447/*---------------------------------------------------------------------------*/
2448void
2449uip_send(const void *data, int len)
2450{
2451 int copylen;
2452
2453 if(uip_sappdata != NULL) {
2454 copylen = MIN(len, UIP_BUFSIZE - UIP_IPTCPH_LEN -
2455 (int)((char *)uip_sappdata - (char *)UIP_TCP_PAYLOAD));
2456 } else {
2457 copylen = MIN(len, UIP_BUFSIZE - UIP_IPTCPH_LEN);
2458 }
2459 if(copylen > 0) {
2460 uip_slen = copylen;
2461 if(data != uip_sappdata) {
2462 if(uip_sappdata == NULL) {
2463 memcpy(UIP_TCP_PAYLOAD, (data), uip_slen);
2464 } else {
2465 memcpy(uip_sappdata, (data), uip_slen);
2466 }
2467 }
2468 }
2469}
2470/*---------------------------------------------------------------------------*/
2471/** @} */
Default definitions of C compiler quirk work-arounds.
#define CLOCK_SECOND
A second, measured in system clock time.
Definition clock.h:105
void etimer_stop(struct etimer *et)
Stop a pending event timer.
Definition etimer.c:237
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
Definition etimer.c:177
void uip_send(const void *data, int len)
Send data on the current connection.
Definition uip6.c:2449
#define ICMP6_TIME_EXCEEDED
time exceeded
Definition uip-icmp6.h:55
void uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param)
Send an icmpv6 error message.
Definition uip-icmp6.c:155
#define ICMP6_DST_UNREACH
dest unreachable
Definition uip-icmp6.h:53
uint8_t uip_icmp6_input(uint8_t type, uint8_t icode)
Handle an incoming ICMPv6 message.
Definition uip-icmp6.c:85
uint16_t uip_icmp6chksum(void)
Calculate the ICMP checksum of the packet in uip_buf.
Definition uip6.c:404
uip_lladdr_t uip_lladdr
Host L2 address.
Definition uip6.c:107
#define uip_is_addr_mcast_routable(a)
is address a routable multicast address.
Definition uip.h:1888
#define ICMP6_DST_UNREACH_NOTNEIGHBOR
not a neighbor(obsolete)
Definition uip-icmp6.h:81
#define uip_is_addr_unspecified(a)
Is IPv6 address a the unspecified address a is of type uip_ipaddr_t.
Definition uip.h:1725
#define ICMP6_TIME_EXCEED_REASSEMBLY
ttl==0 in reass
Definition uip-icmp6.h:90
void uip_listen(uint16_t port)
Start listening to the specified port.
Definition uip6.c:619
void uip_ds6_init(void)
Initialize data structures.
Definition uip-ds6.c:115
void * uip_appdata
Pointer to the application data in the packet buffer.
Definition uip6.c:148
#define UIP_ICMP_BUF
Direct access to ICMP, UDP, and TCP headers and payload, with implicit ext header offset (global uip_...
Definition uip.h:77
void uip_add32(uint8_t *op32, uint16_t op16)
Carry out a 32-bit addition.
Definition uip6.c:252
#define ICMP6_PACKET_TOO_BIG
packet too big
Definition uip-icmp6.h:54
struct etimer uip_reass_timer
Timer for reassembly.
Definition uip6.c:665
struct uip_icmp6_conn uip_icmp6_conns
single possible icmpv6 "connection"
Definition uip6.c:243
#define uip_is_addr_mcast(a)
is address a multicast address, see RFC 4291 a is of type uip_ipaddr_t*
Definition uip.h:1860
void uip_icmp6_init()
Initialise the uIP ICMPv6 core.
Definition uip-icmp6.c:323
#define UIP_EXT_HDR_OPT_PAD1
Destination and Hop By Hop extension headers option types.
Definition uip.h:1674
#define ICMP6_PARAM_PROB
ip6 header bad
Definition uip-icmp6.h:56
void uip_nd6_init()
Initialise the uIP ND core.
Definition uip-nd6.c:1146
#define ICMP6_DST_UNREACH_NOPORT
port unreachable
Definition uip-icmp6.h:84
bool uip_remove_ext_hdr(void)
Removes all IPv6 extension headers from uip_buf, updates length fields (uip_len and uip_ext_len).
Definition uip6.c:532
#define UIP_STAT(s)
The uIP TCP/IP statistics.
Definition uip.h:1351
struct uip_udp_conn * uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport)
Set up a new UDP connection.
Definition uip6.c:561
#define uip_is_addr_linklocal(a)
is addr (a) a link local unicast address, see RFC 4291 i.e.
Definition uip.h:1766
void uip_unlisten(uint16_t port)
Stop listening to the specified port.
Definition uip6.c:607
void uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
Source address selection, see RFC 3484.
Definition uip-ds6.c:529
void uip_init(void)
uIP initialization function.
Definition uip6.c:428
static uint8_t ext_hdr_options_process(uint8_t *ext_buf)
Process the options in Destination and Hop By Hop extension headers.
Definition uip6.c:872
#define ICMP6_PARAMPROB_NEXTHEADER
unrecognized next header
Definition uip-icmp6.h:96
uint16_t uip_chksum(uint16_t *data, uint16_t len)
Calculate the Internet checksum over a buffer.
Definition uip6.c:354
uint16_t uip_htons(uint16_t val)
Convert a 16-bit quantity from host byte order to network byte order.
Definition uip6.c:2437
#define ICMP6_PARAMPROB_HEADER
erroneous header field
Definition uip-icmp6.h:95
#define UIP_EXT_HDR_BITMAP_HBHO
Bitmaps for extension header processing.
Definition uip.h:1690
uint16_t uip_udpchksum(void)
Calculate the UDP checksum of the packet in uip_buf and uip_appdata.
uip_ds6_netif_t uip_ds6_if
The single interface.
Definition uip-ds6.c:74
#define ICMP6_PARAMPROB_OPTION
unrecognized option
Definition uip-icmp6.h:97
#define uip_is_addr_loopback(a)
Is IPv6 address a the unspecified address a is of type uip_ipaddr_t.
Definition uip.h:1711
void uip_reass_over(void)
Abandon the reassembly of the current packet.
Definition uip6.c:824
#define UIP_PROTO_HBHO
extension headers types
Definition uip.h:1663
#define UIP_IP_BUF
Direct access to IPv6 header.
Definition uip.h:71
uint8_t uip_ext_bitmap
bitmap we use to record which IPv6 headers we have already seen
Definition uip6.c:118
#define ICMP6_TIME_EXCEED_TRANSIT
ttl==0 in transit
Definition uip-icmp6.h:89
struct uip_conn * uip_connect(const uip_ipaddr_t *ripaddr, uint16_t port)
Connect to a remote host using TCP.
uint16_t uip_ipchksum(void)
Calculate the IP header checksum of the packet header in uip_buf.
Definition uip6.c:361
uint16_t uip_tcpchksum(void)
Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
Definition uip6.c:412
uint8_t uip_acc32[4]
4-byte array used for the 32-bit sequence number calculations.
Definition uip6.c:219
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
Definition uip.h:1157
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
Definition uip.h:969
uint16_t uip_htons(uint16_t val)
Convert a 16-bit quantity from host byte order to network byte order.
Definition uip6.c:2437
#define uip_buf
Macro to access uip_aligned_buf as an array of bytes.
Definition uip.h:465
uip_buf_t uip_aligned_buf
Packet buffer for incoming and outgoing packets.
Definition uip6.c:144
uint16_t uip_ext_len
The length of the extension headers.
Definition uip6.c:122
uint16_t uip_len
The length of the packet in the uip_buf buffer.
Definition uip6.c:159
uint8_t uip_last_proto
The final protocol after IPv6 extension headers: UIP_PROTO_TCP, UIP_PROTO_UDP or UIP_PROTO_ICMP6.
Definition uip6.c:125
#define UIP_BUFSIZE
The size of the uIP packet buffer.
Definition uipopt.h:92
#define UIP_REASS_MAXAGE
The maximum time in seconds that an IP fragment should wait in the reassembly buffer before it is dro...
Definition uipopt.h:133
#define UIP_LINK_MTU
The maximum transmission unit at the IP layer.
Definition uipopt.h:145
#define UIP_RTO
The initial retransmission timeout counted in timer pulses.
Definition uipopt.h:297
#define UIP_MAXSYNRTX
The maximum number of times a SYN segment should be retransmitted before a connection request should ...
Definition uipopt.h:314
#define UIP_TIME_WAIT_TIMEOUT
How long a connection should stay in the TIME_WAIT state.
Definition uipopt.h:352
#define UIP_TCP_MSS
The TCP maximum segment size.
Definition uipopt.h:328
#define UIP_RECEIVE_WINDOW
The size of the advertised receiver's window.
Definition uipopt.h:341
#define UIP_MAXRTX
The maximum number of times a segment should be retransmitted before the connection should be aborted...
Definition uipopt.h:305
#define UIP_LISTENPORTS
The maximum number of simultaneously listening TCP ports.
Definition uipopt.h:276
#define UIP_TCP_CONNS
The maximum number of simultaneously open TCP connections.
Definition uipopt.h:262
#define UIP_UDP_CONNS
The maximum amount of concurrent UDP connections.
Definition uipopt.h:215
Header file for the logging system.
Routing driver header file.
A timer.
Definition etimer.h:79
A timer.
Definition timer.h:84
Representation of a uIP TCP connection.
Definition uip.h:1258
uint8_t rcv_nxt[4]
The sequence number that we expect to receive next.
Definition uip.h:1265
uint8_t timer
The retransmission timer.
Definition uip.h:1275
uint16_t mss
Current maximum segment size for the connection.
Definition uip.h:1269
uint8_t sa
Retransmission time-out calculation state variable.
Definition uip.h:1271
uint16_t len
Length of the data that was previously sent.
Definition uip.h:1268
uint16_t lport
The local TCP port, in network byte order.
Definition uip.h:1261
uint16_t rport
The local remote TCP port, in network byte order.
Definition uip.h:1262
uip_ipaddr_t ripaddr
The IP address of the remote host.
Definition uip.h:1259
uint8_t sv
Retransmission time-out calculation state variable.
Definition uip.h:1272
uint8_t nrtx
The number of retransmissions for the last segment sent.
Definition uip.h:1276
uint16_t initialmss
Initial maximum segment size for the connection.
Definition uip.h:1270
uint8_t snd_nxt[4]
The sequence number that was last sent by us.
Definition uip.h:1267
uint8_t tcpstateflags
TCP state and flags.
Definition uip.h:1274
uint8_t rto
Retransmission time-out.
Definition uip.h:1273
The structure holding the TCP/IP statistics that are gathered if UIP_STATISTICS is set to 1.
Definition uip.h:1359
Representation of a uIP UDP connection.
Definition uip.h:1309
uip_ipaddr_t ripaddr
The IP address of the remote peer.
Definition uip.h:1310
uint8_t ttl
Default time-to-live.
Definition uip.h:1313
uint16_t rport
The remote port number in network byte order.
Definition uip.h:1312
uint16_t lport
The local port number in network byte order.
Definition uip.h:1311
Declarations of architecture specific functions.
IPv6 Neighbor cache (link-layer/IPv6 address mapping).
Header file for IPv6-related data structures.
Header file for ICMPv6 message and error handing (RFC 4443).
This header file contains configuration directives for uIPv6 multicast support.
Header file for IPv6 Neighbor discovery (RFC 4861).
Header file for the uIP TCP/IP stack.
Configuration options for uIP.
The uIP packet buffer.
Definition uip.h:457