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;
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 {
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) {
845 LOG_DBG("Processing PAD1 option\n");
846 opt_offset += 1;
847 break;
848 case UIP_EXT_HDR_OPT_PADN:
849 LOG_DBG("Processing PADN option\n");
850 opt_offset += opt_len;
851 break;
852 case UIP_EXT_HDR_OPT_RPL:
853 /* Fixes situation when a node that is not using RPL
854 * joins a network which does. The received packages will include the
855 * RPL header and processed by the "default" case of the switch
856 * (0x63 & 0xC0 = 0x40). Hence, the packet is discarded as the header
857 * is considered invalid.
858 * Using this fix, the header is ignored, and the next header (if
859 * present) is processed.
860 */
861 LOG_DBG("Processing RPL option\n");
862 if(!NETSTACK_ROUTING.ext_header_hbh_update(ext_buf, opt_offset)) {
863 LOG_ERR("RPL Option Error: Dropping Packet\n");
864 return 1;
865 }
866 opt_offset += opt_len;
867 break;
868#if UIP_MCAST6_ENGINE == UIP_MCAST6_ENGINE_MPL
869 case UIP_EXT_HDR_OPT_MPL:
870 /* MPL (RFC7731) Introduces the 0x6D hop by hop option. Hosts that do not
871 * recognise the option should drop the packet. Since we want to keep the packet,
872 * we want to process the option and not revert to the default case.
873 */
874 LOG_DBG("Processing MPL option\n");
875 opt_offset += opt_len + opt_len;
876 break;
877#endif
878 default:
879 /*
880 * check the two highest order bits of the option
881 * - 00 skip over this option and continue processing the header.
882 * - 01 discard the packet.
883 * - 10 discard the packet and, regardless of whether or not the
884 * packet's Destination Address was a multicast address, send an
885 * ICMP Parameter Problem, Code 2, message to the packet's
886 * Source Address, pointing to the unrecognized Option Type.
887 * - 11 discard the packet and, only if the packet's Destination
888 * Address was not a multicast address, send an ICMP Parameter
889 * Problem, Code 2, message to the packet's Source Address,
890 * pointing to the unrecognized Option Type.
891 */
892 LOG_DBG("Unrecognized option, MSB 0x%x\n", opt_hdr->type);
893 switch(opt_hdr->type & 0xC0) {
894 case 0:
895 break;
896 case 0x40:
897 return 1;
898 case 0xC0:
899 if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
900 return 1;
901 }
902 case 0x80:
904 (ext_buf + opt_offset) - uip_buf);
905 return 2;
906 }
907 /* in the cases were we did not discard, update ext_opt* */
908 opt_offset += opt_len;
909 break;
910 }
911 }
912 return 0;
913}
914/*---------------------------------------------------------------------------*/
915#if UIP_TCP
916static void
917process_tcp_options(struct uip_conn *conn)
918{
919 if((UIP_TCP_BUF->tcpoffset & 0xf0) <= 0x50) {
920 return;
921 }
922
923 /* Parse the TCP MSS option, if present. */
924 for(unsigned c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
925 if(UIP_IPTCPH_LEN + c >= UIP_BUFSIZE) {
926 /* TCP option data out of bounds. */
927 return;
928 }
929 uint8_t opt = uip_buf[UIP_IPTCPH_LEN + c];
930 switch(opt) {
931 case TCP_OPT_END:
932 /* Stop processing options. */
933 return;
934 case TCP_OPT_NOOP:
935 c++;
936 break;
937 case TCP_OPT_MSS:
938 if(UIP_IPTCPH_LEN + 3 + c >= UIP_BUFSIZE ||
939 uip_buf[UIP_IPTCPH_LEN + 1 + c] != TCP_OPT_MSS_LEN) {
940 /* TCP option data out of bounds or invalid MSS option length. */
941 return;
942 }
943
944 /* An MSS option with the right option length. */
945 uint16_t tmp16 = (uip_buf[UIP_IPTCPH_LEN + 2 + c] << 8) |
946 uip_buf[UIP_IPTCPH_LEN + 3 + c];
947 conn->initialmss = conn->mss =
948 tmp16 > UIP_TCP_MSS ? UIP_TCP_MSS : tmp16;
949 /* Stop processing options. */
950 return;
951 default:
952 if(UIP_IPTCPH_LEN + 1 + c >= UIP_BUFSIZE) {
953 /* TCP option data out of bounds. */
954 return;
955 }
956 /* All other options have a length field, so that we easily
957 can skip past them. */
958 if(uip_buf[UIP_IPTCPH_LEN + 1 + c] == 0) {
959 /* If the length field is zero, the options are malformed
960 and we don't process them further. */
961 return;
962 }
963 c += uip_buf[UIP_IPTCPH_LEN + 1 + c];
964 break;
965 }
966 }
967}
968#endif /* UIP_TCP */
969/*---------------------------------------------------------------------------*/
970static bool
971uip_check_mtu(void)
972{
973 if(uip_len > UIP_LINK_MTU) {
975 UIP_STAT(++uip_stat.ip.drop);
976 return false;
977 } else {
978 return true;
979 }
980}
981/*---------------------------------------------------------------------------*/
982static bool
983uip_update_ttl(void)
984{
985 if(UIP_IP_BUF->ttl <= 1) {
987 UIP_STAT(++uip_stat.ip.drop);
988 return false;
989 } else {
990 UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1;
991 return true;
992 }
993}
994/*---------------------------------------------------------------------------*/
995void
996uip_process(uint8_t flag)
997{
998 uint8_t *last_header;
999 uint8_t protocol;
1000 uint8_t *next_header;
1001 struct uip_ext_hdr *ext_ptr;
1002#if UIP_TCP
1003 int c;
1004 register struct uip_conn *uip_connr = uip_conn;
1005#endif /* UIP_TCP */
1006#if UIP_UDP
1007 if(flag == UIP_UDP_SEND_CONN) {
1008 goto udp_send;
1009 }
1010#endif /* UIP_UDP */
1011 uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN];
1012
1013 /* Check if we were invoked because of a poll request for a
1014 particular connection. */
1015 if(flag == UIP_POLL_REQUEST) {
1016#if UIP_TCP
1017 if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
1018 !uip_outstanding(uip_connr)) {
1019 uip_flags = UIP_POLL;
1020 UIP_APPCALL();
1021 goto appsend;
1022#if UIP_ACTIVE_OPEN
1023 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
1024 /* In the SYN_SENT state, we retransmit out SYN. */
1025 UIP_TCP_BUF->flags = 0;
1026 goto tcp_send_syn;
1027#endif /* UIP_ACTIVE_OPEN */
1028 }
1029 goto drop;
1030#endif /* UIP_TCP */
1031 /* Check if we were invoked because of the perodic timer fireing. */
1032 } else if(flag == UIP_TIMER) {
1033 /* Reset the length variables. */
1034#if UIP_TCP
1035 uipbuf_clear();
1036 uip_slen = 0;
1037
1038 /* Increase the initial sequence number. */
1039 if(++iss[3] == 0) {
1040 if(++iss[2] == 0) {
1041 if(++iss[1] == 0) {
1042 ++iss[0];
1043 }
1044 }
1045 }
1046
1047 /*
1048 * Check if the connection is in a state in which we simply wait
1049 * for the connection to time out. If so, we increase the
1050 * connection's timer and remove the connection if it times
1051 * out.
1052 */
1053 if(uip_connr->tcpstateflags == UIP_TIME_WAIT ||
1054 uip_connr->tcpstateflags == UIP_FIN_WAIT_2) {
1055 ++(uip_connr->timer);
1056 if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
1057 uip_connr->tcpstateflags = UIP_CLOSED;
1058 }
1059 } else if(uip_connr->tcpstateflags != UIP_CLOSED) {
1060 /*
1061 * If the connection has outstanding data, we increase the
1062 * connection's timer and see if it has reached the RTO value
1063 * in which case we retransmit.
1064 */
1065 if(uip_outstanding(uip_connr)) {
1066 if(uip_connr->timer-- == 0) {
1067 if(uip_connr->nrtx == UIP_MAXRTX ||
1068 ((uip_connr->tcpstateflags == UIP_SYN_SENT ||
1069 uip_connr->tcpstateflags == UIP_SYN_RCVD) &&
1070 uip_connr->nrtx == UIP_MAXSYNRTX)) {
1071 uip_connr->tcpstateflags = UIP_CLOSED;
1072
1073 /*
1074 * We call UIP_APPCALL() with uip_flags set to
1075 * UIP_TIMEDOUT to inform the application that the
1076 * connection has timed out.
1077 */
1078 uip_flags = UIP_TIMEDOUT;
1079 UIP_APPCALL();
1080
1081 /* We also send a reset packet to the remote host. */
1082 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1083 goto tcp_send_nodata;
1084 }
1085
1086 /* Exponential backoff. */
1087 uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
1088 4:
1089 uip_connr->nrtx);
1090 ++(uip_connr->nrtx);
1091
1092 /*
1093 * Ok, so we need to retransmit. We do this differently
1094 * depending on which state we are in. In ESTABLISHED, we
1095 * call upon the application so that it may prepare the
1096 * data for the retransmit. In SYN_RCVD, we resend the
1097 * SYNACK that we sent earlier and in LAST_ACK we have to
1098 * retransmit our FINACK.
1099 */
1100 UIP_STAT(++uip_stat.tcp.rexmit);
1101 switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
1102 case UIP_SYN_RCVD:
1103 /* In the SYN_RCVD state, we should retransmit our SYNACK. */
1104 goto tcp_send_synack;
1105
1106#if UIP_ACTIVE_OPEN
1107 case UIP_SYN_SENT:
1108 /* In the SYN_SENT state, we retransmit out SYN. */
1109 UIP_TCP_BUF->flags = 0;
1110 goto tcp_send_syn;
1111#endif /* UIP_ACTIVE_OPEN */
1112
1113 case UIP_ESTABLISHED:
1114 /*
1115 * In the ESTABLISHED state, we call upon the application
1116 * to do the actual retransmit after which we jump into
1117 * the code for sending out the packet (the apprexmit
1118 * label).
1119 */
1120 uip_flags = UIP_REXMIT;
1121 UIP_APPCALL();
1122 goto apprexmit;
1123
1124 case UIP_FIN_WAIT_1:
1125 case UIP_CLOSING:
1126 case UIP_LAST_ACK:
1127 /* In all these states we should retransmit a FINACK. */
1128 goto tcp_send_finack;
1129 }
1130 }
1131 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
1132 /*
1133 * If there was no need for a retransmission, we poll the
1134 * application for new data.
1135 */
1136 uip_flags = UIP_POLL;
1137 UIP_APPCALL();
1138 goto appsend;
1139 }
1140 }
1141 goto drop;
1142#endif /* UIP_TCP */
1143 }
1144#if UIP_UDP
1145 if(flag == UIP_UDP_TIMER) {
1146 if(uip_udp_conn->lport != 0) {
1147 uip_conn = NULL;
1148 uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN];
1149 uip_len = uip_slen = 0;
1150 uip_flags = UIP_POLL;
1151 UIP_UDP_APPCALL();
1152 goto udp_send;
1153 } else {
1154 goto drop;
1155 }
1156 }
1157#endif /* UIP_UDP */
1158
1159
1160 /* This is where the input processing starts. */
1161 UIP_STAT(++uip_stat.ip.recv);
1162
1163 /* Start of IP input header processing code. */
1164
1165 /* First check that we have received a full IPv6 header. */
1166 if(uip_len < UIP_IPH_LEN) {
1167 UIP_STAT(++uip_stat.ip.drop);
1168 LOG_WARN("incomplete IPv6 header received (%d bytes)\n", (int)uip_len);
1169 goto drop;
1170 }
1171
1172 /* Check validity of the IP header. */
1173 if((UIP_IP_BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */
1174 UIP_STAT(++uip_stat.ip.drop);
1175 UIP_STAT(++uip_stat.ip.vhlerr);
1176 LOG_ERR("invalid version\n");
1177 goto drop;
1178 }
1179
1180 /*
1181 * Check the size of the packet. If the size reported to us in
1182 * uip_len is smaller the size reported in the IP header, we assume
1183 * that the packet has been corrupted in transit.
1184 *
1185 * If the size of uip_len is larger than the size reported in the IP
1186 * packet header, the packet has been padded, and we set uip_len to
1187 * the correct value.
1188 */
1189 if(uip_len < uipbuf_get_len_field(UIP_IP_BUF)) {
1190 UIP_STAT(++uip_stat.ip.drop);
1191 LOG_ERR("packet shorter than reported in IP header\n");
1192 goto drop;
1193 }
1194
1195 /*
1196 * The length reported in the IPv6 header is the length of the
1197 * payload that follows the header. However, uIP uses the uip_len
1198 * variable for holding the size of the entire packet, including the
1199 * IP header. For IPv4 this is not a problem as the length field in
1200 * the IPv4 header contains the length of the entire packet. But for
1201 * IPv6 we need to add the size of the IPv6 header (40 bytes).
1202 */
1203 uip_len = uipbuf_get_len_field(UIP_IP_BUF) + UIP_IPH_LEN;
1204
1205 /* Check that the packet length is acceptable given our IP buffer size. */
1206 if(uip_len > sizeof(uip_buf)) {
1207 UIP_STAT(++uip_stat.ip.drop);
1208 LOG_WARN("dropping packet with length %d > %d\n",
1209 (int)uip_len, (int)sizeof(uip_buf));
1210 goto drop;
1211 }
1212
1213 /* Check sanity of extension headers, and compute the total extension header
1214 * length (uip_ext_len) as well as the final protocol (uip_last_proto) */
1215 uip_last_proto = 0;
1216 last_header = uipbuf_get_last_header(uip_buf, uip_len, &uip_last_proto);
1217 if(last_header == NULL) {
1218 LOG_ERR("invalid extension header chain\n");
1219 goto drop;
1220 }
1221 /* Set uip_ext_len */
1222 uip_ext_len = last_header - UIP_IP_PAYLOAD(0);
1223
1224 LOG_INFO("packet received from ");
1225 LOG_INFO_6ADDR(&UIP_IP_BUF->srcipaddr);
1226 LOG_INFO_(" to ");
1227 LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
1228 LOG_INFO_("\n");
1229
1230 if(uip_is_addr_mcast(&UIP_IP_BUF->srcipaddr)){
1231 UIP_STAT(++uip_stat.ip.drop);
1232 LOG_ERR("Dropping packet, src is mcast\n");
1233 goto drop;
1234 }
1235
1236 /* Refresh neighbor state after receiving a unicast message */
1237#if UIP_ND6_SEND_NS
1238 if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
1239 uip_ds6_nbr_refresh_reachable_state(&UIP_IP_BUF->srcipaddr);
1240 }
1241#endif /* UIP_ND6_SEND_NS */
1242
1243#if UIP_CONF_ROUTER
1244 /*
1245 * If present, the Hop-by-Hop Option must be processed before forwarding
1246 * the packet.
1247 */
1248
1249 next_header = uipbuf_get_next_header(uip_buf, uip_len, &protocol, true);
1250 if(next_header != NULL && protocol == UIP_PROTO_HBHO) {
1251 switch(ext_hdr_options_process(next_header)) {
1252 case 0:
1253 break; /* done */
1254 case 1:
1255 goto drop; /* silently discard */
1256 case 2:
1257 goto send; /* send icmp error message (created in
1258 ext_hdr_options_process) and discard */
1259 }
1260 }
1261
1262 /*
1263 * Process Packets with a routable multicast destination:
1264 * - We invoke the multicast engine and let it do its thing
1265 * (cache, forward etc).
1266 * - We never execute the datagram forwarding logic in this file here. When
1267 * the engine returns, forwarding has been handled if and as required.
1268 * - Depending on the return value, we either discard or deliver up the stack
1269 *
1270 * All multicast engines must hook in here. After this function returns, we
1271 * expect UIP_BUF to be unmodified
1272 */
1273#if UIP_IPV6_MULTICAST
1274 if(uip_is_addr_mcast_routable(&UIP_IP_BUF->destipaddr)) {
1275 if(UIP_MCAST6.in() == UIP_MCAST6_ACCEPT) {
1276 /* Deliver up the stack */
1277 goto process;
1278 } else {
1279 /* Don't deliver up the stack */
1280 goto drop;
1281 }
1282 }
1283#endif /* UIP_IPV6_MULTICAST */
1284
1285 /* TBD Some Parameter problem messages */
1286 if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) &&
1287 !uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr)) {
1288 if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr) &&
1289 !uip_is_addr_linklocal(&UIP_IP_BUF->destipaddr) &&
1290 !uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr) &&
1291 !uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr) &&
1292 !uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) {
1293
1294 if(!uip_check_mtu() || !uip_update_ttl()) {
1295 /* Send ICMPv6 error, prepared by the function that just returned false */
1296 goto send;
1297 }
1298
1299 LOG_INFO("Forwarding packet to next hop, dest: ");
1300 LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
1301 LOG_INFO_("\n");
1302 UIP_STAT(++uip_stat.ip.forwarded);
1303 goto send;
1304 } else {
1305 if((uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr)) &&
1306 (!uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) &&
1307 (!uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) &&
1308 (!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) &&
1309 (!uip_ds6_is_addr_onlink((&UIP_IP_BUF->destipaddr)))) {
1310 LOG_ERR("LL source address with off link destination, dropping\n");
1313 goto send;
1314 }
1315 LOG_ERR("Dropping packet, not for me and link local or multicast\n");
1316 UIP_STAT(++uip_stat.ip.drop);
1317 goto drop;
1318 }
1319 }
1320#else /* UIP_CONF_ROUTER */
1321 if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) &&
1322 !uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr) &&
1323 !uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
1324 LOG_ERR("Dropping packet, not for me\n");
1325 UIP_STAT(++uip_stat.ip.drop);
1326 goto drop;
1327 }
1328#endif /* UIP_CONF_ROUTER */
1329
1330#if UIP_IPV6_MULTICAST && UIP_CONF_ROUTER
1331 process:
1332#endif /* UIP_IPV6_MULTICAST && UIP_CONF_ROUTER */
1333
1334 /* IPv6 extension header processing: loop until reaching upper-layer protocol */
1335 uip_ext_bitmap = 0;
1336 for(next_header = uipbuf_get_next_header(uip_buf, uip_len, &protocol, true);
1337 next_header != NULL && uip_is_proto_ext_hdr(protocol);
1338 next_header = uipbuf_get_next_header(next_header, uip_len - (next_header - uip_buf), &protocol, false)) {
1339
1340 ext_ptr = (struct uip_ext_hdr *)next_header;
1341 switch(protocol) {
1342 case UIP_PROTO_HBHO:
1343 LOG_DBG("Processing hbh header\n");
1344 /* Hop by hop option header */
1345#if UIP_CONF_IPV6_CHECKS
1346 /* Hop by hop option header. If we saw one HBH already, drop */
1348 goto bad_hdr;
1349 } else {
1351 }
1352#endif /*UIP_CONF_IPV6_CHECKS*/
1353 /* HBH options should have been processed already if
1354 UIP_CONF_ROUTER != 0. */
1355 if(!UIP_CONF_ROUTER) {
1356 switch(ext_hdr_options_process(next_header)) {
1357 case 0:
1358 break; /* done */
1359 case 1:
1360 goto drop; /* silently discard */
1361 case 2:
1362 goto send; /* send icmp error message (created in
1363 ext_hdr_options_process) and discard */
1364 }
1365 }
1366 break;
1367 case UIP_PROTO_DESTO:
1368#if UIP_CONF_IPV6_CHECKS
1369 /* Destination option header. if we saw two already, drop */
1370 LOG_DBG("Processing desto header\n");
1371 if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO1) {
1372 if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO2) {
1373 goto bad_hdr;
1374 } else{
1375 uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO2;
1376 }
1377 } else {
1378 uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO1;
1379 }
1380#endif /*UIP_CONF_IPV6_CHECKS*/
1381 switch(ext_hdr_options_process(next_header)) {
1382 case 0:
1383 break; /* done */
1384 case 1:
1385 goto drop; /* silently discard */
1386 case 2:
1387 goto send; /* send icmp error message (created in
1388 ext_hdr_options_process) and discard */
1389 }
1390 break;
1391 case UIP_PROTO_ROUTING:
1392#if UIP_CONF_IPV6_CHECKS
1393 /* Routing header. If we saw one already, drop */
1394 if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_ROUTING) {
1395 goto bad_hdr;
1396 } else {
1397 uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_ROUTING;
1398 }
1399#endif /*UIP_CONF_IPV6_CHECKS*/
1400 /*
1401 * Routing Header length field is in units of 8 bytes, excluding
1402 * As per RFC2460 section 4.4, if routing type is unrecognized:
1403 * if segments left = 0, ignore the header
1404 * if segments left > 0, discard packet and send icmp error pointing
1405 * to the routing type
1406 */
1407
1408 LOG_DBG("Processing Routing header\n");
1409 if(((struct uip_routing_hdr *)ext_ptr)->seg_left > 0) {
1410 /* Process source routing header */
1411 if(NETSTACK_ROUTING.ext_header_srh_update()) {
1412
1413 /* The MTU and TTL were not checked and updated yet, because with
1414 * a routing header, the IPv6 destination address was set to us
1415 * even though we act only as forwarder. Check MTU and TTL now */
1416 if(!uip_check_mtu() || !uip_update_ttl()) {
1417 /* Send ICMPv6 error, prepared by the function that just returned false */
1418 goto send;
1419 }
1420
1421 if(uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) ||
1422 uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr) ||
1423 uip_is_addr_mcast(&UIP_IP_BUF->destipaddr) ||
1424 uip_is_addr_unspecified(&UIP_IP_BUF->destipaddr) ||
1425 uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) {
1426 LOG_ERR("SRH next hop address is unacceptable; drop the packet\n");
1427 goto bad_hdr;
1428 }
1429
1430 LOG_INFO("Forwarding packet to next hop ");
1431 LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
1432 LOG_INFO_("\n");
1433 UIP_STAT(++uip_stat.ip.forwarded);
1434
1435 goto send; /* Proceed to forwarding */
1436 } else {
1437 LOG_ERR("Unrecognized routing type\n");
1438 goto bad_hdr;
1439 }
1440 }
1441 break;
1442 case UIP_PROTO_FRAG:
1443 /* Fragmentation header:call the reassembly function, then leave */
1444#if UIP_CONF_IPV6_REASSEMBLY
1445 LOG_INFO("Processing fragmentation header\n");
1446 uip_len = uip_reass(&ext_ptr->next);
1447 if(uip_len == 0) {
1448 goto drop;
1449 }
1450 if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG) {
1451 /* we are not done with reassembly, this is an error message */
1452 goto send;
1453 }
1454 /* packet is reassembled. Restart the parsing of the reassembled pkt */
1455 LOG_INFO("Processing reassembled packet\n");
1456 uip_ext_bitmap = 0;
1457 next_header = uipbuf_get_next_header(uip_buf, uip_len, &protocol, true);
1458 break;
1459#else /* UIP_CONF_IPV6_REASSEMBLY */
1460 UIP_STAT(++uip_stat.ip.drop);
1461 UIP_STAT(++uip_stat.ip.fragerr);
1462 LOG_ERR("fragment dropped.");
1463 goto drop;
1464#endif /* UIP_CONF_IPV6_REASSEMBLY */
1465 case UIP_PROTO_NONE:
1466 goto drop;
1467 default:
1468 goto bad_hdr;
1469 }
1470 }
1471
1472 /* Process upper-layer input */
1473 if(next_header != NULL) {
1474 switch(protocol) {
1475#if UIP_TCP
1476 case UIP_PROTO_TCP:
1477 /* TCP, for both IPv4 and IPv6 */
1478 goto tcp_input;
1479#endif
1480#if UIP_UDP
1481 case UIP_PROTO_UDP:
1482 /* UDP, for both IPv4 and IPv6 */
1483 goto udp_input;
1484#endif
1485 case UIP_PROTO_ICMP6:
1486 /* ICMPv6 */
1487 goto icmp6_input;
1488 }
1489 }
1490
1491 bad_hdr:
1492 /*
1493 * RFC 2460 send error message parameterr problem, code unrecognized
1494 * next header, pointing to the next header field
1495 */
1497 UIP_STAT(++uip_stat.ip.drop);
1498 UIP_STAT(++uip_stat.ip.protoerr);
1499 LOG_ERR("unrecognized header\n");
1500 goto send;
1501 /* End of headers processing */
1502
1503 icmp6_input:
1504 /* This is IPv6 ICMPv6 processing code. */
1505 LOG_INFO("icmpv6 input length %d type: %d \n", uip_len, UIP_ICMP_BUF->type);
1506
1507#if UIP_CONF_IPV6_CHECKS
1508 /* Compute and check the ICMP header checksum */
1509 if(uip_icmp6chksum() != 0xffff) {
1510 UIP_STAT(++uip_stat.icmp.drop);
1511 UIP_STAT(++uip_stat.icmp.chkerr);
1512 LOG_ERR("icmpv6 bad checksum\n");
1513 goto drop;
1514 }
1515#endif /*UIP_CONF_IPV6_CHECKS*/
1516
1517 UIP_STAT(++uip_stat.icmp.recv);
1518 /*
1519 * Here we process incoming ICMPv6 packets
1520 * For echo request, we send echo reply
1521 * For ND pkts, we call the appropriate function in uip-nd6.c
1522 * We do not treat Error messages for now
1523 * If no pkt is to be sent as an answer to the incoming one, we
1524 * "goto drop". Else we just break; then at the after the "switch"
1525 * we "goto send"
1526 */
1527#if UIP_CONF_ICMP6
1528 UIP_ICMP6_APPCALL(UIP_ICMP_BUF->type);
1529#endif /*UIP_CONF_ICMP6*/
1530
1531 /*
1532 * Search generic input handlers.
1533 * The handler is in charge of setting uip_len to 0
1534 */
1536 UIP_ICMP_BUF->icode) == UIP_ICMP6_INPUT_ERROR) {
1537 LOG_ERR("Unknown ICMPv6 message type/code %d\n", UIP_ICMP_BUF->type);
1538 UIP_STAT(++uip_stat.icmp.drop);
1539 UIP_STAT(++uip_stat.icmp.typeerr);
1540 uipbuf_clear();
1541 }
1542
1543 if(uip_len > 0) {
1544 goto send;
1545 } else {
1546 goto drop;
1547 }
1548 /* End of IPv6 ICMP processing. */
1549
1550
1551#if UIP_UDP
1552 /* UDP input processing. */
1553 udp_input:
1554
1556
1557 LOG_INFO("Receiving UDP packet\n");
1558
1559 /* UDP processing is really just a hack. We don't do anything to the
1560 UDP/IP headers, but let the UDP application do all the hard
1561 work. If the application sets uip_slen, it has a packet to
1562 send. */
1563#if UIP_UDP_CHECKSUMS
1564 /* XXX hack: UDP/IPv6 receivers should drop packets with UDP
1565 checksum 0. Here, we explicitly receive UDP packets with checksum
1566 0. This is to be able to debug code that for one reason or
1567 another miscomputes UDP checksums. The reception of zero UDP
1568 checksums should be turned into a configration option. */
1569 if(UIP_UDP_BUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
1570 UIP_STAT(++uip_stat.udp.drop);
1571 UIP_STAT(++uip_stat.udp.chkerr);
1572 LOG_ERR("udp: bad checksum 0x%04x 0x%04x\n", UIP_UDP_BUF->udpchksum,
1573 uip_udpchksum());
1574 goto drop;
1575 }
1576#endif /* UIP_UDP_CHECKSUMS */
1577
1578 /* Make sure that the UDP destination port number is not zero. */
1579 if(UIP_UDP_BUF->destport == 0) {
1580 LOG_ERR("udp: zero port.\n");
1581 goto drop;
1582 }
1583
1584 /* Demultiplex this UDP packet between the UDP "connections". */
1585 for(uip_udp_conn = &uip_udp_conns[0];
1586 uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
1587 ++uip_udp_conn) {
1588 /* If the local UDP port is non-zero, the connection is considered
1589 to be used. If so, the local port number is checked against the
1590 destination port number in the received packet. If the two port
1591 numbers match, the remote port number is checked if the
1592 connection is bound to a remote port. Finally, if the
1593 connection is bound to a remote IP address, the source IP
1594 address of the packet is checked. */
1595 if(uip_udp_conn->lport != 0 &&
1596 UIP_UDP_BUF->destport == uip_udp_conn->lport &&
1597 (uip_udp_conn->rport == 0 ||
1598 UIP_UDP_BUF->srcport == uip_udp_conn->rport) &&
1600 uip_ipaddr_cmp(&UIP_IP_BUF->srcipaddr, &uip_udp_conn->ripaddr))) {
1601 goto udp_found;
1602 }
1603 }
1604 LOG_ERR("udp: no matching connection found\n");
1605 UIP_STAT(++uip_stat.udp.drop);
1606
1608 goto send;
1609
1610 udp_found:
1611 LOG_DBG("In udp_found\n");
1612 UIP_STAT(++uip_stat.udp.recv);
1613
1614 uip_len = uip_len - UIP_IPUDPH_LEN;
1615 uip_appdata = &uip_buf[UIP_IPUDPH_LEN];
1616 uip_conn = NULL;
1617 uip_flags = UIP_NEWDATA;
1618 uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN];
1619 uip_slen = 0;
1620 UIP_UDP_APPCALL();
1621
1622 udp_send:
1623 LOG_DBG("In udp_send\n");
1624
1625 if(uip_slen == 0) {
1626 goto drop;
1627 }
1628 uip_len = uip_slen + UIP_IPUDPH_LEN;
1629
1630 /* For IPv6, the IP length field does not include the IPv6 IP header
1631 length. */
1632 uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
1633
1634 UIP_IP_BUF->vtc = 0x60;
1635 UIP_IP_BUF->tcflow = 0x00;
1636 UIP_IP_BUF->ttl = uip_udp_conn->ttl;
1637 UIP_IP_BUF->proto = UIP_PROTO_UDP;
1638
1639 UIP_UDP_BUF->udplen = UIP_HTONS(uip_slen + UIP_UDPH_LEN);
1640 UIP_UDP_BUF->udpchksum = 0;
1641
1642 UIP_UDP_BUF->srcport = uip_udp_conn->lport;
1643 UIP_UDP_BUF->destport = uip_udp_conn->rport;
1644
1646 uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
1647
1648 uip_appdata = &uip_buf[UIP_IPTCPH_LEN];
1649
1650#if UIP_UDP_CHECKSUMS
1651 /* Calculate UDP checksum. */
1652 UIP_UDP_BUF->udpchksum = ~(uip_udpchksum());
1653 if(UIP_UDP_BUF->udpchksum == 0) {
1654 UIP_UDP_BUF->udpchksum = 0xffff;
1655 }
1656#endif /* UIP_UDP_CHECKSUMS */
1657
1658 UIP_STAT(++uip_stat.udp.sent);
1659 goto ip_send_nolen;
1660#endif /* UIP_UDP */
1661
1662#if UIP_TCP
1663 /* TCP input processing. */
1664 tcp_input:
1665
1667
1668 UIP_STAT(++uip_stat.tcp.recv);
1669 LOG_INFO("Receiving TCP packet\n");
1670 /* Start of TCP input header processing code. */
1671
1672 if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
1673 checksum. */
1674 UIP_STAT(++uip_stat.tcp.drop);
1675 UIP_STAT(++uip_stat.tcp.chkerr);
1676 LOG_ERR("tcp: bad checksum 0x%04x 0x%04x\n", UIP_TCP_BUF->tcpchksum,
1677 uip_tcpchksum());
1678 goto drop;
1679 }
1680
1681 /* Make sure that the TCP port number is not zero. */
1682 if(UIP_TCP_BUF->destport == 0 || UIP_TCP_BUF->srcport == 0) {
1683 LOG_ERR("tcp: zero port\n");
1684 goto drop;
1685 }
1686
1687 /* Demultiplex this segment. */
1688 /* First check any active connections. */
1689 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_TCP_CONNS - 1];
1690 ++uip_connr) {
1691 if(uip_connr->tcpstateflags != UIP_CLOSED &&
1692 UIP_TCP_BUF->destport == uip_connr->lport &&
1693 UIP_TCP_BUF->srcport == uip_connr->rport &&
1694 uip_ipaddr_cmp(&UIP_IP_BUF->srcipaddr, &uip_connr->ripaddr)) {
1695 goto found;
1696 }
1697 }
1698
1699 /* If we didn't find and active connection that expected the packet,
1700 either this packet is an old duplicate, or this is a SYN packet
1701 destined for a connection in LISTEN. If the SYN flag isn't set,
1702 it is an old packet and we send a RST. */
1703 if((UIP_TCP_BUF->flags & TCP_CTL) != TCP_SYN) {
1704 goto reset;
1705 }
1706
1707 uint16_t tmp16 = UIP_TCP_BUF->destport;
1708 /* Next, check listening connections. */
1709 for(c = 0; c < UIP_LISTENPORTS; ++c) {
1710 if(tmp16 == uip_listenports[c]) {
1711 goto found_listen;
1712 }
1713 }
1714
1715 /* No matching connection found, so we send a RST packet. */
1716 UIP_STAT(++uip_stat.tcp.synrst);
1717
1718 reset:
1719 LOG_WARN("In reset\n");
1720 /* We do not send resets in response to resets. */
1721 if(UIP_TCP_BUF->flags & TCP_RST) {
1722 goto drop;
1723 }
1724
1725 UIP_STAT(++uip_stat.tcp.rst);
1726
1727 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1728 uip_len = UIP_IPTCPH_LEN;
1729 UIP_TCP_BUF->tcpoffset = 5 << 4;
1730
1731 /* Flip the seqno and ackno fields in the TCP header. */
1732 c = UIP_TCP_BUF->seqno[3];
1733 UIP_TCP_BUF->seqno[3] = UIP_TCP_BUF->ackno[3];
1734 UIP_TCP_BUF->ackno[3] = c;
1735
1736 c = UIP_TCP_BUF->seqno[2];
1737 UIP_TCP_BUF->seqno[2] = UIP_TCP_BUF->ackno[2];
1738 UIP_TCP_BUF->ackno[2] = c;
1739
1740 c = UIP_TCP_BUF->seqno[1];
1741 UIP_TCP_BUF->seqno[1] = UIP_TCP_BUF->ackno[1];
1742 UIP_TCP_BUF->ackno[1] = c;
1743
1744 c = UIP_TCP_BUF->seqno[0];
1745 UIP_TCP_BUF->seqno[0] = UIP_TCP_BUF->ackno[0];
1746 UIP_TCP_BUF->ackno[0] = c;
1747
1748 /* We also have to increase the sequence number we are
1749 acknowledging. If the least significant byte overflowed, we need
1750 to propagate the carry to the other bytes as well. */
1751 if(++UIP_TCP_BUF->ackno[3] == 0) {
1752 if(++UIP_TCP_BUF->ackno[2] == 0) {
1753 if(++UIP_TCP_BUF->ackno[1] == 0) {
1754 ++UIP_TCP_BUF->ackno[0];
1755 }
1756 }
1757 }
1758
1759 /* Swap port numbers. */
1760 tmp16 = UIP_TCP_BUF->srcport;
1761 UIP_TCP_BUF->srcport = UIP_TCP_BUF->destport;
1762 UIP_TCP_BUF->destport = tmp16;
1763
1764 /* Swap IP addresses. */
1765 uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr);
1766 uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
1767 /* And send out the RST packet! */
1768 goto tcp_send_noconn;
1769
1770 /* This label will be jumped to if we matched the incoming packet
1771 with a connection in LISTEN. In that case, we should create a new
1772 connection and send a SYNACK in return. */
1773 found_listen:
1774 LOG_DBG("In found listen\n");
1775 /* First we check if there are any connections avaliable. Unused
1776 connections are kept in the same table as used connections, but
1777 unused ones have the tcpstate set to CLOSED. Also, connections in
1778 TIME_WAIT are kept track of and we'll use the oldest one if no
1779 CLOSED connections are found. Thanks to Eddie C. Dost for a very
1780 nice algorithm for the TIME_WAIT search. */
1781 uip_connr = 0;
1782 for(c = 0; c < UIP_TCP_CONNS; ++c) {
1783 if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
1784 uip_connr = &uip_conns[c];
1785 break;
1786 }
1787 if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
1788 if(uip_connr == 0 ||
1789 uip_conns[c].timer > uip_connr->timer) {
1790 uip_connr = &uip_conns[c];
1791 }
1792 }
1793 }
1794
1795 if(uip_connr == 0) {
1796 /* All connections are used already, we drop packet and hope that
1797 the remote end will retransmit the packet at a time when we
1798 have more spare connections. */
1799 UIP_STAT(++uip_stat.tcp.syndrop);
1800 LOG_ERR("tcp: found no unused connections\n");
1801 goto drop;
1802 }
1803 uip_conn = uip_connr;
1804
1805 /* Fill in the necessary fields for the new connection. */
1806 uip_connr->rto = uip_connr->timer = UIP_RTO;
1807 uip_connr->sa = 0;
1808 uip_connr->sv = 4;
1809 uip_connr->nrtx = 0;
1810 uip_connr->lport = UIP_TCP_BUF->destport;
1811 uip_connr->rport = UIP_TCP_BUF->srcport;
1812 uip_ipaddr_copy(&uip_connr->ripaddr, &UIP_IP_BUF->srcipaddr);
1813 uip_connr->tcpstateflags = UIP_SYN_RCVD;
1814
1815 uip_connr->snd_nxt[0] = iss[0];
1816 uip_connr->snd_nxt[1] = iss[1];
1817 uip_connr->snd_nxt[2] = iss[2];
1818 uip_connr->snd_nxt[3] = iss[3];
1819 uip_connr->len = 1;
1820
1821 /* rcv_nxt should be the seqno from the incoming packet + 1. */
1822 uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
1823 uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
1824 uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
1825 uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
1826 uip_add_rcv_nxt(1);
1827
1828 process_tcp_options(uip_connr);
1829
1830 /* Our response will be a SYNACK. */
1831#if UIP_ACTIVE_OPEN
1832 tcp_send_synack:
1833 UIP_TCP_BUF->flags = TCP_ACK;
1834
1835 tcp_send_syn:
1836 UIP_TCP_BUF->flags |= TCP_SYN;
1837#else /* UIP_ACTIVE_OPEN */
1838 tcp_send_synack:
1839 UIP_TCP_BUF->flags = TCP_SYN | TCP_ACK;
1840#endif /* UIP_ACTIVE_OPEN */
1841
1842 /* We send out the TCP Maximum Segment Size option with our
1843 SYNACK. */
1844 UIP_TCP_BUF->optdata[0] = TCP_OPT_MSS;
1845 UIP_TCP_BUF->optdata[1] = TCP_OPT_MSS_LEN;
1846 UIP_TCP_BUF->optdata[2] = (UIP_TCP_MSS) / 256;
1847 UIP_TCP_BUF->optdata[3] = (UIP_TCP_MSS) & 255;
1848 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
1849 UIP_TCP_BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
1850 goto tcp_send;
1851
1852 /* This label will be jumped to if we found an active connection. */
1853 found:
1854 LOG_DBG("In found\n");
1855 uip_conn = uip_connr;
1856 uip_flags = 0;
1857 /* We do a very naive form of TCP reset processing; we just accept
1858 any RST and kill our connection. We should in fact check if the
1859 sequence number of this reset is wihtin our advertised window
1860 before we accept the reset. */
1861 if(UIP_TCP_BUF->flags & TCP_RST) {
1862 uip_connr->tcpstateflags = UIP_CLOSED;
1863 LOG_WARN("tcp: got reset, aborting connection.");
1864 uip_flags = UIP_ABORT;
1865 UIP_APPCALL();
1866 goto drop;
1867 }
1868 /* Calculate the length of the data, if the application has sent
1869 any data to us. */
1870 c = (UIP_TCP_BUF->tcpoffset >> 4) << 2;
1871
1872 /* Check that the indicated length of the TCP header is not too large
1873 for the total packet length. */
1874 if(uip_len < c + UIP_IPH_LEN) {
1875 LOG_WARN("Dropping TCP packet with too large data offset (%u bytes)\n",
1876 (unsigned)c);
1877 goto drop;
1878 }
1879
1880 /* uip_len will contain the length of the actual TCP data. This is
1881 calculated by subtracing the length of the TCP header (in
1882 c) and the length of the IP header (20 bytes). */
1883 uip_len = uip_len - c - UIP_IPH_LEN;
1884
1885 /* First, check if the sequence number of the incoming packet is
1886 what we're expecting next. If not, we send out an ACK with the
1887 correct numbers in, unless we are in the SYN_RCVD state and
1888 receive a SYN, in which case we should retransmit our SYNACK
1889 (which is done futher down). */
1890 if(!((((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
1891 ((UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
1892 (((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) &&
1893 ((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN)))) {
1894 if((uip_len > 0 || ((UIP_TCP_BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
1895 (UIP_TCP_BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
1896 UIP_TCP_BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
1897 UIP_TCP_BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
1898 UIP_TCP_BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
1899
1900 if((UIP_TCP_BUF->flags & TCP_SYN)) {
1901 if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) {
1902 goto tcp_send_synack;
1903#if UIP_ACTIVE_OPEN
1904 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
1905 goto tcp_send_syn;
1906#endif
1907 }
1908 }
1909 goto tcp_send_ack;
1910 }
1911 }
1912
1913 /* Next, check if the incoming segment acknowledges any outstanding
1914 data. If so, we update the sequence number, reset the length of
1915 the outstanding data, calculate RTT estimations, and reset the
1916 retransmission timer. */
1917 if((UIP_TCP_BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
1918 uip_add32(uip_connr->snd_nxt, uip_connr->len);
1919
1920 if(UIP_TCP_BUF->ackno[0] == uip_acc32[0] &&
1921 UIP_TCP_BUF->ackno[1] == uip_acc32[1] &&
1922 UIP_TCP_BUF->ackno[2] == uip_acc32[2] &&
1923 UIP_TCP_BUF->ackno[3] == uip_acc32[3]) {
1924 /* Update sequence number. */
1925 uip_connr->snd_nxt[0] = uip_acc32[0];
1926 uip_connr->snd_nxt[1] = uip_acc32[1];
1927 uip_connr->snd_nxt[2] = uip_acc32[2];
1928 uip_connr->snd_nxt[3] = uip_acc32[3];
1929
1930 /* Do RTT estimation, unless we have done retransmissions. */
1931 if(uip_connr->nrtx == 0) {
1932 signed char m;
1933 m = uip_connr->rto - uip_connr->timer;
1934 /* This is taken directly from VJs original code in his paper */
1935 m = m - (uip_connr->sa >> 3);
1936 uip_connr->sa += m;
1937 if(m < 0) {
1938 m = -m;
1939 }
1940 m = m - (uip_connr->sv >> 2);
1941 uip_connr->sv += m;
1942 uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
1943
1944 }
1945 /* Set the acknowledged flag. */
1946 uip_flags = UIP_ACKDATA;
1947 /* Reset the retransmission timer. */
1948 uip_connr->timer = uip_connr->rto;
1949
1950 /* Reset length of outstanding data. */
1951 uip_connr->len = 0;
1952 }
1953
1954 }
1955
1956 /* Do different things depending on in what state the connection is. */
1957 switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
1958 /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
1959 implemented, since we force the application to close when the
1960 peer sends a FIN (hence the application goes directly from
1961 ESTABLISHED to LAST_ACK). */
1962 case UIP_SYN_RCVD:
1963 /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
1964 we are waiting for an ACK that acknowledges the data we sent
1965 out the last time. Therefore, we want to have the UIP_ACKDATA
1966 flag set. If so, we enter the ESTABLISHED state. */
1967 if(uip_flags & UIP_ACKDATA) {
1968 uip_connr->tcpstateflags = UIP_ESTABLISHED;
1969 uip_flags = UIP_CONNECTED;
1970 uip_connr->len = 0;
1971 if(uip_len > 0) {
1972 uip_flags |= UIP_NEWDATA;
1973 uip_add_rcv_nxt(uip_len);
1974 }
1975 uip_slen = 0;
1976 UIP_APPCALL();
1977 goto appsend;
1978 }
1979 /* We need to retransmit the SYNACK */
1980 if((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN) {
1981 goto tcp_send_synack;
1982 }
1983 goto drop;
1984#if UIP_ACTIVE_OPEN
1985 case UIP_SYN_SENT:
1986 /* In SYN_SENT, we wait for a SYNACK that is sent in response to
1987 our SYN. The rcv_nxt is set to sequence number in the SYNACK
1988 plus one, and we send an ACK. We move into the ESTABLISHED
1989 state. */
1990 if((uip_flags & UIP_ACKDATA) &&
1991 (UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
1992
1993 process_tcp_options(uip_connr);
1994
1995 uip_connr->tcpstateflags = UIP_ESTABLISHED;
1996 uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
1997 uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
1998 uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
1999 uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
2000 uip_add_rcv_nxt(1);
2001 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
2002 uip_connr->len = 0;
2003 uipbuf_clear();
2004 uip_slen = 0;
2005 UIP_APPCALL();
2006 goto appsend;
2007 }
2008 /* Inform the application that the connection failed */
2009 uip_flags = UIP_ABORT;
2010 UIP_APPCALL();
2011 /* The connection is closed after we send the RST */
2012 uip_conn->tcpstateflags = UIP_CLOSED;
2013 goto reset;
2014#endif /* UIP_ACTIVE_OPEN */
2015
2016 case UIP_ESTABLISHED:
2017 /* In the ESTABLISHED state, we call upon the application to feed
2018 data into the uip_buf. If the UIP_ACKDATA flag is set, the
2019 application should put new data into the buffer, otherwise we are
2020 retransmitting an old segment, and the application should put that
2021 data into the buffer.
2022
2023 If the incoming packet is a FIN, we should close the connection on
2024 this side as well, and we send out a FIN and enter the LAST_ACK
2025 state. We require that there is no outstanding data; otherwise the
2026 sequence numbers will be screwed up. */
2027
2028 if(UIP_TCP_BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
2029 if(uip_outstanding(uip_connr)) {
2030 goto drop;
2031 }
2032 uip_add_rcv_nxt(1 + uip_len);
2033 uip_flags |= UIP_CLOSE;
2034 if(uip_len > 0) {
2035 uip_flags |= UIP_NEWDATA;
2036 }
2037 UIP_APPCALL();
2038 uip_connr->len = 1;
2039 uip_connr->tcpstateflags = UIP_LAST_ACK;
2040 uip_connr->nrtx = 0;
2041 tcp_send_finack:
2042 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2043 goto tcp_send_nodata;
2044 }
2045
2046 /* Check the URG flag. If this is set, the segment carries urgent
2047 data that we must pass to the application. */
2048 if((UIP_TCP_BUF->flags & TCP_URG) != 0) {
2049 tmp16 = (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1];
2050 if(tmp16 > uip_len) {
2051 /* There is more urgent data in the next segment to come.
2052 Cap the urgent data length at the segment length for
2053 further processing. */
2054 tmp16 = uip_len;
2055 }
2056#if UIP_URGDATA > 0
2057 uip_urglen = tmp16;
2058 uip_add_rcv_nxt(uip_urglen);
2059 uip_len -= uip_urglen;
2060 uip_urgdata = uip_appdata;
2061 uip_appdata += uip_urglen;
2062 } else {
2063 uip_urglen = 0;
2064#else /* UIP_URGDATA > 0 */
2065 /* Ignore and discard any urgent data in this segment. */
2066 uip_appdata = ((char *)uip_appdata) + tmp16;
2067 uip_len -= tmp16;
2068#endif /* UIP_URGDATA > 0 */
2069 }
2070
2071 /* If uip_len > 0 we have TCP data in the packet, and we flag this
2072 by setting the UIP_NEWDATA flag and update the sequence number
2073 we acknowledge. If the application has stopped the dataflow
2074 using uip_stop(), we must not accept any data packets from the
2075 remote host. */
2076 if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
2077 uip_flags |= UIP_NEWDATA;
2078 uip_add_rcv_nxt(uip_len);
2079 }
2080
2081 /* Check if the available buffer space advertised by the other end
2082 is smaller than the initial MSS for this connection. If so, we
2083 set the current MSS to the window size to ensure that the
2084 application does not send more data than the other end can
2085 handle.
2086
2087 If the remote host advertises a zero window, we set the MSS to
2088 the initial MSS so that the application will send an entire MSS
2089 of data. This data will not be acknowledged by the receiver,
2090 and the application will retransmit it. This is called the
2091 "persistent timer" and uses the retransmission mechanim.
2092 */
2093 tmp16 = ((uint16_t)UIP_TCP_BUF->wnd[0] << 8) + (uint16_t)UIP_TCP_BUF->wnd[1];
2094 if(tmp16 > uip_connr->initialmss ||
2095 tmp16 == 0) {
2096 tmp16 = uip_connr->initialmss;
2097 }
2098 uip_connr->mss = tmp16;
2099
2100 /* If this packet constitutes an ACK for outstanding data (flagged
2101 by the UIP_ACKDATA flag, we should call the application since it
2102 might want to send more data. If the incoming packet had data
2103 from the peer (as flagged by the UIP_NEWDATA flag), the
2104 application must also be notified.
2105
2106 When the application is called, the global variable uip_len
2107 contains the length of the incoming data. The application can
2108 access the incoming data through the global pointer
2109 uip_appdata, which usually points UIP_IPTCPH_LEN
2110 bytes into the uip_buf array.
2111
2112 If the application wishes to send any data, this data should be
2113 put into the uip_appdata and the length of the data should be
2114 put into uip_len. If the application don't have any data to
2115 send, uip_len must be set to 0. */
2116 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
2117 uip_slen = 0;
2118 UIP_APPCALL();
2119
2120 appsend:
2121
2122 if(uip_flags & UIP_ABORT) {
2123 uip_slen = 0;
2124 uip_connr->tcpstateflags = UIP_CLOSED;
2125 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
2126 goto tcp_send_nodata;
2127 }
2128
2129 if(uip_flags & UIP_CLOSE) {
2130 uip_slen = 0;
2131 uip_connr->len = 1;
2132 uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
2133 uip_connr->nrtx = 0;
2134 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2135 goto tcp_send_nodata;
2136 }
2137
2138 /* If uip_slen > 0, the application has data to be sent. */
2139 if(uip_slen > 0) {
2140
2141 /* If the connection has acknowledged data, the contents of
2142 the ->len variable should be discarded. */
2143 if((uip_flags & UIP_ACKDATA) != 0) {
2144 uip_connr->len = 0;
2145 }
2146
2147 /* If the ->len variable is non-zero the connection has
2148 already data in transit and cannot send anymore right
2149 now. */
2150 if(uip_connr->len == 0) {
2151
2152 /* The application cannot send more than what is allowed by
2153 the mss (the minumum of the MSS and the available
2154 window). */
2155 if(uip_slen > uip_connr->mss) {
2156 uip_slen = uip_connr->mss;
2157 }
2158
2159 /* Remember how much data we send out now so that we know
2160 when everything has been acknowledged. */
2161 uip_connr->len = uip_slen;
2162 } else {
2163
2164 /* If the application already had unacknowledged data, we
2165 make sure that the application does not send (i.e.,
2166 retransmit) out more than it previously sent out. */
2167 uip_slen = uip_connr->len;
2168 }
2169 }
2170 uip_connr->nrtx = 0;
2171 apprexmit:
2172 uip_appdata = uip_sappdata;
2173
2174 /* If the application has data to be sent, or if the incoming
2175 packet had new data in it, we must send out a packet. */
2176 if(uip_slen > 0 && uip_connr->len > 0) {
2177 /* Add the length of the IP and TCP headers. */
2178 uip_len = uip_connr->len + UIP_IPTCPH_LEN;
2179 /* We always set the ACK flag in response packets. */
2180 UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH;
2181 /* Send the packet. */
2182 goto tcp_send_noopts;
2183 }
2184 /* If there is no data to send, just send out a pure ACK if
2185 there is newdata. */
2186 if(uip_flags & UIP_NEWDATA) {
2187 uip_len = UIP_IPTCPH_LEN;
2188 UIP_TCP_BUF->flags = TCP_ACK;
2189 goto tcp_send_noopts;
2190 }
2191 }
2192 goto drop;
2193 case UIP_LAST_ACK:
2194 /* We can close this connection if the peer has acknowledged our
2195 FIN. This is indicated by the UIP_ACKDATA flag. */
2196 if(uip_flags & UIP_ACKDATA) {
2197 uip_connr->tcpstateflags = UIP_CLOSED;
2198 uip_flags = UIP_CLOSE;
2199 UIP_APPCALL();
2200 }
2201 break;
2202
2203 case UIP_FIN_WAIT_1:
2204 /* The application has closed the connection, but the remote host
2205 hasn't closed its end yet. Thus we do nothing but wait for a
2206 FIN from the other side. */
2207 if(uip_len > 0) {
2208 uip_add_rcv_nxt(uip_len);
2209 }
2210 if(UIP_TCP_BUF->flags & TCP_FIN) {
2211 if(uip_flags & UIP_ACKDATA) {
2212 uip_connr->tcpstateflags = UIP_TIME_WAIT;
2213 uip_connr->timer = 0;
2214 uip_connr->len = 0;
2215 } else {
2216 uip_connr->tcpstateflags = UIP_CLOSING;
2217 }
2218 uip_add_rcv_nxt(1);
2219 uip_flags = UIP_CLOSE;
2220 UIP_APPCALL();
2221 goto tcp_send_ack;
2222 } else if(uip_flags & UIP_ACKDATA) {
2223 uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
2224 uip_connr->len = 0;
2225 goto drop;
2226 }
2227 if(uip_len > 0) {
2228 goto tcp_send_ack;
2229 }
2230 goto drop;
2231
2232 case UIP_FIN_WAIT_2:
2233 if(uip_len > 0) {
2234 uip_add_rcv_nxt(uip_len);
2235 }
2236 if(UIP_TCP_BUF->flags & TCP_FIN) {
2237 uip_connr->tcpstateflags = UIP_TIME_WAIT;
2238 uip_connr->timer = 0;
2239 uip_add_rcv_nxt(1);
2240 uip_flags = UIP_CLOSE;
2241 UIP_APPCALL();
2242 goto tcp_send_ack;
2243 }
2244 if(uip_len > 0) {
2245 goto tcp_send_ack;
2246 }
2247 goto drop;
2248
2249 case UIP_TIME_WAIT:
2250 goto tcp_send_ack;
2251
2252 case UIP_CLOSING:
2253 if(uip_flags & UIP_ACKDATA) {
2254 uip_connr->tcpstateflags = UIP_TIME_WAIT;
2255 uip_connr->timer = 0;
2256 }
2257 }
2258 goto drop;
2259
2260 /* We jump here when we are ready to send the packet, and just want
2261 to set the appropriate TCP sequence numbers in the TCP header. */
2262 tcp_send_ack:
2263 UIP_TCP_BUF->flags = TCP_ACK;
2264
2265 tcp_send_nodata:
2266 uip_len = UIP_IPTCPH_LEN;
2267
2268 tcp_send_noopts:
2269 UIP_TCP_BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
2270
2271 /* We're done with the input processing. We are now ready to send a
2272 reply. Our job is to fill in all the fields of the TCP and IP
2273 headers before calculating the checksum and finally send the
2274 packet. */
2275 tcp_send:
2276 LOG_DBG("In tcp_send\n");
2277
2278 UIP_TCP_BUF->ackno[0] = uip_connr->rcv_nxt[0];
2279 UIP_TCP_BUF->ackno[1] = uip_connr->rcv_nxt[1];
2280 UIP_TCP_BUF->ackno[2] = uip_connr->rcv_nxt[2];
2281 UIP_TCP_BUF->ackno[3] = uip_connr->rcv_nxt[3];
2282
2283 UIP_TCP_BUF->seqno[0] = uip_connr->snd_nxt[0];
2284 UIP_TCP_BUF->seqno[1] = uip_connr->snd_nxt[1];
2285 UIP_TCP_BUF->seqno[2] = uip_connr->snd_nxt[2];
2286 UIP_TCP_BUF->seqno[3] = uip_connr->snd_nxt[3];
2287
2288 UIP_TCP_BUF->srcport = uip_connr->lport;
2289 UIP_TCP_BUF->destport = uip_connr->rport;
2290
2291 UIP_IP_BUF->vtc = 0x60;
2292 UIP_IP_BUF->tcflow = 0x00;
2293
2294 uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_connr->ripaddr);
2295 uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
2296 LOG_INFO("Sending TCP packet to ");
2297 LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
2298 LOG_INFO_(" from ");
2299 LOG_INFO_6ADDR(&UIP_IP_BUF->srcipaddr);
2300 LOG_INFO_("\n");
2301
2302 if(uip_connr->tcpstateflags & UIP_STOPPED) {
2303 /* If the connection has issued uip_stop(), we advertise a zero
2304 window so that the remote host will stop sending data. */
2305 UIP_TCP_BUF->wnd[0] = UIP_TCP_BUF->wnd[1] = 0;
2306 } else {
2307 UIP_TCP_BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
2308 UIP_TCP_BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
2309 }
2310
2311 tcp_send_noconn:
2312 UIP_IP_BUF->proto = UIP_PROTO_TCP;
2313
2314 UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit;
2315 uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
2316
2317 UIP_TCP_BUF->urgp[0] = UIP_TCP_BUF->urgp[1] = 0;
2318
2319 /* Calculate TCP checksum. */
2320 UIP_TCP_BUF->tcpchksum = 0;
2321 UIP_TCP_BUF->tcpchksum = ~(uip_tcpchksum());
2322 UIP_STAT(++uip_stat.tcp.sent);
2323
2324#endif /* UIP_TCP */
2325#if UIP_UDP
2326 ip_send_nolen:
2327#endif
2328 UIP_IP_BUF->flow = 0x00;
2329 send:
2330 LOG_INFO("Sending packet with length %d (%d)\n", uip_len, uipbuf_get_len_field(UIP_IP_BUF));
2331
2332 UIP_STAT(++uip_stat.ip.sent);
2333 /* Return and let the caller do the actual transmission. */
2334 uip_flags = 0;
2335 return;
2336
2337 drop:
2338 uipbuf_clear();
2339 uip_ext_bitmap = 0;
2340 uip_flags = 0;
2341 return;
2342}
2343/*---------------------------------------------------------------------------*/
2344uint16_t
2345uip_htons(uint16_t val)
2346{
2347 return UIP_HTONS(val);
2348}
2349
2350uint32_t
2351uip_htonl(uint32_t val)
2352{
2353 return UIP_HTONL(val);
2354}
2355/*---------------------------------------------------------------------------*/
2356void
2357uip_send(const void *data, int len)
2358{
2359 int copylen;
2360
2361 if(uip_sappdata != NULL) {
2362 copylen = MIN(len, UIP_BUFSIZE - UIP_IPTCPH_LEN -
2363 (int)((char *)uip_sappdata - (char *)UIP_TCP_PAYLOAD));
2364 } else {
2365 copylen = MIN(len, UIP_BUFSIZE - UIP_IPTCPH_LEN);
2366 }
2367 if(copylen > 0) {
2368 uip_slen = copylen;
2369 if(data != uip_sappdata) {
2370 if(uip_sappdata == NULL) {
2371 memcpy(UIP_TCP_PAYLOAD, (data), uip_slen);
2372 } else {
2373 memcpy(uip_sappdata, (data), uip_slen);
2374 }
2375 }
2376 }
2377}
2378/*---------------------------------------------------------------------------*/
2379/** @} */
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:2357
#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:1086
#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:2345
#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: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
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