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