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; }
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; }
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(ð_net_prefix, &UIP_ND6_NS_BUF->tgtipaddr, 64)) || uip_ipaddr_prefixcmp(ð_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; }
static uint8_t bridge_output(const uip_lladdr_t * dest) { uint8_t isEthOutput = UIP_TRANSMITTED_INTERFACE_TYPE & UIP_ETH_INTERFACE_MASK; uint8_t isWirelessOutput = UIP_TRANSMITTED_INTERFACE_TYPE & UIP_LN_INTERFACE_MASK; //Filter WSN vs Ethernet segment traffic if(isEthOutput) { eth_output(NULL, dest); } if( isWirelessOutput) { wireless_output(NULL, dest); } return 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; } }
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(ð_net_prefix, &UIP_IP_BUF->destipaddr, 64)) { LOG6LBR_6ADDR_PRINTF(PACKET, PF_OUT, ð_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(ð_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(ð_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); }