Contiki 2.6
|
00001 /** 00002 * \file sicslow_ethernet.c 00003 * Routines to interface between Ethernet and 6LowPan 00004 * 00005 * \author 00006 * Colin O'Flynn <coflynn@newae.com> 00007 * 00008 * \addtogroup usbstick 00009 */ 00010 00011 /* Copyright (c) 2008 by: 00012 * Colin O'Flynn coflynn@newae.com 00013 * Eric Gnoske egnoske@gmail.com 00014 * Blake Leverett bleverett@gmail.com 00015 * Mike Vidales mavida404@gmail.com 00016 * Kevin Brown kbrown3@uccs.edu 00017 * Nate Bohlmann nate@elfwerks.com 00018 * 00019 * All rights reserved. 00020 * 00021 * Redistribution and use in source and binary forms, with or without 00022 * modification, are permitted provided that the following conditions 00023 * are met: 00024 * 00025 * * Redistributions of source code must retain the above copyright 00026 * notice, this list of conditions and the following disclaimer. 00027 * * Redistributions in binary form must reproduce the above copyright 00028 * notice, this list of conditions and the following disclaimer in 00029 * the documentation and/or other materials provided with the 00030 * distribution. 00031 * * Neither the name of the copyright holders nor the names of 00032 * contributors may be used to endorse or promote products derived 00033 * from this software without specific prior written permission. 00034 * 00035 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00036 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00037 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00038 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00039 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00040 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00041 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00042 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00043 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00044 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00045 * POSSIBILITY OF SUCH DAMAGE. 00046 */ 00047 00048 /** 00049 \ingroup usbstick 00050 \defgroup sicslowinterop 6LowPan Ethernet Interop 00051 @{ 00052 */ 00053 00054 //TODO: Should be able to always use this SIMPLE mode, hence can remove the 'complex' mode permanently 00055 //TODO: RF230BB !SIMPLE works on XP, Ubuntu. SIMPLE works on Vista, W7. Find out why! 00056 00057 #ifndef UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS 00058 #define UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS 0 00059 #endif // ifndef UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS 00060 00061 #ifndef UIP_CONF_AUTO_SUBSTITUTE_LOCAL_MAC_ADDR 00062 #define UIP_CONF_AUTO_SUBSTITUTE_LOCAL_MAC_ADDR 1 00063 #endif // ifndef UIP_CONF_AUTO_SUBSTITUTE_LOCAL_MAC_ADDR 00064 00065 #if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS 00066 /** 00067 \par Ethernet to 6LowPan Address Translation 00068 00069 It should be obvious that since 802.15.4 addresses are 8 00070 bytes, and 802.3 addresses are 6 bytes, some form of 00071 address translation is needed. These routines provide this 00072 00073 \par Address Translation on Packets coming FROM Ethernet 00074 00075 Packets coming from Ethernet, have any addresses inside 00076 IPv6 packets (such as 'source link-layer address') expanded 00077 by inserting a 0xFF 0xFE sequence as such: 00078 00079 \verbatim 00080 AA:BB:CC:DD:EE:FF 00081 00082 becomes 00083 00084 AA:BB:CC:FF:FE:DD:EE:FF 00085 \endverbatim 00086 00087 The 802.15.4 destination address is always derived from the IPv6 00088 destination address. 00089 00090 \par Address Translation on Packets coming FROM 802.15.4 00091 00092 Packets coming from 802.15.4, have any addresses inside IPv6 00093 packets (such as a 'source link-layer address') replaced 00094 with the local_ethernet_addr, defined to 3A:3B:3C:3D:3E:3F here. 00095 00096 The destination ethernet address is performed by performing 00097 the reverse process used to make the 802.15.4 addresses before. 00098 00099 \par Comments on Using This 00100 00101 Thus you always send IPv6 messages to the local_ethernet_addr, 00102 which is 3A:3B:3C:3D:3E:3F. The actual 802.15.4 destination 00103 address is based on the lower 64-bits of your IPv6 destination 00104 address. IPv6 addresses must always be based on link-layer 00105 addresses in the 802.15.4 network for this to work. 00106 00107 \par Notes on how addresses are stored 00108 00109 An 802.15.4 address will be reported for example as: 00110 00111 0x8877665544332211 00112 00113 Stored in the array as passed to these functions, it will be: 00114 \verbatim 00115 array[0] = 0x88; 00116 array[1] = 0x77; 00117 array[2] = 0x66; 00118 etc. 00119 \endverbatim 00120 00121 An 802.3 address will be reported for example as: 00122 02:43:53:35:45:45 00123 00124 Stored in the array as passed to these functions, it will be: 00125 \verbatim 00126 array[0] = 0x02; 00127 array[1] = 0x43; 00128 array[2] = 0x53; 00129 array[3] = 0x35 00130 etc. 00131 \endverbatim 00132 */ 00133 #else 00134 /** 00135 \par Ethernet to 6LowPan Address Translation 00136 00137 It should be obvious that since 802.15.4 addresses are 8 00138 bytes, and 802.3 addresses are 6 bytes, some form of 00139 address translation is needed. These routines provide this 00140 00141 \par 802.3 Address Formats 00142 00143 802.3 MAC addresses used here have this form: 00144 00145 \verbatim 00146 +----+----+----+----+----+----+----+----+ 00147 + + + + + + TR + GL + MU + 00148 +----+----+----+----+----+----+----+----+ 00149 \endverbatim 00150 00151 00152 It can be seen this is like a normal ethernet MAC address, 00153 with GL being the Global/Local bit, and MU being the 00154 Multicast/Unicast bit. 00155 00156 The addition is the 'TR' bit, which if set indicates that 00157 the address must be translated when going between 802.15.4 00158 and 802.3. 00159 00160 \par Address Translation 00161 00162 If the TRANSLATE (TR) bit is CLEAR, this means the 5th and 00163 4th LSBytes of the 802.15.4 address are fffe, aka the address 00164 has the hexidecial form: 00165 00166 xxxxxxfffexxxxxx 00167 00168 \note 00169 You should always aim to set the 802.15.4 addresses 00170 of the devices on your network to ones that will 00171 satisfy this requirement. Some examples are: 00172 \note 00173 0x02 23 42 ff fe 73 92 28 00174 \note 00175 0x82 00 82 ff fe cd ee 22 00176 00177 \note 00178 So the most significant octets MUST 00179 have bit 0 CLEAR, bit 1 SET, and bit 2 CLEAR. The remaining 00180 bits in this octet can be anything. 00181 00182 If the TRANSLATE bit is SET, this means the address on the 00183 802.3 side does not directly convert to an 802.15.4 address. 00184 To translate it, the remainder of the octet is used as an 00185 index in a look-up table. This look-up table simply stores 00186 the 4th, 5th, and 8th octet of the 802.15.4 address, and attaches 00187 them to the remaining 5 bytes of the 802.3 address. 00188 00189 In this way there can be 32 different 802.15.4 'prefixes', 00190 requiring only 96 bytes of RAM in a storage table on the 00191 802.3 to 802.15.4 bridge. 00192 00193 Mulitcast addresses on 802.3 are mapped to broadcast addresses on 00194 802.15.4 and vis-versa. Since IPv6 does not use 802.3 broadcast, 00195 this code will drop all 802.3 broadcast packets. They are most 00196 likely something unwanted, such as IPv4 packets that snuck in. 00197 00198 \par Notes on how addresses are stored 00199 00200 An 802.15.4 address will be reported for example as: 00201 00202 0x8877665544332211 00203 00204 Stored in the array as passed to these functions, it will be: 00205 \verbatim 00206 array[0] = 0x88; 00207 array[1] = 0x77; 00208 array[2] = 0x66; 00209 etc. 00210 \endverbatim 00211 00212 An 802.3 address will be reported for example as: 00213 02:43:53:35:45:45 00214 00215 Stored in the array as passed to these functions, it will be: 00216 \verbatim 00217 array[0] = 0x02; 00218 array[1] = 0x43; 00219 array[2] = 0x53; 00220 array[3] = 0x35 00221 etc. 00222 \endverbatim 00223 */ 00224 #endif 00225 00226 #include "uip.h" 00227 #include "uip_arp.h" //For ethernet header structure 00228 00229 #include "net/rime.h" 00230 #include "sicslowpan.h" 00231 #include "sicslow_ethernet.h" 00232 #if !RF230BB 00233 #include "zmac.h" 00234 #include "frame.h" 00235 #include "radio.h" 00236 #endif 00237 #include "rndis/rndis_protocol.h" 00238 #include "rndis/rndis_task.h" 00239 00240 #include <stdint.h> 00241 #include <stdio.h> 00242 #include <string.h> 00243 00244 #define DEBUG 0 00245 #if DEBUG 00246 #define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) 00247 #else 00248 #define PRINTF(...) 00249 #endif 00250 00251 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) 00252 #define ETHBUF(x) ((struct uip_eth_hdr *)x) 00253 00254 //For little endian, such as our friend mr. AVR 00255 #ifndef LSB 00256 #define LSB(u16) (((uint8_t *)&(u16))[0]) //!< Least significant byte of \a u16. 00257 #define MSB(u16) (((uint8_t *)&(u16))[1]) //!< Most significant byte of \a u16. 00258 #endif 00259 00260 static const uint64_t simple_trans_ethernet_addr = 0x3E3D3C3B3AF2ULL; 00261 00262 #if UIP_CONF_IPV6_RPL 00263 static uip_ipaddr_t last_sender; 00264 #endif 00265 00266 extern uint64_t usb_ethernet_addr; 00267 00268 extern uint64_t macLongAddr; 00269 00270 #if !RF230BB 00271 extern void (*pinput)(const struct mac_driver *r); 00272 void (*sicslowinput)(const struct mac_driver *r); 00273 parsed_frame_t * parsed_frame; 00274 #endif 00275 usbstick_mode_t usbstick_mode; 00276 00277 uint8_t mac_createSicslowpanLongAddr(uint8_t * ethernet, uip_lladdr_t * lowpan); 00278 uint8_t mac_createEthernetAddr(uint8_t * ethernet, uip_lladdr_t * lowpan); 00279 uint8_t mac_createDefaultEthernetAddr(uint8_t * ethernet); 00280 void mac_ethhijack_nondata(const struct mac_driver *r); 00281 void mac_ethhijack(const struct mac_driver *r); 00282 00283 extern void (*sicslowmac_snifferhook)(const struct mac_driver *r); 00284 00285 00286 //! Location of TRANSLATE (TR) bit in Ethernet address 00287 #define TRANSLATE_BIT_MASK (1<<2) 00288 //! Location of LOCAL (GL) bit in Ethernet address 00289 #define LOCAL_BIT_MASK (1<<1) 00290 //! Location of MULTICAST (MU) bit in Ethernet address 00291 #define MULTICAST_BIT_MASK (1<<0) 00292 00293 #define PREFIX_BUFFER_SIZE 32 00294 00295 uint8_t prefixCounter; 00296 uint8_t prefixBuffer[PREFIX_BUFFER_SIZE][3]; 00297 00298 /* 6lowpan max size + ethernet header size + 1 */ 00299 uint8_t raw_buf[127+ UIP_LLH_LEN +1]; 00300 00301 /** 00302 * \brief Perform any setup needed 00303 */ 00304 #if !RF230BB 00305 struct mac_driver * pmac; 00306 #endif 00307 void mac_ethernetSetup(void) 00308 { 00309 usbstick_mode.sicslowpan = 1; 00310 usbstick_mode.sendToRf = 1; 00311 usbstick_mode.translate = 1; 00312 usbstick_mode.debugOn= 1; 00313 usbstick_mode.raw = 0; 00314 usbstick_mode.sneeze=0; 00315 00316 #if !RF230BB 00317 sicslowinput = pinput; 00318 00319 pmac = sicslowmac_get_driver(); 00320 pmac->set_receive_function(mac_ethhijack); 00321 sicslowmac_snifferhook = mac_ethhijack_nondata; 00322 #endif 00323 } 00324 00325 00326 /** 00327 * \brief Take a packet received over the ethernet link, and send it 00328 * out over 802.15.4 00329 */ 00330 void mac_ethernetToLowpan(uint8_t * ethHeader) 00331 { 00332 //Dest address 00333 uip_lladdr_t destAddr; 00334 uip_lladdr_t *destAddrPtr = NULL; 00335 00336 PRINTF("Packet type: 0x%04x\n\r", uip_ntohs(((struct uip_eth_hdr *) ethHeader)->type)); 00337 00338 //RUM doesn't support sending data 00339 #if UIP_CONF_USE_RUM 00340 return; 00341 #endif 00342 00343 /* In sniffer or sneezr mode we don't ever send anything */ 00344 if ((usbstick_mode.sendToRf == 0) || (usbstick_mode.sneeze != 0)) { 00345 uip_len = 0; 00346 return; 00347 } 00348 00349 00350 /* If not IPv6 we don't do anything. Disable ipv4 on the interface to prevent possible hangs from discovery packet flooding */ 00351 if (((struct uip_eth_hdr *) ethHeader)->type != UIP_HTONS(UIP_ETHTYPE_IPV6)) { 00352 PRINTF("eth2low: Dropping packet w/type=0x%04x\n",uip_ntohs(((struct uip_eth_hdr *) ethHeader)->type)); 00353 // printf("!ipv6"); 00354 #if !RF230BB 00355 usb_eth_stat.txbad++; 00356 #endif 00357 uip_len = 0; 00358 return; 00359 } 00360 00361 /* IPv6 uses 33-33-xx-xx-xx-xx prefix for multicast ND stuff */ 00362 if ( (((struct uip_eth_hdr *) ethHeader)->dest.addr[0] == 0x33) && 00363 (((struct uip_eth_hdr *) ethHeader)->dest.addr[1] == 0x33) ) 00364 { 00365 PRINTF("eth2low: Ethernet multicast packet received\n\r"); 00366 ;//Do Nothing 00367 } else if ( (((struct uip_eth_hdr *) ethHeader)->dest.addr[0] == 0xFF) && 00368 (((struct uip_eth_hdr *) ethHeader)->dest.addr[1] == 0xFF) && 00369 (((struct uip_eth_hdr *) ethHeader)->dest.addr[2] == 0xFF) && 00370 (((struct uip_eth_hdr *) ethHeader)->dest.addr[3] == 0xFF) && 00371 (((struct uip_eth_hdr *) ethHeader)->dest.addr[4] == 0xFF) && 00372 (((struct uip_eth_hdr *) ethHeader)->dest.addr[5] == 0xFF) ) { 00373 /* IPv6 does not use broadcast addresses, hence this should not happen */ 00374 PRINTF("eth2low: Dropping broadcast packet\n\r"); 00375 #if !RF230BB 00376 usb_eth_stat.txbad++; 00377 #endif 00378 uip_len = 0; 00379 return; 00380 } else { 00381 00382 /* Simple Address Translation */ 00383 if(memcmp((uint8_t *)&simple_trans_ethernet_addr, &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), 6) == 0) { 00384 #if UIP_CONF_IPV6 00385 //Addressed to us: make 802.15.4 address from IPv6 Address 00386 destAddr.addr[0] = UIP_IP_BUF->destipaddr.u8[8] ^ 0x02; 00387 destAddr.addr[1] = UIP_IP_BUF->destipaddr.u8[9]; 00388 destAddr.addr[2] = UIP_IP_BUF->destipaddr.u8[10]; 00389 destAddr.addr[3] = UIP_IP_BUF->destipaddr.u8[11]; 00390 destAddr.addr[4] = UIP_IP_BUF->destipaddr.u8[12]; 00391 destAddr.addr[5] = UIP_IP_BUF->destipaddr.u8[13]; 00392 destAddr.addr[6] = UIP_IP_BUF->destipaddr.u8[14]; 00393 destAddr.addr[7] = UIP_IP_BUF->destipaddr.u8[15]; 00394 #else 00395 //Not intended to be functional, but allows ip4 build without errors. 00396 destAddr.addr[0] = UIP_IP_BUF->destipaddr.u8[0] ^ 0x02; 00397 destAddr.addr[1] = UIP_IP_BUF->destipaddr.u8[1]; 00398 destAddr.addr[2] = UIP_IP_BUF->destipaddr.u8[2]; 00399 destAddr.addr[3] = UIP_IP_BUF->destipaddr.u8[3]; 00400 destAddr.addr[4] = UIP_IP_BUF->destipaddr.u8[0]; 00401 destAddr.addr[5] = UIP_IP_BUF->destipaddr.u8[1]; 00402 destAddr.addr[6] = UIP_IP_BUF->destipaddr.u8[2]; 00403 destAddr.addr[7] = UIP_IP_BUF->destipaddr.u8[3]; 00404 00405 #endif 00406 00407 destAddrPtr = &destAddr; 00408 } 00409 #if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS 00410 else { 00411 //Not addressed to us 00412 uip_len = 0; 00413 return; 00414 } 00415 #else 00416 00417 /* Complex Address Translation */ 00418 PRINTF("eth2low: Addressed packet received... "); 00419 //Check this returns OK 00420 if (mac_createSicslowpanLongAddr( &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), &destAddr) == 0) { 00421 PRINTF(" translation failed\n\r"); 00422 #if !RF230BB 00423 usb_eth_stat.txbad++; 00424 #endif 00425 uip_len = 0; 00426 return; 00427 } 00428 PRINTF(" translated OK\n\r"); 00429 destAddrPtr = &destAddr; 00430 #endif /* UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS */ 00431 00432 00433 } 00434 00435 //Remove header from length before passing onward 00436 uip_len -= UIP_LLH_LEN; 00437 00438 //Some IP packets have link layer in them, need to change them around! 00439 if (usbstick_mode.translate) { 00440 #if DEBUG 00441 uint8_t transReturn = mac_translateIPLinkLayer(ll_802154_type); 00442 PRINTF("IPTranslation: returns %d\n\r", transReturn); 00443 #else 00444 mac_translateIPLinkLayer(ll_802154_type); 00445 #endif 00446 } 00447 00448 #if UIP_CONF_IPV6 00449 /* Send the packet to the uip6 stack if it exists, else send to 6lowpan */ 00450 #if UIP_CONF_IPV6_RPL 00451 /* Save the destination address, to trap ponging it back to the interface */ 00452 uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr); 00453 tcpip_input(); 00454 #else 00455 // PRINTF("Input from %x %x %x %x %x %x %x %x\n",UIP_IP_BUF->srcipaddr.u8[0],UIP_IP_BUF->srcipaddr.u8[1],UIP_IP_BUF->srcipaddr.u8[2],UIP_IP_BUF->srcipaddr.u8[3],UIP_IP_BUF->srcipaddr.u8[4],UIP_IP_BUF->srcipaddr.u8[5],UIP_IP_BUF->srcipaddr.u8[6],UIP_IP_BUF->srcipaddr.u8[7]); 00456 // PRINTF("Output to %x %x %x %x %x %x %x %x\n",destAddr.addr[0],destAddr.addr[1],destAddr.addr[2],destAddr.addr[3],destAddr.addr[4],destAddr.addr[5],destAddr.addr[6],destAddr.addr[7]); 00457 tcpip_output(destAddrPtr); 00458 #endif 00459 #else /* UIP_CONF_IPV6 */ 00460 tcpip_output(); //Allow non-ipv6 builds (Hello World) 00461 #endif /* UIP_CONF_IPV6 */ 00462 00463 #if !RF230BB 00464 usb_eth_stat.txok++; 00465 #endif 00466 uip_len = 0; 00467 00468 } 00469 00470 00471 /** 00472 * \brief Take a packet received over the 802.15.4 link, and send it 00473 * out over ethernet, performing any translations needed. 00474 */ 00475 void mac_LowpanToEthernet(void) 00476 { 00477 #if !RF230BB 00478 parsed_frame = sicslowmac_get_frame(); 00479 #endif 00480 00481 //Setup generic ethernet stuff 00482 ETHBUF(uip_buf)->type = uip_htons(UIP_ETHTYPE_IPV6); 00483 00484 //Check for broadcast message 00485 00486 #if RF230BB 00487 if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) { 00488 // if(rimeaddr_cmp((const rimeaddr_t *)destAddr, &rimeaddr_null)) { 00489 #else 00490 if( ( parsed_frame->fcf->destAddrMode == SHORTADDRMODE) && 00491 ( parsed_frame->dest_addr->addr16 == 0xffff) ) { 00492 #endif 00493 ETHBUF(uip_buf)->dest.addr[0] = 0x33; 00494 ETHBUF(uip_buf)->dest.addr[1] = 0x33; 00495 00496 #if UIP_CONF_IPV6 00497 ETHBUF(uip_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12]; 00498 ETHBUF(uip_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13]; 00499 ETHBUF(uip_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14]; 00500 ETHBUF(uip_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15]; 00501 #else 00502 //Not intended to be functional, but allows ip4 build without errors. 00503 ETHBUF(uip_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[0]; 00504 ETHBUF(uip_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[1]; 00505 ETHBUF(uip_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[2]; 00506 ETHBUF(uip_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[3]; 00507 #endif 00508 } else { 00509 //Otherwise we have a real address 00510 mac_createEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->dest.addr[0]), 00511 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); 00512 } 00513 00514 #if !UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS 00515 //Source ethernet depends on node 00516 if(!mac_createEthernetAddr( 00517 (uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]), 00518 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER) 00519 )) 00520 #endif 00521 00522 { 00523 mac_createDefaultEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->src.addr[0])); 00524 } 00525 00526 //We only do address translation in network mode! 00527 if (usbstick_mode.translate) { 00528 //Some IP packets have link layer in them, need to change them around! 00529 mac_translateIPLinkLayer(ll_8023_type); 00530 } 00531 00532 #if UIP_CONF_IPV6_RPL 00533 /* We won't play ping-pong with the host! */ 00534 if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) { 00535 PRINTF("siclow_ethernet: Destination off-link but no route\n"); 00536 uip_len=0; 00537 return; 00538 } 00539 #endif 00540 00541 PRINTF("Low2Eth: Sending packet to ethernet\n\r"); 00542 00543 uip_len += UIP_LLH_LEN; 00544 00545 usb_eth_send(uip_buf, uip_len, 1); 00546 #if !RF230BB 00547 usb_eth_stat.rxok++; 00548 #endif 00549 uip_len = 0; 00550 } 00551 00552 /** 00553 * \brief Translate IP packet's possible link-layer addresses, passing 00554 * the message to the appropriate higher level function for this 00555 * packet (aka: ICMP) 00556 * \param target The target we want to end up with - either ll_8023_type 00557 * for ethernet, or ll_802154_type for 802.15.4 00558 * \return Returns how successful the translation was 00559 * \retval 0 Addresses, if present, were translated. 00560 * \retval <0 Negative return values indicate various errors, as defined 00561 * by the higher level function. 00562 */ 00563 int8_t mac_translateIPLinkLayer(lltype_t target) 00564 { 00565 00566 #if UIP_LLADDR_LEN == 8 00567 if (UIP_IP_BUF->proto == UIP_PROTO_ICMP6) { 00568 PRINTF("eth2low: ICMP Message detected\n\r"); 00569 return mac_translateIcmpLinkLayer(target); 00570 } 00571 return 0; 00572 #else 00573 return 1; 00574 #endif 00575 00576 } 00577 00578 #include "net/uip-icmp6.h" 00579 #include "net/uip-nd6.h" 00580 00581 typedef struct { 00582 uint8_t type; 00583 uint8_t length; 00584 uint8_t data[16]; 00585 } icmp_opts_t; 00586 00587 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN]) 00588 #define UIP_ICMP_OPTS(x) ((icmp_opts_t *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN + x]) 00589 00590 void slide(uint8_t * data, uint8_t length, int16_t slide); 00591 00592 /** 00593 * \brief Translate the link-layer (L2) addresses in an ICMP packet. 00594 * This will just be NA/NS/RA/RS packets currently. 00595 * \param target The target we want to end up with - either ll_8023_type 00596 * for ethernet, or ll_802154_type for 802.15.4 00597 * \return Returns how successful the translation was 00598 * \retval 0 Addresses, if present, were translated. 00599 * \retval -1 ICMP message was unknown type, nothing done. 00600 * \retval -2 ICMP Length does not make sense? 00601 * \retval -3 Unknown 'target' type 00602 */ 00603 int8_t mac_translateIcmpLinkLayer(lltype_t target) 00604 { 00605 uint16_t icmp_opt_offset = 0; 00606 int16_t len = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0] << 8); 00607 00608 uint16_t iplen; 00609 00610 uint8_t i; 00611 00612 int16_t sizechange; 00613 00614 uint8_t llbuf[16]; 00615 00616 //Figure out offset to start of options 00617 switch(UIP_ICMP_BUF->type) { 00618 case ICMP6_NS: 00619 case ICMP6_NA: 00620 icmp_opt_offset = 24; 00621 break; 00622 00623 case ICMP6_RS: 00624 icmp_opt_offset = 8; 00625 break; 00626 00627 case ICMP6_RA: 00628 icmp_opt_offset = 16; 00629 break; 00630 00631 case ICMP6_REDIRECT: 00632 icmp_opt_offset = 40; 00633 break; 00634 00635 /** Things without link-layer */ 00636 case ICMP6_DST_UNREACH: 00637 case ICMP6_PACKET_TOO_BIG: 00638 case ICMP6_TIME_EXCEEDED: 00639 case ICMP6_PARAM_PROB: 00640 case ICMP6_ECHO_REQUEST: 00641 case ICMP6_ECHO_REPLY: 00642 return 0; 00643 break; 00644 00645 default: 00646 return -1; 00647 } 00648 00649 //Figure out length of options 00650 len -= icmp_opt_offset; 00651 00652 //Sanity check 00653 if (len < 8) return -2; 00654 00655 //While we have options to do... 00656 while (len >= 8){ 00657 00658 //If we have one of these, we have something useful! 00659 if (((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_SLLAO) || 00660 ((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_TLLAO) ) { 00661 00662 /* Shrinking the buffer may thrash things, so we store the old 00663 link-layer address */ 00664 for(i = 0; i < (UIP_ICMP_OPTS(icmp_opt_offset)->length*8 - 2); i++) { 00665 llbuf[i] = UIP_ICMP_OPTS(icmp_opt_offset)->data[i]; 00666 } 00667 00668 //Shrink/grow buffer as needed 00669 if (target == ll_802154_type) { 00670 //Current is 802.3, Hence current link-layer option is 6 extra bytes 00671 sizechange = 8; 00672 slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 6, len - 6, sizechange); 00673 } else if (target == ll_8023_type) { 00674 /* Current is 802.15.4, Hence current link-layer option is 14 extra 00675 * bytes. 00676 * (Actual LL is 8 bytes, but total option length is in multiples of 00677 * 8 Bytes, hence 8 + 2 = 10. Closest is 16 bytes, then 16 bytes for 00678 * total optional length - 2 bytes for type + length leaves 14 ) 00679 */ 00680 sizechange = -8; 00681 slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 14, len - 14, sizechange); 00682 } else { 00683 return -3; //Uh-oh! 00684 } 00685 00686 //Translate addresses 00687 if (target == ll_802154_type) { 00688 mac_createSicslowpanLongAddr(llbuf, (uip_lladdr_t *)UIP_ICMP_OPTS(icmp_opt_offset)->data); 00689 } else { 00690 #if !UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS 00691 if(!mac_createEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data, (uip_lladdr_t *)llbuf)) 00692 #endif 00693 mac_createDefaultEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data); 00694 } 00695 00696 //Adjust the length 00697 if (target == ll_802154_type) { 00698 UIP_ICMP_OPTS(icmp_opt_offset)->length = 2; 00699 } else { 00700 UIP_ICMP_OPTS(icmp_opt_offset)->length = 1; 00701 } 00702 00703 //Adjust the IP header length, as well as uIP length 00704 iplen = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0]<<8); 00705 iplen += sizechange; 00706 len += sizechange; 00707 00708 UIP_IP_BUF->len[1] = (uint8_t)iplen; 00709 UIP_IP_BUF->len[0] = (uint8_t)(iplen >> 8); 00710 00711 uip_len += sizechange; 00712 00713 //We broke ICMP checksum, be sure to fix that 00714 UIP_ICMP_BUF->icmpchksum = 0; 00715 #if UIP_CONF_IPV6 //allow non ipv6 builds 00716 UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); 00717 #endif 00718 00719 //Finally set up next run in while loop 00720 len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length; 00721 icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length; 00722 } else { 00723 00724 //Not an option we care about, ignore it 00725 len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length; 00726 00727 //This shouldn't happen! 00728 if (UIP_ICMP_OPTS(icmp_opt_offset)->length == 0) { 00729 PRINTF("Option in ND packet has length zero, error?\n\r"); 00730 len = 0; 00731 } 00732 00733 icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length; 00734 00735 } //If ICMP_OPT is one we care about 00736 00737 } //while(len >= 8) 00738 00739 return 0; 00740 00741 } 00742 00743 00744 /** 00745 * \brief Create a 802.15.4 long address from a 802.3 address 00746 * \param ethernet Pointer to ethernet address 00747 * \param lowpan Pointer to 802.15.4 address 00748 */ 00749 uint8_t mac_createSicslowpanLongAddr(uint8_t * ethernet, uip_lladdr_t * lowpan) 00750 { 00751 #if UIP_CONF_AUTO_SUBSTITUTE_LOCAL_MAC_ADDR 00752 //Special case - if the address is our address, we just copy over what we know to be 00753 //our 802.15.4 address 00754 if (memcmp((uint8_t *)&usb_ethernet_addr, ethernet, 6) == 0) 00755 { 00756 memcpy((uint8_t *)lowpan, &macLongAddr, UIP_LLADDR_LEN); 00757 return 1; 00758 } 00759 #endif 00760 00761 #if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS 00762 00763 //Easy does it! 00764 lowpan->addr[0] = ethernet[0]; 00765 lowpan->addr[1] = ethernet[1]; 00766 lowpan->addr[2] = ethernet[2]; 00767 lowpan->addr[3] = 0xff; 00768 lowpan->addr[4] = 0xfe; 00769 lowpan->addr[5] = ethernet[3]; 00770 lowpan->addr[6] = ethernet[4]; 00771 lowpan->addr[7] = ethernet[5]; 00772 00773 #else //!UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS 00774 00775 uint8_t index; 00776 00777 #if UIP_LLADDR_LEN == 8 00778 //Check if translate bit is set, hence we have to look up the prefix 00779 if((ethernet[0]&(TRANSLATE_BIT_MASK|MULTICAST_BIT_MASK|LOCAL_BIT_MASK)) == (TRANSLATE_BIT_MASK|LOCAL_BIT_MASK)) { 00780 //Get top bits 00781 index = ethernet[0] >> 3; 00782 00783 //Copy over prefix 00784 lowpan->addr[0] = prefixBuffer[index][0]; 00785 lowpan->addr[1] = prefixBuffer[index][1]; 00786 lowpan->addr[2] = prefixBuffer[index][2]; 00787 lowpan->addr[3] = ethernet[1]; 00788 lowpan->addr[4] = ethernet[2]; 00789 00790 //Check this is plausible... 00791 if (index >= prefixCounter) 00792 return 0; 00793 } else { 00794 lowpan->addr[0] = ethernet[0]; 00795 lowpan->addr[1] = ethernet[1]; 00796 lowpan->addr[2] = ethernet[2]; 00797 lowpan->addr[3] = 0xff; 00798 lowpan->addr[4] = 0xfe; 00799 } 00800 00801 lowpan->addr[5] = ethernet[3]; 00802 lowpan->addr[6] = ethernet[4]; 00803 lowpan->addr[7] = ethernet[5]; 00804 00805 #else //UIP_LLADDR != 8 00806 // Not sure when we would ever hit this case... 00807 uint8_t i; 00808 for(i = 0; i < UIP_LLADDR_LEN; i++) { 00809 lowpan->addr[i] = ethernet[i]; 00810 } 00811 #endif //UIP_LLADDR == 8 00812 00813 #endif //UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS 00814 00815 return 1; 00816 } 00817 00818 00819 /** 00820 * \brief Create a 802.3 address from a 802.15.4 long address 00821 * \param ethernet Pointer to ethernet address 00822 * \param lowpan Pointer to 802.15.4 address 00823 */ 00824 uint8_t mac_createEthernetAddr(uint8_t * ethernet, uip_lladdr_t * lowpan) 00825 { 00826 #if UIP_CONF_AUTO_SUBSTITUTE_LOCAL_MAC_ADDR 00827 //Special case - if the address is our address, we just copy over what we know to be 00828 //our 802.3 address 00829 if (memcmp((uint8_t *)&macLongAddr, (uint8_t *)lowpan, UIP_LLADDR_LEN) == 0) { 00830 usb_eth_get_mac_address(ethernet); 00831 return 1; 00832 } 00833 #endif 00834 00835 #if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS 00836 00837 /** Just copy over 6 bytes **/ 00838 ethernet[0] = lowpan->addr[0]; 00839 ethernet[1] = lowpan->addr[1]; 00840 ethernet[2] = lowpan->addr[2]; 00841 ethernet[3] = lowpan->addr[5]; 00842 ethernet[4] = lowpan->addr[6]; 00843 ethernet[5] = lowpan->addr[7]; 00844 00845 #else //!UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS 00846 00847 uint8_t index = 0; 00848 uint8_t i; 00849 00850 #if UIP_LLADDR_LEN == 8 00851 00852 //Check if we need to do anything: 00853 if ((lowpan->addr[3] == 0xff) && (lowpan->addr[4] == 0xfe) && 00854 ((lowpan->addr[0] & TRANSLATE_BIT_MASK) == 0) && 00855 ((lowpan->addr[0] & MULTICAST_BIT_MASK) == 0) && 00856 (lowpan->addr[0] & LOCAL_BIT_MASK)) { 00857 00858 /** Nope: just copy over 6 bytes **/ 00859 ethernet[0] = lowpan->addr[0]; 00860 ethernet[1] = lowpan->addr[1]; 00861 ethernet[2] = lowpan->addr[2]; 00862 ethernet[3] = lowpan->addr[5]; 00863 ethernet[4] = lowpan->addr[6]; 00864 ethernet[5] = lowpan->addr[7]; 00865 00866 00867 } else { 00868 00869 /** Yes: need to store prefix **/ 00870 for (i = 0; i < prefixCounter; i++) { 00871 //Check the current prefix - if it fails, check next one 00872 if ((lowpan->addr[0] == prefixBuffer[i][0]) && 00873 (lowpan->addr[1] == prefixBuffer[i][1]) && 00874 (lowpan->addr[2] == prefixBuffer[i][2])) { 00875 break; 00876 } 00877 } 00878 index = i; 00879 00880 if (index >= PREFIX_BUFFER_SIZE) { 00881 // Overflow. Fall back to simple translation. 00882 // TODO: Implement me! 00883 ethernet[0] = lowpan->addr[0]; 00884 ethernet[1] = lowpan->addr[1]; 00885 ethernet[2] = lowpan->addr[2]; 00886 ethernet[3] = lowpan->addr[5]; 00887 ethernet[4] = lowpan->addr[6]; 00888 ethernet[5] = lowpan->addr[7]; 00889 return 0; 00890 } else { 00891 //Are we making a new one? 00892 if (index == prefixCounter) { 00893 prefixCounter++; 00894 prefixBuffer[index][0] = lowpan->addr[0]; 00895 prefixBuffer[index][1] = lowpan->addr[1]; 00896 prefixBuffer[index][2] = lowpan->addr[2]; 00897 } 00898 00899 //Create ethernet MAC address now 00900 ethernet[0] = TRANSLATE_BIT_MASK | LOCAL_BIT_MASK | (index << 3); 00901 ethernet[1] = lowpan->addr[3]; 00902 ethernet[2] = lowpan->addr[4]; 00903 ethernet[3] = lowpan->addr[5]; 00904 ethernet[4] = lowpan->addr[6]; 00905 ethernet[5] = lowpan->addr[7]; 00906 } 00907 } 00908 00909 #else //UIP_LLADDR_LEN != 8 00910 // Not sure when we would ever hit this case... 00911 //Create ethernet MAC address now 00912 for(i = 0; i < UIP_LLADDR_LEN; i++) { 00913 ethernet[i] = lowpan->addr[i]; 00914 } 00915 #endif //UIP_LLADDR_LEN == 8 00916 00917 #endif //UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS 00918 00919 return 1; 00920 } 00921 /** 00922 * \brief Create a 802.3 address (default) 00923 * \param ethernet Pointer to ethernet address 00924 */ 00925 uint8_t mac_createDefaultEthernetAddr(uint8_t * ethernet) 00926 { 00927 memcpy(ethernet, &simple_trans_ethernet_addr, 6); 00928 return 1; 00929 } 00930 /** 00931 * \brief Slide the pointed to memory up a certain amount, 00932 * growing/shrinking a buffer 00933 * \param data Pointer to start of data buffer 00934 * \param length Length of the data buffer 00935 * \param slide How many bytes to slide the buffer up in memory (if +) or 00936 * down in memory (if -) 00937 */ 00938 void slide(uint8_t * data, uint8_t length, int16_t slide) 00939 { 00940 //Sanity checks 00941 if (!length) return; 00942 if (!slide) return; 00943 00944 uint8_t i = 0; 00945 00946 while(length) { 00947 length--; 00948 00949 //If we are sliding up, we do from the top of the buffer down 00950 if (slide > 0) { 00951 *(data + length + slide) = *(data + length); 00952 00953 //If we are sliding down, we do from the bottom of the buffer up 00954 } else { 00955 *(data + slide + i) = *(data + i); 00956 } 00957 00958 i++; 00959 } 00960 } 00961 00962 //#define ETHBUF(x) ((struct uip_eth_hdr *)x) 00963 //#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) 00964 00965 void 00966 mac_log_802_15_4_tx(const uint8_t* buffer, size_t total_len) { 00967 if (usbstick_mode.raw != 0) { 00968 uint8_t sendlen; 00969 00970 static uint8_t raw_buf[127+ UIP_LLH_LEN +1]; 00971 00972 /* Get the raw frame */ 00973 memcpy(&raw_buf[UIP_LLH_LEN], buffer, total_len); 00974 sendlen = total_len; 00975 00976 /* Setup generic ethernet stuff */ 00977 ETHBUF(raw_buf)->type = uip_htons(0x809A); //UIP_ETHTYPE_802154 0x809A 00978 00979 /* Check for broadcast message */ 00980 if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) { 00981 ETHBUF(raw_buf)->dest.addr[0] = 0x33; 00982 ETHBUF(raw_buf)->dest.addr[1] = 0x33; 00983 ETHBUF(raw_buf)->dest.addr[2] = 0x00; 00984 ETHBUF(raw_buf)->dest.addr[3] = 0x00; 00985 ETHBUF(raw_buf)->dest.addr[4] = 0x80; 00986 ETHBUF(raw_buf)->dest.addr[5] = 0x9A; 00987 00988 /* 00989 ETHBUF(raw_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12]; 00990 ETHBUF(raw_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13]; 00991 ETHBUF(raw_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14]; 00992 ETHBUF(raw_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15]; 00993 */ 00994 } else { 00995 /* Otherwise we have a real address */ 00996 mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->dest.addr[0]), 00997 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); 00998 } 00999 01000 // mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]),(uip_lladdr_t *)&uip_lladdr.addr); 01001 mac_createDefaultEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0])); 01002 01003 sendlen += UIP_LLH_LEN; 01004 usb_eth_send(raw_buf, sendlen, 0); 01005 } 01006 } 01007 01008 void 01009 mac_log_802_15_4_rx(const uint8_t* buf, size_t len) { 01010 if (usbstick_mode.raw != 0) { 01011 uint8_t sendlen; 01012 01013 /* Get the raw frame */ 01014 memcpy(&raw_buf[UIP_LLH_LEN], buf, len); 01015 sendlen = len; 01016 01017 /* Setup generic ethernet stuff */ 01018 ETHBUF(raw_buf)->type = uip_htons(0x809A); //UIP_ETHTYPE_802154 0x809A 01019 01020 /* Check for broadcast message */ 01021 if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) { 01022 ETHBUF(raw_buf)->dest.addr[0] = 0x33; 01023 ETHBUF(raw_buf)->dest.addr[1] = 0x33; 01024 ETHBUF(raw_buf)->dest.addr[2] = 0x00; 01025 ETHBUF(raw_buf)->dest.addr[3] = 0x00; 01026 ETHBUF(raw_buf)->dest.addr[4] = 0x80; 01027 ETHBUF(raw_buf)->dest.addr[5] = 0x9A; 01028 /* 01029 ETHBUF(raw_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12]; 01030 ETHBUF(raw_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13]; 01031 ETHBUF(raw_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14]; 01032 ETHBUF(raw_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15]; 01033 */ 01034 } else { 01035 /* Otherwise we have a real address */ 01036 mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->dest.addr[0]), 01037 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); 01038 } 01039 01040 // mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]),(uip_lladdr_t *)&uip_lladdr.addr); 01041 mac_createDefaultEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0])); 01042 01043 sendlen += UIP_LLH_LEN; 01044 usb_eth_send(raw_buf, sendlen, 0); 01045 } 01046 } 01047 /* The rf230bb send driver may call this routine via RF230BB_HOOK_IS_SEND_ENABLED */ 01048 bool 01049 mac_is_send_enabled(void) { 01050 if ((usbstick_mode.sendToRf == 0) || (usbstick_mode.sneeze != 0)) return 0; 01051 return 1; 01052 //return usbstick_mode.sendToRf; 01053 } 01054 01055 /** @} */ 01056 01057 01058 01059 /** @} */ 01060 01061 01062 #if !RF230BB 01063 /*--------------------------------------------------------------------*/ 01064 /** \brief Process a received 6lowpan packet. Hijack function. 01065 * \param r The MAC layer 01066 * 01067 * The 6lowpan packet is put in packetbuf by the MAC. This routine calls 01068 * any other needed layers (either 6lowpan, or just raw ethernet dump) 01069 */ 01070 void mac_ethhijack(const struct mac_driver *r) 01071 { 01072 if (usbstick_mode.raw) { 01073 mac_802154raw(r); 01074 } 01075 01076 if (usbstick_mode.sicslowpan) { 01077 01078 #if UIP_CONF_USE_RUM 01079 if (parsed_frame->payload[4]) { /* RUM 6lowpan frame type */ 01080 #endif 01081 sicslowinput(r); 01082 #if UIP_CONF_USE_RUM 01083 } 01084 #endif 01085 01086 01087 } 01088 01089 } 01090 01091 void mac_ethhijack_nondata(const struct mac_driver *r) 01092 { 01093 if (usbstick_mode.raw) 01094 mac_802154raw(r); 01095 } 01096 01097 01098 /*--------------------------------------------------------------------*/ 01099 /*--------------------------------------------------------------------*/ 01100 /** \brief Logs a sent 6lowpan frame 01101 * 01102 * This routine passes a frame 01103 * directly to the ethernet layer without decompressing. 01104 */ 01105 void mac_logTXtoEthernet(frame_create_params_t *p,frame_result_t *frame_result) 01106 { 01107 mac_log_802_15_4_tx(frame_result->frame, frame_result->length); 01108 } 01109 01110 01111 /*--------------------------------------------------------------------*/ 01112 /** \brief Process a received 6lowpan packet. 01113 * \param r The MAC layer 01114 * 01115 * The 6lowpan packet is put in packetbuf by the MAC. This routine passes 01116 * it directly to the ethernet layer without decompressing. 01117 */ 01118 void mac_802154raw(const struct mac_driver *r) { 01119 mac_log_802_15_4_tx(radio_frame_data(), radio_frame_length()); 01120 } 01121 01122 #endif /* !RF230BB */ 01123 01124 01125