Exemplo n.º 1
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 */

}
Exemplo n.º 2
0
/*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
rpl_get_nbr(rpl_parent_t *parent)
{
  linkaddr_t *lladdr = NULL;
  lladdr = nbr_table_get_lladdr(rpl_parents, parent);
  if(lladdr != NULL) {
    return uip_ds6_nbr_ll_lookup((uip_lladdr_t*) lladdr);
  } else {
    return NULL;
  }
}
Exemplo n.º 3
0
/*---------------------------------------------------------------------------*/
uint16_t
rpl_get_parent_link_metric(const uip_lladdr_t *addr)
{
  uip_ds6_nbr_t *nbr;
  nbr = uip_ds6_nbr_ll_lookup(addr);
  
  if(nbr != NULL) {
    return nbr->link_metric;
  } else {
    return 0;
  }
}
Exemplo n.º 4
0
uint8_t
switch_lookup_get_itf_for(const uip_lladdr_t *lladdr)
{
#if UIP_SWITCH_LOOKUP
  if(lladdr != NULL && !linkaddr_cmp((linkaddr_t *)lladdr, &linkaddr_null)) {
    uip_ds6_nbr_t *nbr;
    nbr = uip_ds6_nbr_ll_lookup(lladdr);
    if(nbr) {
      return nbr->ifindex;
    }
  }
#endif
  return NETWORK_ITF_UNKNOWN;
}
Exemplo 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);
}
Exemplo n.º 6
0
void
switch_lookup_learn_addr(const uip_lladdr_t *lladdr, uint8_t ifindex)
{
#if UIP_SWITCH_LOOKUP
  if(lladdr != NULL && !linkaddr_cmp((linkaddr_t *)lladdr, &linkaddr_null)) {
    uip_ds6_nbr_t *nbr;
    nbr = uip_ds6_nbr_ll_lookup(lladdr);
    if(nbr) {
      nbr->ifindex = ifindex;
    } else {
      LOG6LBR_LLADDR(PACKET, lladdr, "No neighbor found for ");
    }
  } else {
    LOG6LBR_DEBUG("Can not learn broadcast or null addr\n");
  }
#endif
}
Exemplo 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 */

}
Exemplo n.º 8
0
/*---------------------------------------------------------------------------*/
uip_ipaddr_t *
uip_ds6_nbr_ipaddr_from_lladdr(const uip_lladdr_t *lladdr)
{
  uip_ds6_nbr_t *nbr = uip_ds6_nbr_ll_lookup(lladdr);
  return nbr ? &nbr->ipaddr : NULL;
}
Exemplo n.º 9
0
void
eth_input(void)
{
	int processFrame = 0;

	//Packet type filtering
	//---------------------
	//Keep only IPv6 traffic
	if(BUF->type != UIP_HTONS(UIP_ETHTYPE_IPV6)) {
		LOG6LBR_PRINTF(PACKET, PF_IN, "eth_input: Dropping packet type=0x%04x\n", uip_ntohs(BUF->type));
		uip_len = 0;
		return;
	}
	if((UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] + 40 < uip_len) {
#if CONTIKI_TARGET_NATIVE
		if(ethernet_has_fcs) {
			uip_len = (UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] + 40;
		} else
#endif
		{
			LOG6LBR_PRINTF(PACKET, PF_IN, "eth_input: packet size different than reported in IPv6 header, %d vs %d\n", uip_len, (UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] + 40);
		}
	} else if((UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] + 40 > uip_len) {
		LOG6LBR_PRINTF(PACKET, PF_IN, "eth_input: packet shorter than reported in IPv6 header, %d vs %d\n", uip_len, (UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] + 40);
		uip_len = 0;
		return;
	}

	//Packet source Filtering
	//-----------------------
	/* IPv6 uses 33-33-xx-xx-xx-xx prefix for multicast ND stuff */
	if((BUF->dest.addr[0] == 0x33) && (BUF->dest.addr[1] == 0x33)) {
		processFrame = 1;
	} else if((BUF->dest.addr[0] == 0xFF)
			&& (BUF->dest.addr[1] == 0xFF)
			&& (BUF->dest.addr[2] == 0xFF)
			&& (BUF->dest.addr[3] == 0xFF)
			&& (BUF->dest.addr[4] == 0xFF)
			&& (BUF->dest.addr[5] == 0xFF)) {
		/* IPv6 does not use broadcast addresses, hence this should not happen */
		LOG6LBR_PRINTF(PACKET, PF_IN, "eth_input: Dropping broadcast packet\n");
		uip_len = 0;
		return;
	}

	//Destination filtering
	//---------------------
	if(memcmp((uint8_t *) & eth_mac_addr, BUF->dest.addr, 6) == 0) {
		processFrame = 1;
	} else {
		if(!processFrame) {
			// Also search our neighbor list to see if we should accept it
			if(uip_ds6_nbr_ll_lookup((const uip_lladdr_t*)BUF->dest.addr)) {
				processFrame = 1;
			}
		}
	}

	//Handle packet
	//-------------
	if(processFrame) {
		LOG6LBR_PRINTF(PACKET, PF_IN, "eth_input: Processing frame\n");
		send_to_uip();
	} else {
		printf("eth_input: Dropping frame, not for us or any known node\n");
		//Drop packet
		uip_len = 0;
	}
}