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