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