void mac_LowpanToEthernet(void) { //Setup generic ethernet stuff ETHBUF(uip_buf)->type = uip_htons(UIP_ETHTYPE_IPV6); //Check for broadcast message if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) { ETHBUF(uip_buf)->dest.addr[0] = 0x33; ETHBUF(uip_buf)->dest.addr[1] = 0x33; ETHBUF(uip_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12]; ETHBUF(uip_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13]; ETHBUF(uip_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14]; ETHBUF(uip_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15]; } else { //Otherwise we have a real address mac_createEthernetAddr((uint8_t *) ETHBUF(uip_buf)->dest.addr, (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); } mac_createEthernetAddr((uint8_t *) ETHBUF(uip_buf)->src.addr, (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); // Some IP packets have link layer in them, need to change them around! mac_translateIPLinkLayer(ll_8023_type); uip_len += UIP_LLH_LEN; }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(eth_drv_process, ev, data) { PROCESS_BEGIN(); #if !CETIC_6LBR_ONE_ITF if(!sixlbr_config_use_raw_ethernet) { //We must create our own Ethernet MAC address while(!radio_ready) { PROCESS_PAUSE(); } mac_createEthernetAddr((uint8_t *) eth_mac_addr, &wsn_mac_addr); eth_mac_addr[0] &= ~TRANSLATE_BIT_MASK; eth_mac_addr_ready = 1; } #else //TODO: Ethernet Bridge bullshit ! eth_mac_addr[5] += 1; mac_createSicslowpanLongAddr((uint8_t *)eth_mac_addr, &wsn_mac_addr); memcpy(uip_lladdr.addr, wsn_mac_addr.addr, sizeof(uip_lladdr.addr)); linkaddr_set_node_addr((linkaddr_t *) &wsn_mac_addr); #endif LOG6LBR_ETHADDR(INFO, ð_mac_addr, "Eth MAC address : "); ethernet_ready = 1; PROCESS_END(); }
/** * \brief Take a packet received over the 802.15.4 link, and send it * out over ethernet, performing any translations needed. */ void mac_LowpanToEthernet(void) { /* parsed_frame = sicslowmac_get_frame(); */ //Setup generic ethernet stuff ETHBUF(uip_buf)->type = htons(UIP_ETHTYPE_IPV6); //Check for broadcast message if(packetbuf_holds_broadcast()) { /* if( ( parsed_frame->fcf->destAddrMode == SHORTADDRMODE) && */ /* ( parsed_frame->dest_addr->addr16 == 0xffff) ) { */ ETHBUF(uip_buf)->dest.addr[0] = 0x33; ETHBUF(uip_buf)->dest.addr[1] = 0x33; ETHBUF(uip_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12]; ETHBUF(uip_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13]; ETHBUF(uip_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14]; ETHBUF(uip_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15]; } else { //Otherwise we have a real address mac_createEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->dest.addr[0]), (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); } mac_createEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]), (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); //We only do address translation in network mode! if (usbstick_mode.translate) { //Some IP packets have link layer in them, need to change them around! mac_translateIPLinkLayer(ll_8023_type); } PRINTF("Low2Eth: Sending packet to ethernet\n"); uip_len += UIP_LLH_LEN; /* rndis_send(uip_buf, uip_len, 1); */ /* rndis_stat.rxok++; */ /* uip_len = 0; */ }
/*---------------------------------------------------------------------------*/ void eth_drv_init() { LOG6LBR_INFO("ENC28J60 init\n"); linkaddr_copy((linkaddr_t *) & wsn_mac_addr, &linkaddr_node_addr); mac_createEthernetAddr((uint8_t *) eth_mac_addr, &wsn_mac_addr); LOG6LBR_ETHADDR(INFO, ð_mac_addr, "Eth MAC address : "); eth_mac_addr_ready = 1; enc28j60_init(eth_mac_addr); process_start(ð_drv_process, NULL); ethernet_ready = 1; }
/** * \brief Take a packet received over the 802.15.4 link, and send it * out over ethernet, performing any translations needed. */ void mac_LowpanToEthernet(void) { #if !RF230BB && !RF212BB parsed_frame = sicslowmac_get_frame(); #endif //Setup generic ethernet stuff ETHBUF(uip_buf)->type = uip_htons(UIP_ETHTYPE_IPV6); //Check for broadcast message #if RF230BB || RF212BB if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) { // if(rimeaddr_cmp((const rimeaddr_t *)destAddr, &rimeaddr_null)) { #else if( ( parsed_frame->fcf->destAddrMode == SHORTADDRMODE) && ( parsed_frame->dest_addr->addr16 == 0xffff) ) { #endif ETHBUF(uip_buf)->dest.addr[0] = 0x33; ETHBUF(uip_buf)->dest.addr[1] = 0x33; #if UIP_CONF_IPV6 ETHBUF(uip_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12]; ETHBUF(uip_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13]; ETHBUF(uip_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14]; ETHBUF(uip_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15]; #else //Not intended to be functional, but allows ip4 build without errors. ETHBUF(uip_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[0]; ETHBUF(uip_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[1]; ETHBUF(uip_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[2]; ETHBUF(uip_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[3]; #endif } else { //Otherwise we have a real address mac_createEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->dest.addr[0]), (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); } #if !UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS //Source ethernet depends on node if(!mac_createEthernetAddr( (uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]), (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER) )) #endif { mac_createDefaultEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->src.addr[0])); } //We only do address translation in network mode! if (usbstick_mode.translate) { //Some IP packets have link layer in them, need to change them around! mac_translateIPLinkLayer(ll_8023_type); } #if UIP_CONF_IPV6_RPL /* We won't play ping-pong with the host! */ if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) { PRINTF("siclow_ethernet: Destination off-link but no route\n"); uip_len=0; return; } #endif PRINTF("Low2Eth: Sending packet to ethernet\n\r"); uip_len += UIP_LLH_LEN; if (usbstick_mode.raw == 0) usb_eth_send(uip_buf, uip_len, 1); #if !RF230BB && !RF212BB usb_eth_stat.rxok++; #endif uip_len = 0; } /** * \brief Translate IP packet's possible link-layer addresses, passing * the message to the appropriate higher level function for this * packet (aka: ICMP) * \param target The target we want to end up with - either ll_8023_type * for ethernet, or ll_802154_type for 802.15.4 * \return Returns how successful the translation was * \retval 0 Addresses, if present, were translated. * \retval <0 Negative return values indicate various errors, as defined * by the higher level function. */ int8_t mac_translateIPLinkLayer(lltype_t target) { #if UIP_LLADDR_LEN == 8 if (UIP_IP_BUF->proto == UIP_PROTO_ICMP6) { PRINTF("eth2low: ICMP Message detected\n\r"); return mac_translateIcmpLinkLayer(target); } return 0; #else return 1; #endif } #include "net/uip-icmp6.h" #include "net/uip-nd6.h" typedef struct { uint8_t type; uint8_t length; uint8_t data[16]; } icmp_opts_t; #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN]) #define UIP_ICMP_OPTS(x) ((icmp_opts_t *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN + x]) void slide(uint8_t * data, uint8_t length, int16_t slide); /** * \brief Translate the link-layer (L2) addresses in an ICMP packet. * This will just be NA/NS/RA/RS packets currently. * \param target The target we want to end up with - either ll_8023_type * for ethernet, or ll_802154_type for 802.15.4 * \return Returns how successful the translation was * \retval 0 Addresses, if present, were translated. * \retval -1 ICMP message was unknown type, nothing done. * \retval -2 ICMP Length does not make sense? * \retval -3 Unknown 'target' type */ int8_t mac_translateIcmpLinkLayer(lltype_t target) { uint16_t icmp_opt_offset = 0; int16_t len = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0] << 8); uint16_t iplen; uint8_t i; int16_t sizechange; uint8_t llbuf[16]; //Figure out offset to start of options switch(UIP_ICMP_BUF->type) { case ICMP6_NS: case ICMP6_NA: icmp_opt_offset = 24; break; case ICMP6_RS: icmp_opt_offset = 8; break; case ICMP6_RA: icmp_opt_offset = 16; break; case ICMP6_REDIRECT: icmp_opt_offset = 40; break; /** Things without link-layer */ case ICMP6_DST_UNREACH: case ICMP6_PACKET_TOO_BIG: case ICMP6_TIME_EXCEEDED: case ICMP6_PARAM_PROB: case ICMP6_ECHO_REQUEST: case ICMP6_ECHO_REPLY: return 0; break; default: return -1; } //Figure out length of options len -= icmp_opt_offset; //Sanity check if (len < 8) return -2; //While we have options to do... while (len >= 8){ //If we have one of these, we have something useful! if (((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_SLLAO) || ((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_TLLAO) ) { /* Shrinking the buffer may thrash things, so we store the old link-layer address */ for(i = 0; i < (UIP_ICMP_OPTS(icmp_opt_offset)->length*8 - 2); i++) { llbuf[i] = UIP_ICMP_OPTS(icmp_opt_offset)->data[i]; } //Shrink/grow buffer as needed if (target == ll_802154_type) { //Current is 802.3, Hence current link-layer option is 6 extra bytes sizechange = 8; slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 6, len - 6, sizechange); } else if (target == ll_8023_type) { /* Current is 802.15.4, Hence current link-layer option is 14 extra * bytes. * (Actual LL is 8 bytes, but total option length is in multiples of * 8 Bytes, hence 8 + 2 = 10. Closest is 16 bytes, then 16 bytes for * total optional length - 2 bytes for type + length leaves 14 ) */ sizechange = -8; slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 14, len - 14, sizechange); } else { return -3; //Uh-oh! } //Translate addresses if (target == ll_802154_type) { mac_createSicslowpanLongAddr(llbuf, (uip_lladdr_t *)UIP_ICMP_OPTS(icmp_opt_offset)->data); } else { #if !UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS if(!mac_createEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data, (uip_lladdr_t *)llbuf)) #endif mac_createDefaultEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data); } //Adjust the length if (target == ll_802154_type) { UIP_ICMP_OPTS(icmp_opt_offset)->length = 2; } else { UIP_ICMP_OPTS(icmp_opt_offset)->length = 1; } //Adjust the IP header length, as well as uIP length iplen = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0]<<8); iplen += sizechange; len += sizechange; UIP_IP_BUF->len[1] = (uint8_t)iplen; UIP_IP_BUF->len[0] = (uint8_t)(iplen >> 8); uip_len += sizechange; //We broke ICMP checksum, be sure to fix that UIP_ICMP_BUF->icmpchksum = 0; #if UIP_CONF_IPV6 //allow non ipv6 builds UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); #endif //Finally set up next run in while loop len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length; icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length; } else { //Not an option we care about, ignore it len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length; //This shouldn't happen! if (UIP_ICMP_OPTS(icmp_opt_offset)->length == 0) { PRINTF("Option in ND packet has length zero, error?\n\r"); len = 0; } icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length; } //If ICMP_OPT is one we care about } //while(len >= 8)
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, ð_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; }
/** * \brief Translate the link-layer (L2) addresses in an ICMP packet. * This will just be NA/NS/RA/RS packets currently. * \param target The target we want to end up with - either ll_8023_type * for ethernet, or ll_802154_type for 802.15.4 * \return Returns how successful the translation was * \retval 0 Addresses, if present, were translated. * \retval -1 ICMP message was unknown type, nothing done. * \retval -2 ICMP Length does not make sense? * \retval -3 Unknown 'target' type */ static int8_t mac_translateIcmpLinkLayer(lltype_t target) { uint16_t icmp_opt_offset=0, sizechange, iplen; int16_t len = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0] << 8); uint8_t i, llbuf[6]; // Figure out offset to start of options switch(UIP_ICMP_BUF->type) { case ICMP6_NS: case ICMP6_NA: icmp_opt_offset = 24; break; case ICMP6_RS: icmp_opt_offset = 8; break; case ICMP6_RA: icmp_opt_offset = 16; break; case ICMP6_REDIRECT: icmp_opt_offset = 40; break; /** Things without link-layer */ case ICMP6_DST_UNREACH: case ICMP6_PACKET_TOO_BIG: case ICMP6_TIME_EXCEEDED: case ICMP6_PARAM_PROB: case ICMP6_ECHO_REQUEST: case ICMP6_ECHO_REPLY: return 0; break; default: return -1; } // Figure out length of options len -= icmp_opt_offset; // Sanity check if (len < 8) return -2; // While we have options to do... while (len >= 8) { // If we have one of these, we have something useful! if (((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_SLLAO) || ((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_TLLAO) ) { /* Shrinking the buffer may thrash things, so we store the old link-layer address */ for(i=0; i<(UIP_ICMP_OPTS(icmp_opt_offset)->length*8 - 2); i++) { llbuf[i] = UIP_ICMP_OPTS(icmp_opt_offset)->data[i]; } // Shrink/grow buffer as needed if (target == ll_802154_type) { // Current is 802.3, Hence current link-layer option is 6 extra bytes sizechange = 8; slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 6, len - 6, sizechange); } else if (target == ll_8023_type) { /* Current is 802.15.4, Hence current link-layer option is 14 extra * bytes. * (Actual LL is 8 bytes, but total option length is in multiples of * 8 Bytes, hence 8 + 2 = 10. Closest is 16 bytes, then 16 bytes for * total optional length - 2 bytes for type + length leaves 14 ) */ sizechange = -8; slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 14, len - 14, sizechange); } else { return -3; //Uh-oh! } // Translate addresses if (target == ll_802154_type) mac_createSicslowpanLongAddr(llbuf, (uip_lladdr_t *)UIP_ICMP_OPTS(icmp_opt_offset)->data); else mac_createEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data, (uip_lladdr_t *)llbuf); // adjust the length if (target == ll_802154_type) UIP_ICMP_OPTS(icmp_opt_offset)->length = 2; else UIP_ICMP_OPTS(icmp_opt_offset)->length = 1; // Adjust the IP header length, as well as uIP length iplen = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0]<<8); iplen += sizechange; len += sizechange; UIP_IP_BUF->len[1] = (uint8_t)iplen; UIP_IP_BUF->len[0] = (uint8_t)(iplen >> 8); uip_len += sizechange; // We broke ICMP checksum, be sure to fix that UIP_ICMP_BUF->icmpchksum = 0; UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); // Finally set up next run in while loop len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length; icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length; } else { // Not an option we care about, ignore it len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length; // This shouldn't happen! if (UIP_ICMP_OPTS(icmp_opt_offset)->length == 0) len = 0; icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length; } }
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, ð_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; }