Ejemplo n.º 1
0
void
eth_drv_send(void)
{
  LOG6LBR_PRINTF(PACKET, ETH_OUT, "write: %d\n", uip_len + ETHERNET_LLH_LEN);
  LOG6LBR_COND_FUNC(DUMP, ETH_OUT,
    int i;
#if WIRESHARK_IMPORT_FORMAT
    printf("0000");
    for(i = 0; i < ETHERNET_LLH_LEN; i++)
      printf(" %02x", ll_header[i]);
    for(i = 0; i < uip_len; i++)
      printf(" %02x", uip_buf[i]);
#else
    printf("         ");
    for(i = 0; i < uip_len + ETHERNET_LLH_LEN; i++) {
      if ( i < ETHERNET_LLH_LEN ) {
        printf("%02x", ll_header[i]);
      } else {
        printf("%02x", uip_buf[i - ETHERNET_LLH_LEN]);
      }
      if((i & 3) == 3)
        printf(" ");
      if((i & 15) == 15)
        printf("\n         ");
    }
#endif
    printf("\n");
  )
Ejemplo n.º 2
0
/*---------------------------------------------------------------------------*/
static void
packet_input(void)
{
  LOG6LBR_PRINTF(PACKET, RADIO_IN, "read: %d\n", packetbuf_datalen());
  if (LOG6LBR_COND(DUMP, RADIO_IN)) {
    uint8_t *data = packetbuf_dataptr();
    int len = packetbuf_datalen();
    int i;
#if WIRESHARK_IMPORT_FORMAT
    printf("0000");
    for(i = 0; i < len; i++)
      printf(" %02x", data[i]);
#else
    printf("         ");
    for(i = 0; i < len; i++) {
      printf("%02x", data[i]);
      if((i & 3) == 3)
        printf(" ");
      if((i & 15) == 15)
        printf("\n         ");
    }
#endif
    printf("\n");
  }
  if(NETSTACK_FRAMER.parse() < 0) {
    LOG6LBR_ERROR("br-rdc: failed to parse %u\n", packetbuf_datalen());
  } else {
    NETSTACK_MAC.input();
  }
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
uint8_t
wireless_output(const uip_lladdr_t * src, const uip_lladdr_t * dest)
{
	int ret;

	//Packet filtering
	//----------------
	if(uip_len == 0) {
		LOG6LBR_ERROR("wireless_output: uip_len = 0\n");
		return 0;
	}
	if(dest && linkaddr_cmp((linkaddr_t *) & dest,
			(linkaddr_t *) & wsn_mac_addr)) {
		LOG6LBR_ERROR("wireless_output: sending to self\n");
		return 0;
	}

	//Packet sending
	//--------------
	if(wireless_outputfunc != NULL) {
		LOG6LBR_PRINTF(PACKET, PF_OUT, "wireless_output: sending packet\n");
		ret = wireless_outputfunc(dest);
	} else {
		ret = 0;
	}
	return ret;
}
Ejemplo n.º 5
0
void
eth_drv_send(uint8_t *packet, uint16_t len)
{
  LOG6LBR_PRINTF(PACKET, ETH_OUT, "write: %d\n", len);
  LOG6LBR_DUMP_PACKET(ETH_OUT, packet, len);

  eth_dev_output(packet, len);
}
Ejemplo n.º 6
0
/*---------------------------------------------------------------------------*/
void
eth_dev_output(uint8_t * data, int len)
{
  if(write(eth_fd, data, len) != len) {
    LOG6LBR_FATAL("write() : %s\n", strerror(errno));
    exit(1);
  }
  LOG6LBR_PRINTF(PACKET, TAP_OUT, "write: %d\n", len);
}
Ejemplo n.º 7
0
/*---------------------------------------------------------------------------*/
static int
eth_dev_input(unsigned char *data, int maxlen)
{
  int size;

  if((size = read(eth_fd, data, maxlen)) == -1) {
    LOG6LBR_FATAL("read() : %s\n", strerror(errno));
    exit(1);
  }
  LOG6LBR_PRINTF(PACKET, TAP_IN, "read: %d\n", size);
  return size;
}
Ejemplo n.º 8
0
/*---------------------------------------------------------------------------*/
static void
packet_input(void)
{
    LOG6LBR_PRINTF(PACKET, RADIO_IN, "read: %d\n", packetbuf_datalen());
    LOG6LBR_DUMP_PACKET(RADIO_IN, packetbuf_dataptr(), packetbuf_datalen());

    if(NETSTACK_FRAMER.parse() < 0) {
        LOG6LBR_ERROR("br-rdc: failed to parse %u\n", packetbuf_datalen());
        native_rdc_parse_error++;
    } else {
        NETSTACK_MAC.input();
    }
}
Ejemplo n.º 9
0
/*---------------------------------------------------------------------------*/
static void
send_packet(mac_callback_t sent, void *ptr)
{
  int size;

  /* 3 bytes per packet attribute is required for serialization */
  uint8_t buf[PACKETBUF_NUM_ATTRS * 3 + PACKETBUF_SIZE + 3];
  int sid;

  packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &linkaddr_node_addr);

  /* ack or not ? */
  packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);

  if(NETSTACK_FRAMER.create_and_secure() < 0) {
    /* Failed to allocate space for headers */
    LOG6LBR_ERROR("br-rdc: send failed, too large header\n");
    mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1);

  } else {
    /* here we send the data over SLIP to the radio-chip */
    size = 0;
    if(sixlbr_config_slip_serialize_tx_attrs) {
      size = packetutils_serialize_atts(&buf[3], sizeof(buf) - 3);
    }
    if(size < 0 || size + packetbuf_totlen() + 3 > sizeof(buf)) {
      LOG6LBR_ERROR("br-rdc: send failed, too large header\n");
      mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1);
    } else {
      sid = setup_callback(sent, ptr);
      if (sid != -1) {
        LOG6LBR_PRINTF(PACKET, RADIO_OUT, "write: %d (sid: %d, cb: %d)\n", packetbuf_datalen(), sid, callback_count);
        LOG6LBR_DUMP_PACKET(RADIO_OUT, packetbuf_dataptr(), packetbuf_datalen());

        buf[0] = '!';
        buf[1] = 'S';
        buf[2] = sid;             /* sequence or session number for this packet */

        /* Copy packet data */
        memcpy(&buf[3 + size], packetbuf_hdrptr(), packetbuf_totlen());
        callbacks[sid].buf_len = packetbuf_totlen() + size + 3;
        memcpy(callbacks[sid].buf, buf, callbacks[sid].buf_len);
        write_to_slip(buf, callbacks[sid].buf_len);
      } else {
        LOG6LBR_INFO("native-rdc queue full\n");
        mac_call_sent_callback(sent, ptr, MAC_TX_NOACK, 1);
      }
    }
  }
}
Ejemplo n.º 10
0
static int
eth_output(const uip_lladdr_t * src, const uip_lladdr_t * dest)
{
	//Packet filtering
	//----------------
	if(uip_len == 0) {
		LOG6LBR_ERROR("eth_output: uip_len = 0\n");
		return 0;
	}

	if(dest && linkaddr_cmp((linkaddr_t *) & dest,
			(linkaddr_t *) & eth_mac64_addr)) {
		LOG6LBR_ERROR("ethernet_output: sending to self\n");
		return 0;
	}

	//Create packet header
	//--------------------
	//Packet type
	BUF->type = uip_htons(UIP_ETHTYPE_IPV6);

	//Destination address
	if(IS_BROADCAST_ADDR(dest)) {
		BUF->dest.addr[0] = 0x33;
		BUF->dest.addr[1] = 0x33;
		BUF->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
		BUF->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
		BUF->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
		BUF->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
	} else {
		memcpy(BUF->dest.addr, dest, 6);
	}

	//Source address
	if ( src != NULL ) {
		memcpy(BUF->src.addr, src, 6);
	} else {
		memcpy(BUF->src.addr, eth_mac_addr, 6);
	}
	//Sending packet
	//--------------
	LOG6LBR_PRINTF(PACKET, PF_OUT, "eth_output: Sending packet to Ethernet\n");
	eth_drv_send();

	return 1;
}
Ejemplo n.º 11
0
uint8_t
wireless_output(const uip_lladdr_t * src, const uip_lladdr_t * dest)
{
  int ret;

  //Packet filtering
  //----------------
  if(uip_len == 0) {
    LOG6LBR_ERROR("wireless_output: uip_len = 0\n");
    return 0;
  }
  if(dest && linkaddr_cmp((linkaddr_t *) & dest,
      (linkaddr_t *) & wsn_mac_addr)) {
    LOG6LBR_ERROR("wireless_output: sending to self\n");
    return 0;
  }

#if CETIC_6LBR_WSN_FILTER_RA
  //Filter out RA/RS towards WSN
  if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 &&
     (UIP_ICMP_BUF->type == ICMP6_RS || UIP_ICMP_BUF->type == ICMP6_RA)) {
    return 0;
  }
#endif

  //Packet sending
  //--------------
  if(wireless_outputfunc != NULL) {
#if CETIC_6LBR_TRANSPARENTBRIDGE
	if ( src != NULL ) {
      platform_set_wsn_mac((linkaddr_t *)src);
	}
#endif
	LOG6LBR_PRINTF(PACKET, PF_OUT, "wireless_output: sending packet\n");
    ret = wireless_outputfunc(dest);
#if CETIC_6LBR_TRANSPARENTBRIDGE
	if ( src != NULL ) {
      //Restore node address
	  platform_set_wsn_mac((linkaddr_t *) & wsn_mac_addr);
	}
#endif
  } else {
    ret = 0;
  }
  return ret;
}
Ejemplo n.º 12
0
/*---------------------------------------------------------------------------*/
static void
write_to_serial(int outfd, const uint8_t * inbuf, int len)
{
  const uint8_t *p = inbuf;
  int i;

  slip_message_sent++;

  LOG6LBR_PRINTF(PACKET, SLIP_OUT, "write: %d\n", len);

  if (LOG6LBR_COND(DUMP, SLIP_OUT)) {
    printf("         ");
    for(i = 0; i < len; i++) {
      printf("%02x", p[i]);
      if((i & 3) == 3)
        printf(" ");
      if((i & 15) == 15)
        printf("\n         ");
    }
    printf("\n");
  }

  /* It would be ``nice'' to send a SLIP_END here but it's not
   * really necessary.
   */
  /* slip_send(outfd, SLIP_END); */

  for(i = 0; i < len; i++) {
    switch (p[i]) {
    case SLIP_END:
      slip_send(outfd, SLIP_ESC);
      slip_send(outfd, SLIP_ESC_END);
      break;
    case SLIP_ESC:
      slip_send(outfd, SLIP_ESC);
      slip_send(outfd, SLIP_ESC_ESC);
      break;
    default:
      slip_send(outfd, p[i]);
      break;
    }
  }
  slip_send(outfd, SLIP_END);
  PROGRESS("t");
}
Ejemplo n.º 13
0
/*---------------------------------------------------------------------------*/
void
eth_drv_input(uint8_t *packet, uint16_t len)
{
  LOG6LBR_PRINTF(PACKET, ETH_IN, "read: %d\n", len);
  LOG6LBR_DUMP_PACKET(ETH_IN, packet, len);

#if CETIC_6LBR_IP64
  if((nvm_data.global_flags & CETIC_GLOBAL_IP64) != 0 &&
      (((struct uip_eth_hdr *)packet)->type != UIP_HTONS(UIP_ETHTYPE_IPV6))) {
    IP64_INPUT(packet, len);
  } else {
#endif
    uip_len = len - UIP_LLH_LEN;
    memcpy(uip_buf, packet, len);
    eth_input();
#if CETIC_6LBR_IP64
  }
#endif
}
Ejemplo n.º 14
0
static uint8_t
bridge_output(const uip_lladdr_t * dest)
{
  int isBroadcast = IS_BROADCAST_ADDR(dest);
  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");
  }
  //Filter WSN vs Ethernet segment traffic
  if(IS_EUI48_ADDR(dest)) {
    eth_output(NULL, dest);
  } else if(IS_EUI64_ADDR(dest)) {
    wireless_output(NULL, dest);
  } else {
    if (UIP_IP_BUF->proto != UIP_PROTO_ICMP6 || UIP_ICMP_BUF->type != ICMP6_NA) {
      wireless_output(NULL, dest);
    }
    eth_output(NULL, dest);
  }
  return 0;
}
Ejemplo n.º 15
0
/*---------------------------------------------------------------------------*/
void
packet_sent(uint8_t sessionid, uint8_t status, uint8_t tx)
{
    LOG6LBR_PRINTF(PACKET, RADIO_OUT, "sid ack: %d (%d, %d)\n", sessionid, status, tx);
    if(sessionid < MAX_CALLBACKS) {
        struct tx_callback *callback;

        callback = &callbacks[sessionid];
        if (callback->isused) {
            callback_count--;
            callback->isused = 0;
            packetbuf_clear();
            packetbuf_attr_copyfrom(callback->attrs, callback->addrs);
            ctimer_stop(&callback->timeout);
            mac_call_sent_callback(callback->cback, callback->ptr, status, tx);
        } else {
            LOG6LBR_ERROR("br-rdc: ack received for unknown packet (%d)\n", callback->sid);
        }
    } else {
        LOG6LBR_ERROR("*** ERROR: too high session id %d\n", sessionid);
    }
}
Ejemplo n.º 16
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;
}
Ejemplo n.º 17
0
static int
eth_output(uip_lladdr_t * src, uip_lladdr_t * dest)
{
  if(IS_BROADCAST_ADDR(dest)) {
    LOG6LBR_PRINTF(PACKET, PF_OUT, "eth_output: broadcast\n");
  } else {
    LOG6LBR_LLADDR_PRINTF(PACKET, PF_OUT, dest, "eth_output: ");
  }

  //Packet filtering
  //----------------
  if(uip_len == 0) {
    LOG6LBR_ERROR("eth_output: uip_len = 0\n");
    return 0;
  }
#if CETIC_6LBR_ETH_FILTER_RPL
  //Filter out RPL (broadcast) traffic
  if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 &&
     UIP_ICMP_BUF->type == ICMP6_RPL) {
    //LOG6LBR_PRINTF(PACKET, PF_OUT, "eth_output: Filtering out RPL traffic\n");
    return 0;
  }
#endif

  //IP packet alteration
  //--------------------
#if CETIC_6LBR_ROUTER
  //Modify source address
  if((nvm_data.mode & CETIC_MODE_REWRITE_ADDR_MASK) != 0
     && uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)
     && uip_ds6_is_my_addr(&UIP_IP_BUF->srcipaddr)) {
    LOG6LBR_PRINTF(PACKET, PF_OUT, "eth_output: Update src address\n");
    uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &eth_ip_local_addr);
  }
#endif
#if CETIC_6LBR_SMARTBRIDGE
  //Reset Hop Limit when in smart-bridge for NDP packets
  //TODO: Is this still needed after #4467 ?
  if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 &&
     (UIP_ICMP_BUF->type == ICMP6_NS || UIP_ICMP_BUF->type == ICMP6_NA
      || UIP_ICMP_BUF->type == ICMP6_RS || UIP_ICMP_BUF->type == ICMP6_RA)) {
    UIP_IP_BUF->ttl = 255;
  }
#endif
#if CETIC_6LBR_SMARTBRIDGE || CETIC_6LBR_TRANSPARENTBRIDGE
  //Remove ROUTER flag when in bridge mode
  if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type == ICMP6_NA) {
    //LOG6LBR_PRINTF(PACKET, PF_OUT, "eth_output: Updating NA\n");
    UIP_ND6_NA_BUF->flagsreserved &= ~UIP_ND6_NA_FLAG_ROUTER;
  }
#endif
  //Some IP packets have link layer in them, need to change them around!
  mac_translateIPLinkLayer(ll_8023_type);

  //IP header alteration
  //--------------------
  //Remove Hop-by-hop extension header
  if(uip_ext_len > 0) {
    extern void remove_ext_hdr(void);
    uint8_t proto = *((uint8_t *) UIP_IP_BUF + 40);

    remove_ext_hdr();
    UIP_IP_BUF->proto = proto;
  }
  //Create packet header
  //--------------------
  //Packet type
  BUF->type = uip_htons(UIP_ETHTYPE_IPV6);

  //Destination address
  if(IS_BROADCAST_ADDR(dest)) {
    BUF->dest.addr[0] = 0x33;
    BUF->dest.addr[1] = 0x33;
    BUF->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
    BUF->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
    BUF->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
    BUF->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
  } else {
    mac_createEthernetAddr(BUF->dest.addr, dest);
  }

  //Source address
  if ( src != NULL ) {
    mac_createEthernetAddr(BUF->src.addr, src);
  } else {
    memcpy(BUF->src.addr, eth_mac_addr, 6);
  }
  //Sending packet
  //--------------
  LOG6LBR_PRINTF(PACKET, PF_OUT, "eth_output: Sending packet to Ethernet\n");
  eth_drv_send();

  return 1;
}
Ejemplo n.º 18
0
void
eth_input(void)
{
#if CETIC_6LBR_TRANSPARENTBRIDGE || CETIC_6LBR_ONE_ITF || CETIC_6LBR_6LR
  uip_lladdr_t srcAddr;
#endif
  uip_lladdr_t destAddr;
  int processFrame = 0;
  int forwardFrame = 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;
  }
  //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)) {
    forwardFrame = 1;
    processFrame = 1;
    rimeaddr_copy((rimeaddr_t *) & destAddr, &rimeaddr_null);
  } 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;
  } else {
    /* Complex Address Translation */
    if(mac_createSicslowpanLongAddr(&(BUF->dest.addr[0]), &destAddr) == 0) {
      LOG6LBR_WARN("eth_input: Address translation failed\n");
      uip_len = 0;
      return;
    }
  }

  //Packet content rewriting
  //------------------------
  //Some IP packets have link layer in them, need to change them around!
  uint8_t transReturn = mac_translateIPLinkLayer(ll_802154_type);

  if(transReturn != 0) {
    LOG6LBR_WARN("eth_input: IPTranslation returns %d\n", transReturn);
  }

  //Destination filtering
  //---------------------
  if(memcmp((uint8_t *) & eth_mac_addr, BUF->dest.addr, 6) == 0) {
    processFrame = 1;
  } else {
#if CETIC_6LBR_TRANSPARENTBRIDGE
    //Not for us, forward it directly
    forwardFrame = 1;
#endif
  }

  //Handle packet
  //-------------
#if CETIC_6LBR_TRANSPARENTBRIDGE
  if(forwardFrame) {
    mac_createSicslowpanLongAddr(&(BUF->src.addr[0]), &srcAddr);
#if CETIC_6LBR_LEARN_RPL_MAC
    if (UIP_IP_BUF->proto == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type == ICMP6_RPL) {
      uint8_t *buffer = UIP_ICMP_PAYLOAD;
      uint16_t rank = (uint16_t)buffer[2] << 8 | buffer[2 + 1];
      if ( rank == RPL_MIN_HOPRANKINC ) {
    	platform_set_wsn_mac((rimeaddr_t *) &srcAddr);
        rpl_mac_known=1;
      }
    }
    if (!rpl_mac_known) {
      //Rpl Relay not yet configured, drop packet
      uip_len = 0;
      return;
    }
    if(rimeaddr_cmp((rimeaddr_t *) &srcAddr, &rimeaddr_node_addr) != 0) {
      //Only forward RplRoot packets
      LOG6LBR_LLADDR_PRINTF(PACKET, PF_IN, &destAddr, "eth_input: Forwarding frame to ");
      wireless_output(NULL, &destAddr);
    }
#else
    LOG6LBR_LLADDR_PRINTF(PACKET, PF_IN, &destAddr, "eth_input: Forwarding frame to ");
    wireless_output(&srcAddr, &destAddr);
#endif
  }
#endif
  if(processFrame) {
    LOG6LBR_PRINTF(PACKET, PF_IN, "eth_input: Processing frame\n");
#if CETIC_6LBR_ONE_ITF || CETIC_6LBR_6LR
  //RPL uses source packet address to populate its neighbor table
  //In this two modes RPL packets are incoming from Eth interface
  mac_createSicslowpanLongAddr(&(BUF->src.addr[0]), &srcAddr);
  packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (rimeaddr_t *) &srcAddr);
#endif
    send_to_uip();
  } else {
    //Drop packet
    uip_len = 0;
  }
}
Ejemplo n.º 19
0
/*---------------------------------------------------------------------------*/
static void
send_packet(mac_callback_t sent, void *ptr)
{
  int size;

  /* 3 bytes per packet attribute is required for serialization */
  uint8_t buf[PACKETBUF_NUM_ATTRS * 3 + PACKETBUF_SIZE + 3];
  uint8_t sid;

  packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr);

  /* ack or not ? */
  packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);

  if(NETSTACK_FRAMER.create() < 0) {
    /* Failed to allocate space for headers */
    LOG6LBR_ERROR("br-rdc: send failed, too large header\n");
    mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1);

  } else {
    /* here we send the data over SLIP to the radio-chip */
    size = 0;
#if SERIALIZE_ATTRIBUTES
    size = packetutils_serialize_atts(&buf[3], sizeof(buf) - 3);
#endif
    if(size < 0 || size + packetbuf_totlen() + 3 > sizeof(buf)) {
      LOG6LBR_ERROR("br-rdc: send failed, too large header\n");
      mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1);
    } else {
      LOG6LBR_PRINTF(PACKET, RADIO_OUT, "write: %d\n", packetbuf_datalen());
      if (LOG6LBR_COND(DUMP, RADIO_OUT)) {
        uint8_t *data = packetbuf_dataptr();
        int len = packetbuf_datalen();
        int i;
    #if WIRESHARK_IMPORT_FORMAT
        printf("0000");
        for(i = 0; i < len; i++)
          printf(" %02x", data[i]);
    #else
        printf("         ");
        for(i = 0; i < len; i++) {
          printf("%02x", data[i]);
          if((i & 3) == 3)
            printf(" ");
          if((i & 15) == 15)
            printf("\n         ");
        }
    #endif
        printf("\n");
      }

      sid = setup_callback(sent, ptr);

      buf[0] = '!';
      buf[1] = 'S';
      buf[2] = sid;             /* sequence or session number for this packet */

      /* Copy packet data */
      memcpy(&buf[3 + size], packetbuf_hdrptr(), packetbuf_totlen());

      write_to_slip(buf, packetbuf_totlen() + size + 3);
    }
  }
}
Ejemplo n.º 20
0
static int
eth_output(const uip_lladdr_t * src, const uip_lladdr_t * dest)
{
  if(IS_BROADCAST_ADDR(dest)) {
    LOG6LBR_PRINTF(PACKET, PF_OUT, "eth_output: broadcast\n");
  } else {
    LOG6LBR_LLADDR_PRINTF(PACKET, PF_OUT, dest, "eth_output: ");
  }

  //Packet filtering
  //----------------
  if(uip_len == 0) {
    LOG6LBR_ERROR("eth_output: uip_len = 0\n");
    return 0;
  }

  if(dest && linkaddr_cmp((linkaddr_t *) & dest,
      (linkaddr_t *) & eth_mac64_addr)) {
    LOG6LBR_ERROR("ethernet_output: sending to self\n");
    return 0;
  }

#if CETIC_6LBR_ETH_FILTER_RPL
  //Filter out RPL (broadcast) traffic
  if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 &&
     UIP_ICMP_BUF->type == ICMP6_RPL) {
    //LOG6LBR_PRINTF(PACKET, PF_OUT, "eth_output: Filtering out RPL traffic\n");
    return 0;
  }
#endif

  //IP packet alteration
  //--------------------
#if CETIC_6LBR_ROUTER
  //Modify source address
  if((nvm_data.mode & CETIC_MODE_REWRITE_ADDR_MASK) != 0
     && uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)
     && uip_ipaddr_cmp(&UIP_IP_BUF->srcipaddr, &wsn_ip_local_addr)) {
    LOG6LBR_PRINTF(PACKET, PF_OUT, "eth_output: Update src address\n");
    uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &eth_ip_local_addr);
    if(UIP_IP_BUF->proto == UIP_PROTO_UDP) {
#if UIP_UDP_CHECKSUMS
      /* Calculate UDP checksum. */
      UIP_UDP_BUF->udpchksum = 0;
      UIP_UDP_BUF->udpchksum = ~(uip_udpchksum());
      if(UIP_UDP_BUF->udpchksum == 0) {
        UIP_UDP_BUF->udpchksum = 0xffff;
      }
#endif /* UIP_UDP_CHECKSUMS */
    } else if(UIP_IP_BUF->proto == UIP_PROTO_TCP) {
      /* Calculate TCP checksum. */
      UIP_TCP_BUF->tcpchksum = 0;
      UIP_TCP_BUF->tcpchksum = ~(uip_tcpchksum());
    } else if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6) {
      /* Calculate ICMP checksum. */
      UIP_ICMP_BUF->icmpchksum = 0;
      UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
    }
  }
#endif
#if CETIC_6LBR_SMARTBRIDGE
  //Reset Hop Limit when in smart-bridge for NDP packets
  //TODO: Is this still needed after #4467 ?
  if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 &&
     (UIP_ICMP_BUF->type == ICMP6_NS || UIP_ICMP_BUF->type == ICMP6_NA
      || UIP_ICMP_BUF->type == ICMP6_RS || UIP_ICMP_BUF->type == ICMP6_RA)) {
    UIP_IP_BUF->ttl = 255;
  }
#endif
#if CETIC_6LBR_SMARTBRIDGE || CETIC_6LBR_TRANSPARENTBRIDGE
  //Remove ROUTER flag when in bridge mode
  if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type == ICMP6_NA) {
    //LOG6LBR_PRINTF(PACKET, PF_OUT, "eth_output: Updating NA\n");
    UIP_ND6_NA_BUF->flagsreserved &= ~UIP_ND6_NA_FLAG_ROUTER;
  }
#endif
  //Some IP packets have link layer in them, need to change them around!
  mac_translateIPLinkLayer(ll_8023_type);

  //IP header alteration
  //--------------------
#if UIP_CONF_IPV6_RPL
  rpl_remove_header();
#endif

  //Create packet header
  //--------------------
  //Packet type
  BUF->type = uip_htons(UIP_ETHTYPE_IPV6);

  //Destination address
  if(IS_BROADCAST_ADDR(dest)) {
    BUF->dest.addr[0] = 0x33;
    BUF->dest.addr[1] = 0x33;
    BUF->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
    BUF->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
    BUF->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
    BUF->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
  } else {
    mac_createEthernetAddr(BUF->dest.addr, dest);
  }

  //Source address
  if ( src != NULL ) {
    mac_createEthernetAddr(BUF->src.addr, src);
  } else {
    memcpy(BUF->src.addr, eth_mac_addr, 6);
  }
  //Sending packet
  //--------------
  LOG6LBR_PRINTF(PACKET, PF_OUT, "eth_output: Sending packet to Ethernet\n");
  eth_drv_send(uip_buf, uip_len + UIP_LLH_LEN);

  return 1;
}
Ejemplo n.º 21
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);
}
Ejemplo n.º 22
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;
	}
}
Ejemplo n.º 23
0
static void
wireless_input(void)
{
	LOG6LBR_PRINTF(PACKET, PF_IN, "wireless_input: processing frame\n");
	send_to_uip();
}
Ejemplo n.º 24
0
static void
wireless_input(void)
{
  int processFrame = 0;
  int forwardFrame = 0;

  LOG6LBR_PRINTF(PACKET, PF_IN, "wireless_input\n");

  //Source filtering
  //----------------
#if CETIC_6LBR_TRANSPARENTBRIDGE && CETIC_6LBR_LEARN_RPL_MAC
  if (!rpl_mac_known) {
    //Rpl Relay not yet configured, drop packet
    uip_len = 0;
    return;
  }
  if (rimeaddr_cmp
	  (packetbuf_addr(PACKETBUF_ADDR_SENDER),
	   & rimeaddr_node_addr) != 0) {
    LOG6LBR_WARN("WSN packet received with RplRoot address, another TB is within range, dropping it\n");
    //Drop packet
    uip_len = 0;
    return;
  }
#endif

  //Destination filtering
  //---------------------
  if(IS_BROADCAST_ADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER))) {      //Broadcast
    LOG6LBR_PRINTF(PACKET, PF_IN, "wireless_input : broadcast\n");
    forwardFrame = 1;
    processFrame = 1;
  } else {                      //unicast
    LOG6LBR_LLADDR_PRINTF(PACKET, PF_IN, (uip_lladdr_t *) packetbuf_addr(PACKETBUF_ADDR_RECEIVER), "wireless_input: dest: ");
    if(rimeaddr_cmp
       (packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
        (rimeaddr_t *) & wsn_mac_addr) != 0) {
      processFrame = 1;         //For us
    } else {                    //For another host
#if CETIC_6LBR_TRANSPARENTBRIDGE
      //Not for us, forward it directly
      forwardFrame = 1;
      LOG6LBR_PRINTF(PACKET, PF_IN, "wireless_input : to forward\n");
#endif
    }
  }

  //Packet forwarding
  //-----------------
#if CETIC_6LBR_TRANSPARENTBRIDGE
  if(forwardFrame) {
    LOG6LBR_PRINTF(PACKET, PF_IN, "wireless_input: forwarding frame\n");
    if(eth_output((uip_lladdr_t *) packetbuf_addr(PACKETBUF_ADDR_SENDER),
                  (uip_lladdr_t *) packetbuf_addr(PACKETBUF_ADDR_RECEIVER))) {
      //Restore packet as eth_output might have converted its content
      mac_translateIPLinkLayer(ll_802154_type);
    }
  }
#endif


  //Handle packet
  //-------------
  if(processFrame) {
    LOG6LBR_PRINTF(PACKET, PF_IN, "wireless_input: processing frame\n");
    send_to_uip();
  } else {
    //Drop packet
    uip_len = 0;
  }
}
Ejemplo n.º 25
0
/*
 * Read from serial, when we have a packet call slip_packet_input. No output
 * buffering, input buffered by stdio.
 */
void
serial_input(FILE * inslip)
{
  static unsigned char inbuf[2048];
  static int inbufptr = 0;
  int ret, i;
  unsigned char c;

#ifdef linux
  ret = fread(&c, 1, 1, inslip);
  if(ret == -1 || ret == 0) {
    LOG6LBR_FATAL("read() : %s\n", strerror(errno));
    exit(1);
  }
  goto after_fread;
#endif

read_more:
  if(inbufptr >= sizeof(inbuf)) {
    LOG6LBR_ERROR("*** dropping large %d byte packet\n", inbufptr);
    inbufptr = 0;
  }
  ret = fread(&c, 1, 1, inslip);
#ifdef linux
after_fread:
#endif
  if(ret == -1) {
    LOG6LBR_FATAL("read() : %s\n", strerror(errno));
    exit(1);
  }
  if(ret == 0) {
    clearerr(inslip);
    return;
  }
  slip_received++;
  switch (c) {
  case SLIP_END:
    if(inbufptr > 0) {
      slip_message_received++;
      LOG6LBR_PRINTF(PACKET, SLIP_IN, "read: %d\n", inbufptr);
      if (LOG6LBR_COND(DUMP, SLIP_IN)) {
        printf("         ");
        for(i = 0; i < inbufptr; i++) {
          printf("%02x", inbuf[i]);
          if((i & 3) == 3)
            printf(" ");
          if((i & 15) == 15)
            printf("\n         ");
        }
        printf("\n");
      }
      if(inbuf[0] == '!') {
        command_context = CMD_CONTEXT_RADIO;
        cmd_input(inbuf, inbufptr);
      } else if(inbuf[0] == '?') {
      } else if(inbuf[0] == DEBUG_LINE_MARKER) {
        LOG6LBR_WRITE(INFO, SLIP_DBG, inbuf + 1, inbufptr - 1);
      } else if(inbuf[0] == 'E' && is_sensible_string(inbuf, inbufptr) ) {
        LOG6LBR_WRITE(ERROR, GLOBAL, inbuf + 1, inbufptr - 1);
        LOG6LBR_APPEND(ERROR, GLOBAL, "\n");
      } else if(is_sensible_string(inbuf, inbufptr)) {
        LOG6LBR_WRITE(INFO, SLIP_DBG, inbuf, inbufptr);
      } else {
        slip_packet_input(inbuf, inbufptr);
      }
      inbufptr = 0;
    }
    break;

  case SLIP_ESC:
    if(fread(&c, 1, 1, inslip) != 1) {
      clearerr(inslip);
      /* Put ESC back and give up! */
      ungetc(SLIP_ESC, inslip);
      return;
    }

    switch (c) {
    case SLIP_ESC_END:
      c = SLIP_END;
      break;
    case SLIP_ESC_ESC:
      c = SLIP_ESC;
      break;
    }
    /* FALLTHROUGH */
  default:
    inbuf[inbufptr++] = c;
    break;
  }

  goto read_more;
}