Ejemplo n.º 1
0
/*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr,
                uint8_t isrouter, uint8_t state)
{
  uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr);
  if(nbr) {
    uip_ipaddr_copy(&nbr->ipaddr, ipaddr);
    nbr->isrouter = isrouter;
    nbr->state = state;
  #if UIP_CONF_IPV6_QUEUE_PKT
    uip_packetqueue_new(&nbr->packethandle);
  #endif /* UIP_CONF_IPV6_QUEUE_PKT */
    /* timers are set separately, for now we put them in expired state */
    stimer_set(&nbr->reachable, 0);
    stimer_set(&nbr->sendns, 0);
    nbr->nscount = 0;
    PRINTF("Adding neighbor with ip addr ");
    PRINT6ADDR(ipaddr);
    PRINTF(" link addr ");
    PRINTLLADDR(lladdr);
    PRINTF(" state %u\n", state);
    NEIGHBOR_STATE_CHANGED(nbr);
    return nbr;
  } else {
    PRINTF("uip_ds6_nbr_add drop ip addr ");
    PRINT6ADDR(ipaddr);
    PRINTF(" link addr (%p) ", lladdr);
    PRINTLLADDR(lladdr);
    PRINTF(" state %u\n", state);
    return NULL;
  }
}
Ejemplo n.º 2
0
/*---------------------------------------------------------------------------*/
static int
parse(struct net_buf *buf)
{
  frame802154_t frame;
  int hdr_len;
  
  hdr_len = frame802154_parse(packetbuf_dataptr(buf), packetbuf_datalen(buf), &frame);
  
  if(hdr_len && packetbuf_hdrreduce(buf, hdr_len)) {
    packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_TYPE, frame.fcf.frame_type);
    
    if(frame.fcf.dest_addr_mode) {
      if(frame.dest_pid != mac_src_pan_id &&
          frame.dest_pid != FRAME802154_BROADCASTPANDID) {
        /* Packet to another PAN */
        PRINTF("15.4: for another pan %u (0x%x)\n", frame.dest_pid,
               frame.dest_pid);
        return FRAMER_FAILED;
      }
      if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) {
        packetbuf_set_addr(buf, PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr);
      }
    }
    packetbuf_set_addr(buf, PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr);
    packetbuf_set_attr(buf, PACKETBUF_ATTR_PENDING, frame.fcf.frame_pending);
    /*    packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, frame.fcf.ack_required);*/
    packetbuf_set_attr(buf, PACKETBUF_ATTR_PACKET_ID, frame.seq);
    
#if LLSEC802154_SECURITY_LEVEL
    if(frame.fcf.security_enabled) {
      packetbuf_set_attr(buf, PACKETBUF_ATTR_SECURITY_LEVEL, frame.aux_hdr.security_control.security_level);
      packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, frame.aux_hdr.frame_counter.u16[0]);
      packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, frame.aux_hdr.frame_counter.u16[1]);
#if LLSEC802154_USES_EXPLICIT_KEYS
      packetbuf_set_attr(buf, PACKETBUF_ATTR_KEY_ID_MODE, frame.aux_hdr.security_control.key_id_mode);
      packetbuf_set_attr(buf, PACKETBUF_ATTR_KEY_INDEX, frame.aux_hdr.key_index);
      packetbuf_set_attr(buf, PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1, frame.aux_hdr.key_source.u16[0]);
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
    }
#endif /* LLSEC802154_SECURITY_LEVEL */

    PRINTF("15.4-IN: %2X ", frame.fcf.frame_type);
    PRINTLLADDR((const uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_SENDER));
    PRINTF(" ");
    PRINTLLADDR((const uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER));
    PRINTF(" %d %u (%u)\n", hdr_len, packetbuf_datalen(buf), packetbuf_totlen(buf));

#ifdef FRAMER_802154_HANDLER
    if(FRAMER_802154_HANDLER(&frame)) {
      return FRAMER_FRAME_HANDLED;
    }
#endif
    
    return hdr_len;
  }
  return FRAMER_FAILED;
}
Ejemplo n.º 3
0
/*---------------------------------------------------------------------------*/
static uint8_t
input_packet(struct net_buf *buf)
{
  frame802154_t frame;
  int len;

  len = packetbuf_datalen(buf);
  PRINTF("6MAC: received %d bytes\n", len);

  if(frame802154_parse(packetbuf_dataptr(buf), len, &frame) &&
     packetbuf_hdrreduce(buf, len - frame.payload_len)) {
    if(frame.fcf.dest_addr_mode) {
      if(frame.dest_pid != mac_src_pan_id &&
         frame.dest_pid != FRAME802154_BROADCASTPANDID) {
        /* Not broadcast or for our PAN */
        PRINTF("6MAC: for another pan %u (0x%x)\n", frame.dest_pid,
               frame.dest_pid);
        goto error;
      }
      if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) {
        packetbuf_set_addr(buf, PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr);
#if !NETSTACK_CONF_BRIDGE_MODE
        if(!linkaddr_cmp(packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER),
                         &linkaddr_node_addr)) {
          /* Not for this node */
	  PRINTF("6MAC: not for us, we are ");
	  PRINTLLADDR((uip_lladdr_t *)&linkaddr_node_addr);
	  PRINTF(" recipient is ");
	  PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER));
	  PRINTF("\n");
	  goto error;
        }
#endif
      }
    }
    packetbuf_set_addr(buf, PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr);

    PRINTF("6MAC-IN: type 0x%X sender ", frame.fcf.frame_type);
    PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_SENDER));
    PRINTF(" receiver ");
    PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER));
    PRINTF(" len %u\n", packetbuf_datalen(buf));
    return NETSTACK_MAC.input(buf);
  } else {
    PRINTF("6MAC: failed to parse hdr\n");
  }
error:
  return 0;
}
Ejemplo n.º 4
0
/*---------------------------------------------------------------------------*/
void
uip_ds6_link_neighbor_callback(int status, int numtx)
{
  const linkaddr_t *dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
  if(linkaddr_cmp(dest, &linkaddr_null)) {
    return;
  }

  LINK_NEIGHBOR_CALLBACK(dest, status, numtx);

#if UIP_DS6_LL_NUD
  if(status == MAC_TX_OK) {
    uip_ds6_nbr_t *nbr;
    nbr = uip_ds6_nbr_ll_lookup((uip_lladdr_t *)dest);
    if(nbr != NULL &&
        (nbr->state == NBR_STALE || nbr->state == NBR_DELAY ||
         nbr->state == NBR_PROBE)) {
      nbr->state = NBR_REACHABLE;
      stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
      PRINTF("uip-ds6-neighbor : received a link layer ACK : ");
      PRINTLLADDR((uip_lladdr_t *)dest);
      PRINTF(" is reachable.\n");
    }
  }
#endif /* UIP_DS6_LL_NUD */

}
Ejemplo n.º 5
0
/*---------------------------------------------------------------------------*/
void
neighbor_info_packet_sent(int status, int numtx)
{
  const rimeaddr_t *dest;
  link_metric_t packet_metric;
#if UIP_DS6_LL_NUD
  uip_ds6_nbr_t *nbr;
#endif /* UIP_DS6_LL_NUD */

  dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
  if(rimeaddr_cmp(dest, &rimeaddr_null)) {
    return;
  }

  packet_metric = numtx;

  PRINTF("neighbor-info: packet sent to %d.%d, status=%d, metric=%u\n",
	dest->u8[sizeof(*dest) - 2], dest->u8[sizeof(*dest) - 1],
	status, (unsigned)packet_metric);

  switch(status) {
  case MAC_TX_OK:
    add_neighbor(dest);
#if UIP_DS6_LL_NUD
    nbr = uip_ds6_nbr_ll_lookup((uip_lladdr_t *)dest);
    if(nbr != NULL &&
       (nbr->state == STALE || nbr->state == DELAY || nbr->state == PROBE)) {
      nbr->state = REACHABLE;
//      stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
      PRINTF("neighbor-info : received a link layer ACK : ");
      PRINTLLADDR((uip_lladdr_t *)dest);
      PRINTF(" is reachable.\n");
    }
#endif /* UIP_DS6_LL_NUD */
    break;
  case MAC_TX_NOACK:
    add_neighbor(dest);
    printf("neighbor-info: ETX_NOACK_PENALTY\n");
    packet_metric = ETX_NOACK_PENALTY;
    break;
  default:
    /* Do not penalize the ETX when collisions or transmission
       errors occur. */
    return;
  }

  update_metric(dest, packet_metric);
}
Ejemplo n.º 6
0
/*---------------------------------------------------------------------------*/
void ntp_client_send(struct uip_udp_conn *udpconn, uip_ipaddr_t srv_ipaddr, struct ntp_msg clientmsg)
{
	clientmsg.status = MODE_CLIENT | (NTP_VERSION << 3) | LI_ALARM;

	clock_get_time(&ts);
	//TODO: could be in danger when timer change!
	clientmsg.xmttime.int_partl = uip_htonl(ts.sec + JAN_1970);
	clientmsg.xmttime.fractionl = uip_htonl(ts.nsec);

	uip_udp_packet_sendto(udpconn, &clientmsg, sizeof(struct ntp_msg),
			&srv_ipaddr, UIP_HTONS(SERVER_PORT));
	PRINTF("Sent timestamp: %ld sec %ld nsec to ", ts.sec, ts.nsec);
#ifdef UIP_CONF_IPV6
	PRINT6ADDR(&udpconn->ripaddr);
#else
	PRINTLLADDR(&udpconn->ripaddr);
#endif /* UIP_CONF_IPV6 */
	PRINTF("\n");
}
Ejemplo n.º 7
0
/*---------------------------------------------------------------------------*/
void
uip_ds6_link_neighbor_callback(int status, int numtx)
{
  const linkaddr_t *dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
  if(linkaddr_cmp(dest, &linkaddr_null)) {
    return;
  }

  LINK_NEIGHBOR_CALLBACK(dest, status, numtx);

#if UIP_DS6_LL_NUD
  /* From RFC4861, page 72, last paragraph of section 7.3.3:
   *
   *         "In some cases, link-specific information may indicate that a path to
   *         a neighbor has failed (e.g., the resetting of a virtual circuit). In
   *         such cases, link-specific information may be used to purge Neighbor
   *         Cache entries before the Neighbor Unreachability Detection would do
   *         so. However, link-specific information MUST NOT be used to confirm
   *         the reachability of a neighbor; such information does not provide
   *         end-to-end confirmation between neighboring IP layers."
   *
   * However, we assume that receiving a link layer ack ensures the delivery
   * of the transmitted packed to the IP stack of the neighbour. This is a
   * fair assumption and allows battery powered nodes save some battery by
   * not re-testing the state of a neighbour periodically if it
   * acknowledges link packets. */
  if(status == MAC_TX_OK) {
    uip_ds6_nbr_t *nbr;
    nbr = uip_ds6_nbr_ll_lookup((uip_lladdr_t *)dest);
    if(nbr != NULL && nbr->state != NBR_INCOMPLETE) {
      nbr->state = NBR_REACHABLE;
      stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
      PRINTF("uip-ds6-neighbor : received a link layer ACK : ");
      PRINTLLADDR((uip_lladdr_t *)dest);
      PRINTF(" is reachable.\n");
    }
  }
#endif /* UIP_DS6_LL_NUD */

}
Ejemplo n.º 8
0
/*---------------------------------------------------------------------------*/
static void
set_rime_addr(void)
{
  int i;
  union {
    u8_t u8[8];
  }eui64;
  
  //rimeaddr_t lladdr;
  
  int8u *stm32w_eui64 = ST_RadioGetEui64();
  {
          int8u c;
          for(c = 0; c < 8; c++) {      // Copy the EUI-64 to lladdr converting from Little-Endian to Big-Endian.
                  eui64.u8[c] = stm32w_eui64[7 - c];
          }
  }
  PRINTF("\n\rRadio EUI-64:");
  PRINTLLADDR(eui64);
  PRINTF("\n\r");
  
#if UIP_CONF_IPV6
  memcpy(&uip_lladdr.addr, &eui64, sizeof(uip_lladdr.addr));
#endif

#if UIP_CONF_IPV6
  rimeaddr_set_node_addr((rimeaddr_t *)&eui64);
#else  
  rimeaddr_set_node_addr((rimeaddr_t *)&eui64.u8[8-RIMEADDR_SIZE]);
#endif

  printf("Rime started with address ");
  for(i = 0; i < sizeof(rimeaddr_t) - 1; i++) {
    printf("%d.", rimeaddr_node_addr.u8[i]);
  }
  printf("%d\n", rimeaddr_node_addr.u8[i]);
  
}
Ejemplo n.º 9
0
/*---------------------------------------------------------------------------*/
rpl_parent_t *
rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
{
  rpl_parent_t *p = NULL;
  /* Is the parent known by ds6? Drop this request if not.
   * Typically, the parent is added upon receiving a DIO. */
  const uip_lladdr_t *lladdr = uip_ds6_nbr_lladdr_from_ipaddr(addr);

  PRINTF("RPL: rpl_add_parent lladdr %p ", lladdr);
  PRINTLLADDR(lladdr);
  PRINTF(" ");
  PRINT6ADDR(addr);
  PRINTF("\n");
  if(lladdr != NULL) {
    /* Add parent in rpl_parents */
    p = nbr_table_add_lladdr(rpl_parents, (linkaddr_t *)lladdr);
    if(p == NULL) {
      PRINTF("RPL: rpl_add_parent p NULL\n");
    } else {
      uip_ds6_nbr_t *nbr;
      nbr = rpl_get_nbr(p);

      p->dag = dag;
      p->rank = dio->rank;
      p->dtsn = dio->dtsn;

      /* Check whether we have a neighbor that has not gotten a link metric yet */
      if(nbr != NULL && nbr->link_metric == 0) {
	nbr->link_metric = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
      }
#if RPL_DAG_MC != RPL_DAG_MC_NONE
      memcpy(&p->mc, &dio->mc, sizeof(p->mc));
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
    }
  }

  return p;
}
Ejemplo n.º 10
0
/* Attempt to associate to a network form an incoming EB */
static int
tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp)
{
  frame802154_t frame;
  struct ieee802154_ies ies;
  uint8_t hdrlen;
  int i;

  if(input_eb == NULL || tsch_packet_parse_eb(input_eb->payload, input_eb->len,
                                              &frame, &ies, &hdrlen, 0) == 0) {
    PRINTF("TSCH:! failed to parse EB (len %u)\n", input_eb->len);
    return 0;
  }

  current_asn = ies.ie_asn;
  tsch_join_priority = ies.ie_join_priority + 1;

#if TSCH_JOIN_SECURED_ONLY
  if(frame.fcf.security_enabled == 0) {
    PRINTF("TSCH:! parse_eb: EB is not secured\n");
    return 0;
  }
#endif /* TSCH_JOIN_SECURED_ONLY */
  
#if TSCH_SECURITY_ENABLED
  if(!tsch_security_parse_frame(input_eb->payload, hdrlen,
      input_eb->len - hdrlen - tsch_security_mic_len(&frame),
      &frame, (linkaddr_t*)&frame.src_addr, &current_asn)) {
    PRINTF("TSCH:! parse_eb: failed to authenticate\n");
    return 0;
  }
#endif /* TSCH_SECURITY_ENABLED */

#if !TSCH_SECURITY_ENABLED
  if(frame.fcf.security_enabled == 1) {
    PRINTF("TSCH:! parse_eb: we do not support security, but EB is secured\n");
    return 0;
  }
#endif /* !TSCH_SECURITY_ENABLED */

#if TSCH_JOIN_MY_PANID_ONLY
  /* Check if the EB comes from the PAN ID we expect */
  if(frame.src_pid != IEEE802154_PANID) {
    PRINTF("TSCH:! parse_eb: PAN ID %x != %x\n", frame.src_pid, IEEE802154_PANID);
    return 0;
  }
#endif /* TSCH_JOIN_MY_PANID_ONLY */

  /* There was no join priority (or 0xff) in the EB, do not join */
  if(ies.ie_join_priority == 0xff) {
    PRINTF("TSCH:! parse_eb: no join priority\n");
    return 0;
  }

  /* TSCH timeslot timing */
  for(i = 0; i < tsch_ts_elements_count; i++) {
    if(ies.ie_tsch_timeslot_id == 0) {
      tsch_timing[i] = US_TO_RTIMERTICKS(tsch_default_timing_us[i]);
    } else {
      tsch_timing[i] = US_TO_RTIMERTICKS(ies.ie_tsch_timeslot[i]);
    }
  }

  /* TSCH hopping sequence */
  if(ies.ie_channel_hopping_sequence_id == 0) {
    memcpy(tsch_hopping_sequence, TSCH_DEFAULT_HOPPING_SEQUENCE, sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE));
    ASN_DIVISOR_INIT(tsch_hopping_sequence_length, sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE));
  } else {
    if(ies.ie_hopping_sequence_len <= sizeof(tsch_hopping_sequence)) {
      memcpy(tsch_hopping_sequence, ies.ie_hopping_sequence_list, ies.ie_hopping_sequence_len);
      ASN_DIVISOR_INIT(tsch_hopping_sequence_length, ies.ie_hopping_sequence_len);
    } else {
      PRINTF("TSCH:! parse_eb: hopping sequence too long (%u)\n", ies.ie_hopping_sequence_len);
      return 0;
    }
  }

#if TSCH_CHECK_TIME_AT_ASSOCIATION > 0
  /* Divide by 4k and multiply again to avoid integer overflow */
  uint32_t expected_asn = 4096 * TSCH_CLOCK_TO_SLOTS(clock_time() / 4096, tsch_timing_timeslot_length); /* Expected ASN based on our current time*/
  int32_t asn_threshold = TSCH_CHECK_TIME_AT_ASSOCIATION * 60ul * TSCH_CLOCK_TO_SLOTS(CLOCK_SECOND, tsch_timing_timeslot_length);
  int32_t asn_diff = (int32_t)current_asn.ls4b - expected_asn;
  if(asn_diff > asn_threshold) {
    PRINTF("TSCH:! EB ASN rejected %lx %lx %ld\n",
           current_asn.ls4b, expected_asn, asn_diff);
    return 0;
  }
#endif

#if TSCH_INIT_SCHEDULE_FROM_EB
  /* Create schedule */
  if(ies.ie_tsch_slotframe_and_link.num_slotframes == 0) {
#if TSCH_SCHEDULE_WITH_6TISCH_MINIMAL
    PRINTF("TSCH: parse_eb: no schedule, setting up minimal schedule\n");
    tsch_schedule_create_minimal();
#else
    PRINTF("TSCH: parse_eb: no schedule\n");
#endif
  } else {
    /* First, empty current schedule */
    tsch_schedule_remove_all_slotframes();
    /* We support only 0 or 1 slotframe in this IE */
    int num_links = ies.ie_tsch_slotframe_and_link.num_links;
    if(num_links <= FRAME802154E_IE_MAX_LINKS) {
      int i;
      struct tsch_slotframe *sf = tsch_schedule_add_slotframe(
          ies.ie_tsch_slotframe_and_link.slotframe_handle,
          ies.ie_tsch_slotframe_and_link.slotframe_size);
      for(i = 0; i < num_links; i++) {
        tsch_schedule_add_link(sf,
            ies.ie_tsch_slotframe_and_link.links[i].link_options,
            LINK_TYPE_ADVERTISING, &tsch_broadcast_address,
            ies.ie_tsch_slotframe_and_link.links[i].timeslot, ies.ie_tsch_slotframe_and_link.links[i].channel_offset);
      }
    } else {
      PRINTF("TSCH:! parse_eb: too many links in schedule (%u)\n", num_links);
      return 0;
    }
  }
#endif /* TSCH_INIT_SCHEDULE_FROM_EB */

  if(tsch_join_priority < TSCH_MAX_JOIN_PRIORITY) {
    struct tsch_neighbor *n;

    /* Add coordinator to list of neighbors, lock the entry */
    n = tsch_queue_add_nbr((linkaddr_t *)&frame.src_addr);

    if(n != NULL) {
      tsch_queue_update_time_source((linkaddr_t *)&frame.src_addr);

#ifdef TSCH_CALLBACK_JOINING_NETWORK
      TSCH_CALLBACK_JOINING_NETWORK();
#endif

      /* Set PANID */
      frame802154_set_pan_id(frame.src_pid);

      /* Synchronize on EB */
      tsch_slot_operation_sync(timestamp - tsch_timing[tsch_ts_tx_offset], &current_asn);

      /* Update global flags */
      tsch_is_associated = 1;
      tsch_is_pan_secured = frame.fcf.security_enabled;

      /* Association done, schedule keepalive messages */
      tsch_schedule_keepalive();

      PRINTF("TSCH: association done, sec %u, PAN ID %x, asn-%x.%lx, jp %u, timeslot id %u, hopping id %u, slotframe len %u with %u links, from ",
             tsch_is_pan_secured,
             frame.src_pid,
             current_asn.ms1b, current_asn.ls4b, tsch_join_priority,
             ies.ie_tsch_timeslot_id,
             ies.ie_channel_hopping_sequence_id,
             ies.ie_tsch_slotframe_and_link.slotframe_size,
             ies.ie_tsch_slotframe_and_link.num_links);
      PRINTLLADDR((const uip_lladdr_t *)&frame.src_addr);
      PRINTF("\n");

      return 1;
    }
  }
  PRINTF("TSCH:! did not associate.\n");
  return 0;
}
Ejemplo n.º 11
0
/*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
uip_ds6_nbr_add(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr,
                uint8_t isrouter, uint8_t state)
{
  int r;

  r = uip_ds6_list_loop
     ((uip_ds6_element_t *)uip_ds6_nbr_cache, UIP_DS6_NBR_NB,
      sizeof(uip_ds6_nbr_t), ipaddr, 128,
      (uip_ds6_element_t **)&locnbr);

  if(r == FREESPACE) {
    locnbr->isused = 1;
    uip_ipaddr_copy(&locnbr->ipaddr, ipaddr);
    if(lladdr != NULL) {
      memcpy(&locnbr->lladdr, lladdr, UIP_LLADDR_LEN);
    } else {
      memset(&locnbr->lladdr, 0, UIP_LLADDR_LEN);
    }
    locnbr->isrouter = isrouter;
    locnbr->state = state;
#if UIP_CONF_IPV6_QUEUE_PKT
    uip_packetqueue_new(&locnbr->packethandle);
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
    /* timers are set separately, for now we put them in expired state */
    stimer_set(&locnbr->reachable, 0);
    stimer_set(&locnbr->sendns, 0);
    locnbr->nscount = 0;
    PRINTF("Adding neighbor with ip addr ");
    PRINT6ADDR(ipaddr);
    PRINTF("link addr ");
    PRINTLLADDR((&(locnbr->lladdr)));
    PRINTF("state %u\n", state);
    NEIGHBOR_STATE_CHANGED(locnbr);

    locnbr->last_lookup = clock_time();
    return locnbr;
  } else if(r == NOSPACE) {
    /* We did not find any empty slot on the neighbor list, so we need
       to remove one old entry to make room. */
    uip_ds6_nbr_t *n, *oldest;
    clock_time_t oldest_time;

    oldest = NULL;
    oldest_time = clock_time();

    for(n = uip_ds6_nbr_cache;
        n < &uip_ds6_nbr_cache[UIP_DS6_NBR_NB];
        n++) {
      if(n->isused) {
        if(n->last_lookup < oldest_time) {
          oldest = n;
          oldest_time = n->last_lookup;
        }
      }
    }
    if(oldest != NULL) {
      uip_ds6_nbr_rm(oldest);
      return uip_ds6_nbr_add(ipaddr, lladdr, isrouter, state);
    }
  }
  PRINTF("uip_ds6_nbr_add drop\n");
  return NULL;
}
Ejemplo n.º 12
0
/*---------------------------------------------------------------------------*/
static uint8_t
process_request()
{
  uint8_t len;
  uint8_t count; /* How many did we pack? */
  uint8_t i;
  uint8_t left;
  uint8_t entry_size;

  left = VIZTOOL_MAX_PAYLOAD_LEN - 1;
  len = 2; /* start filling the buffer from position [2] */
  count = 0;
  if(buf[0] == REQUEST_TYPE_ND) {
    /* Neighbors */
    PRINTF("Neighbors\n");
    for(i = buf[1]; i < UIP_DS6_NBR_NB; i++) {
      if(uip_ds6_nbr_cache[i].isused) {
        entry_size = sizeof(i) + sizeof(uip_ipaddr_t) + sizeof(uip_lladdr_t)
            + sizeof(uip_ds6_nbr_cache[i].state);
        PRINTF("%02u: ", i);
        PRINT6ADDR(&uip_ds6_nbr_cache[i].ipaddr);
        PRINTF(" - ");
        PRINTLLADDR(&uip_ds6_nbr_cache[i].lladdr);
        PRINTF(" - %u\n", uip_ds6_nbr_cache[i].state);

        memcpy(buf + len, &i, sizeof(i));
        len += sizeof(i);
        memcpy(buf + len, &uip_ds6_nbr_cache[i].ipaddr, sizeof(uip_ipaddr_t));
        len += sizeof(uip_ipaddr_t);
        memcpy(buf + len, &uip_ds6_nbr_cache[i].lladdr, sizeof(uip_lladdr_t));
        len += sizeof(uip_lladdr_t);
        memcpy(buf + len, &uip_ds6_nbr_cache[i].state,
            sizeof(uip_ds6_nbr_cache[i].state));
        len += sizeof(uip_ds6_nbr_cache[i].state);

        count++;
        left -= entry_size;

        if(left < entry_size) {
          break;
        }
      }
    }
  } else if(buf[0] == REQUEST_TYPE_RT) {
    uint32_t flip = 0;
    PRINTF("Routing table\n");
    for(i = buf[1]; i < UIP_DS6_ROUTE_NB; i++) {
      if(uip_ds6_routing_table[i].isused) {
        entry_size = sizeof(i) + sizeof(uip_ds6_routing_table[i].ipaddr)
            + sizeof(uip_ds6_routing_table[i].length)
            + sizeof(uip_ds6_routing_table[i].metric)
            + sizeof(uip_ds6_routing_table[i].nexthop)
            + sizeof(uip_ds6_routing_table[i].state.lifetime)
            + sizeof(uip_ds6_routing_table[i].state.learned_from);

        memcpy(buf + len, &i, sizeof(i));
        len += sizeof(i);
        memcpy(buf + len, &uip_ds6_routing_table[i].ipaddr,
            sizeof(uip_ds6_routing_table[i].ipaddr));
        len += sizeof(uip_ds6_routing_table[i].ipaddr);
        memcpy(buf + len, &uip_ds6_routing_table[i].length,
            sizeof(uip_ds6_routing_table[i].length));
        len += sizeof(uip_ds6_routing_table[i].length);
        memcpy(buf + len, &uip_ds6_routing_table[i].metric,
            sizeof(uip_ds6_routing_table[i].metric));
        len += sizeof(uip_ds6_routing_table[i].metric);
        memcpy(buf + len, &uip_ds6_routing_table[i].nexthop,
            sizeof(uip_ds6_routing_table[i].nexthop));
        len += sizeof(uip_ds6_routing_table[i].nexthop);

        PRINT6ADDR(&uip_ds6_routing_table[i].ipaddr);
        PRINTF(" - %02x", uip_ds6_routing_table[i].length);
        PRINTF(" - %02x", uip_ds6_routing_table[i].metric);
        PRINTF(" - ");
        PRINT6ADDR(&uip_ds6_routing_table[i].nexthop);

        flip = uip_htonl(uip_ds6_routing_table[i].state.lifetime);
        memcpy(buf + len, &flip, sizeof(flip));
        len += sizeof(flip);
        PRINTF(" - %08lx", uip_ds6_routing_table[i].state.lifetime);

        memcpy(buf + len, &uip_ds6_routing_table[i].state.learned_from,
            sizeof(uip_ds6_routing_table[i].state.learned_from));
        len += sizeof(uip_ds6_routing_table[i].state.learned_from);

        PRINTF(" - %02x [%u]\n", uip_ds6_routing_table[i].state.learned_from,
             entry_size);

        count++;
        left -= entry_size;

        if(left < entry_size) {
          break;
        }
      }
    }
  } else if (buf[0] == REQUEST_TYPE_DRT) {
    uint32_t flip = 0;
    PRINTF("Default Routes\n");
    for(i = buf[1]; i < UIP_DS6_DEFRT_NB; i++) {
      if(uip_ds6_defrt_list[i].isused) {
        entry_size = sizeof(i) + sizeof(uip_ds6_defrt_list[i].ipaddr)
            + sizeof(uip_ds6_defrt_list[i].isinfinite);

        memcpy(buf + len, &i, sizeof(i));
        len += sizeof(i);
        memcpy(buf + len, &uip_ds6_defrt_list[i].ipaddr,
            sizeof(uip_ds6_defrt_list[i].ipaddr));
        len += sizeof(uip_ds6_defrt_list[i].ipaddr);
        memcpy(buf + len, &uip_ds6_defrt_list[i].isinfinite,
            sizeof(uip_ds6_defrt_list[i].isinfinite));
        len += sizeof(uip_ds6_defrt_list[i].isinfinite);

        PRINT6ADDR(&uip_ds6_defrt_list[i].ipaddr);
        PRINTF(" - %u\n", uip_ds6_defrt_list[i].isinfinite);
        count++;
        left -= entry_size;

        if(left < entry_size) {
          break;
        }
      }
    }
  } else if (buf[0] == REQUEST_TYPE_ADDR) {
    PRINTF("Unicast Addresses\n");
    for(i = buf[1]; i < UIP_DS6_ADDR_NB; i++) {
      if(uip_ds6_if.addr_list[i].isused) {
        entry_size = sizeof(i) + sizeof(uip_ds6_if.addr_list[i].ipaddr);

        memcpy(buf + len, &i, sizeof(i));
        len += sizeof(i);
        memcpy(buf + len, &uip_ds6_if.addr_list[i].ipaddr,
            sizeof(uip_ds6_if.addr_list[i].ipaddr));
        len += sizeof(uip_ds6_if.addr_list[i].ipaddr);

        PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
        PRINTF("\n");
        count++;
        left -= entry_size;

        if(left < entry_size) {
          break;
        }
      }
    }
  } else if (buf[0] == REQUEST_TYPE_TOTALS) {
    memset(&buf[2], 0, 4);
    for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
      if(uip_ds6_if.addr_list[i].isused) {
        buf[2]++;
      }
    }
    for(i = 0; i < UIP_DS6_NBR_NB; i++) {
      if(uip_ds6_nbr_cache[i].isused) {
        buf[3]++;
      }
    }
    for(i = 0; i < UIP_DS6_ROUTE_NB; i++) {
      if(uip_ds6_routing_table[i].isused) {
        buf[4]++;
      }
    }
    for(i = 0; i < UIP_DS6_DEFRT_NB; i++) {
      if(uip_ds6_defrt_list[i].isused) {
        buf[5]++;
      }
    }
    len += 4;
    count = 4;
  } else {
    return 0;
  }
  buf[1] = count;
  return len;
}
Ejemplo n.º 13
0
/* Parse a IEEE 802.15.4e TSCH Enhanced Beacon (EB) */
int
tsch_packet_parse_eb(const uint8_t *buf, int buf_size,
                     frame802154_t *frame, struct ieee802154_ies *ies, uint8_t *hdr_len, int frame_without_mic)
{
    uint8_t curr_len = 0;
    int ret;

    if(frame == NULL || buf_size < 0) {
        return 0;
    }

    /* Parse 802.15.4-2006 frame, i.e. all fields before Information Elements */
    if((ret = frame802154_parse((uint8_t *)buf, buf_size, frame)) == 0) {
        PRINTF("TSCH:! parse_eb: failed to parse frame\n");
        return 0;
    }

    if(frame->fcf.frame_version < FRAME802154_IEEE802154E_2012
            || frame->fcf.frame_type != FRAME802154_BEACONFRAME) {
        PRINTF("TSCH:! parse_eb: frame is not a valid TSCH beacon. Frame version %u, type %u, FCF %02x %02x\n",
               frame->fcf.frame_version, frame->fcf.frame_type, buf[0], buf[1]);
        PRINTF("TSCH:! parse_eb: frame was from 0x%x/", frame->src_pid);
        PRINTLLADDR((const uip_lladdr_t *)&frame->src_addr);
        PRINTF(" to 0x%x/", frame->dest_pid);
        PRINTLLADDR((const uip_lladdr_t *)&frame->dest_addr);
        PRINTF("\n");
        return 0;
    }

    if(hdr_len != NULL) {
        *hdr_len = ret;
    }
    curr_len += ret;

    if(ies != NULL) {
        memset(ies, 0, sizeof(struct ieee802154_ies));
        ies->ie_join_priority = 0xff; /* Use max value in case the Beacon does not include a join priority */
    }
    if(frame->fcf.ie_list_present) {
        /* Calculate space needed for the security MIC, if any, before attempting to parse IEs */
        int mic_len = 0;
#if LLSEC802154_ENABLED
        if(!frame_without_mic) {
            mic_len = tsch_security_mic_len(frame);
            if(buf_size < curr_len + mic_len) {
                return 0;
            }
        }
#endif /* LLSEC802154_ENABLED */

        /* Parse information elements. We need to substract the MIC length, as the exact payload len is needed while parsing */
        if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) {
            PRINTF("TSCH:! parse_eb: failed to parse IEs\n");
            return 0;
        }
        curr_len += ret;
    }

    if(hdr_len != NULL) {
        *hdr_len += ies->ie_payload_ie_offset;
    }

    return curr_len;
}
Ejemplo n.º 14
0
/*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
uip_ds6_nbr_add(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr,
                u8_t isrouter, u8_t state)
{
  int r;

  r = uip_ds6_list_loop
     ((uip_ds6_element_t *) uip_ds6_nbr_cache, UIP_DS6_NBR_NB,
      sizeof(uip_ds6_nbr_t), ipaddr, 128,
      (uip_ds6_element_t **) &locnbr);
  //  printf("r %d\n", r);

  if(r == FREESPACE) {
    locnbr->isused = 1;
    uip_ipaddr_copy(&(locnbr->ipaddr), ipaddr);
    if(lladdr != NULL) {
      memcpy(&(locnbr->lladdr), lladdr, UIP_LLADDR_LEN);
    } else {
      memset(&(locnbr->lladdr), 0, UIP_LLADDR_LEN);
    }
    locnbr->isrouter = isrouter;
    locnbr->state = state;
    /* timers are set separately, for now we put them in expired state */
    stimer_set(&(locnbr->reachable), 0);
    stimer_set(&(locnbr->sendns), 0);
    locnbr->nscount = 0;
    PRINTF("Adding neighbor with ip addr");
    PRINT6ADDR(ipaddr);
    PRINTF("link addr");
    PRINTLLADDR((&(locnbr->lladdr)));
    PRINTF("state %u\n", state);
    NEIGHBOR_STATE_CHANGED(locnbr);

    locnbr->last_lookup = clock_time();
    //    printf("add %p\n", locnbr);
    return locnbr;
  } else if(r == NOSPACE) {
    /* We did not find any empty slot on the neighbor list, so we need
       to remove one old entry to make room. */
    uip_ds6_nbr_t *n, *oldest;
    clock_time_t oldest_time;

    oldest = NULL;
    oldest_time = clock_time();

    for(n = uip_ds6_nbr_cache;
        n < &uip_ds6_nbr_cache[UIP_DS6_NBR_NB];
        n++) {
      if(n->isused) {
        if((n->last_lookup < oldest_time) && (uip_ds6_is_nbr_garbage_collectible(n))) {
        	/* We do not want to remove any non-garbage-collectible entry */
          oldest = n;
          oldest_time = n->last_lookup;
        }
      }
    }
    if(oldest != NULL) {
      //      printf("rm3\n");
      uip_ds6_nbr_rm(oldest);
      locdefrt = uip_ds6_defrt_lookup(&oldest->ipaddr);
      uip_ds6_defrt_rm(locdefrt);
      uip_ds6_reg_cleanup_defrt(locdefrt);
			return uip_ds6_nbr_add(ipaddr, lladdr, isrouter, state);
    }
  }
  PRINTF("uip_ds6_nbr_add drop\n");
  return NULL;
}
Ejemplo n.º 15
0
/*---------------------------------------------------------------------------*/
static int
create_frame(struct net_buf *buf, int do_create)
{
  frame802154_t params;
  int hdr_len;

  /* init to zeros */
  memset(&params, 0, sizeof(params));

  /* Build the FCF. */
  params.fcf.frame_type = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_TYPE);
  params.fcf.frame_pending = packetbuf_attr(buf, PACKETBUF_ATTR_PENDING);
  if(packetbuf_holds_broadcast(buf)) {
    params.fcf.ack_required = 0;
  } else {
    params.fcf.ack_required = packetbuf_attr(buf, PACKETBUF_ATTR_MAC_ACK);
  }
  params.fcf.panid_compression = 0;

  /* Insert IEEE 802.15.4 (2006) version bits. */
  params.fcf.frame_version = FRAME802154_IEEE802154_2006;
  
#if LLSEC802154_SECURITY_LEVEL
  if(packetbuf_attr(buf, PACKETBUF_ATTR_SECURITY_LEVEL)) {
    params.fcf.security_enabled = 1;
  }
  /* Setting security-related attributes */
  params.aux_hdr.security_control.security_level = packetbuf_attr(buf, PACKETBUF_ATTR_SECURITY_LEVEL);
  params.aux_hdr.frame_counter.u16[0] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1);
  params.aux_hdr.frame_counter.u16[1] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3);
#if LLSEC802154_USES_EXPLICIT_KEYS
  params.aux_hdr.security_control.key_id_mode = packetbuf_attr(buf, PACKETBUF_ATTR_KEY_ID_MODE);
  params.aux_hdr.key_index = packetbuf_attr(buf, PACKETBUF_ATTR_KEY_INDEX);
  params.aux_hdr.key_source.u16[0] = packetbuf_attr(buf, PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1);
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
#endif /* LLSEC802154_SECURITY_LEVEL */

  /* Increment and set the data sequence number. */
  if(!do_create) {
    /* Only length calculation - no sequence number is needed and
       should not be consumed. */

  } else if(packetbuf_attr(buf, PACKETBUF_ATTR_MAC_SEQNO)) {
    params.seq = packetbuf_attr(buf, PACKETBUF_ATTR_MAC_SEQNO);

  } else {
    params.seq = framer_802154_next_seqno();
    packetbuf_set_attr(buf, PACKETBUF_ATTR_MAC_SEQNO, params.seq);
  }

  /* Complete the addressing fields. */
  /**
     \todo For phase 1 the addresses are all long. We'll need a mechanism
     in the rime attributes to tell the mac to use long or short for phase 2.
  */
  if(LINKADDR_SIZE == 2) {
    /* Use short address mode if linkaddr size is short. */
    params.fcf.src_addr_mode = FRAME802154_SHORTADDRMODE;
  } else {
    params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
  }
  params.dest_pid = mac_dst_pan_id;

  if(packetbuf_holds_broadcast(buf)) {
    /* Broadcast requires short address mode. */
    params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
    params.dest_addr[0] = 0xFF;
    params.dest_addr[1] = 0xFF;

  } else {
    linkaddr_copy((linkaddr_t *)&params.dest_addr,
                  packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER));
    /* Use short address mode if linkaddr size is small */
    if(LINKADDR_SIZE == 2) {
      params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
    } else {
      params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE;
    }
  }

  /* Set the source PAN ID to the global variable. */
  params.src_pid = mac_src_pan_id;

  /*
   * Set up the source address using only the long address mode for
   * phase 1.
   */
  linkaddr_copy((linkaddr_t *)&params.src_addr, &linkaddr_node_addr);

  params.payload = packetbuf_dataptr(buf);
  params.payload_len = packetbuf_datalen(buf);
  hdr_len = frame802154_hdrlen(&params);
  if(!do_create) {
    /* Only calculate header length */
    return hdr_len;

  } else if(packetbuf_hdralloc(buf, hdr_len)) {
    frame802154_create(&params, packetbuf_hdrptr(buf), hdr_len);

    PRINTF("15.4-OUT: %2X ", params.fcf.frame_type);
    PRINTLLADDR((const uip_lladdr_t *)params.dest_addr);
    PRINTF(" %d %u (%u)\n", hdr_len, packetbuf_datalen(buf), packetbuf_totlen(buf));

    return hdr_len;
  } else {
    PRINTF("15.4-OUT: too large header: %u\n", hdr_len);
    return FRAMER_FAILED;
  }
}
Ejemplo n.º 16
0
/*---------------------------------------------------------------------------*/
static uint8_t
send_packet(struct net_buf *buf, mac_callback_t sent, void *ptr)
{
  frame802154_t params;
  uint8_t len;
  uint8_t ret = 0;

  /* init to zeros */
  memset(&params, 0, sizeof(params));

  /* Build the FCF. */
  params.fcf.frame_type = FRAME802154_DATAFRAME;
  params.fcf.security_enabled = 0;
  params.fcf.frame_pending = 0;
  params.fcf.ack_required = packetbuf_attr(buf, PACKETBUF_ATTR_RELIABLE);
  params.fcf.panid_compression = 0;

  /* Insert IEEE 802.15.4 (2003) version bit. */
  params.fcf.frame_version = FRAME802154_IEEE802154_2003;

  /* Increment and set the data sequence number. */
  params.seq = mac_dsn++;

  /* Complete the addressing fields. */
  /**
     \todo For phase 1 the addresses are all long. We'll need a mechanism
     in the rime attributes to tell the mac to use long or short for phase 2.
  */
  params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
  params.dest_pid = mac_dst_pan_id;

  if(packetbuf_holds_broadcast(buf)) {
    /* Broadcast requires short address mode. */
    params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
    params.dest_addr[0] = 0xFF;
    params.dest_addr[1] = 0xFF;

  } else {
    linkaddr_copy((linkaddr_t *)&params.dest_addr,
                  packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER));
    params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE;
  }

  /* Set the source PAN ID to the global variable. */
  params.src_pid = mac_src_pan_id;

  /*
   * Set up the source address using only the long address mode for
   * phase 1.
   */
#if NETSTACK_CONF_BRIDGE_MODE
  linkaddr_copy((linkaddr_t *)&params.src_addr,packetbuf_addr(PACKETBUF_ADDR_SENDER));
#else
  linkaddr_copy((linkaddr_t *)&params.src_addr, &linkaddr_node_addr);
#endif

  params.payload = packetbuf_dataptr(buf);
  params.payload_len = packetbuf_datalen(buf);
  len = frame802154_hdrlen(&params);
  if(packetbuf_hdralloc(buf, len)) {
    frame802154_create(&params, packetbuf_hdrptr(buf), len);

    PRINTF("6MAC-UT: type %X dest ", params.fcf.frame_type);
    PRINTLLADDR((uip_lladdr_t *)params.dest_addr);
    PRINTF(" len %u datalen %u (totlen %u)\n", len, packetbuf_datalen(buf),
	   packetbuf_totlen(buf));

    ret = NETSTACK_RADIO.send(buf, packetbuf_hdrptr(buf), packetbuf_totlen(buf));
    if(sent) {
      switch(ret) {
      case RADIO_TX_OK:
        sent(buf, ptr, MAC_TX_OK, 1);
        break;
      case RADIO_TX_ERR:
        sent(buf, ptr, MAC_TX_ERR, 1);
        break;
      case RADIO_TX_COLLISION:
        sent(buf, ptr, MAC_TX_COLLISION, 1);
        break;
      }
    }
  } else {
    PRINTF("6MAC-UT: too large header: %u\n", len);
  }

  return ret;
}