Contiki-NG
tcpip.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004, Swedish Institute of Computer Science.
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. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  */
31 
32 /**
33  * \file
34  * Core of the TCP/IP stack, handles input/output/routing
35  *
36  * \author Adam Dunkels <adam@sics.se>\author
37  * \author Mathilde Durvy <mdurvy@cisco.com> (IPv6 related code)
38  * \author Julien Abeille <jabeille@cisco.com> (IPv6 related code)
39  */
40 
41 #include "contiki.h"
42 #include "contiki-net.h"
43 #include "net/ipv6/uip-packetqueue.h"
44 
45 #include "net/ipv6/uip-nd6.h"
46 #include "net/ipv6/uip-ds6.h"
47 #include "net/ipv6/uip-ds6-nbr.h"
48 #include "net/linkaddr.h"
49 #include "net/routing/routing.h"
50 
51 #include <string.h>
52 
53 /* Log configuration */
54 #include "sys/log.h"
55 #define LOG_MODULE "TCP/IP"
56 #define LOG_LEVEL LOG_LEVEL_TCPIP
57 
58 #ifdef UIP_FALLBACK_INTERFACE
59 extern struct uip_fallback_interface UIP_FALLBACK_INTERFACE;
60 #endif
61 
62 process_event_t tcpip_event;
63 #if UIP_CONF_ICMP6
64 process_event_t tcpip_icmp6_event;
65 #endif /* UIP_CONF_ICMP6 */
66 
67 /* Periodic check of active connections. */
68 static struct etimer periodic;
69 
70 #if UIP_CONF_IPV6_REASSEMBLY
71 /* Timer for reassembly. */
72 extern struct etimer uip_reass_timer;
73 #endif
74 
75 #if UIP_TCP
76 /**
77  * \internal Structure for holding a TCP port and a process ID.
78  */
79 struct listenport {
80  uint16_t port;
81  struct process *p;
82 };
83 
84 static struct internal_state {
85  struct listenport listenports[UIP_LISTENPORTS];
86  struct process *p;
87 } s;
88 #endif
89 
90 enum {
91  TCP_POLL,
92  UDP_POLL,
93  PACKET_INPUT
94 };
95 
96 /*---------------------------------------------------------------------------*/
97 static void
98 init_appstate(uip_tcp_appstate_t *as, void *state)
99 {
100  as->p = PROCESS_CURRENT();
101  as->state = state;
102 }
103 /*---------------------------------------------------------------------------*/
104 
105 uint8_t
106 tcpip_output(const uip_lladdr_t *a)
107 {
108  int ret;
109 
110  /* Tag Traffic Class if we are using TC for variable retrans */
111 #if UIP_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS
112  if(uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS) !=
114  LOG_INFO("Tagging TC with retrans: %d\n", uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
115  /* Encapsulate the MAC transmission limit in the Traffic Class field */
116  UIP_IP_BUF->vtc = 0x60 | (UIP_TC_MAC_TRANSMISSION_COUNTER_BIT >> 4);
117  UIP_IP_BUF->tcflow =
118  uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS) << 4;
119  }
120 #endif
121 
122  if(netstack_process_ip_callback(NETSTACK_IP_OUTPUT, (const linkaddr_t *)a) ==
123  NETSTACK_IP_PROCESS) {
124  ret = NETSTACK_NETWORK.output((const linkaddr_t *) a);
125  return ret;
126  } else {
127  /* Ok, ignore and drop... */
128  uipbuf_clear();
129  return 0;
130  }
131 }
132 
133 PROCESS(tcpip_process, "TCP/IP stack");
134 
135 /*---------------------------------------------------------------------------*/
136 #if UIP_TCP
137 static void
138 start_periodic_tcp_timer(void)
139 {
140  if(etimer_expired(&periodic)) {
141  etimer_restart(&periodic);
142  }
143 }
144 #endif /* UIP_TCP */
145 /*---------------------------------------------------------------------------*/
146 static void
147 check_for_tcp_syn(void)
148 {
149 #if UIP_TCP
150  /* This is a hack that is needed to start the periodic TCP timer if
151  an incoming packet contains a SYN: since uIP does not inform the
152  application if a SYN arrives, we have no other way of starting
153  this timer. This function is called for every incoming IP packet
154  to check for such SYNs. */
155 #define TCP_SYN 0x02
156  if(UIP_IP_BUF->proto == UIP_PROTO_TCP &&
157  (UIP_TCP_BUF->flags & TCP_SYN) == TCP_SYN) {
158  start_periodic_tcp_timer();
159  }
160 #endif /* UIP_TCP */
161 }
162 /*---------------------------------------------------------------------------*/
163 static void
164 packet_input(void)
165 {
166  if(uip_len > 0) {
167  LOG_INFO("input: received %u bytes\n", uip_len);
168 
169  check_for_tcp_syn();
170 
171 #if UIP_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS
172  {
173  uint8_t traffic_class = (UIP_IP_BUF->vtc << 4) | (UIP_IP_BUF->tcflow >> 4);
174  if(traffic_class & UIP_TC_MAC_TRANSMISSION_COUNTER_BIT) {
175  uint8_t max_mac_transmissions = traffic_class & UIP_TC_MAC_TRANSMISSION_COUNTER_MASK;
176  uipbuf_set_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, max_mac_transmissions);
177  LOG_INFO("Received packet tagged with TC retrans: %d (%x)",
178  max_mac_transmissions, traffic_class);
179  }
180  }
181 #endif /* UIP_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS */
182 
183  uip_input();
184  if(uip_len > 0) {
186  }
187  }
188 }
189 /*---------------------------------------------------------------------------*/
190 #if UIP_TCP
191 #if UIP_ACTIVE_OPEN
192 struct uip_conn *
193 tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
194 {
195  struct uip_conn *c;
196 
197  c = uip_connect(ripaddr, port);
198  if(c == NULL) {
199  return NULL;
200  }
201 
202  init_appstate(&c->appstate, appstate);
203 
204  tcpip_poll_tcp(c);
205 
206  return c;
207 }
208 #endif /* UIP_ACTIVE_OPEN */
209 /*---------------------------------------------------------------------------*/
210 void
211 tcp_unlisten(uint16_t port)
212 {
213  unsigned char i;
214  struct listenport *l;
215 
216  l = s.listenports;
217  for(i = 0; i < UIP_LISTENPORTS; ++i) {
218  if(l->port == port &&
219  l->p == PROCESS_CURRENT()) {
220  l->port = 0;
221  uip_unlisten(port);
222  break;
223  }
224  ++l;
225  }
226 }
227 /*---------------------------------------------------------------------------*/
228 void
229 tcp_listen(uint16_t port)
230 {
231  unsigned char i;
232  struct listenport *l;
233 
234  l = s.listenports;
235  for(i = 0; i < UIP_LISTENPORTS; ++i) {
236  if(l->port == 0) {
237  l->port = port;
238  l->p = PROCESS_CURRENT();
239  uip_listen(port);
240  break;
241  }
242  ++l;
243  }
244 }
245 /*---------------------------------------------------------------------------*/
246 void
247 tcp_attach(struct uip_conn *conn, void *appstate)
248 {
249  init_appstate(&conn->appstate, appstate);
250 }
251 #endif /* UIP_TCP */
252 /*---------------------------------------------------------------------------*/
253 #if UIP_UDP
254 void
255 udp_attach(struct uip_udp_conn *conn, void *appstate)
256 {
257  init_appstate(&conn->appstate, appstate);
258 }
259 /*---------------------------------------------------------------------------*/
260 struct uip_udp_conn *
261 udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
262 {
263  struct uip_udp_conn *c = uip_udp_new(ripaddr, port);
264 
265  if(c == NULL) {
266  return NULL;
267  }
268 
269  init_appstate(&c->appstate, appstate);
270 
271  return c;
272 }
273 /*---------------------------------------------------------------------------*/
274 struct uip_udp_conn *
275 udp_broadcast_new(uint16_t port, void *appstate)
276 {
277  uip_ipaddr_t addr;
278  struct uip_udp_conn *conn;
279 
281 
282  conn = udp_new(&addr, port, appstate);
283  if(conn != NULL) {
284  udp_bind(conn, port);
285  }
286  return conn;
287 }
288 #endif /* UIP_UDP */
289 /*---------------------------------------------------------------------------*/
290 #if UIP_CONF_ICMP6
291 uint8_t
293  if(uip_icmp6_conns.appstate.p == PROCESS_NONE) {
294  init_appstate(&uip_icmp6_conns.appstate, appstate);
295  return 0;
296  }
297  return 1;
298 }
299 
300 void
301 tcpip_icmp6_call(uint8_t type)
302 {
303  if(uip_icmp6_conns.appstate.p != PROCESS_NONE) {
304  /* XXX: This is a hack that needs to be updated. Passing a pointer (&type)
305  like this only works with process_post_synch. */
307  }
308  return;
309 }
310 #endif /* UIP_CONF_ICMP6 */
311 /*---------------------------------------------------------------------------*/
312 static void
313 eventhandler(process_event_t ev, process_data_t data)
314 {
315 #if UIP_TCP
316  unsigned char i;
317  register struct listenport *l;
318 #endif /*UIP_TCP*/
319  struct process *p;
320 
321  switch(ev) {
322  case PROCESS_EVENT_EXITED:
323  /* This is the event we get if a process has exited. We go through
324  the TCP/IP tables to see if this process had any open
325  connections or listening TCP ports. If so, we'll close those
326  connections. */
327 
328  p = (struct process *)data;
329 #if UIP_TCP
330  l = s.listenports;
331  for(i = 0; i < UIP_LISTENPORTS; ++i) {
332  if(l->p == p) {
333  uip_unlisten(l->port);
334  l->port = 0;
335  l->p = PROCESS_NONE;
336  }
337  ++l;
338  }
339 
340  {
341  struct uip_conn *cptr;
342 
343  for(cptr = &uip_conns[0]; cptr < &uip_conns[UIP_TCP_CONNS]; ++cptr) {
344  if(cptr->appstate.p == p) {
345  cptr->appstate.p = PROCESS_NONE;
346  cptr->tcpstateflags = UIP_CLOSED;
347  }
348  }
349  }
350 #endif /* UIP_TCP */
351 #if UIP_UDP
352  {
353  struct uip_udp_conn *cptr;
354 
355  for(cptr = &uip_udp_conns[0];
356  cptr < &uip_udp_conns[UIP_UDP_CONNS]; ++cptr) {
357  if(cptr->appstate.p == p) {
358  cptr->lport = 0;
359  }
360  }
361  }
362 #endif /* UIP_UDP */
363  break;
364 
365  case PROCESS_EVENT_TIMER:
366  /* We get this event if one of our timers have expired. */
367  {
368  /* Check the clock so see if we should call the periodic uIP
369  processing. */
370  if(data == &periodic &&
371  etimer_expired(&periodic)) {
372 #if UIP_TCP
373  for(i = 0; i < UIP_TCP_CONNS; ++i) {
374  if(uip_conn_active(i)) {
375  /* Only restart the timer if there are active
376  connections. */
377  etimer_restart(&periodic);
378  uip_periodic(i);
380  }
381  }
382 #endif /* UIP_TCP */
383  }
384 
385 #if UIP_CONF_IPV6_REASSEMBLY
386  /*
387  * check the timer for reassembly
388  */
389  if(data == &uip_reass_timer &&
391  uip_reass_over();
393  }
394 #endif /* UIP_CONF_IPV6_REASSEMBLY */
395  /*
396  * check the different timers for neighbor discovery and
397  * stateless autoconfiguration
398  */
399  /*if(data == &uip_ds6_timer_periodic &&
400  etimer_expired(&uip_ds6_timer_periodic)) {
401  uip_ds6_periodic();
402  tcpip_ipv6_output();
403  }*/
404 #if !UIP_CONF_ROUTER
405  if(data == &uip_ds6_timer_rs &&
407  uip_ds6_send_rs();
409  }
410 #endif /* !UIP_CONF_ROUTER */
411  if(data == &uip_ds6_timer_periodic &&
415  }
416  }
417  break;
418 
419 #if UIP_TCP
420  case TCP_POLL:
421  if(data != NULL) {
422  uip_poll_conn(data);
424  /* Start the periodic polling, if it isn't already active. */
425  start_periodic_tcp_timer();
426  }
427  break;
428 #endif /* UIP_TCP */
429 #if UIP_UDP
430  case UDP_POLL:
431  if(data != NULL) {
432  uip_udp_periodic_conn(data);
434  }
435  break;
436 #endif /* UIP_UDP */
437 
438  case PACKET_INPUT:
439  packet_input();
440  break;
441  };
442 }
443 /*---------------------------------------------------------------------------*/
444 void
446 {
447  if(netstack_process_ip_callback(NETSTACK_IP_INPUT, NULL) ==
448  NETSTACK_IP_PROCESS) {
449  process_post_synch(&tcpip_process, PACKET_INPUT, NULL);
450  } /* else - do nothing and drop */
451  uipbuf_clear();
452 }
453 /*---------------------------------------------------------------------------*/
454 static void
455 output_fallback(void)
456 {
457 #ifdef UIP_FALLBACK_INTERFACE
458  uip_last_proto = *((uint8_t *)UIP_IP_BUF + 40);
459  LOG_INFO("fallback: removing ext hdrs & setting proto %d %d\n",
462  /* Inform the other end that the destination is not reachable. If it's
463  * not informed routes might get lost unexpectedly until there's a need
464  * to send a new packet to the peer */
465  if(UIP_FALLBACK_INTERFACE.output() < 0) {
466  LOG_ERR("fallback: output error. Reporting DST UNREACH\n");
468  uip_flags = 0;
470  return;
471  }
472 #else
473  LOG_ERR("output: destination off-link and no default route\n");
474 #endif /* !UIP_FALLBACK_INTERFACE */
475 }
476 /*---------------------------------------------------------------------------*/
477 static void
478 annotate_transmission(const uip_ipaddr_t *nexthop)
479 {
480 #if TCPIP_CONF_ANNOTATE_TRANSMISSIONS
481  static uint8_t annotate_last;
482  static uint8_t annotate_has_last = 0;
483 
484  if(annotate_has_last) {
485  printf("#L %u 0; red\n", annotate_last);
486  }
487  printf("#L %u 1; red\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
488  annotate_last = nexthop->u8[sizeof(uip_ipaddr_t) - 1];
489  annotate_has_last = 1;
490 #endif /* TCPIP_CONF_ANNOTATE_TRANSMISSIONS */
491 }
492 /*---------------------------------------------------------------------------*/
493 static const uip_ipaddr_t*
494 get_nexthop(uip_ipaddr_t *addr)
495 {
496  const uip_ipaddr_t *nexthop;
497  uip_ds6_route_t *route;
498 
499  LOG_INFO("output: processing %u bytes packet from ", uip_len);
500  LOG_INFO_6ADDR(&UIP_IP_BUF->srcipaddr);
501  LOG_INFO_(" to ");
502  LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
503  LOG_INFO_("\n");
504 
505  if(NETSTACK_ROUTING.ext_header_srh_get_next_hop(addr)) {
506  LOG_INFO("output: selected next hop from SRH: ");
507  LOG_INFO_6ADDR(addr);
508  LOG_INFO_("\n");
509  return addr;
510  }
511 
512  /* We first check if the destination address is on our immediate
513  link. If so, we simply use the destination address as our
514  nexthop address. */
515  if(uip_ds6_is_addr_onlink(&UIP_IP_BUF->destipaddr)) {
516  LOG_INFO("output: destination is on link\n");
517  return &UIP_IP_BUF->destipaddr;
518  }
519 
520  /* Check if we have a route to the destination address. */
521  route = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr);
522 
523  /* No route was found - we send to the default route instead. */
524  if(route == NULL) {
525  nexthop = uip_ds6_defrt_choose();
526  if(nexthop == NULL) {
527  output_fallback();
528  } else {
529  LOG_INFO("output: no route found, using default route: ");
530  LOG_INFO_6ADDR(nexthop);
531  LOG_INFO_("\n");
532  }
533 
534  } else {
535  /* A route was found, so we look up the nexthop neighbor for
536  the route. */
537  nexthop = uip_ds6_route_nexthop(route);
538 
539  /* If the nexthop is dead, for example because the neighbor
540  never responded to link-layer acks, we drop its route. */
541  if(nexthop == NULL) {
542  LOG_ERR("output: found dead route\n");
543  /* Notifiy the routing protocol that we are about to remove the route */
544  NETSTACK_ROUTING.drop_route(route);
545  /* Remove the route */
546  uip_ds6_route_rm(route);
547  /* We don't have a nexthop to send the packet to, so we drop it. */
548  } else {
549  LOG_INFO("output: found next hop from routing table: ");
550  LOG_INFO_6ADDR(nexthop);
551  LOG_INFO_("\n");
552  }
553  }
554 
555  return nexthop;
556 }
557 /*---------------------------------------------------------------------------*/
558 #if UIP_ND6_SEND_NS
559 static int
560 queue_packet(uip_ds6_nbr_t *nbr)
561 {
562  /* Copy outgoing pkt in the queuing buffer for later transmit. */
563 #if UIP_CONF_IPV6_QUEUE_PKT
564  if(uip_packetqueue_alloc(&nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) {
565  memcpy(uip_packetqueue_buf(&nbr->packethandle), UIP_IP_BUF, uip_len);
566  uip_packetqueue_set_buflen(&nbr->packethandle, uip_len);
567  return 0;
568  }
569 #endif
570 
571  return 1;
572 }
573 #endif
574 /*---------------------------------------------------------------------------*/
575 static void
576 send_queued(uip_ds6_nbr_t *nbr)
577 {
578 #if UIP_CONF_IPV6_QUEUE_PKT
579  /*
580  * Send the queued packets from here, may not be 100% perfect though.
581  * This happens in a few cases, for example when instead of receiving a
582  * NA after sendiong a NS, you receive a NS with SLLAO: the entry moves
583  * to STALE, and you must both send a NA and the queued packet.
584  */
585  if(uip_packetqueue_buflen(&nbr->packethandle) != 0) {
586  uip_len = uip_packetqueue_buflen(&nbr->packethandle);
587  memcpy(UIP_IP_BUF, uip_packetqueue_buf(&nbr->packethandle), uip_len);
588  uip_packetqueue_free(&nbr->packethandle);
590  }
591 #endif /*UIP_CONF_IPV6_QUEUE_PKT*/
592 }
593 /*---------------------------------------------------------------------------*/
594 static int
595 send_nd6_ns(const uip_ipaddr_t *nexthop)
596 {
597  int err = 1;
598 
599 #if UIP_ND6_SEND_NS
600  uip_ds6_nbr_t *nbr = NULL;
601  if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE, NBR_TABLE_REASON_IPV6_ND, NULL)) != NULL) {
602  err = 0;
603 
604  queue_packet(nbr);
605  /* RFC4861, 7.2.2:
606  * "If the source address of the packet prompting the solicitation is the
607  * same as one of the addresses assigned to the outgoing interface, that
608  * address SHOULD be placed in the IP Source Address of the outgoing
609  * solicitation. Otherwise, any one of the addresses assigned to the
610  * interface should be used."*/
611  if(uip_ds6_is_my_addr(&UIP_IP_BUF->srcipaddr)){
612  uip_nd6_ns_output(&UIP_IP_BUF->srcipaddr, NULL, &nbr->ipaddr);
613  } else {
614  uip_nd6_ns_output(NULL, NULL, &nbr->ipaddr);
615  }
616 
617  stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000);
618  nbr->nscount = 1;
619  /* Send the first NS try from here (multicast destination IP address). */
620  }
621 #else
622  LOG_ERR("output: neighbor not in cache: ");
623  LOG_ERR_6ADDR(nexthop);
624  LOG_ERR_("\n");
625 #endif
626 
627  return err;
628 }
629 /*---------------------------------------------------------------------------*/
630 void
632 {
633  uip_ipaddr_t ipaddr;
634  uip_ds6_nbr_t *nbr = NULL;
635  const uip_lladdr_t *linkaddr;
636  const uip_ipaddr_t *nexthop;
637 
638  if(uip_len == 0) {
639  return;
640  }
641 
642  if(uip_len > UIP_LINK_MTU) {
643  LOG_ERR("output: Packet too big");
644  goto exit;
645  }
646 
647  if(uip_is_addr_unspecified(&UIP_IP_BUF->destipaddr)){
648  LOG_ERR("output: Destination address unspecified");
649  goto exit;
650  }
651 
652 
653  if(!NETSTACK_ROUTING.ext_header_update()) {
654  /* Packet can not be forwarded */
655  LOG_ERR("output: routing protocol extension header update error\n");
656  uipbuf_clear();
657  return;
658  }
659 
660  if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
661  linkaddr = NULL;
662  goto send_packet;
663  }
664 
665  /* We first check if the destination address is one of ours. There is no
666  * loopback interface -- instead, process this directly as incoming. */
667  if(uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr)) {
668  LOG_INFO("output: sending to ourself\n");
669  packet_input();
670  return;
671  }
672 
673  /* Look for a next hop */
674  if((nexthop = get_nexthop(&ipaddr)) == NULL) {
675  goto exit;
676  }
677  annotate_transmission(nexthop);
678 
679  nbr = uip_ds6_nbr_lookup(nexthop);
680 
681 #if UIP_ND6_AUTOFILL_NBR_CACHE
682  if(nbr == NULL) {
683  /* Neighbor not found in cache? Derive its link-layer address from it's
684  link-local IPv6, assuming it used autoconfiguration. This is not
685  standard-compliant but this is a convenient way to keep the
686  neighbor cache out of the way in cases ND is not used */
687  uip_lladdr_t lladdr;
688  uip_ds6_set_lladdr_from_iid(&lladdr, nexthop);
689  if((nbr = uip_ds6_nbr_add(nexthop, &lladdr,
690  0, NBR_REACHABLE, NBR_TABLE_REASON_IPV6_ND_AUTOFILL, NULL)) == NULL) {
691  LOG_ERR("output: failed to autofill neighbor cache for host ");
692  LOG_ERR_6ADDR(nexthop);
693  LOG_ERR_(", link-layer addr ");
694  LOG_ERR_LLADDR((linkaddr_t*)&lladdr);
695  LOG_ERR_("\n");
696  goto exit;
697  }
698  }
699 #endif /* UIP_ND6_AUTOFILL_NBR_CACHE */
700 
701  if(nbr == NULL) {
702  if(send_nd6_ns(nexthop)) {
703  LOG_ERR("output: failed to add neighbor to cache\n");
704  goto exit;
705  } else {
706  /* We're sending NS here instead of original packet */
707  goto send_packet;
708  }
709  }
710 
711 #if UIP_ND6_SEND_NS
712  if(nbr->state == NBR_INCOMPLETE) {
713  LOG_ERR("output: nbr cache entry incomplete\n");
714  queue_packet(nbr);
715  goto exit;
716  }
717  /* Send in parallel if we are running NUD (nbc state is either STALE,
718  DELAY, or PROBE). See RFC 4861, section 7.3.3 on node behavior. */
719  if(nbr->state == NBR_STALE) {
720  nbr->state = NBR_DELAY;
721  stimer_set(&nbr->reachable, UIP_ND6_DELAY_FIRST_PROBE_TIME);
722  nbr->nscount = 0;
723  LOG_INFO("output: nbr cache entry stale moving to delay\n");
724  }
725 #endif /* UIP_ND6_SEND_NS */
726 
728  if(nbr) {
729  linkaddr = uip_ds6_nbr_get_ll(nbr);
730  } else {
731  linkaddr = NULL;
732  }
733 
734  LOG_INFO("output: sending to ");
735  LOG_INFO_LLADDR((linkaddr_t *)linkaddr);
736  LOG_INFO_("\n");
737  tcpip_output(linkaddr);
738 
739  if(nbr) {
740  send_queued(nbr);
741  }
742 
743 exit:
744  uipbuf_clear();
745  return;
746 }
747 /*---------------------------------------------------------------------------*/
748 #if UIP_UDP
749 void
751 {
752  process_post(&tcpip_process, UDP_POLL, conn);
753 }
754 #endif /* UIP_UDP */
755 /*---------------------------------------------------------------------------*/
756 #if UIP_TCP
757 void
759 {
760  process_post(&tcpip_process, TCP_POLL, conn);
761 }
762 #endif /* UIP_TCP */
763 /*---------------------------------------------------------------------------*/
764 void
765 tcpip_uipcall(void)
766 {
767  uip_udp_appstate_t *ts;
768 
769 #if UIP_UDP
770  if(uip_conn != NULL) {
771  ts = &uip_conn->appstate;
772  } else {
773  ts = &uip_udp_conn->appstate;
774  }
775 #else /* UIP_UDP */
776  ts = &uip_conn->appstate;
777 #endif /* UIP_UDP */
778 
779 #if UIP_TCP
780  {
781  unsigned char i;
782  struct listenport *l;
783 
784  /* If this is a connection request for a listening port, we must
785  mark the connection with the right process ID. */
786  if(uip_connected()) {
787  l = &s.listenports[0];
788  for(i = 0; i < UIP_LISTENPORTS; ++i) {
789  if(l->port == uip_conn->lport &&
790  l->p != PROCESS_NONE) {
791  ts->p = l->p;
792  ts->state = NULL;
793  break;
794  }
795  ++l;
796  }
797 
798  /* Start the periodic polling, if it isn't already active. */
799  start_periodic_tcp_timer();
800  }
801  }
802 #endif /* UIP_TCP */
803 
804  if(ts->p != NULL) {
805  process_post_synch(ts->p, tcpip_event, ts->state);
806  }
807 }
808 /*---------------------------------------------------------------------------*/
809 PROCESS_THREAD(tcpip_process, ev, data)
810 {
811  PROCESS_BEGIN();
812 
813 #if UIP_TCP
814  memset(s.listenports, 0, UIP_LISTENPORTS*sizeof(*(s.listenports)));
815  s.p = PROCESS_CURRENT();
816 #endif
817 
819 #if UIP_CONF_ICMP6
821 #endif /* UIP_CONF_ICMP6 */
822  etimer_set(&periodic, CLOCK_SECOND / 2);
823 
824  uip_init();
825 #ifdef UIP_FALLBACK_INTERFACE
826  UIP_FALLBACK_INTERFACE.init();
827 #endif
828  /* Initialize routing protocol */
829  NETSTACK_ROUTING.init();
830 
831  while(1) {
832  PROCESS_YIELD();
833  eventhandler(ev, data);
834  }
835 
836  PROCESS_END();
837 }
838 /*---------------------------------------------------------------------------*/
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
Definition: uip-nd6.c:116
#define UIP_IP_BUF
Direct access to IPv6 header.
Definition: uip.h:71
void process_post_synch(struct process *p, process_event_t ev, process_data_t data)
Post a synchronous event to a process.
Definition: process.c:362
uint8_t uip_last_proto
The final protocol after IPv6 extension headers: UIP_PROTO_TCP, UIP_PROTO_UDP or UIP_PROTO_ICMP6.
Definition: uip6.c:125
struct uip_udp_conn * uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport)
Set up a new UDP connection.
Definition: uip6.c:522
uint8_t tcpip_output(const uip_lladdr_t *a)
Output packet to layer 2 The eventual parameter is the MAC address of the destination.
Definition: tcpip.c:106
void uip_reass_over(void)
Abandon the reassembly of the current packet.
Definition: uip6.c:775
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
void udp_attach(struct uip_udp_conn *conn, void *appstate)
Attach the current process to a UDP connection.
Definition: tcpip.c:255
void tcpip_poll_udp(struct uip_udp_conn *conn)
Cause a specified UDP connection to be polled.
Definition: tcpip.c:750
Representation of a uIP TCP connection.
Definition: uip.h:1324
static uip_ds6_nbr_t * nbr
Pointer to llao option in uip_buf.
Definition: uip-nd6.c:106
void uip_ds6_send_rs(void)
Send periodic RS to find router.
Definition: uip-ds6.c:733
uint16_t uip_len
The length of the packet in the uip_buf buffer.
Definition: uip6.c:159
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition: uip-nd6.c:107
void tcpip_ipv6_output(void)
This function does address resolution and then calls tcpip_output.
Definition: tcpip.c:631
void etimer_restart(struct etimer *et)
Restart an event timer from the current point in time.
Definition: etimer.c:199
#define uip_connected()
Has the connection just been connected?
Definition: uip.h:749
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
#define UIP_TCP_CONNS
The maximum number of simultaneously open TCP connections.
Definition: uipopt.h:359
Header file for the link-layer address representation
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
process_event_t tcpip_event
The uIP event.
Definition: tcpip.c:62
void tcp_attach(struct uip_conn *conn, void *appstate)
Attach a TCP connection to the current process.
Definition: tcpip.c:247
static void send_packet(linkaddr_t *dest)
This function is called by the 6lowpan code to send out a packet.
Definition: sicslowpan.c:1491
#define UIP_UDP_CONNS
The maximum amount of concurrent UDP connections.
Definition: uipopt.h:305
IPv6 Neighbor cache (link-layer/IPv6 address mapping)
void(* drop_route)(uip_ds6_route_t *route)
Called by uIP if it has decided to drop a route because.
Definition: routing.h:184
void tcpip_poll_tcp(struct uip_conn *conn)
Cause a specified TCP connection to be polled.
Definition: tcpip.c:758
uip_ipaddr_t ripaddr
The IP address of the remote host.
Definition: uip.h:1325
struct uip_icmp6_conn uip_icmp6_conns
single possible icmpv6 "connection"
Definition: uip6.c:243
#define ICMP6_DST_UNREACH
dest unreachable
Definition: uip-icmp6.h:53
struct uip_udp_conn * udp_broadcast_new(uint16_t port, void *appstate)
Create a new UDP broadcast connection.
Definition: tcpip.c:275
#define UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED
This is the default value of MAC-layer transmissons for uIPv6.
Definition: uipopt.h:519
void uip_ds6_set_lladdr_from_iid(uip_lladdr_t *lladdr, const uip_ipaddr_t *ipaddr)
Build a link-layer address from an IPv6 address based on its UUID64.
Definition: uip-ds6.c:597
void uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param)
Send an icmpv6 error message.
Definition: uip-icmp6.c:155
void uip_unlisten(uint16_t port)
Stop listening to the specified port.
Definition: uip6.c:568
#define uip_periodic(conn)
Periodic processing for a connection identified by its number.
Definition: uip.h:394
#define UIP_LINK_MTU
The maximum transmission unit at the IP Layer.
Definition: uipopt.h:228
#define UIP_TC_MAC_TRANSMISSION_COUNTER_BIT
The MAC-layer transmissons limit is encapslated in "Traffic Class" field.
Definition: uipopt.h:501
Header file for IPv6-related data structures.
uint16_t lport
The local port number in network byte order.
Definition: uip.h:1377
#define ICMP6_DST_UNREACH_ADDR
address unreachable
Definition: uip-icmp6.h:83
void tcp_unlisten(uint16_t port)
Close a listening TCP port.
Definition: tcpip.c:211
void(* init)(void)
Initialize the routing protocol.
Definition: routing.h:63
#define PROCESS_CURRENT()
Get a pointer to the currently running process.
Definition: process.h:402
process_event_t tcpip_icmp6_event
The ICMP6 event.
Definition: tcpip.c:64
An entry in the routing table.
void uip_init(void)
uIP initialization function.
Definition: uip6.c:387
void uip_nd6_ns_output(uip_ipaddr_t *src, uip_ipaddr_t *dest, uip_ipaddr_t *tgt)
Send a neighbor solicitation, send a Neighbor Advertisement.
#define uip_conn_active(conn)
Macro to determine whether a specific uIP connection is active.
Definition: uip.h:403
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82
void stimer_set(struct stimer *t, unsigned long interval)
Set a timer.
Definition: stimer.c:67
uint16_t uip_ext_len
The length of the extension headers.
Definition: uip6.c:122
struct etimer uip_ds6_timer_periodic
Timer for maintenance of data structures.
Definition: uip-ds6.c:60
struct tcpip_uipstate uip_udp_appstate_t
The type of the application state that is to be stored in the uip_conn structure. ...
Definition: tcpip.h:85
uint8_t tcpstateflags
TCP state and flags.
Definition: uip.h:1340
#define uip_poll_conn(conn)
Request that a particular connection should be polled.
Definition: uip.h:432
struct uip_udp_conn * udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Create a new UDP connection.
Definition: tcpip.c:261
#define uip_create_linklocal_allnodes_mcast(a)
set IP address a to the link local all-nodes multicast address
Definition: uip.h:1885
uip_ds6_nbr_t * uip_ds6_nbr_lookup(const uip_ipaddr_t *ipaddr)
Get the neighbor cache associated with a specified IPv6 address.
Definition: uip-ds6-nbr.c:467
uint16_t lport
The local TCP port, in network byte order.
Definition: uip.h:1327
#define uip_is_addr_unspecified(a)
Is IPv6 address a the unspecified address a is of type uip_ipaddr_t.
Definition: uip.h:1836
Routing driver header file
int(* ext_header_srh_get_next_hop)(uip_ipaddr_t *ipaddr)
Look for next hop from SRH of current uIP packet.
Definition: routing.h:162
void uip_listen(uint16_t port)
Start listening to the specified port.
Definition: uip6.c:580
int etimer_expired(struct etimer *et)
Check if an event timer has expired.
Definition: etimer.c:213
#define PROCESS_YIELD()
Yield the currently running process.
Definition: process.h:164
#define NBR_INCOMPLETE
Possible states for the nbr cache entries.
Definition: uip-ds6-nbr.h:64
A timer.
Definition: etimer.h:76
process_event_t process_alloc_event(void)
Allocate a global event number.
Definition: process.c:93
#define uip_is_addr_mcast(a)
is address a multicast address, see RFC 4291 a is of type uip_ipaddr_t*
Definition: uip.h:1961
void uip_ds6_periodic(void)
Periodic processing of data structures.
Definition: uip-ds6.c:177
struct etimer uip_reass_timer
Timer for reassembly.
Definition: uip6.c:621
struct etimer uip_ds6_timer_rs
RS timer, to schedule RS sending.
Definition: uip-ds6.c:69
uip_ds6_nbr_t * uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr, uint8_t isrouter, uint8_t state, nbr_table_reason_t reason, void *data)
Add a neighbor cache for a specified IPv6 address, which is associated with a specified link-layer ad...
Definition: uip-ds6-nbr.c:122
Header file for IPv6 Neighbor discovery (RFC 4861)
uip_ds6_netif_t uip_ds6_if
The single interface.
Definition: uip-ds6.c:75
bool uip_remove_ext_hdr(void)
Removes all IPv6 extension headers from uip_buf, updates length fields (uip_len and uip_ext_len) ...
Definition: uip6.c:493
void tcp_listen(uint16_t port)
Open a TCP port.
Definition: tcpip.c:229
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
Definition: process.c:322
uip_ipaddr_t ripaddr
The IP address of the remote peer.
Definition: uip.h:1376
#define UIP_LISTENPORTS
The maximum number of simultaneously listening TCP ports.
Definition: uipopt.h:373
const uip_lladdr_t * uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr)
Get the link-layer address associated with a specified nbr cache.
Definition: uip-ds6-nbr.c:392
uint8_t icmp6_new(void *appstate)
register an ICMPv6 callback
Definition: tcpip.c:292
#define uip_udp_periodic_conn(conn)
Periodic processing for a UDP connection identified by a pointer to its structure.
Definition: uip.h:486
int(* ext_header_update)(void)
Adds/updates routing protocol extension headers to current uIP packet.
Definition: routing.h:138
struct uip_conn * uip_connect(const uip_ipaddr_t *ripaddr, uint16_t port)
Connect to a remote host using TCP.
#define UIP_TC_MAC_TRANSMISSION_COUNTER_MASK
The bits in the "Traffic Class" field that describe the MAC transmission limit.
Definition: uipopt.h:506
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
Definition: cc2538-rf.c:1107
Header file for the logging system
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
Definition: etimer.c:177
#define udp_bind(conn, port)
Bind a UDP connection to a local port.
Definition: tcpip.h:261
#define uip_input()
Process an incoming packet.
Definition: uip.h:348
struct uip_conn * tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Open a TCP connection to the specified IP address and port.
struct tcpip_uipstate uip_tcp_appstate_t
The type of the application state that is to be stored in the uip_conn structure. ...
Definition: tcpip.h:86
void tcpip_input(void)
Deliver an incoming packet to the TCP/IP stack.
Definition: tcpip.c:445
Representation of a uIP UDP connection.
Definition: uip.h:1375
void tcpip_icmp6_call(uint8_t type)
This function is called at reception of an ICMPv6 packet If an application registered as an ICMPv6 li...
Definition: tcpip.c:301
The default nbr_table entry (when UIP_DS6_NBR_MULTI_IPV6_ADDRS is disabled), that implements nbr cach...
Definition: uip-ds6-nbr.h:105
uip_udp_appstate_t appstate
The application state.
Definition: uip.h:1381