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