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