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