Contiki-Inga 3.x
uip6.c
Go to the documentation of this file.
1 /**
2  * \addtogroup uip6
3  * @{
4  */
5 
6 /**
7  * \file
8  * The uIP TCP/IPv6 stack code.
9  *
10  * \author Adam Dunkels <adam@sics.se>
11  * \author Julien Abeille <jabeille@cisco.com> (IPv6 related code)
12  * \author Mathilde Durvy <mdurvy@cisco.com> (IPv6 related code)
13  */
14 /*
15  * Copyright (c) 2001-2003, Adam Dunkels.
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21  * 1. Redistributions of source code must retain the above copyright
22  * notice, this list of conditions and the following disclaimer.
23  * 2. Redistributions in binary form must reproduce the above copyright
24  * notice, this list of conditions and the following disclaimer in the
25  * documentation and/or other materials provided with the distribution.
26  * 3. The name of the author may not be used to endorse or promote
27  * products derived from this software without specific prior
28  * written permission.
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
31  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
34  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
36  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
37  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
38  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
39  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41  *
42  * This file is part of the uIP TCP/IP stack.
43  *
44  *
45  */
46 
47 /*
48  * uIP is a small implementation of the IP, UDP and TCP protocols (as
49  * well as some basic ICMP stuff). The implementation couples the IP,
50  * UDP, TCP and the application layers very tightly. To keep the size
51  * of the compiled code down, this code frequently uses the goto
52  * statement. While it would be possible to break the uip_process()
53  * function into many smaller functions, this would increase the code
54  * size because of the overhead of parameter passing and the fact that
55  * the optimizer would not be as efficient.
56  *
57  * The principle is that we have a small buffer, called the uip_buf,
58  * in which the device driver puts an incoming packet. The TCP/IP
59  * stack parses the headers in the packet, and calls the
60  * application. If the remote host has sent data to the application,
61  * this data is present in the uip_buf and the application read the
62  * data from there. It is up to the application to put this data into
63  * a byte stream if needed. The application will not be fed with data
64  * that is out of sequence.
65  *
66  * If the application wishes to send data to the peer, it should put
67  * its data into the uip_buf. The uip_appdata pointer points to the
68  * first available byte. The TCP/IP stack will calculate the
69  * checksums, and fill in the necessary header fields and finally send
70  * the packet back to the peer.
71  */
72 
73 #include "net/ip/uip.h"
74 #include "net/ip/uipopt.h"
75 #include "net/ipv6/uip-icmp6.h"
76 #include "net/ipv6/uip-nd6.h"
77 #include "net/ipv6/uip-ds6.h"
79 
80 #include <string.h>
81 
82 #if UIP_CONF_IPV6
83 /*---------------------------------------------------------------------------*/
84 /* For Debug, logging, statistics */
85 /*---------------------------------------------------------------------------*/
86 
87 #define DEBUG DEBUG_NONE
88 #include "net/ip/uip-debug.h"
89 
90 #if UIP_CONF_IPV6_RPL
91 #include "rpl/rpl.h"
92 #endif /* UIP_CONF_IPV6_RPL */
93 
94 #if UIP_LOGGING == 1
95 #include <stdio.h>
96 void uip_log(char *msg);
97 #define UIP_LOG(m) uip_log(m)
98 #else
99 #define UIP_LOG(m)
100 #endif /* UIP_LOGGING == 1 */
101 
102 #if UIP_STATISTICS == 1
103 struct uip_stats uip_stat;
104 #endif /* UIP_STATISTICS == 1 */
105 
106 
107 /*---------------------------------------------------------------------------*/
108 /** @{ \name Layer 2 variables */
109 /*---------------------------------------------------------------------------*/
110 /** Host L2 address */
111 #if UIP_CONF_LL_802154
113 #else /*UIP_CONF_LL_802154*/
114 uip_lladdr_t uip_lladdr = {{0x00,0x06,0x98,0x00,0x02,0x32}};
115 #endif /*UIP_CONF_LL_802154*/
116 /** @} */
117 
118 /*---------------------------------------------------------------------------*/
119 /** @{ \name Layer 3 variables */
120 /*---------------------------------------------------------------------------*/
121 /**
122  * \brief Type of the next header in IPv6 header or extension headers
123  *
124  * Can be the next header field in the IPv6 header or in an extension header.
125  * When doing fragment reassembly, we must change the value of the next header
126  * field in the header before the fragmentation header, hence we need a pointer
127  * to this field.
128  */
129 uint8_t *uip_next_hdr;
130 /** \brief bitmap we use to record which IPv6 headers we have already seen */
131 uint8_t uip_ext_bitmap = 0;
132 /**
133  * \brief length of the extension headers read. updated each time we process
134  * a header
135  */
136 uint8_t uip_ext_len = 0;
137 /** \brief length of the header options read */
138 uint8_t uip_ext_opt_offset = 0;
139 /** @} */
140 
141 /*---------------------------------------------------------------------------*/
142 /* Buffers */
143 /*---------------------------------------------------------------------------*/
144 /** \name Buffer defines
145  * @{
146  */
147 #define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
148 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
149 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
150 #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
151 #define UIP_TCP_BUF ((struct uip_tcp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
152 #define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len])
153 #define UIP_ROUTING_BUF ((struct uip_routing_hdr *)&uip_buf[uip_l2_l3_hdr_len])
154 #define UIP_FRAG_BUF ((struct uip_frag_hdr *)&uip_buf[uip_l2_l3_hdr_len])
155 #define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len])
156 #define UIP_DESTO_BUF ((struct uip_desto_hdr *)&uip_buf[uip_l2_l3_hdr_len])
157 #define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
158 #define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
159 #if UIP_CONF_IPV6_RPL
160 #define UIP_EXT_HDR_OPT_RPL_BUF ((struct uip_ext_hdr_opt_rpl *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
161 #endif /* UIP_CONF_IPV6_RPL */
162 #define UIP_ICMP6_ERROR_BUF ((struct uip_icmp6_error *)&uip_buf[uip_l2_l3_icmp_hdr_len])
163 /** @} */
164 /** \name Buffer variables
165  * @{
166  */
167 /** Packet buffer for incoming and outgoing packets */
168 #ifndef UIP_CONF_EXTERNAL_BUFFER
170 #endif /* UIP_CONF_EXTERNAL_BUFFER */
171 
172 /* The uip_appdata pointer points to application data. */
174 /* The uip_appdata pointer points to the application data which is to be sent*/
175 void *uip_sappdata;
176 
177 #if UIP_URGDATA > 0
178 /* The uip_urgdata pointer points to urgent data (out-of-band data), if present */
179 void *uip_urgdata;
180 uint16_t uip_urglen, uip_surglen;
181 #endif /* UIP_URGDATA > 0 */
182 
183 /* The uip_len is either 8 or 16 bits, depending on the maximum packet size.*/
184 uint16_t uip_len, uip_slen;
185 /** @} */
186 
187 /*---------------------------------------------------------------------------*/
188 /** @{ \name General variables */
189 /*---------------------------------------------------------------------------*/
190 
191 /* The uip_flags variable is used for communication between the TCP/IP stack
192 and the application program. */
193 uint8_t uip_flags;
194 
195 /* uip_conn always points to the current connection (set to NULL for UDP). */
197 
198 /* Temporary variables. */
199 #if (UIP_TCP || UIP_UDP)
200 static uint8_t c;
201 #endif
202 
203 #if UIP_ACTIVE_OPEN || UIP_UDP
204 /* Keeps track of the last port used for a new connection. */
205 static uint16_t lastport;
206 #endif /* UIP_ACTIVE_OPEN || UIP_UDP */
207 /** @} */
208 
209 /*---------------------------------------------------------------------------*/
210 /* TCP */
211 /*---------------------------------------------------------------------------*/
212 /** \name TCP defines
213  *@{
214  */
215 /* Structures and definitions. */
216 #define TCP_FIN 0x01
217 #define TCP_SYN 0x02
218 #define TCP_RST 0x04
219 #define TCP_PSH 0x08
220 #define TCP_ACK 0x10
221 #define TCP_URG 0x20
222 #define TCP_CTL 0x3f
223 
224 #define TCP_OPT_END 0 /* End of TCP options list */
225 #define TCP_OPT_NOOP 1 /* "No-operation" TCP option */
226 #define TCP_OPT_MSS 2 /* Maximum segment size TCP option */
227 
228 #define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */
229 /** @} */
230 /** \name TCP variables
231  *@{
232  */
233 #if UIP_TCP
234 /* The uip_conns array holds all TCP connections. */
235 struct uip_conn uip_conns[UIP_CONNS];
236 
237 /* The uip_listenports list all currently listning ports. */
238 uint16_t uip_listenports[UIP_LISTENPORTS];
239 
240 /* The iss variable is used for the TCP initial sequence number. */
241 static uint8_t iss[4];
242 
243 /* Temporary variables. */
244 uint8_t uip_acc32[4];
245 static uint8_t opt;
246 static uint16_t tmp16;
247 #endif /* UIP_TCP */
248 /** @} */
249 
250 /*---------------------------------------------------------------------------*/
251 /** @{ \name UDP variables */
252 /*---------------------------------------------------------------------------*/
253 #if UIP_UDP
254 struct uip_udp_conn *uip_udp_conn;
255 struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
256 #endif /* UIP_UDP */
257 /** @} */
258 
259 /*---------------------------------------------------------------------------*/
260 /** @{ \name ICMPv6 variables */
261 /*---------------------------------------------------------------------------*/
262 #if UIP_CONF_ICMP6
263 /** single possible icmpv6 "connection" */
264 struct uip_icmp6_conn uip_icmp6_conns;
265 #endif /*UIP_CONF_ICMP6*/
266 /** @} */
267 
268 /*---------------------------------------------------------------------------*/
269 /* Functions */
270 /*---------------------------------------------------------------------------*/
271 #if (!UIP_ARCH_ADD32 && UIP_TCP)
272 void
273 uip_add32(uint8_t *op32, uint16_t op16)
274 {
275  uip_acc32[3] = op32[3] + (op16 & 0xff);
276  uip_acc32[2] = op32[2] + (op16 >> 8);
277  uip_acc32[1] = op32[1];
278  uip_acc32[0] = op32[0];
279 
280  if(uip_acc32[2] < (op16 >> 8)) {
281  ++uip_acc32[1];
282  if(uip_acc32[1] == 0) {
283  ++uip_acc32[0];
284  }
285  }
286 
287 
288  if(uip_acc32[3] < (op16 & 0xff)) {
289  ++uip_acc32[2];
290  if(uip_acc32[2] == 0) {
291  ++uip_acc32[1];
292  if(uip_acc32[1] == 0) {
293  ++uip_acc32[0];
294  }
295  }
296  }
297 }
298 
299 #endif /* UIP_ARCH_ADD32 && UIP_TCP */
300 
301 #if ! UIP_ARCH_CHKSUM
302 /*---------------------------------------------------------------------------*/
303 static uint16_t
304 chksum(uint16_t sum, const uint8_t *data, uint16_t len)
305 {
306  uint16_t t;
307  const uint8_t *dataptr;
308  const uint8_t *last_byte;
309 
310  dataptr = data;
311  last_byte = data + len - 1;
312 
313  while(dataptr < last_byte) { /* At least two more bytes */
314  t = (dataptr[0] << 8) + dataptr[1];
315  sum += t;
316  if(sum < t) {
317  sum++; /* carry */
318  }
319  dataptr += 2;
320  }
321 
322  if(dataptr == last_byte) {
323  t = (dataptr[0] << 8) + 0;
324  sum += t;
325  if(sum < t) {
326  sum++; /* carry */
327  }
328  }
329 
330  /* Return sum in host byte order. */
331  return sum;
332 }
333 /*---------------------------------------------------------------------------*/
334 uint16_t
335 uip_chksum(uint16_t *data, uint16_t len)
336 {
337  return uip_htons(chksum(0, (uint8_t *)data, len));
338 }
339 /*---------------------------------------------------------------------------*/
340 #ifndef UIP_ARCH_IPCHKSUM
341 uint16_t
343 {
344  uint16_t sum;
345 
346  sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
347  PRINTF("uip_ipchksum: sum 0x%04x\n", sum);
348  return (sum == 0) ? 0xffff : uip_htons(sum);
349 }
350 #endif
351 /*---------------------------------------------------------------------------*/
352 static uint16_t
353 upper_layer_chksum(uint8_t proto)
354 {
355 /* gcc 4.4.0 - 4.6.1 (maybe 4.3...) with -Os on 8 bit CPUS incorrectly compiles:
356  * int bar (int);
357  * int foo (unsigned char a, unsigned char b) {
358  * int len = (a << 8) + b; //len becomes 0xff00&<random>+b
359  * return len + bar (len);
360  * }
361  * upper_layer_len triggers this bug unless it is declared volatile.
362  * See https://sourceforge.net/apps/mantisbt/contiki/view.php?id=3
363  */
364  volatile uint16_t upper_layer_len;
365  uint16_t sum;
366 
367  upper_layer_len = (((uint16_t)(UIP_IP_BUF->len[0]) << 8) + UIP_IP_BUF->len[1] - uip_ext_len);
368 
369  PRINTF("Upper layer checksum len: %d from: %d\n", upper_layer_len,
370  UIP_IPH_LEN + UIP_LLH_LEN + uip_ext_len);
371 
372  /* First sum pseudoheader. */
373  /* IP protocol and length fields. This addition cannot carry. */
374  sum = upper_layer_len + proto;
375  /* Sum IP source and destination addresses. */
376  sum = chksum(sum, (uint8_t *)&UIP_IP_BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t));
377 
378  /* Sum TCP header and data. */
379  sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN + uip_ext_len],
380  upper_layer_len);
381 
382  return (sum == 0) ? 0xffff : uip_htons(sum);
383 }
384 /*---------------------------------------------------------------------------*/
385 uint16_t
387 {
388  return upper_layer_chksum(UIP_PROTO_ICMP6);
389 
390 }
391 /*---------------------------------------------------------------------------*/
392 #if UIP_TCP
393 uint16_t
394 uip_tcpchksum(void)
395 {
396  return upper_layer_chksum(UIP_PROTO_TCP);
397 }
398 #endif /* UIP_TCP */
399 /*---------------------------------------------------------------------------*/
400 #if UIP_UDP && UIP_UDP_CHECKSUMS
401 uint16_t
402 uip_udpchksum(void)
403 {
404  return upper_layer_chksum(UIP_PROTO_UDP);
405 }
406 #endif /* UIP_UDP && UIP_UDP_CHECKSUMS */
407 #endif /* UIP_ARCH_CHKSUM */
408 /*---------------------------------------------------------------------------*/
409 void
410 uip_init(void)
411 {
412 
413  uip_ds6_init();
414 
415 #if UIP_TCP
416  for(c = 0; c < UIP_LISTENPORTS; ++c) {
417  uip_listenports[c] = 0;
418  }
419  for(c = 0; c < UIP_CONNS; ++c) {
420  uip_conns[c].tcpstateflags = UIP_CLOSED;
421  }
422 #endif /* UIP_TCP */
423 
424 #if UIP_ACTIVE_OPEN || UIP_UDP
425  lastport = 1024;
426 #endif /* UIP_ACTIVE_OPEN || UIP_UDP */
427 
428 #if UIP_UDP
429  for(c = 0; c < UIP_UDP_CONNS; ++c) {
430  uip_udp_conns[c].lport = 0;
431  }
432 #endif /* UIP_UDP */
433 
434 #if UIP_CONF_IPV6_MULTICAST
435  UIP_MCAST6.init();
436 #endif
437 }
438 /*---------------------------------------------------------------------------*/
439 #if UIP_TCP && UIP_ACTIVE_OPEN
440 struct uip_conn *
441 uip_connect(uip_ipaddr_t *ripaddr, uint16_t rport)
442 {
443  register struct uip_conn *conn, *cconn;
444 
445  /* Find an unused local port. */
446  again:
447  ++lastport;
448 
449  if(lastport >= 32000) {
450  lastport = 4096;
451  }
452 
453  /* Check if this port is already in use, and if so try to find
454  another one. */
455  for(c = 0; c < UIP_CONNS; ++c) {
456  conn = &uip_conns[c];
457  if(conn->tcpstateflags != UIP_CLOSED &&
458  conn->lport == uip_htons(lastport)) {
459  goto again;
460  }
461  }
462 
463  conn = 0;
464  for(c = 0; c < UIP_CONNS; ++c) {
465  cconn = &uip_conns[c];
466  if(cconn->tcpstateflags == UIP_CLOSED) {
467  conn = cconn;
468  break;
469  }
470  if(cconn->tcpstateflags == UIP_TIME_WAIT) {
471  if(conn == 0 ||
472  cconn->timer > conn->timer) {
473  conn = cconn;
474  }
475  }
476  }
477 
478  if(conn == 0) {
479  return 0;
480  }
481 
482  conn->tcpstateflags = UIP_SYN_SENT;
483 
484  conn->snd_nxt[0] = iss[0];
485  conn->snd_nxt[1] = iss[1];
486  conn->snd_nxt[2] = iss[2];
487  conn->snd_nxt[3] = iss[3];
488 
489  conn->rcv_nxt[0] = 0;
490  conn->rcv_nxt[1] = 0;
491  conn->rcv_nxt[2] = 0;
492  conn->rcv_nxt[3] = 0;
493 
494  conn->initialmss = conn->mss = UIP_TCP_MSS;
495 
496  conn->len = 1; /* TCP length of the SYN is one. */
497  conn->nrtx = 0;
498  conn->timer = 1; /* Send the SYN next time around. */
499  conn->rto = UIP_RTO;
500  conn->sa = 0;
501  conn->sv = 16; /* Initial value of the RTT variance. */
502  conn->lport = uip_htons(lastport);
503  conn->rport = rport;
504  uip_ipaddr_copy(&conn->ripaddr, ripaddr);
505 
506  return conn;
507 }
508 #endif /* UIP_TCP && UIP_ACTIVE_OPEN */
509 /*---------------------------------------------------------------------------*/
510 void
511 remove_ext_hdr(void)
512 {
513  /* Remove ext header before TCP/UDP processing. */
514  if(uip_ext_len > 0) {
515  PRINTF("Cutting ext-header before processing (extlen: %d, uiplen: %d)\n",
517  if(uip_len < UIP_IPH_LEN + uip_ext_len) {
518  PRINTF("ERROR: uip_len too short compared to ext len\n");
519  uip_ext_len = 0;
520  uip_len = 0;
521  return;
522  }
523  memmove(((uint8_t *)UIP_TCP_BUF), (uint8_t *)UIP_TCP_BUF + uip_ext_len,
524  uip_len - UIP_IPH_LEN - uip_ext_len);
525 
526  uip_len -= uip_ext_len;
527 
528  /* Update the IP length. */
529  UIP_IP_BUF->len[0] = (uip_len - UIP_IPH_LEN) >> 8;
530  UIP_IP_BUF->len[1] = (uip_len - UIP_IPH_LEN) & 0xff;
531  uip_ext_len = 0;
532  }
533 }
534 /*---------------------------------------------------------------------------*/
535 #if UIP_UDP
536 struct uip_udp_conn *
537 uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport)
538 {
539  register struct uip_udp_conn *conn;
540 
541  /* Find an unused local port. */
542  again:
543  ++lastport;
544 
545  if(lastport >= 32000) {
546  lastport = 4096;
547  }
548 
549  for(c = 0; c < UIP_UDP_CONNS; ++c) {
550  if(uip_udp_conns[c].lport == uip_htons(lastport)) {
551  goto again;
552  }
553  }
554 
555  conn = 0;
556  for(c = 0; c < UIP_UDP_CONNS; ++c) {
557  if(uip_udp_conns[c].lport == 0) {
558  conn = &uip_udp_conns[c];
559  break;
560  }
561  }
562 
563  if(conn == 0) {
564  return 0;
565  }
566 
567  conn->lport = UIP_HTONS(lastport);
568  conn->rport = rport;
569  if(ripaddr == NULL) {
570  memset(&conn->ripaddr, 0, sizeof(uip_ipaddr_t));
571  } else {
572  uip_ipaddr_copy(&conn->ripaddr, ripaddr);
573  }
574  conn->ttl = uip_ds6_if.cur_hop_limit;
575 
576  return conn;
577 }
578 #endif /* UIP_UDP */
579 /*---------------------------------------------------------------------------*/
580 #if UIP_TCP
581 void
582 uip_unlisten(uint16_t port)
583 {
584  for(c = 0; c < UIP_LISTENPORTS; ++c) {
585  if(uip_listenports[c] == port) {
586  uip_listenports[c] = 0;
587  return;
588  }
589  }
590 }
591 /*---------------------------------------------------------------------------*/
592 void
593 uip_listen(uint16_t port)
594 {
595  for(c = 0; c < UIP_LISTENPORTS; ++c) {
596  if(uip_listenports[c] == 0) {
597  uip_listenports[c] = port;
598  return;
599  }
600  }
601 }
602 #endif
603 /*---------------------------------------------------------------------------*/
604 
605 #if UIP_CONF_IPV6_REASSEMBLY
606 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
607 
608 static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE];
609 
610 static uint8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
611 /*the first byte of an IP fragment is aligned on an 8-byte boundary */
612 
613 static const uint8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
614  0x0f, 0x07, 0x03, 0x01};
615 static uint16_t uip_reasslen;
616 static uint8_t uip_reassflags;
617 
618 #define UIP_REASS_FLAG_LASTFRAG 0x01
619 #define UIP_REASS_FLAG_FIRSTFRAG 0x02
620 #define UIP_REASS_FLAG_ERROR_MSG 0x04
621 
622 
623 /*
624  * See RFC 2460 for a description of fragmentation in IPv6
625  * A typical Ipv6 fragment
626  * +------------------+--------+--------------+
627  * | Unfragmentable |Fragment| first |
628  * | Part | Header | fragment |
629  * +------------------+--------+--------------+
630  */
631 
632 
633 struct etimer uip_reass_timer; /* timer for reassembly */
634 uint8_t uip_reass_on; /* equal to 1 if we are currently reassembling a packet */
635 
636 static uint32_t uip_id; /* For every packet that is to be fragmented, the source
637  node generates an Identification value that is present
638  in all the fragments */
639 #define IP_MF 0x0001
640 
641 static uint16_t
642 uip_reass(void)
643 {
644  uint16_t offset=0;
645  uint16_t len;
646  uint16_t i;
647 
648  /* If ip_reasstmr is zero, no packet is present in the buffer */
649  /* We first write the unfragmentable part of IP header into the reassembly
650  buffer. The reset the other reassembly variables. */
651  if(uip_reass_on == 0) {
652  PRINTF("Starting reassembly\n");
653  memcpy(FBUF, UIP_IP_BUF, uip_ext_len + UIP_IPH_LEN);
654  /* temporary in case we do not receive the fragment with offset 0 first */
655  etimer_set(&uip_reass_timer, UIP_REASS_MAXAGE*CLOCK_SECOND);
656  uip_reass_on = 1;
657  uip_reassflags = 0;
658  uip_id = UIP_FRAG_BUF->id;
659  /* Clear the bitmap. */
660  memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap));
661  }
662  /*
663  * Check if the incoming fragment matches the one currently present
664  * in the reasembly buffer. If so, we proceed with copying the fragment
665  * into the buffer.
666  */
667  if(uip_ipaddr_cmp(&FBUF->srcipaddr, &UIP_IP_BUF->srcipaddr) &&
668  uip_ipaddr_cmp(&FBUF->destipaddr, &UIP_IP_BUF->destipaddr) &&
669  UIP_FRAG_BUF->id == uip_id) {
670  len = uip_len - uip_ext_len - UIP_IPH_LEN - UIP_FRAGH_LEN;
671  offset = (uip_ntohs(UIP_FRAG_BUF->offsetresmore) & 0xfff8);
672  /* in byte, originaly in multiple of 8 bytes*/
673  PRINTF("len %d\n", len);
674  PRINTF("offset %d\n", offset);
675  if(offset == 0){
676  uip_reassflags |= UIP_REASS_FLAG_FIRSTFRAG;
677  /*
678  * The Next Header field of the last header of the Unfragmentable
679  * Part is obtained from the Next Header field of the first
680  * fragment's Fragment header.
681  */
682  *uip_next_hdr = UIP_FRAG_BUF->next;
683  memcpy(FBUF, UIP_IP_BUF, uip_ext_len + UIP_IPH_LEN);
684  PRINTF("src ");
685  PRINT6ADDR(&FBUF->srcipaddr);
686  PRINTF("dest ");
687  PRINT6ADDR(&FBUF->destipaddr);
688  PRINTF("next %d\n", UIP_IP_BUF->proto);
689 
690  }
691 
692  /* If the offset or the offset + fragment length overflows the
693  reassembly buffer, we discard the entire packet. */
694  if(offset > UIP_REASS_BUFSIZE ||
695  offset + len > UIP_REASS_BUFSIZE) {
696  uip_reass_on = 0;
697  etimer_stop(&uip_reass_timer);
698  return 0;
699  }
700 
701  /* If this fragment has the More Fragments flag set to zero, it is the
702  last fragment*/
703  if((uip_ntohs(UIP_FRAG_BUF->offsetresmore) & IP_MF) == 0) {
704  uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
705  /*calculate the size of the entire packet*/
706  uip_reasslen = offset + len;
707  PRINTF("LAST FRAGMENT reasslen %d\n", uip_reasslen);
708  } else {
709  /* If len is not a multiple of 8 octets and the M flag of that fragment
710  is 1, then that fragment must be discarded and an ICMP Parameter
711  Problem, Code 0, message should be sent to the source of the fragment,
712  pointing to the Payload Length field of the fragment packet. */
713  if(len % 8 != 0){
715  uip_reassflags |= UIP_REASS_FLAG_ERROR_MSG;
716  /* not clear if we should interrupt reassembly, but it seems so from
717  the conformance tests */
718  uip_reass_on = 0;
719  etimer_stop(&uip_reass_timer);
720  return uip_len;
721  }
722  }
723 
724  /* Copy the fragment into the reassembly buffer, at the right
725  offset. */
726  memcpy((uint8_t *)FBUF + UIP_IPH_LEN + uip_ext_len + offset,
727  (uint8_t *)UIP_FRAG_BUF + UIP_FRAGH_LEN, len);
728 
729  /* Update the bitmap. */
730  if(offset >> 6 == (offset + len) >> 6) {
731  uip_reassbitmap[offset >> 6] |=
732  bitmap_bits[(offset >> 3) & 7] &
733  ~bitmap_bits[((offset + len) >> 3) & 7];
734  } else {
735  /* If the two endpoints are in different bytes, we update the
736  bytes in the endpoints and fill the stuff inbetween with
737  0xff. */
738  uip_reassbitmap[offset >> 6] |= bitmap_bits[(offset >> 3) & 7];
739 
740  for(i = (1 + (offset >> 6)); i < ((offset + len) >> 6); ++i) {
741  uip_reassbitmap[i] = 0xff;
742  }
743  uip_reassbitmap[(offset + len) >> 6] |=
744  ~bitmap_bits[((offset + len) >> 3) & 7];
745  }
746 
747  /* Finally, we check if we have a full packet in the buffer. We do
748  this by checking if we have the last fragment and if all bits
749  in the bitmap are set. */
750 
751  if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
752  /* Check all bytes up to and including all but the last byte in
753  the bitmap. */
754  for(i = 0; i < (uip_reasslen >> 6); ++i) {
755  if(uip_reassbitmap[i] != 0xff) {
756  return 0;
757  }
758  }
759  /* Check the last byte in the bitmap. It should contain just the
760  right amount of bits. */
761  if(uip_reassbitmap[uip_reasslen >> 6] !=
762  (uint8_t)~bitmap_bits[(uip_reasslen >> 3) & 7]) {
763  return 0;
764  }
765 
766  /* If we have come this far, we have a full packet in the
767  buffer, so we copy it to uip_buf. We also reset the timer. */
768  uip_reass_on = 0;
769  etimer_stop(&uip_reass_timer);
770 
771  uip_reasslen += UIP_IPH_LEN + uip_ext_len;
772  memcpy(UIP_IP_BUF, FBUF, uip_reasslen);
773  UIP_IP_BUF->len[0] = ((uip_reasslen - UIP_IPH_LEN) >> 8);
774  UIP_IP_BUF->len[1] = ((uip_reasslen - UIP_IPH_LEN) & 0xff);
775  PRINTF("REASSEMBLED PAQUET %d (%d)\n", uip_reasslen,
776  (UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]);
777 
778  return uip_reasslen;
779 
780  }
781  } else {
782  PRINTF("Already reassembling another paquet\n");
783  }
784  return 0;
785 }
786 
787 void
788 uip_reass_over(void)
789 {
790  /* to late, we abandon the reassembly of the packet */
791 
792  uip_reass_on = 0;
793  etimer_stop(&uip_reass_timer);
794 
795  if(uip_reassflags & UIP_REASS_FLAG_FIRSTFRAG){
796  PRINTF("FRAG INTERRUPTED TOO LATE\n");
797  /* If the first fragment has been received, an ICMP Time Exceeded
798  -- Fragment Reassembly Time Exceeded message should be sent to the
799  source of that fragment. */
800  /** \note
801  * We don't have a complete packet to put in the error message.
802  * We could include the first fragment but since its not mandated by
803  * any RFC, we decided not to include it as it reduces the size of
804  * the packet.
805  */
806  uip_len = 0;
807  uip_ext_len = 0;
808  memcpy(UIP_IP_BUF, FBUF, UIP_IPH_LEN); /* copy the header for src
809  and dest address*/
811 
812  UIP_STAT(++uip_stat.ip.sent);
813  uip_flags = 0;
814  }
815 }
816 
817 #endif /* UIP_CONF_IPV6_REASSEMBLY */
818 
819 /*---------------------------------------------------------------------------*/
820 #if UIP_TCP
821 static void
822 uip_add_rcv_nxt(uint16_t n)
823 {
824  uip_add32(uip_conn->rcv_nxt, n);
825  uip_conn->rcv_nxt[0] = uip_acc32[0];
826  uip_conn->rcv_nxt[1] = uip_acc32[1];
827  uip_conn->rcv_nxt[2] = uip_acc32[2];
828  uip_conn->rcv_nxt[3] = uip_acc32[3];
829 }
830 #endif
831 /*---------------------------------------------------------------------------*/
832 
833 /**
834  * \brief Process the options in Destination and Hop By Hop extension headers
835  */
836 static uint8_t
837 ext_hdr_options_process(void)
838 {
839  /*
840  * Length field in the extension header: length of the header in units of
841  * 8 bytes, excluding the first 8 bytes
842  * length field in an option : the length of data in the option
843  */
844  uip_ext_opt_offset = 2;
845  while(uip_ext_opt_offset < ((UIP_EXT_BUF->len << 3) + 8)) {
846  switch(UIP_EXT_HDR_OPT_BUF->type) {
847  /*
848  * for now we do not support any options except padding ones
849  * PAD1 does not make sense as the header must be 8bytes aligned,
850  * hence we can only have
851  */
853  PRINTF("Processing PAD1 option\n");
854  uip_ext_opt_offset += 1;
855  break;
856  case UIP_EXT_HDR_OPT_PADN:
857  PRINTF("Processing PADN option\n");
858  uip_ext_opt_offset += UIP_EXT_HDR_OPT_PADN_BUF->opt_len + 2;
859  break;
860  case UIP_EXT_HDR_OPT_RPL:
861  /* Fixes situation when a node that is not using RPL
862  * joins a network which does. The received packages will include the
863  * RPL header and processed by the "default" case of the switch
864  * (0x63 & 0xC0 = 0x40). Hence, the packet is discarded as the header
865  * is considered invalid.
866  * Using this fix, the header is ignored, and the next header (if
867  * present) is processed.
868  */
869 #if UIP_CONF_IPV6_RPL
870  PRINTF("Processing RPL option\n");
871  if(rpl_verify_header(uip_ext_opt_offset)) {
872  PRINTF("RPL Option Error: Dropping Packet\n");
873  return 1;
874  }
875 #endif /* UIP_CONF_IPV6_RPL */
876  uip_ext_opt_offset += (UIP_EXT_HDR_OPT_BUF->len) + 2;
877  return 0;
878  default:
879  /*
880  * check the two highest order bits of the option
881  * - 00 skip over this option and continue processing the header.
882  * - 01 discard the packet.
883  * - 10 discard the packet and, regardless of whether or not the
884  * packet's Destination Address was a multicast address, send an
885  * ICMP Parameter Problem, Code 2, message to the packet's
886  * Source Address, pointing to the unrecognized Option Type.
887  * - 11 discard the packet and, only if the packet's Destination
888  * Address was not a multicast address, send an ICMP Parameter
889  * Problem, Code 2, message to the packet's Source Address,
890  * pointing to the unrecognized Option Type.
891  */
892  PRINTF("MSB %x\n", UIP_EXT_HDR_OPT_BUF->type);
893  switch(UIP_EXT_HDR_OPT_BUF->type & 0xC0) {
894  case 0:
895  break;
896  case 0x40:
897  return 1;
898  case 0xC0:
899  if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
900  return 1;
901  }
902  case 0x80:
904  (uint32_t)UIP_IPH_LEN + uip_ext_len + uip_ext_opt_offset);
905  return 2;
906  }
907  /* in the cases were we did not discard, update ext_opt* */
908  uip_ext_opt_offset += UIP_EXT_HDR_OPT_BUF->len + 2;
909  break;
910  }
911  }
912  return 0;
913 }
914 
915 
916 /*---------------------------------------------------------------------------*/
917 void
918 uip_process(uint8_t flag)
919 {
920 #if UIP_TCP
921  register struct uip_conn *uip_connr = uip_conn;
922 #endif /* UIP_TCP */
923 #if UIP_UDP
924  if(flag == UIP_UDP_SEND_CONN) {
925  goto udp_send;
926  }
927 #endif /* UIP_UDP */
928  uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
929 
930  /* Check if we were invoked because of a poll request for a
931  particular connection. */
932  if(flag == UIP_POLL_REQUEST) {
933 #if UIP_TCP
934  if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
935  !uip_outstanding(uip_connr)) {
936  uip_flags = UIP_POLL;
937  UIP_APPCALL();
938  goto appsend;
939 #if UIP_ACTIVE_OPEN
940  } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
941  /* In the SYN_SENT state, we retransmit out SYN. */
942  UIP_TCP_BUF->flags = 0;
943  goto tcp_send_syn;
944 #endif /* UIP_ACTIVE_OPEN */
945  }
946  goto drop;
947 #endif /* UIP_TCP */
948  /* Check if we were invoked because of the perodic timer fireing. */
949  } else if(flag == UIP_TIMER) {
950  /* Reset the length variables. */
951 #if UIP_TCP
952  uip_len = 0;
953  uip_slen = 0;
954 
955  /* Increase the initial sequence number. */
956  if(++iss[3] == 0) {
957  if(++iss[2] == 0) {
958  if(++iss[1] == 0) {
959  ++iss[0];
960  }
961  }
962  }
963 
964  /*
965  * Check if the connection is in a state in which we simply wait
966  * for the connection to time out. If so, we increase the
967  * connection's timer and remove the connection if it times
968  * out.
969  */
970  if(uip_connr->tcpstateflags == UIP_TIME_WAIT ||
971  uip_connr->tcpstateflags == UIP_FIN_WAIT_2) {
972  ++(uip_connr->timer);
973  if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
974  uip_connr->tcpstateflags = UIP_CLOSED;
975  }
976  } else if(uip_connr->tcpstateflags != UIP_CLOSED) {
977  /*
978  * If the connection has outstanding data, we increase the
979  * connection's timer and see if it has reached the RTO value
980  * in which case we retransmit.
981  */
982  if(uip_outstanding(uip_connr)) {
983  if(uip_connr->timer-- == 0) {
984  if(uip_connr->nrtx == UIP_MAXRTX ||
985  ((uip_connr->tcpstateflags == UIP_SYN_SENT ||
986  uip_connr->tcpstateflags == UIP_SYN_RCVD) &&
987  uip_connr->nrtx == UIP_MAXSYNRTX)) {
988  uip_connr->tcpstateflags = UIP_CLOSED;
989 
990  /*
991  * We call UIP_APPCALL() with uip_flags set to
992  * UIP_TIMEDOUT to inform the application that the
993  * connection has timed out.
994  */
995  uip_flags = UIP_TIMEDOUT;
996  UIP_APPCALL();
997 
998  /* We also send a reset packet to the remote host. */
999  UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1000  goto tcp_send_nodata;
1001  }
1002 
1003  /* Exponential backoff. */
1004  uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
1005  4:
1006  uip_connr->nrtx);
1007  ++(uip_connr->nrtx);
1008 
1009  /*
1010  * Ok, so we need to retransmit. We do this differently
1011  * depending on which state we are in. In ESTABLISHED, we
1012  * call upon the application so that it may prepare the
1013  * data for the retransmit. In SYN_RCVD, we resend the
1014  * SYNACK that we sent earlier and in LAST_ACK we have to
1015  * retransmit our FINACK.
1016  */
1017  UIP_STAT(++uip_stat.tcp.rexmit);
1018  switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
1019  case UIP_SYN_RCVD:
1020  /* In the SYN_RCVD state, we should retransmit our SYNACK. */
1021  goto tcp_send_synack;
1022 
1023 #if UIP_ACTIVE_OPEN
1024  case UIP_SYN_SENT:
1025  /* In the SYN_SENT state, we retransmit out SYN. */
1026  UIP_TCP_BUF->flags = 0;
1027  goto tcp_send_syn;
1028 #endif /* UIP_ACTIVE_OPEN */
1029 
1030  case UIP_ESTABLISHED:
1031  /*
1032  * In the ESTABLISHED state, we call upon the application
1033  * to do the actual retransmit after which we jump into
1034  * the code for sending out the packet (the apprexmit
1035  * label).
1036  */
1037  uip_flags = UIP_REXMIT;
1038  UIP_APPCALL();
1039  goto apprexmit;
1040 
1041  case UIP_FIN_WAIT_1:
1042  case UIP_CLOSING:
1043  case UIP_LAST_ACK:
1044  /* In all these states we should retransmit a FINACK. */
1045  goto tcp_send_finack;
1046  }
1047  }
1048  } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
1049  /*
1050  * If there was no need for a retransmission, we poll the
1051  * application for new data.
1052  */
1053  uip_flags = UIP_POLL;
1054  UIP_APPCALL();
1055  goto appsend;
1056  }
1057  }
1058  goto drop;
1059 #endif /* UIP_TCP */
1060  }
1061 #if UIP_UDP
1062  if(flag == UIP_UDP_TIMER) {
1063  if(uip_udp_conn->lport != 0) {
1064  uip_conn = NULL;
1065  uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN];
1066  uip_len = uip_slen = 0;
1067  uip_flags = UIP_POLL;
1068  UIP_UDP_APPCALL();
1069  goto udp_send;
1070  } else {
1071  goto drop;
1072  }
1073  }
1074 #endif /* UIP_UDP */
1075 
1076 
1077  /* This is where the input processing starts. */
1078  UIP_STAT(++uip_stat.ip.recv);
1079 
1080  /* Start of IP input header processing code. */
1081 
1082  /* Check validity of the IP header. */
1083  if((UIP_IP_BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */
1084  UIP_STAT(++uip_stat.ip.drop);
1085  UIP_STAT(++uip_stat.ip.vhlerr);
1086  UIP_LOG("ipv6: invalid version.");
1087  goto drop;
1088  }
1089  /*
1090  * Check the size of the packet. If the size reported to us in
1091  * uip_len is smaller the size reported in the IP header, we assume
1092  * that the packet has been corrupted in transit. If the size of
1093  * uip_len is larger than the size reported in the IP packet header,
1094  * the packet has been padded and we set uip_len to the correct
1095  * value..
1096  */
1097 
1098  if((UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] <= uip_len) {
1099  uip_len = (UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] + UIP_IPH_LEN;
1100  /*
1101  * The length reported in the IPv6 header is the
1102  * length of the payload that follows the
1103  * header. However, uIP uses the uip_len variable
1104  * for holding the size of the entire packet,
1105  * including the IP header. For IPv4 this is not a
1106  * problem as the length field in the IPv4 header
1107  * contains the length of the entire packet. But
1108  * for IPv6 we need to add the size of the IPv6
1109  * header (40 bytes).
1110  */
1111  } else {
1112  UIP_LOG("ip: packet shorter than reported in IP header.");
1113  goto drop;
1114  }
1115 
1116  PRINTF("IPv6 packet received from ");
1117  PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
1118 #if UIP_UDP
1119  PRINTF(": %u", UIP_HTONS(UIP_UDP_BUF->srcport));
1120 #endif
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  switch(UIP_ICMP_BUF->type) {
1427  case ICMP6_NS:
1428 #if UIP_ND6_SEND_NA
1429  uip_nd6_ns_input();
1430 #else /* UIP_ND6_SEND_NA */
1431  UIP_STAT(++uip_stat.icmp.drop);
1432  uip_len = 0;
1433 #endif /* UIP_ND6_SEND_NA */
1434  break;
1435  case ICMP6_NA:
1436 #if UIP_ND6_SEND_NA
1437  uip_nd6_na_input();
1438 #else /* UIP_ND6_SEND_NA */
1439  UIP_STAT(++uip_stat.icmp.drop);
1440  uip_len = 0;
1441 #endif /* UIP_ND6_SEND_NA */
1442  break;
1443  case ICMP6_RS:
1444 #if UIP_CONF_ROUTER && UIP_ND6_SEND_RA
1445  uip_nd6_rs_input();
1446 #else /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */
1447  UIP_STAT(++uip_stat.icmp.drop);
1448  uip_len = 0;
1449 #endif /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */
1450  break;
1451  case ICMP6_RA:
1452 #if UIP_CONF_ROUTER
1453  UIP_STAT(++uip_stat.icmp.drop);
1454  uip_len = 0;
1455 #else /* UIP_CONF_ROUTER */
1456  uip_nd6_ra_input();
1457 #endif /* UIP_CONF_ROUTER */
1458  break;
1459 #if UIP_CONF_IPV6_RPL
1460  case ICMP6_RPL:
1461  uip_rpl_input();
1462  break;
1463 #endif /* UIP_CONF_IPV6_RPL */
1464  case ICMP6_ECHO_REQUEST:
1466  break;
1467  case ICMP6_ECHO_REPLY:
1468  /** Call echo reply input function. */
1470  PRINTF("Received an icmp6 echo reply\n");
1471  UIP_STAT(++uip_stat.icmp.recv);
1472  uip_len = 0;
1473  break;
1474 #if UIP_CONF_IPV6_ROLL_TM
1475  case ICMP6_ROLL_TM:
1477  uip_len = 0;
1478  break;
1479 #endif
1480  default:
1481  PRINTF("Unknown icmp6 message type %d\n", UIP_ICMP_BUF->type);
1482  UIP_STAT(++uip_stat.icmp.drop);
1483  UIP_STAT(++uip_stat.icmp.typeerr);
1484  UIP_LOG("icmp6: unknown ICMP message.");
1485  uip_len = 0;
1486  break;
1487  }
1488 
1489  if(uip_len > 0) {
1490  goto send;
1491  } else {
1492  goto drop;
1493  }
1494  /* End of IPv6 ICMP processing. */
1495 
1496 
1497 #if UIP_UDP
1498  /* UDP input processing. */
1499  udp_input:
1500 
1501  remove_ext_hdr();
1502 
1503  PRINTF("Receiving UDP packet\n");
1504 
1505  /* UDP processing is really just a hack. We don't do anything to the
1506  UDP/IP headers, but let the UDP application do all the hard
1507  work. If the application sets uip_slen, it has a packet to
1508  send. */
1509 #if UIP_UDP_CHECKSUMS
1510  uip_len = uip_len - UIP_IPUDPH_LEN;
1511  uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN];
1512  /* XXX hack: UDP/IPv6 receivers should drop packets with UDP
1513  checksum 0. Here, we explicitly receive UDP packets with checksum
1514  0. This is to be able to debug code that for one reason or
1515  another miscomputes UDP checksums. The reception of zero UDP
1516  checksums should be turned into a configration option. */
1517  if(UIP_UDP_BUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
1518  UIP_STAT(++uip_stat.udp.drop);
1519  UIP_STAT(++uip_stat.udp.chkerr);
1520  PRINTF("udp: bad checksum 0x%04x 0x%04x\n", UIP_UDP_BUF->udpchksum,
1521  uip_udpchksum());
1522  goto drop;
1523  }
1524 #else /* UIP_UDP_CHECKSUMS */
1525  uip_len = uip_len - UIP_IPUDPH_LEN;
1526 #endif /* UIP_UDP_CHECKSUMS */
1527 
1528  /* Make sure that the UDP destination port number is not zero. */
1529  if(UIP_UDP_BUF->destport == 0) {
1530  PRINTF("udp: zero port.\n");
1531  goto drop;
1532  }
1533 
1534  /* Demultiplex this UDP packet between the UDP "connections". */
1535  for(uip_udp_conn = &uip_udp_conns[0];
1536  uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
1537  ++uip_udp_conn) {
1538  /* If the local UDP port is non-zero, the connection is considered
1539  to be used. If so, the local port number is checked against the
1540  destination port number in the received packet. If the two port
1541  numbers match, the remote port number is checked if the
1542  connection is bound to a remote port. Finally, if the
1543  connection is bound to a remote IP address, the source IP
1544  address of the packet is checked. */
1545  if(uip_udp_conn->lport != 0 &&
1546  UIP_UDP_BUF->destport == uip_udp_conn->lport &&
1547  (uip_udp_conn->rport == 0 ||
1548  UIP_UDP_BUF->srcport == uip_udp_conn->rport) &&
1549  (uip_is_addr_unspecified(&uip_udp_conn->ripaddr) ||
1550  uip_ipaddr_cmp(&UIP_IP_BUF->srcipaddr, &uip_udp_conn->ripaddr))) {
1551  goto udp_found;
1552  }
1553  }
1554  PRINTF("udp: no matching connection found\n");
1555  UIP_STAT(++uip_stat.udp.drop);
1556 
1557 #if UIP_UDP_SEND_UNREACH_NOPORT
1559  goto send;
1560 #else
1561  goto drop;
1562 #endif
1563 
1564  udp_found:
1565  PRINTF("In udp_found\n");
1566  UIP_STAT(++uip_stat.udp.recv);
1567 
1568  uip_conn = NULL;
1569  uip_flags = UIP_NEWDATA;
1570  uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN];
1571  uip_slen = 0;
1572  UIP_UDP_APPCALL();
1573 
1574  udp_send:
1575  PRINTF("In udp_send\n");
1576 
1577  if(uip_slen == 0) {
1578  goto drop;
1579  }
1580  uip_len = uip_slen + UIP_IPUDPH_LEN;
1581 
1582  /* For IPv6, the IP length field does not include the IPv6 IP header
1583  length. */
1584  UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
1585  UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
1586 
1587  UIP_IP_BUF->ttl = uip_udp_conn->ttl;
1588  UIP_IP_BUF->proto = UIP_PROTO_UDP;
1589 
1590  UIP_UDP_BUF->udplen = UIP_HTONS(uip_slen + UIP_UDPH_LEN);
1591  UIP_UDP_BUF->udpchksum = 0;
1592 
1593  UIP_UDP_BUF->srcport = uip_udp_conn->lport;
1594  UIP_UDP_BUF->destport = uip_udp_conn->rport;
1595 
1596  uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_udp_conn->ripaddr);
1597  uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
1598 
1599  uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
1600 
1601 #if UIP_CONF_IPV6_RPL
1602  rpl_insert_header();
1603 #endif /* UIP_CONF_IPV6_RPL */
1604 
1605 #if UIP_UDP_CHECKSUMS
1606  /* Calculate UDP checksum. */
1607  UIP_UDP_BUF->udpchksum = ~(uip_udpchksum());
1608  if(UIP_UDP_BUF->udpchksum == 0) {
1609  UIP_UDP_BUF->udpchksum = 0xffff;
1610  }
1611 #endif /* UIP_UDP_CHECKSUMS */
1612  UIP_STAT(++uip_stat.udp.sent);
1613  goto ip_send_nolen;
1614 #endif /* UIP_UDP */
1615 
1616 #if UIP_TCP
1617  /* TCP input processing. */
1618  tcp_input:
1619 
1620  remove_ext_hdr();
1621 
1622  UIP_STAT(++uip_stat.tcp.recv);
1623  PRINTF("Receiving TCP packet\n");
1624  /* Start of TCP input header processing code. */
1625 
1626  if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
1627  checksum. */
1628  UIP_STAT(++uip_stat.tcp.drop);
1629  UIP_STAT(++uip_stat.tcp.chkerr);
1630  PRINTF("tcp: bad checksum 0x%04x 0x%04x\n", UIP_TCP_BUF->tcpchksum,
1631  uip_tcpchksum());
1632  goto drop;
1633  }
1634 
1635  /* Make sure that the TCP port number is not zero. */
1636  if(UIP_TCP_BUF->destport == 0 || UIP_TCP_BUF->srcport == 0) {
1637  PRINTF("tcp: zero port.");
1638  goto drop;
1639  }
1640 
1641  /* Demultiplex this segment. */
1642  /* First check any active connections. */
1643  for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
1644  ++uip_connr) {
1645  if(uip_connr->tcpstateflags != UIP_CLOSED &&
1646  UIP_TCP_BUF->destport == uip_connr->lport &&
1647  UIP_TCP_BUF->srcport == uip_connr->rport &&
1648  uip_ipaddr_cmp(&UIP_IP_BUF->srcipaddr, &uip_connr->ripaddr)) {
1649  goto found;
1650  }
1651  }
1652 
1653  /* If we didn't find and active connection that expected the packet,
1654  either this packet is an old duplicate, or this is a SYN packet
1655  destined for a connection in LISTEN. If the SYN flag isn't set,
1656  it is an old packet and we send a RST. */
1657  if((UIP_TCP_BUF->flags & TCP_CTL) != TCP_SYN) {
1658  goto reset;
1659  }
1660 
1661  tmp16 = UIP_TCP_BUF->destport;
1662  /* Next, check listening connections. */
1663  for(c = 0; c < UIP_LISTENPORTS; ++c) {
1664  if(tmp16 == uip_listenports[c]) {
1665  goto found_listen;
1666  }
1667  }
1668 
1669  /* No matching connection found, so we send a RST packet. */
1670  UIP_STAT(++uip_stat.tcp.synrst);
1671 
1672  reset:
1673  PRINTF("In reset\n");
1674  /* We do not send resets in response to resets. */
1675  if(UIP_TCP_BUF->flags & TCP_RST) {
1676  goto drop;
1677  }
1678 
1679  UIP_STAT(++uip_stat.tcp.rst);
1680 
1681  UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1682  uip_len = UIP_IPTCPH_LEN;
1683  UIP_TCP_BUF->tcpoffset = 5 << 4;
1684 
1685  /* Flip the seqno and ackno fields in the TCP header. */
1686  c = UIP_TCP_BUF->seqno[3];
1687  UIP_TCP_BUF->seqno[3] = UIP_TCP_BUF->ackno[3];
1688  UIP_TCP_BUF->ackno[3] = c;
1689 
1690  c = UIP_TCP_BUF->seqno[2];
1691  UIP_TCP_BUF->seqno[2] = UIP_TCP_BUF->ackno[2];
1692  UIP_TCP_BUF->ackno[2] = c;
1693 
1694  c = UIP_TCP_BUF->seqno[1];
1695  UIP_TCP_BUF->seqno[1] = UIP_TCP_BUF->ackno[1];
1696  UIP_TCP_BUF->ackno[1] = c;
1697 
1698  c = UIP_TCP_BUF->seqno[0];
1699  UIP_TCP_BUF->seqno[0] = UIP_TCP_BUF->ackno[0];
1700  UIP_TCP_BUF->ackno[0] = c;
1701 
1702  /* We also have to increase the sequence number we are
1703  acknowledging. If the least significant byte overflowed, we need
1704  to propagate the carry to the other bytes as well. */
1705  if(++UIP_TCP_BUF->ackno[3] == 0) {
1706  if(++UIP_TCP_BUF->ackno[2] == 0) {
1707  if(++UIP_TCP_BUF->ackno[1] == 0) {
1708  ++UIP_TCP_BUF->ackno[0];
1709  }
1710  }
1711  }
1712 
1713  /* Swap port numbers. */
1714  tmp16 = UIP_TCP_BUF->srcport;
1715  UIP_TCP_BUF->srcport = UIP_TCP_BUF->destport;
1716  UIP_TCP_BUF->destport = tmp16;
1717 
1718  /* Swap IP addresses. */
1719  uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr);
1720  uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
1721  /* And send out the RST packet! */
1722  goto tcp_send_noconn;
1723 
1724  /* This label will be jumped to if we matched the incoming packet
1725  with a connection in LISTEN. In that case, we should create a new
1726  connection and send a SYNACK in return. */
1727  found_listen:
1728  PRINTF("In found listen\n");
1729  /* First we check if there are any connections avaliable. Unused
1730  connections are kept in the same table as used connections, but
1731  unused ones have the tcpstate set to CLOSED. Also, connections in
1732  TIME_WAIT are kept track of and we'll use the oldest one if no
1733  CLOSED connections are found. Thanks to Eddie C. Dost for a very
1734  nice algorithm for the TIME_WAIT search. */
1735  uip_connr = 0;
1736  for(c = 0; c < UIP_CONNS; ++c) {
1737  if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
1738  uip_connr = &uip_conns[c];
1739  break;
1740  }
1741  if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
1742  if(uip_connr == 0 ||
1743  uip_conns[c].timer > uip_connr->timer) {
1744  uip_connr = &uip_conns[c];
1745  }
1746  }
1747  }
1748 
1749  if(uip_connr == 0) {
1750  /* All connections are used already, we drop packet and hope that
1751  the remote end will retransmit the packet at a time when we
1752  have more spare connections. */
1753  UIP_STAT(++uip_stat.tcp.syndrop);
1754  UIP_LOG("tcp: found no unused connections.");
1755  goto drop;
1756  }
1757  uip_conn = uip_connr;
1758 
1759  /* Fill in the necessary fields for the new connection. */
1760  uip_connr->rto = uip_connr->timer = UIP_RTO;
1761  uip_connr->sa = 0;
1762  uip_connr->sv = 4;
1763  uip_connr->nrtx = 0;
1764  uip_connr->lport = UIP_TCP_BUF->destport;
1765  uip_connr->rport = UIP_TCP_BUF->srcport;
1766  uip_ipaddr_copy(&uip_connr->ripaddr, &UIP_IP_BUF->srcipaddr);
1767  uip_connr->tcpstateflags = UIP_SYN_RCVD;
1768 
1769  uip_connr->snd_nxt[0] = iss[0];
1770  uip_connr->snd_nxt[1] = iss[1];
1771  uip_connr->snd_nxt[2] = iss[2];
1772  uip_connr->snd_nxt[3] = iss[3];
1773  uip_connr->len = 1;
1774 
1775  /* rcv_nxt should be the seqno from the incoming packet + 1. */
1776  uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
1777  uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
1778  uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
1779  uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
1780  uip_add_rcv_nxt(1);
1781 
1782  /* Parse the TCP MSS option, if present. */
1783  if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) {
1784  for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
1785  opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
1786  if(opt == TCP_OPT_END) {
1787  /* End of options. */
1788  break;
1789  } else if(opt == TCP_OPT_NOOP) {
1790  ++c;
1791  /* NOP option. */
1792  } else if(opt == TCP_OPT_MSS &&
1793  uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
1794  /* An MSS option with the right option length. */
1795  tmp16 = ((uint16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
1796  (uint16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
1797  uip_connr->initialmss = uip_connr->mss =
1798  tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
1799 
1800  /* And we are done processing options. */
1801  break;
1802  } else {
1803  /* All other options have a length field, so that we easily
1804  can skip past them. */
1805  if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
1806  /* If the length field is zero, the options are malformed
1807  and we don't process them further. */
1808  break;
1809  }
1810  c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
1811  }
1812  }
1813  }
1814 
1815  /* Our response will be a SYNACK. */
1816 #if UIP_ACTIVE_OPEN
1817  tcp_send_synack:
1818  UIP_TCP_BUF->flags = TCP_ACK;
1819 
1820  tcp_send_syn:
1821  UIP_TCP_BUF->flags |= TCP_SYN;
1822 #else /* UIP_ACTIVE_OPEN */
1823  tcp_send_synack:
1824  UIP_TCP_BUF->flags = TCP_SYN | TCP_ACK;
1825 #endif /* UIP_ACTIVE_OPEN */
1826 
1827  /* We send out the TCP Maximum Segment Size option with our
1828  SYNACK. */
1829  UIP_TCP_BUF->optdata[0] = TCP_OPT_MSS;
1830  UIP_TCP_BUF->optdata[1] = TCP_OPT_MSS_LEN;
1831  UIP_TCP_BUF->optdata[2] = (UIP_TCP_MSS) / 256;
1832  UIP_TCP_BUF->optdata[3] = (UIP_TCP_MSS) & 255;
1833  uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
1834  UIP_TCP_BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
1835  goto tcp_send;
1836 
1837  /* This label will be jumped to if we found an active connection. */
1838  found:
1839  PRINTF("In found\n");
1840  uip_conn = uip_connr;
1841  uip_flags = 0;
1842  /* We do a very naive form of TCP reset processing; we just accept
1843  any RST and kill our connection. We should in fact check if the
1844  sequence number of this reset is wihtin our advertised window
1845  before we accept the reset. */
1846  if(UIP_TCP_BUF->flags & TCP_RST) {
1847  uip_connr->tcpstateflags = UIP_CLOSED;
1848  UIP_LOG("tcp: got reset, aborting connection.");
1849  uip_flags = UIP_ABORT;
1850  UIP_APPCALL();
1851  goto drop;
1852  }
1853  /* Calculate the length of the data, if the application has sent
1854  any data to us. */
1855  c = (UIP_TCP_BUF->tcpoffset >> 4) << 2;
1856  /* uip_len will contain the length of the actual TCP data. This is
1857  calculated by subtracing the length of the TCP header (in
1858  c) and the length of the IP header (20 bytes). */
1859  uip_len = uip_len - c - UIP_IPH_LEN;
1860 
1861  /* First, check if the sequence number of the incoming packet is
1862  what we're expecting next. If not, we send out an ACK with the
1863  correct numbers in, unless we are in the SYN_RCVD state and
1864  receive a SYN, in which case we should retransmit our SYNACK
1865  (which is done futher down). */
1866  if(!((((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
1867  ((UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
1868  (((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) &&
1869  ((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN)))) {
1870  if((uip_len > 0 || ((UIP_TCP_BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
1871  (UIP_TCP_BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
1872  UIP_TCP_BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
1873  UIP_TCP_BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
1874  UIP_TCP_BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
1875 
1876  if((UIP_TCP_BUF->flags & TCP_SYN)) {
1877  if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) {
1878  goto tcp_send_synack;
1879  } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
1880  goto tcp_send_syn;
1881  }
1882  }
1883  goto tcp_send_ack;
1884  }
1885  }
1886 
1887  /* Next, check if the incoming segment acknowledges any outstanding
1888  data. If so, we update the sequence number, reset the length of
1889  the outstanding data, calculate RTT estimations, and reset the
1890  retransmission timer. */
1891  if((UIP_TCP_BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
1892  uip_add32(uip_connr->snd_nxt, uip_connr->len);
1893 
1894  if(UIP_TCP_BUF->ackno[0] == uip_acc32[0] &&
1895  UIP_TCP_BUF->ackno[1] == uip_acc32[1] &&
1896  UIP_TCP_BUF->ackno[2] == uip_acc32[2] &&
1897  UIP_TCP_BUF->ackno[3] == uip_acc32[3]) {
1898  /* Update sequence number. */
1899  uip_connr->snd_nxt[0] = uip_acc32[0];
1900  uip_connr->snd_nxt[1] = uip_acc32[1];
1901  uip_connr->snd_nxt[2] = uip_acc32[2];
1902  uip_connr->snd_nxt[3] = uip_acc32[3];
1903 
1904  /* Do RTT estimation, unless we have done retransmissions. */
1905  if(uip_connr->nrtx == 0) {
1906  signed char m;
1907  m = uip_connr->rto - uip_connr->timer;
1908  /* This is taken directly from VJs original code in his paper */
1909  m = m - (uip_connr->sa >> 3);
1910  uip_connr->sa += m;
1911  if(m < 0) {
1912  m = -m;
1913  }
1914  m = m - (uip_connr->sv >> 2);
1915  uip_connr->sv += m;
1916  uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
1917 
1918  }
1919  /* Set the acknowledged flag. */
1920  uip_flags = UIP_ACKDATA;
1921  /* Reset the retransmission timer. */
1922  uip_connr->timer = uip_connr->rto;
1923 
1924  /* Reset length of outstanding data. */
1925  uip_connr->len = 0;
1926  }
1927 
1928  }
1929 
1930  /* Do different things depending on in what state the connection is. */
1931  switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
1932  /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
1933  implemented, since we force the application to close when the
1934  peer sends a FIN (hence the application goes directly from
1935  ESTABLISHED to LAST_ACK). */
1936  case UIP_SYN_RCVD:
1937  /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
1938  we are waiting for an ACK that acknowledges the data we sent
1939  out the last time. Therefore, we want to have the UIP_ACKDATA
1940  flag set. If so, we enter the ESTABLISHED state. */
1941  if(uip_flags & UIP_ACKDATA) {
1942  uip_connr->tcpstateflags = UIP_ESTABLISHED;
1943  uip_flags = UIP_CONNECTED;
1944  uip_connr->len = 0;
1945  if(uip_len > 0) {
1946  uip_flags |= UIP_NEWDATA;
1947  uip_add_rcv_nxt(uip_len);
1948  }
1949  uip_slen = 0;
1950  UIP_APPCALL();
1951  goto appsend;
1952  }
1953  /* We need to retransmit the SYNACK */
1954  if((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN) {
1955  goto tcp_send_synack;
1956  }
1957  goto drop;
1958 #if UIP_ACTIVE_OPEN
1959  case UIP_SYN_SENT:
1960  /* In SYN_SENT, we wait for a SYNACK that is sent in response to
1961  our SYN. The rcv_nxt is set to sequence number in the SYNACK
1962  plus one, and we send an ACK. We move into the ESTABLISHED
1963  state. */
1964  if((uip_flags & UIP_ACKDATA) &&
1965  (UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
1966 
1967  /* Parse the TCP MSS option, if present. */
1968  if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) {
1969  for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
1970  opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
1971  if(opt == TCP_OPT_END) {
1972  /* End of options. */
1973  break;
1974  } else if(opt == TCP_OPT_NOOP) {
1975  ++c;
1976  /* NOP option. */
1977  } else if(opt == TCP_OPT_MSS &&
1978  uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
1979  /* An MSS option with the right option length. */
1980  tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
1981  uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
1982  uip_connr->initialmss =
1983  uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
1984 
1985  /* And we are done processing options. */
1986  break;
1987  } else {
1988  /* All other options have a length field, so that we easily
1989  can skip past them. */
1990  if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
1991  /* If the length field is zero, the options are malformed
1992  and we don't process them further. */
1993  break;
1994  }
1995  c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
1996  }
1997  }
1998  }
1999  uip_connr->tcpstateflags = UIP_ESTABLISHED;
2000  uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
2001  uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
2002  uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
2003  uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
2004  uip_add_rcv_nxt(1);
2005  uip_flags = UIP_CONNECTED | UIP_NEWDATA;
2006  uip_connr->len = 0;
2007  uip_len = 0;
2008  uip_slen = 0;
2009  UIP_APPCALL();
2010  goto appsend;
2011  }
2012  /* Inform the application that the connection failed */
2013  uip_flags = UIP_ABORT;
2014  UIP_APPCALL();
2015  /* The connection is closed after we send the RST */
2016  uip_conn->tcpstateflags = UIP_CLOSED;
2017  goto reset;
2018 #endif /* UIP_ACTIVE_OPEN */
2019 
2020  case UIP_ESTABLISHED:
2021  /* In the ESTABLISHED state, we call upon the application to feed
2022  data into the uip_buf. If the UIP_ACKDATA flag is set, the
2023  application should put new data into the buffer, otherwise we are
2024  retransmitting an old segment, and the application should put that
2025  data into the buffer.
2026 
2027  If the incoming packet is a FIN, we should close the connection on
2028  this side as well, and we send out a FIN and enter the LAST_ACK
2029  state. We require that there is no outstanding data; otherwise the
2030  sequence numbers will be screwed up. */
2031 
2032  if(UIP_TCP_BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
2033  if(uip_outstanding(uip_connr)) {
2034  goto drop;
2035  }
2036  uip_add_rcv_nxt(1 + uip_len);
2037  uip_flags |= UIP_CLOSE;
2038  if(uip_len > 0) {
2039  uip_flags |= UIP_NEWDATA;
2040  }
2041  UIP_APPCALL();
2042  uip_connr->len = 1;
2043  uip_connr->tcpstateflags = UIP_LAST_ACK;
2044  uip_connr->nrtx = 0;
2045  tcp_send_finack:
2046  UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2047  goto tcp_send_nodata;
2048  }
2049 
2050  /* Check the URG flag. If this is set, the segment carries urgent
2051  data that we must pass to the application. */
2052  if((UIP_TCP_BUF->flags & TCP_URG) != 0) {
2053 #if UIP_URGDATA > 0
2054  uip_urglen = (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1];
2055  if(uip_urglen > uip_len) {
2056  /* There is more urgent data in the next segment to come. */
2057  uip_urglen = uip_len;
2058  }
2059  uip_add_rcv_nxt(uip_urglen);
2060  uip_len -= uip_urglen;
2061  uip_urgdata = uip_appdata;
2062  uip_appdata += uip_urglen;
2063  } else {
2064  uip_urglen = 0;
2065 #else /* UIP_URGDATA > 0 */
2066  uip_appdata = ((char *)uip_appdata) + ((UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]);
2067  uip_len -= (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1];
2068 #endif /* UIP_URGDATA > 0 */
2069  }
2070 
2071  /* If uip_len > 0 we have TCP data in the packet, and we flag this
2072  by setting the UIP_NEWDATA flag and update the sequence number
2073  we acknowledge. If the application has stopped the dataflow
2074  using uip_stop(), we must not accept any data packets from the
2075  remote host. */
2076  if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
2077  uip_flags |= UIP_NEWDATA;
2078  uip_add_rcv_nxt(uip_len);
2079  }
2080 
2081  /* Check if the available buffer space advertised by the other end
2082  is smaller than the initial MSS for this connection. If so, we
2083  set the current MSS to the window size to ensure that the
2084  application does not send more data than the other end can
2085  handle.
2086 
2087  If the remote host advertises a zero window, we set the MSS to
2088  the initial MSS so that the application will send an entire MSS
2089  of data. This data will not be acknowledged by the receiver,
2090  and the application will retransmit it. This is called the
2091  "persistent timer" and uses the retransmission mechanim.
2092  */
2093  tmp16 = ((uint16_t)UIP_TCP_BUF->wnd[0] << 8) + (uint16_t)UIP_TCP_BUF->wnd[1];
2094  if(tmp16 > uip_connr->initialmss ||
2095  tmp16 == 0) {
2096  tmp16 = uip_connr->initialmss;
2097  }
2098  uip_connr->mss = tmp16;
2099 
2100  /* If this packet constitutes an ACK for outstanding data (flagged
2101  by the UIP_ACKDATA flag, we should call the application since it
2102  might want to send more data. If the incoming packet had data
2103  from the peer (as flagged by the UIP_NEWDATA flag), the
2104  application must also be notified.
2105 
2106  When the application is called, the global variable uip_len
2107  contains the length of the incoming data. The application can
2108  access the incoming data through the global pointer
2109  uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN
2110  bytes into the uip_buf array.
2111 
2112  If the application wishes to send any data, this data should be
2113  put into the uip_appdata and the length of the data should be
2114  put into uip_len. If the application don't have any data to
2115  send, uip_len must be set to 0. */
2116  if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
2117  uip_slen = 0;
2118  UIP_APPCALL();
2119 
2120  appsend:
2121 
2122  if(uip_flags & UIP_ABORT) {
2123  uip_slen = 0;
2124  uip_connr->tcpstateflags = UIP_CLOSED;
2125  UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
2126  goto tcp_send_nodata;
2127  }
2128 
2129  if(uip_flags & UIP_CLOSE) {
2130  uip_slen = 0;
2131  uip_connr->len = 1;
2132  uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
2133  uip_connr->nrtx = 0;
2134  UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2135  goto tcp_send_nodata;
2136  }
2137 
2138  /* If uip_slen > 0, the application has data to be sent. */
2139  if(uip_slen > 0) {
2140 
2141  /* If the connection has acknowledged data, the contents of
2142  the ->len variable should be discarded. */
2143  if((uip_flags & UIP_ACKDATA) != 0) {
2144  uip_connr->len = 0;
2145  }
2146 
2147  /* If the ->len variable is non-zero the connection has
2148  already data in transit and cannot send anymore right
2149  now. */
2150  if(uip_connr->len == 0) {
2151 
2152  /* The application cannot send more than what is allowed by
2153  the mss (the minumum of the MSS and the available
2154  window). */
2155  if(uip_slen > uip_connr->mss) {
2156  uip_slen = uip_connr->mss;
2157  }
2158 
2159  /* Remember how much data we send out now so that we know
2160  when everything has been acknowledged. */
2161  uip_connr->len = uip_slen;
2162  } else {
2163 
2164  /* If the application already had unacknowledged data, we
2165  make sure that the application does not send (i.e.,
2166  retransmit) out more than it previously sent out. */
2167  uip_slen = uip_connr->len;
2168  }
2169  }
2170  uip_connr->nrtx = 0;
2171  apprexmit:
2172  uip_appdata = uip_sappdata;
2173 
2174  /* If the application has data to be sent, or if the incoming
2175  packet had new data in it, we must send out a packet. */
2176  if(uip_slen > 0 && uip_connr->len > 0) {
2177  /* Add the length of the IP and TCP headers. */
2178  uip_len = uip_connr->len + UIP_TCPIP_HLEN;
2179  /* We always set the ACK flag in response packets. */
2180  UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH;
2181  /* Send the packet. */
2182  goto tcp_send_noopts;
2183  }
2184  /* If there is no data to send, just send out a pure ACK if
2185  there is newdata. */
2186  if(uip_flags & UIP_NEWDATA) {
2187  uip_len = UIP_TCPIP_HLEN;
2188  UIP_TCP_BUF->flags = TCP_ACK;
2189  goto tcp_send_noopts;
2190  }
2191  }
2192  goto drop;
2193  case UIP_LAST_ACK:
2194  /* We can close this connection if the peer has acknowledged our
2195  FIN. This is indicated by the UIP_ACKDATA flag. */
2196  if(uip_flags & UIP_ACKDATA) {
2197  uip_connr->tcpstateflags = UIP_CLOSED;
2198  uip_flags = UIP_CLOSE;
2199  UIP_APPCALL();
2200  }
2201  break;
2202 
2203  case UIP_FIN_WAIT_1:
2204  /* The application has closed the connection, but the remote host
2205  hasn't closed its end yet. Thus we do nothing but wait for a
2206  FIN from the other side. */
2207  if(uip_len > 0) {
2208  uip_add_rcv_nxt(uip_len);
2209  }
2210  if(UIP_TCP_BUF->flags & TCP_FIN) {
2211  if(uip_flags & UIP_ACKDATA) {
2212  uip_connr->tcpstateflags = UIP_TIME_WAIT;
2213  uip_connr->timer = 0;
2214  uip_connr->len = 0;
2215  } else {
2216  uip_connr->tcpstateflags = UIP_CLOSING;
2217  }
2218  uip_add_rcv_nxt(1);
2219  uip_flags = UIP_CLOSE;
2220  UIP_APPCALL();
2221  goto tcp_send_ack;
2222  } else if(uip_flags & UIP_ACKDATA) {
2223  uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
2224  uip_connr->len = 0;
2225  goto drop;
2226  }
2227  if(uip_len > 0) {
2228  goto tcp_send_ack;
2229  }
2230  goto drop;
2231 
2232  case UIP_FIN_WAIT_2:
2233  if(uip_len > 0) {
2234  uip_add_rcv_nxt(uip_len);
2235  }
2236  if(UIP_TCP_BUF->flags & TCP_FIN) {
2237  uip_connr->tcpstateflags = UIP_TIME_WAIT;
2238  uip_connr->timer = 0;
2239  uip_add_rcv_nxt(1);
2240  uip_flags = UIP_CLOSE;
2241  UIP_APPCALL();
2242  goto tcp_send_ack;
2243  }
2244  if(uip_len > 0) {
2245  goto tcp_send_ack;
2246  }
2247  goto drop;
2248 
2249  case UIP_TIME_WAIT:
2250  goto tcp_send_ack;
2251 
2252  case UIP_CLOSING:
2253  if(uip_flags & UIP_ACKDATA) {
2254  uip_connr->tcpstateflags = UIP_TIME_WAIT;
2255  uip_connr->timer = 0;
2256  }
2257  }
2258  goto drop;
2259 
2260  /* We jump here when we are ready to send the packet, and just want
2261  to set the appropriate TCP sequence numbers in the TCP header. */
2262  tcp_send_ack:
2263  UIP_TCP_BUF->flags = TCP_ACK;
2264 
2265  tcp_send_nodata:
2266  uip_len = UIP_IPTCPH_LEN;
2267 
2268  tcp_send_noopts:
2269  UIP_TCP_BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
2270 
2271  /* We're done with the input processing. We are now ready to send a
2272  reply. Our job is to fill in all the fields of the TCP and IP
2273  headers before calculating the checksum and finally send the
2274  packet. */
2275  tcp_send:
2276  PRINTF("In tcp_send\n");
2277 
2278  UIP_TCP_BUF->ackno[0] = uip_connr->rcv_nxt[0];
2279  UIP_TCP_BUF->ackno[1] = uip_connr->rcv_nxt[1];
2280  UIP_TCP_BUF->ackno[2] = uip_connr->rcv_nxt[2];
2281  UIP_TCP_BUF->ackno[3] = uip_connr->rcv_nxt[3];
2282 
2283  UIP_TCP_BUF->seqno[0] = uip_connr->snd_nxt[0];
2284  UIP_TCP_BUF->seqno[1] = uip_connr->snd_nxt[1];
2285  UIP_TCP_BUF->seqno[2] = uip_connr->snd_nxt[2];
2286  UIP_TCP_BUF->seqno[3] = uip_connr->snd_nxt[3];
2287 
2288  UIP_IP_BUF->proto = UIP_PROTO_TCP;
2289 
2290  UIP_TCP_BUF->srcport = uip_connr->lport;
2291  UIP_TCP_BUF->destport = uip_connr->rport;
2292 
2293  uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_connr->ripaddr);
2294  uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
2295  PRINTF("Sending TCP packet to ");
2296  PRINT6ADDR(&UIP_IP_BUF->destipaddr);
2297  PRINTF(" from ");
2298  PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
2299  PRINTF("\n");
2300 
2301  if(uip_connr->tcpstateflags & UIP_STOPPED) {
2302  /* If the connection has issued uip_stop(), we advertise a zero
2303  window so that the remote host will stop sending data. */
2304  UIP_TCP_BUF->wnd[0] = UIP_TCP_BUF->wnd[1] = 0;
2305  } else {
2306  UIP_TCP_BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
2307  UIP_TCP_BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
2308  }
2309 
2310  tcp_send_noconn:
2311  UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit;
2312  UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
2313  UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
2314 
2315  UIP_TCP_BUF->urgp[0] = UIP_TCP_BUF->urgp[1] = 0;
2316 
2317  /* Calculate TCP checksum. */
2318  UIP_TCP_BUF->tcpchksum = 0;
2319  UIP_TCP_BUF->tcpchksum = ~(uip_tcpchksum());
2320  UIP_STAT(++uip_stat.tcp.sent);
2321 
2322 #endif /* UIP_TCP */
2323 #if UIP_UDP
2324  ip_send_nolen:
2325 #endif
2326  UIP_IP_BUF->vtc = 0x60;
2327  UIP_IP_BUF->tcflow = 0x00;
2328  UIP_IP_BUF->flow = 0x00;
2329  send:
2330  PRINTF("Sending packet with length %d (%d)\n", uip_len,
2331  (UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]);
2332 
2333  UIP_STAT(++uip_stat.ip.sent);
2334  /* Return and let the caller do the actual transmission. */
2335  uip_flags = 0;
2336  return;
2337 
2338  drop:
2339  uip_len = 0;
2340  uip_ext_len = 0;
2341  uip_ext_bitmap = 0;
2342  uip_flags = 0;
2343  return;
2344 }
2345 /*---------------------------------------------------------------------------*/
2346 uint16_t
2347 uip_htons(uint16_t val)
2348 {
2349  return UIP_HTONS(val);
2350 }
2351 
2352 uint32_t
2353 uip_htonl(uint32_t val)
2354 {
2355  return UIP_HTONL(val);
2356 }
2357 /*---------------------------------------------------------------------------*/
2358 void
2359 uip_send(const void *data, int len)
2360 {
2361  int copylen;
2362 #define MIN(a,b) ((a) < (b)? (a): (b))
2363 
2364  if(uip_sappdata != NULL) {
2365  copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN -
2366  (int)((char *)uip_sappdata -
2367  (char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]));
2368  } else {
2369  copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN);
2370  }
2371  if(copylen > 0) {
2372  uip_slen = copylen;
2373  if(data != uip_sappdata) {
2374  if(uip_sappdata == NULL) {
2375  memcpy((char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN],
2376  (data), uip_slen);
2377  } else {
2378  memcpy(uip_sappdata, (data), uip_slen);
2379  }
2380  }
2381  }
2382  }
2383 /*---------------------------------------------------------------------------*/
2384 /** @} */
2385 #endif /* UIP_CONF_IPV6 */