Contiki 2.6

sicslow_ethernet.c

Go to the documentation of this file.
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