Exemple #1
0
static uint8_t
bridge_output(uip_lladdr_t * dest)
{
  int isBroadcast = IS_BROADCAST_ADDR(dest);
  int wsnDest = 0;
  if(!isBroadcast) {
    LOG6LBR_LLADDR_PRINTF(PACKET, PF_OUT, dest, "bridge_output: Sending packet to ");
  } else {
    LOG6LBR_PRINTF(PACKET, PF_OUT, "bridge_output: Sending packet to Broadcast\n");
  }
  if(isBroadcast) {
    //Obviously we can not guess the target segment for a multicast packet
    //So we have to check the packet source prefix (and match it on the Ethernet segment prefix)
    //or, in case of link-local packet, check packet type and/or packet data
    if((UIP_IP_BUF->proto == UIP_PROTO_ICMP6
        && UIP_ICMP_BUF->type == ICMP6_RA)
       || (UIP_IP_BUF->proto == UIP_PROTO_ICMP6
           && UIP_ICMP_BUF->type == ICMP6_NS
           && uip_ipaddr_prefixcmp(&wsn_net_prefix,
                                   &UIP_ND6_NS_BUF->tgtipaddr, 64))
       || uip_ipaddr_prefixcmp(&wsn_net_prefix, &UIP_IP_BUF->srcipaddr, 64)) {
      wsnDest = 1;
    }
  }
  if(wsnDest || IS_EUI64_ADDR(dest)) {
		wireless_output(NULL, dest);
  } else {
	eth_output(NULL, dest);
  }
  return 0;
}
Exemple #2
0
/*---------------------------------------------------------------------------*/
void
cetic_6lbr_set_prefix(uip_ipaddr_t * prefix, unsigned len,
                      uip_ipaddr_t * ipaddr)
{
#if CETIC_6LBR_SMARTBRIDGE
  int new_prefix = !uip_ipaddr_prefixcmp(&wsn_net_prefix, prefix, len);
  int new_dag_prefix = cetic_dag == NULL || !uip_ipaddr_prefixcmp(&cetic_dag->prefix_info.prefix, prefix, len);
  if((nvm_data.mode & CETIC_MODE_WAIT_RA_MASK) == 0) {
    LOG6LBR_DEBUG("Ignoring RA\n");
    return;
  }

  if(new_prefix) {
    LOG6LBR_6ADDR(INFO, prefix, "Setting prefix : ");
    uip_ipaddr_copy(&wsn_ip_addr, ipaddr);
    uip_ipaddr_copy(&wsn_net_prefix, prefix);
    wsn_net_prefix_len = len;
    LOG6LBR_6ADDR(INFO, &wsn_ip_addr, "Tentative global IPv6 address : ");
#if CONTIKI_TARGET_NATIVE
  cetic_6lbr_save_ip();
#endif
  }
  if(new_dag_prefix) {
    if((nvm_data.rpl_config & CETIC_6LBR_MODE_GLOBAL_DODAG) != 0) {
      cetic_dag = rpl_set_root(nvm_data.rpl_instance_id, &wsn_ip_addr);
      rpl_set_prefix(cetic_dag, prefix, len);
      LOG6LBR_6ADDR(INFO, &cetic_dag->dag_id, "Configured as DODAG Root ");
    } else {
      rpl_set_prefix(cetic_dag, prefix, len);
      LOG6LBR_6ADDR(INFO, prefix, "Setting DAG prefix : ");
      rpl_repair_root(RPL_DEFAULT_INSTANCE);
    }
  }
#endif
}
Exemple #3
0
/*---------------------------------------------------------------------------*/
uint8_t
uip_ds6_list_loop(uip_ds6_element_t *list, uint8_t size,
                  uint16_t elementsize, uip_ipaddr_t *ipaddr,
                  uint8_t ipaddrlen, uip_ds6_element_t **out_element)
{
  uip_ds6_element_t *element;

  *out_element = NULL;

  for(element = list;
      element <
      (uip_ds6_element_t *)((uint8_t *)list + (size * elementsize));
      element = (uip_ds6_element_t *)((uint8_t *)element + elementsize)) {
    if(element->isused) {
      if(uip_ipaddr_prefixcmp(&element->ipaddr, ipaddr, ipaddrlen)) {
        *out_element = element;
        return FOUND;
      }
    } else {
      *out_element = element;
    }
  }

  return *out_element != NULL ? FREESPACE : NOSPACE;
}
Exemple #4
0
/*---------------------------------------------------------------------------*/
u8_t
uip_ds6_list_loop(uip_ds6_element_t * list, u8_t size,
                  u16_t elementsize, uip_ipaddr_t * ipaddr,
                  u8_t ipaddrlen, uip_ds6_element_t ** out_element)
{
  uip_ds6_element_t *element;

  *out_element = NULL;

  for(element = list;
      element <
      (uip_ds6_element_t *) ((u8_t *) list + (size * elementsize));
      element = (uip_ds6_element_t *) ((u8_t *) element + elementsize)) {
    //    printf("+ %p %d\n", &element->isused, element->isused);
    if(element->isused) {
      if(uip_ipaddr_prefixcmp(&(element->ipaddr), ipaddr, ipaddrlen)) {
        *out_element = element;
        return FOUND;
      }
    } else {
      *out_element = element;
    }
  }

  if(*out_element != NULL) {
    return FREESPACE;
  } else {
    return NOSPACE;
  }
}
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_lookup(uip_ipaddr_t *addr)
{
  uip_ds6_route_t *r;
  uip_ds6_route_t *found_route;
  uint8_t longestmatch;

//ADILA EDIT 10/11/14
//uint8_t found_route_ch;
//-------------------

  PRINTF("uip-ds6-route: Looking up route for ");
  PRINT6ADDR(addr);
  PRINTF("\n");


  found_route = NULL;
  longestmatch = 0;
  for(r = uip_ds6_route_head();
      r != NULL;
      r = uip_ds6_route_next(r)) {
    if(r->length >= longestmatch &&
       uip_ipaddr_prefixcmp(addr, &r->ipaddr, r->length)) {
      longestmatch = r->length;
      found_route = r;

//ADILA EDIT 10/11/14
//found_route_ch = r->nbrCh;
//-------------------
    }
  }

  if(found_route != NULL) {
    PRINTF("uip-ds6-route: Found route: ");
    PRINT6ADDR(addr);
    PRINTF(" via ");
    PRINT6ADDR(uip_ds6_route_nexthop(found_route));
    PRINTF("\n");

//ADILA EDIT 10/11/14
/*    printf("uip-ds6-route: Found route: ");
    uip_debug_ipaddr_print(addr);
    printf(" via ");
    uip_debug_ipaddr_print(uip_ds6_route_nexthop(found_route));
    printf("\n");
*/
//printf("FOUND ROUTE CHANGE TO NEXTHOP CHANNEL %d\n\n", found_route_ch);
/*printf("Found route change to nexthop channel %d ", found_route_ch);
uip_debug_ipaddr_print(uip_ds6_route_nexthop(found_route));
printf("\n");*/
//PRINTF("FOUND ROUTE CHANGE TO NEXTHOP CHANNEL %d\n\n", found_route_ch);
//@
//cc2420_set_channel(found_route_ch);
//-------------------
  } else {
    PRINTF("uip-ds6-route: No route found\n");
  }

  return found_route;
}
Exemple #6
0
void
cetic_6lbr_set_prefix(uip_ipaddr_t * prefix, unsigned len,
                      uip_ipaddr_t * ipaddr)
{
#if CETIC_6LBR_SMARTBRIDGE
  int new_prefix = cetic_dag != NULL && !uip_ipaddr_prefixcmp(&cetic_dag->prefix_info.prefix, prefix, len);
  if((nvm_data.mode & CETIC_MODE_WAIT_RA_MASK) == 0) {
    LOG6LBR_DEBUG("Ignoring RA\n");
    return;
  }
  LOG6LBR_INFO("CETIC_BRIDGE : set_prefix\n");

  uip_ipaddr_copy(&wsn_ip_addr, ipaddr);

  if(cetic_dag != NULL) {
    rpl_set_prefix(cetic_dag, prefix, len);
    uip_ipaddr_copy(&wsn_net_prefix, prefix);
    wsn_net_prefix_len = len;
    if(new_prefix) {
      LOG6LBR_6ADDR(INFO, prefix, "Setting DAG prefix : ");
      rpl_repair_root(RPL_DEFAULT_INSTANCE);
    }
  }
#if CONTIKI_TARGET_NATIVE
  cetic_6lbr_save_ip();
#endif
#endif
}
Exemple #7
0
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_lookup(uip_ipaddr_t *destipaddr)
{
  uip_ds6_route_t *locrt = NULL;
  uint8_t longestmatch = 0;

  PRINTF("DS6: Looking up route for ");
  PRINT6ADDR(destipaddr);
  PRINTF("\n");

  for(locroute = uip_ds6_routing_table;
      locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; locroute++) {
    if((locroute->isused) && (locroute->length >= longestmatch)
       &&
       (uip_ipaddr_prefixcmp
        (destipaddr, &locroute->ipaddr, locroute->length))) {
      longestmatch = locroute->length;
      locrt = locroute;
    }
  }

  if(locrt != NULL) {
    PRINTF("DS6: Found route:");
    PRINT6ADDR(destipaddr);
    PRINTF(" via ");
    PRINT6ADDR(&locrt->nexthop);
    PRINTF("\n");
  } else {
    PRINTF("DS6: No route found\n");
  }

  return locrt;
}
Exemple #8
0
/*---------------------------------------------------------------------------*/
static void
check_prefix(rpl_prefix_t *last_prefix, rpl_prefix_t *new_prefix)
{
  uip_ipaddr_t ipaddr;
  uip_ds6_addr_t *rep;

  if(last_prefix != NULL && new_prefix != NULL &&
     last_prefix->length == new_prefix->length &&
     uip_ipaddr_prefixcmp(&last_prefix->prefix, &new_prefix->prefix, new_prefix->length) &&
     last_prefix->flags == new_prefix->flags) {
    /* Nothing has changed. */
    return;
  }

  if(last_prefix != NULL) {
    set_ip_from_prefix(&ipaddr, last_prefix);
    rep = uip_ds6_addr_lookup(&ipaddr);
    if(rep != NULL) {
      PRINTF("RPL: removing global IP address ");
      PRINT6ADDR(&ipaddr);
      PRINTF("\n");
      uip_ds6_addr_rm(rep);
    }
  }

  if(new_prefix != NULL) {
    set_ip_from_prefix(&ipaddr, new_prefix);
    if(uip_ds6_addr_lookup(&ipaddr) == NULL) {
      PRINTF("RPL: adding global IP address ");
      PRINT6ADDR(&ipaddr);
      PRINTF("\n");
      uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
    }
  }
}
Exemple #9
0
/*---------------------------------------------------------------------------*/
struct uip_netif_addr *
uip_netif_addr_lookup(uip_ipaddr_t *ipaddr, u8_t length, uip_netif_type type) {
  for(i = 0; i < UIP_CONF_NETIF_MAX_ADDRESSES; i ++) {
    if((uip_netif_physical_if.addresses[i].state != NOT_USED) &&
       (uip_netif_physical_if.addresses[i].type == type || type == 0) &&
       (uip_ipaddr_prefixcmp(&(uip_netif_physical_if.addresses[i].ipaddr), ipaddr, length))) { 
      return &uip_netif_physical_if.addresses[i]; 
    }
  }
  return NULL; 
}
Exemple #10
0
/*---------------------------------------------------------------------------*/
uint8_t
uip_ds6_is_addr_onlink(uip_ipaddr_t *ipaddr)
{
  for(locprefix = uip_ds6_prefix_list;
      locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) {
    if(locprefix->isused &&
       uip_ipaddr_prefixcmp(&locprefix->ipaddr, ipaddr, locprefix->length)) {
      return 1;
    }
  }
  return 0;
}
Exemple #11
0
/*---------------------------------------------------------------------------*/
uip_ds6_prefix_t *
uip_ds6_prefix_lookup_from_ipaddr(uip_ipaddr_t *ipaddr)
{
  for(locprefix = uip_ds6_prefix_list;
      locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB;
      locprefix++) {
    if(locprefix->isused &&
       uip_ipaddr_prefixcmp(&locprefix->ipaddr, ipaddr, locprefix->length)) {
      return locprefix;
    }
  }
  return NULL;
}
Exemple #12
0
/*---------------------------------------------------------------------------*/
uip_ds6_context_pref_t *
uip_ds6_context_pref_lookup(uip_ipaddr_t *ipaddr)
{
  for(loccontext = uip_ds6_context_pref_list;
      loccontext < uip_ds6_context_pref_list + UIP_DS6_CONTEXT_PREF_NB;
      loccontext++) {
    if(loccontext->state != CONTEXT_PREF_ST_FREE &&
       uip_ipaddr_prefixcmp(ipaddr, &loccontext->ipaddr, loccontext->length)) {
      return loccontext;
    }
  }
  return NULL;
}
Exemple #13
0
pgw_addr_context_t*
pgw_context_lookup_by_prefix(uip_ipaddr_t *prefix) {
	
	for(loccontext = pgw_addr_context_table;
      loccontext < pgw_addr_context_table + SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS; loccontext++) {
    if(loccontext->state != NOT_IN_USE) {
			if (uip_ipaddr_prefixcmp(prefix, &loccontext->prefix, loccontext->length)) {
				return loccontext;
			}
    }
  }
  return NULL;
}
Exemple #14
0
static uint8_t
bridge_output(uip_lladdr_t * dest)
{
  int ethernetDest = 0;
  if(uip_len == 0) {
    LOG6LBR_ERROR("Trying to send empty packet\n");
    return 0;
  }
  if(!IS_BROADCAST_ADDR(dest)) {
    LOG6LBR_LLADDR_PRINTF(PACKET, PF_OUT, dest, "bridge_output: Sending packet to ");
  } else {
    LOG6LBR_PRINTF(PACKET, PF_OUT, "bridge_output: Sending packet to Broadcast\n");
  }
  if(IS_BROADCAST_ADDR(dest)) {
    //Obviously we can not guess the target segment for a multicast packet
    //So we have to check the packet source prefix (and match it on the Ethernet segment prefix)
    //or, in case of link-local packet, check packet type and/or packet data
    if((UIP_IP_BUF->proto == UIP_PROTO_ICMP6
        && UIP_ICMP_BUF->type == ICMP6_RA)
       || (UIP_IP_BUF->proto == UIP_PROTO_ICMP6
           && UIP_ICMP_BUF->type == ICMP6_NS
           && uip_ipaddr_prefixcmp(&eth_net_prefix,
                                   &UIP_ND6_NS_BUF->tgtipaddr, 64))
       || uip_ipaddr_prefixcmp(&eth_net_prefix, &UIP_IP_BUF->srcipaddr, 64)) {
      ethernetDest = 1;
    }
  }
  if(ethernetDest || IS_EUI48_ADDR(dest)) {
    eth_output(NULL, dest);
  } else {
#if CETIC_6LBR_ONE_ITF
	eth_output(&wsn_mac_addr, dest);
#else
	wireless_output(NULL, dest);
#endif
  }
  return 0;
}
Exemple #15
0
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_lookup(uip_ipaddr_t *destipaddr)
{
  uip_ds6_route_t *locrt = NULL;
  uint8_t longestmatch = 0;

  PRINTF("DS6: Looking up route for ");
  PRINT6ADDR(destipaddr);
  PRINTF("\n");

  for(locroute = uip_ds6_routing_table;
      locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; locroute++) {
    if((locroute->isused) && (locroute->length >= longestmatch)
       &&
       (uip_ipaddr_prefixcmp
        (destipaddr, &locroute->ipaddr, locroute->length))) {
      longestmatch = locroute->length;
      locrt = locroute;
    }
  }

  if(locrt != NULL) {
#ifdef UIP_DS6_ROUTE_STATE_CLEAN
    switch (locrt->state.learned_from) {
      case RPL_ROUTE_FROM_UNICAST_DAO:
      case RPL_ROUTE_FROM_MULTICAST_DAO:
      case RPL_ROUTE_FROM_DIO:
        if(UIP_DS6_ROUTE_STATE_CLEAN(&locrt->state)) {
          uip_ds6_route_rm(locrt);
          //TODO : verify that the prefix len is 128
          mob_lost_node(locrt);
          PRINTF("DS6: Route timeout\n");
          return NULL;
        }
        break;
      default:
        break;
    }
#endif /* UIP_DS6_ROUTE_STATE_TYPE */
    PRINTF("DS6: Found route:");
    PRINT6ADDR(destipaddr);
    PRINTF(" via ");
    PRINT6ADDR(&locrt->nexthop);
    PRINTF("\n");
  } else {
    PRINTF("DS6: No route found\n");
  }

  return locrt;
}
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_lookup(uip_ipaddr_t *addr)
{
  uip_ds6_route_t *r;
  uip_ds6_route_t *found_route;
  uint8_t longestmatch;

  PRINTF("uip-ds6-route: Looking up route for ");
  PRINT6ADDR(addr);
  PRINTF("\n");


  found_route = NULL;
  longestmatch = 0;
  for(r = uip_ds6_route_head();
      r != NULL;
      r = uip_ds6_route_next(r)) {
    if(r->length >= longestmatch &&
       uip_ipaddr_prefixcmp(addr, &r->ipaddr, r->length)) {
      longestmatch = r->length;
      found_route = r;
      /* check if total match - e.g. all 128 bits do match */
      if(longestmatch == 128) {
	break;
      }
    }
  }

  if(found_route != NULL) {
    PRINTF("uip-ds6-route: Found route: ");
    PRINT6ADDR(addr);
    PRINTF(" via ");
    PRINT6ADDR(uip_ds6_route_nexthop(found_route));
    PRINTF("\n");
  } else {
    PRINTF("uip-ds6-route: No route found\n");
  }

  if(found_route != NULL && found_route != list_head(routelist)) {
    /* If we found a route, we put it at the start of the routeslist
       list. The list is ordered by how recently we looked them up:
       the least recently used route will be at the end of the
       list - for fast lookups (assuming multiple packets to the same node). */

    list_remove(routelist, found_route);
    list_push(routelist, found_route);
  }

  return found_route;
}
Exemple #17
0
/**
 * \brief 						Searches for a context by prefix.
 * 
 * \param length 			The length of the prefix that is valid
 * 
 * \param prefix 			The prefix of the context to search.
 * 
 * \returns			 			If found, returns a pointer to the context. Otherwise 
 * 										returns NULL.
 */
uip_ds6_addr_context_t *uip_ds6_context_lookup_by_prefix(uip_ipaddr_t *prefix) {
	
	uip_ds6_addr_context_t* context;
																							
	for(context = uip_ds6_addr_context_table;
      context < uip_ds6_addr_context_table + SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS; context++) {
    if(context->state != NOT_IN_USE) {
			if (uip_ipaddr_prefixcmp(prefix, &context->prefix, context->length)) {
				return context;
			}
    }
  }
  return NULL;
}
/** \brief find the context corresponding to prefix ipaddr */
static struct sicslowpan_addr_context*
addr_context_lookup_by_prefix(uip_ipaddr_t *ipaddr)
{
/* Remove code to avoid warnings and save flash if no context is used */
#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
  int i;
  for(i = 0; i < SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS; i++) {
    if((addr_contexts[i].used == 1) &&
       uip_ipaddr_prefixcmp(&addr_contexts[i].prefix, ipaddr, 64)) {
      return &addr_contexts[i];
    }
  }
#endif /* SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 */
  return NULL;
}
Exemple #19
0
/*---------------------------------------------------------------------------*/
uint8_t
uip_ds6_is_addr_onlink(uip_ipaddr_t *ipaddr)
{
#if CONF_6LOWPAN_ND
  return uip_is_addr_link_local(ipaddr);
#else /* CONF_6LOWPAN_ND */
  for(locprefix = uip_ds6_prefix_list;
      locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) {
    if(locprefix->isused &&
       uip_ipaddr_prefixcmp(&locprefix->ipaddr, ipaddr, locprefix->length)) {
      return 1;
    }
  }
  return 0;
#endif /* CONF_6LOWPAN_ND */
}
Exemple #20
0
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_lookup(uip_ipaddr_t *addr)
{
    uip_ds6_route_t *r;
    uip_ds6_route_t *found_route;
    uint8_t longestmatch;

    PRINTF("uip-ds6-route: Looking up route for ");
    PRINT6ADDR(addr);
    PRINTF("\n");


    found_route = NULL;
    longestmatch = 0;
    for(r = uip_ds6_route_head();
            r != NULL;
            r = uip_ds6_route_next(r)) {
        if(r->length >= longestmatch &&
                uip_ipaddr_prefixcmp(addr, &r->ipaddr, r->length)) {
            longestmatch = r->length;
            found_route = r;
        }
    }

    if(found_route != NULL) {
        PRINTF("uip-ds6-route: Found route: ");
        PRINT6ADDR(addr);
        PRINTF(" via ");
        PRINT6ADDR(uip_ds6_route_nexthop(found_route));
        PRINTF("\n");
    } else {
        PRINTF("uip-ds6-route: No route found\n");
    }

    if(found_route != NULL) {
        /* If we found a route, we put it at the end of the routeslist
           list. The list is ordered by how recently we looked them up:
           the least recently used route will be at the start of the
           list. */
        list_remove(routelist, found_route);
        list_add(routelist, found_route);
    }

    return found_route;
}
Exemple #21
0
int
rpl_matching_used_prefix(uip_ipaddr_t *prefix)
{
  int i;
  rpl_instance_t *instance, *end;

  for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) {
    if(instance->used) {
      for(i = 0; i < RPL_MAX_DODAG_PER_INSTANCE; ++i) {
        if((instance->dag_table[i].used)
            && (uip_ipaddr_prefixcmp(&instance->dag_table[i].prefix_info.prefix, prefix, instance->dag_table[i].prefix_info.length))) {
          return 1;
        }
      }
    }
  }
  return 0;
}
Exemple #22
0
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_lookup(uip_ipaddr_t *addr)
{
  uip_ds6_route_t *r;
  uip_ds6_route_t *found_route;
  uint8_t longestmatch;

  PRINTF("uip-ds6-route: Looking up route for ");
  PRINT6ADDR(addr);
  PRINTF("\n");


  found_route = NULL;
  longestmatch = 0;
  for(r = uip_ds6_route_head();
      r != NULL;
      r = uip_ds6_route_next(r)) {
    if(r->length >= longestmatch &&
       uip_ipaddr_prefixcmp(addr, &r->ipaddr, r->length)) {
      longestmatch = r->length;
      found_route = r;
    }
  }

  if(found_route != NULL) {
    PRINTF("uip-ds6-route: Found route: ");
    PRINT6ADDR(addr);
    PRINTF(" via ");
    PRINT6ADDR(uip_ds6_route_nexthop(found_route));
    PRINTF("\n");
  } else {
    PRINTF("uip-ds6-route: No route found\n");
  }

  return found_route;
}
Exemple #23
0
static uint8_t
bridge_output(const uip_lladdr_t * dest)
{
  int ethernetDest = 0;
  int wsnDest = 0;
  if(uip_len == 0) {
    LOG6LBR_ERROR("Trying to send empty packet\n");
    return 0;
  }
  if(!IS_BROADCAST_ADDR(dest)) {
    LOG6LBR_LLADDR_PRINTF(PACKET, PF_OUT, dest, "bridge_output: Sending packet to ");
  } else {
    LOG6LBR_PRINTF(PACKET, PF_OUT, "bridge_output: Sending packet to Broadcast\n");
  }

  if(uip_ipaddr_prefixcmp(&eth_net_prefix, &UIP_IP_BUF->destipaddr, 64)) {
    LOG6LBR_6ADDR_PRINTF(PACKET, PF_OUT, &eth_net_prefix, "dest prefix eth : ");
    LOG6LBR_6ADDR_PRINTF(PACKET, PF_OUT, &UIP_IP_BUF->destipaddr, "dest eth : ");
    //Packet destinated to the Ethernet subnet
    ethernetDest = 1;
  } else if(uip_ipaddr_prefixcmp(&wsn_net_prefix, &UIP_IP_BUF->destipaddr, 64)) {
    LOG6LBR_6ADDR_PRINTF(PACKET, PF_OUT, &wsn_net_prefix, "dest prefix wsn : ");
    LOG6LBR_6ADDR_PRINTF(PACKET, PF_OUT, &UIP_IP_BUF->destipaddr, "dest prefix wsn : ");
    //Packet destinated to the WSN subnet
    wsnDest = 1;
  } else if(IS_EUI64_ADDR(dest)) {
    //Destination unknown but next-hop is in WSN subnet
    wsnDest = 1;
  } else if (IS_EUI48_ADDR(dest)) {
    //Destination unknown but next-hop is in Ethernet subnet
    ethernetDest = 1;
  } else {
    //Obviously we can not guess the target segment for a multicast packet
    //So we have to check the packet source prefix (and match it on the Ethernet segment prefix)
    //or, in case of link-local packet, check packet type and/or packet data
#if UIP_CONF_IPV6_RPL
    //in RPL mode, RA and RS packets are used to configure the Ethernet subnet
    if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 &&
        (UIP_ICMP_BUF->type == ICMP6_RA || UIP_ICMP_BUF->type == ICMP6_RS)) {
      ethernetDest = 1;
    } else if (UIP_IP_BUF->proto == UIP_PROTO_ICMP6
        && UIP_ICMP_BUF->type == ICMP6_NS
        && uip_ipaddr_prefixcmp(&eth_net_prefix,
                                &UIP_ND6_NS_BUF->tgtipaddr, 64)) {
      ethernetDest = 1;
#else
    //in NDP mode, RA and RS packets are used to configure the WSN subnet
    if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 &&
        (UIP_ICMP_BUF->type == ICMP6_RA || UIP_ICMP_BUF->type == ICMP6_RS)) {
      wsnDest = 1;
    } else if (UIP_IP_BUF->proto == UIP_PROTO_ICMP6
        && UIP_ICMP_BUF->type == ICMP6_NS
        && uip_ipaddr_prefixcmp(&wsn_net_prefix,
                                &UIP_ND6_NS_BUF->tgtipaddr, 64)) {
      wsnDest = 1;
#endif
    } else if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 &&
        UIP_ICMP_BUF->type == ICMP6_RPL) {
      //RPL packets are always for WSN subnet
      wsnDest = 1;
    } else if(uip_ipaddr_prefixcmp(&eth_net_prefix, &UIP_IP_BUF->srcipaddr, 64)) {
      //Packet type unknown, but source is from Ethernet subnet
      ethernetDest = 1;
    } else if(uip_ipaddr_prefixcmp(&wsn_net_prefix, &UIP_IP_BUF->srcipaddr, 64)) {
      //Packet type unknown, but source is from WSN subnet
      wsnDest = 1;
    } else {
      // We could not guess the destination, forward to both
      ethernetDest = 1;
      wsnDest = 1;
    }
  }
  if(wsnDest) {
#if CETIC_6LBR_ONE_ITF
    eth_output(&wsn_mac_addr, dest);
#else
    wireless_output(NULL, dest);
#endif
  }
  if(ethernetDest) {
    eth_output(NULL, dest);
  }
  return 0;
}
#endif

/*---------------------------------------------------------------------------*/

void
packet_filter_init(void)
{
  wireless_outputfunc = tcpip_get_outputfunc();
  tcpip_set_outputfunc(bridge_output);

  tcpip_inputfunc = tcpip_get_inputfunc();

  tcpip_set_inputfunc(wireless_input);
}
Exemple #24
0
void
tcpip_ipv6_output(void)
{
  uip_ds6_nbr_t *nbr = NULL;
  uip_ipaddr_t *nexthop;
  uip_ds6_route_t *route = NULL;

  if(uip_len == 0) {
    return;
  }

  PRINTF("IPv6 packet send from ");
  PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
  PRINTF(" to ");
  PRINT6ADDR(&UIP_IP_BUF->destipaddr);
  PRINTF("\n");

  if(uip_len > UIP_LINK_MTU) {
    UIP_LOG("tcpip_ipv6_output: Packet to big");
    uip_clear_buf();
    return;
  }

  if(uip_is_addr_unspecified(&UIP_IP_BUF->destipaddr)){
    UIP_LOG("tcpip_ipv6_output: Destination address unspecified");
    uip_clear_buf();
    return;
  }

  if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
    /* Next hop determination */
    nbr = NULL;

    /* We first check if the destination address is on our immediate
       link. If so, we simply use the destination address as our
       nexthop address. */
    if(uip_ds6_is_addr_onlink(&UIP_IP_BUF->destipaddr)){
      nexthop = &UIP_IP_BUF->destipaddr;
    } else {
      /* Check if we have a route to the destination address. */
      route = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr);

      /* No route was found - we send to the default route instead. */
      if(route == NULL) {
#if CETIC_6LBR_SMARTBRIDGE
        if (uip_ipaddr_prefixcmp(&wsn_net_prefix, &UIP_IP_BUF->destipaddr, 64)) {
          /* In smart-bridge mode, there is no route towards hosts on the Ethernet side
          Therefore we have to check the destination and assume the host is on-link */
          nexthop = &UIP_IP_BUF->destipaddr;
        } else
#endif
#if CETIC_6LBR_ROUTER && UIP_CONF_IPV6_RPL
        if (is_dodag_root() && uip_ipaddr_prefixcmp(&wsn_net_prefix, &UIP_IP_BUF->destipaddr, 64)) {
          //In router mode, we drop packets towards unknown mote
          PRINTF("Dropping wsn packet with no route\n");
          uip_len = 0;
          return;
        } else
#endif
#if CETIC_6LBR_IP64
        if(ip64_addr_is_ip64(&UIP_IP_BUF->destipaddr)) {
#if UIP_CONF_IPV6_RPL
          rpl_remove_header();
#endif
          IP64_CONF_UIP_FALLBACK_INTERFACE.output();
          uip_len = 0;
          uip_ext_len = 0;
          return;
        }
        else
#endif
        {
          PRINTF("tcpip_ipv6_output: no route found, using default route\n");
          nexthop = uip_ds6_defrt_choose();
        }
        if(nexthop == NULL) {
#ifdef UIP_FALLBACK_INTERFACE
	  PRINTF("FALLBACK: removing ext hdrs & setting proto %d %d\n", 
		 uip_ext_len, *((uint8_t *)UIP_IP_BUF + 40));
	  if(uip_ext_len > 0) {
	    extern void remove_ext_hdr(void);
	    uint8_t proto = *((uint8_t *)UIP_IP_BUF + 40);
	    remove_ext_hdr();
	    /* This should be copied from the ext header... */
	    UIP_IP_BUF->proto = proto;
	  }
	  UIP_FALLBACK_INTERFACE.output();
#else
          PRINTF("tcpip_ipv6_output: Destination off-link but no route\n");
#endif /* !UIP_FALLBACK_INTERFACE */
          uip_clear_buf();
          return;
        }

      } else {
        /* A route was found, so we look up the nexthop neighbor for
           the route. */
        nexthop = uip_ds6_route_nexthop(route);

        /* If the nexthop is dead, for example because the neighbor
           never responded to link-layer acks, we drop its route. */
        if(nexthop == NULL) {
#if UIP_CONF_IPV6_RPL
          /* If we are running RPL, and if we are the root of the
             network, we'll trigger a DIO before we remove
             the route. */
          rpl_dag_t *dag;

          dag = (rpl_dag_t *)route->state.dag;
          if(dag != NULL) {
            rpl_reset_dio_timer(dag->instance);
          }
#endif /* UIP_CONF_IPV6_RPL */
          uip_ds6_route_rm(route);

          /* We don't have a nexthop to send the packet to, so we drop
             it. */
          return;
        }
      }
#if TCPIP_CONF_ANNOTATE_TRANSMISSIONS
      if(nexthop != NULL) {
        static uint8_t annotate_last;
        static uint8_t annotate_has_last = 0;

        if(annotate_has_last) {
          printf("#L %u 0; red\n", annotate_last);
        }
        printf("#L %u 1; red\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
        annotate_last = nexthop->u8[sizeof(uip_ipaddr_t) - 1];
        annotate_has_last = 1;
      }
#endif /* TCPIP_CONF_ANNOTATE_TRANSMISSIONS */
    }

    /* End of next hop determination */

#if UIP_CONF_IPV6_RPL
    if(rpl_update_header_final(nexthop)) {
      uip_clear_buf();
      return;
    }
#endif /* UIP_CONF_IPV6_RPL */
    nbr = uip_ds6_nbr_lookup(nexthop);
    if(nbr == NULL) {
#if UIP_ND6_SEND_NA
#if CETIC_6LBR && UIP_CONF_IPV6_RPL
      /* Don't perform NUD if it has been disabled for WSN */
      if((nvm_data.global_flags & CETIC_GLOBAL_DISABLE_WSN_NUD) != 0 &&
         uip_ipaddr_prefixcmp(&wsn_net_prefix, &UIP_IP_BUF->destipaddr, 64) &&
         route != NULL) {
        uip_clear_buf();
        return;
      }
#endif
      if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE)) == NULL) {
        uip_clear_buf();
        return;
      } else {
#if UIP_CONF_IPV6_QUEUE_PKT
        /* Copy outgoing pkt in the queuing buffer for later transmit. */
        if(uip_packetqueue_alloc(&nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) {
          memcpy(uip_packetqueue_buf(&nbr->packethandle), UIP_IP_BUF, uip_len);
          uip_packetqueue_set_buflen(&nbr->packethandle, uip_len);
        }
#endif
      /* RFC4861, 7.2.2:
       * "If the source address of the packet prompting the solicitation is the
       * same as one of the addresses assigned to the outgoing interface, that
       * address SHOULD be placed in the IP Source Address of the outgoing
       * solicitation.  Otherwise, any one of the addresses assigned to the
       * interface should be used."*/
       if(uip_ds6_is_my_addr(&UIP_IP_BUF->srcipaddr)){
          uip_nd6_ns_output(&UIP_IP_BUF->srcipaddr, NULL, &nbr->ipaddr);
        } else {
          uip_nd6_ns_output(NULL, NULL, &nbr->ipaddr);
        }

        stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000);
        nbr->nscount = 1;
        /* Send the first NS try from here (multicast destination IP address). */
      }
#else /* UIP_ND6_SEND_NA */
      uip_len = 0;
      return;  
#endif /* UIP_ND6_SEND_NA */
    } else {
#if UIP_ND6_SEND_NA
      if(nbr->state == NBR_INCOMPLETE) {
        PRINTF("tcpip_ipv6_output: nbr cache entry incomplete\n");
#if UIP_CONF_IPV6_QUEUE_PKT
        /* Copy outgoing pkt in the queuing buffer for later transmit and set
           the destination nbr to nbr. */
        if(uip_packetqueue_alloc(&nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) {
          memcpy(uip_packetqueue_buf(&nbr->packethandle), UIP_IP_BUF, uip_len);
          uip_packetqueue_set_buflen(&nbr->packethandle, uip_len);
        }
#endif /*UIP_CONF_IPV6_QUEUE_PKT*/
        uip_clear_buf();
        return;
      }
      /* Send in parallel if we are running NUD (nbc state is either STALE,
         DELAY, or PROBE). See RFC 4861, section 7.3.3 on node behavior. */
#if CETIC_6LBR && UIP_CONF_IPV6_RPL
      /* Don't update nbr state if we don't want to perform NUD for WSN */
      if((nvm_data.global_flags & CETIC_GLOBAL_DISABLE_WSN_NUD) == 0 ||
         !uip_ipaddr_prefixcmp(&wsn_net_prefix, &UIP_IP_BUF->destipaddr, 64) ||
         route == NULL)
#endif
      if(nbr->state == NBR_STALE) {
        nbr->state = NBR_DELAY;
        stimer_set(&nbr->reachable, UIP_ND6_DELAY_FIRST_PROBE_TIME);
        nbr->nscount = 0;
        PRINTF("tcpip_ipv6_output: nbr cache entry stale moving to delay\n");
      }
#endif /* UIP_ND6_SEND_NA */

      tcpip_output(uip_ds6_nbr_get_ll(nbr));

#if UIP_CONF_IPV6_QUEUE_PKT
      /*
       * Send the queued packets from here, may not be 100% perfect though.
       * This happens in a few cases, for example when instead of receiving a
       * NA after sendiong a NS, you receive a NS with SLLAO: the entry moves
       * to STALE, and you must both send a NA and the queued packet.
       */
      if(uip_packetqueue_buflen(&nbr->packethandle) != 0) {
        uip_len = uip_packetqueue_buflen(&nbr->packethandle);
        memcpy(UIP_IP_BUF, uip_packetqueue_buf(&nbr->packethandle), uip_len);
        uip_packetqueue_free(&nbr->packethandle);
        tcpip_output(uip_ds6_nbr_get_ll(nbr));
      }
#endif /*UIP_CONF_IPV6_QUEUE_PKT*/

      uip_clear_buf();
      return;
    }
  }
  /* Multicast IP destination address. */
  tcpip_output(NULL);
  uip_clear_buf();
}