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