Contiki 2.5
sicslow_ethernet.c
Go to the documentation of this file.
1 /**
2  * \file sicslow_ethernet.c
3  * Routines to interface between Ethernet and 6LowPan
4  *
5  * \author
6  * Colin O'Flynn <coflynn@newae.com>
7  *
8  * \addtogroup usbstick
9  */
10 
11 /* Copyright (c) 2008 by:
12  * Colin O'Flynn coflynn@newae.com
13  * Eric Gnoske egnoske@gmail.com
14  * Blake Leverett bleverett@gmail.com
15  * Mike Vidales mavida404@gmail.com
16  * Kevin Brown kbrown3@uccs.edu
17  * Nate Bohlmann nate@elfwerks.com
18  *
19  * All rights reserved.
20  *
21  * Redistribution and use in source and binary forms, with or without
22  * modification, are permitted provided that the following conditions
23  * are met:
24  *
25  * * Redistributions of source code must retain the above copyright
26  * notice, this list of conditions and the following disclaimer.
27  * * Redistributions in binary form must reproduce the above copyright
28  * notice, this list of conditions and the following disclaimer in
29  * the documentation and/or other materials provided with the
30  * distribution.
31  * * Neither the name of the copyright holders nor the names of
32  * contributors may be used to endorse or promote products derived
33  * from this software without specific prior written permission.
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
36  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
39  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
40  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
41  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
42  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
43  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
44  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
45  * POSSIBILITY OF SUCH DAMAGE.
46  */
47 
48 /**
49  \ingroup usbstick
50  \defgroup sicslowinterop 6LowPan Ethernet Interop
51  @{
52 */
53 
54 //TODO: Should be able to always use this SIMPLE mode, hence can remove the 'complex' mode permanently
55 //TODO: RF230BB !SIMPLE works on XP, Ubuntu. SIMPLE works on Vista, W7. Find out why!
56 
57 #ifndef UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
58 #define UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS 0
59 #endif // ifndef UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
60 
61 #ifndef UIP_CONF_AUTO_SUBSTITUTE_LOCAL_MAC_ADDR
62 #define UIP_CONF_AUTO_SUBSTITUTE_LOCAL_MAC_ADDR 1
63 #endif // ifndef UIP_CONF_AUTO_SUBSTITUTE_LOCAL_MAC_ADDR
64 
65 #if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
66 /**
67  \par Ethernet to 6LowPan Address Translation
68 
69  It should be obvious that since 802.15.4 addresses are 8
70  bytes, and 802.3 addresses are 6 bytes, some form of
71  address translation is needed. These routines provide this
72 
73  \par Address Translation on Packets coming FROM Ethernet
74 
75  Packets coming from Ethernet, have any addresses inside
76  IPv6 packets (such as 'source link-layer address') expanded
77  by inserting a 0xFF 0xFE sequence as such:
78 
79  \verbatim
80  AA:BB:CC:DD:EE:FF
81 
82  becomes
83 
84  AA:BB:CC:FF:FE:DD:EE:FF
85  \endverbatim
86 
87  The 802.15.4 destination address is always derived from the IPv6
88  destination address.
89 
90  \par Address Translation on Packets coming FROM 802.15.4
91 
92  Packets coming from 802.15.4, have any addresses inside IPv6
93  packets (such as a 'source link-layer address') replaced
94  with the local_ethernet_addr, defined to 3A:3B:3C:3D:3E:3F here.
95 
96  The destination ethernet address is performed by performing
97  the reverse process used to make the 802.15.4 addresses before.
98 
99  \par Comments on Using This
100 
101  Thus you always send IPv6 messages to the local_ethernet_addr,
102  which is 3A:3B:3C:3D:3E:3F. The actual 802.15.4 destination
103  address is based on the lower 64-bits of your IPv6 destination
104  address. IPv6 addresses must always be based on link-layer
105  addresses in the 802.15.4 network for this to work.
106 
107  \par Notes on how addresses are stored
108 
109  An 802.15.4 address will be reported for example as:
110 
111  0x8877665544332211
112 
113  Stored in the array as passed to these functions, it will be:
114  \verbatim
115  array[0] = 0x88;
116  array[1] = 0x77;
117  array[2] = 0x66;
118  etc.
119  \endverbatim
120 
121  An 802.3 address will be reported for example as:
122  02:43:53:35:45:45
123 
124  Stored in the array as passed to these functions, it will be:
125  \verbatim
126  array[0] = 0x02;
127  array[1] = 0x43;
128  array[2] = 0x53;
129  array[3] = 0x35
130  etc.
131  \endverbatim
132 */
133 #else
134 /**
135  \par Ethernet to 6LowPan Address Translation
136 
137  It should be obvious that since 802.15.4 addresses are 8
138  bytes, and 802.3 addresses are 6 bytes, some form of
139  address translation is needed. These routines provide this
140 
141  \par 802.3 Address Formats
142 
143  802.3 MAC addresses used here have this form:
144 
145  \verbatim
146  +----+----+----+----+----+----+----+----+
147  + + + + + + TR + GL + MU +
148  +----+----+----+----+----+----+----+----+
149  \endverbatim
150 
151 
152  It can be seen this is like a normal ethernet MAC address,
153  with GL being the Global/Local bit, and MU being the
154  Multicast/Unicast bit.
155 
156  The addition is the 'TR' bit, which if set indicates that
157  the address must be translated when going between 802.15.4
158  and 802.3.
159 
160  \par Address Translation
161 
162  If the TRANSLATE (TR) bit is CLEAR, this means the 5th and
163  4th LSBytes of the 802.15.4 address are fffe, aka the address
164  has the hexidecial form:
165 
166  xxxxxxfffexxxxxx
167 
168  \note
169  You should always aim to set the 802.15.4 addresses
170  of the devices on your network to ones that will
171  satisfy this requirement. Some examples are:
172  \note
173  0x02 23 42 ff fe 73 92 28
174  \note
175  0x82 00 82 ff fe cd ee 22
176 
177  \note
178  So the most significant octets MUST
179  have bit 0 CLEAR, bit 1 SET, and bit 2 CLEAR. The remaining
180  bits in this octet can be anything.
181 
182  If the TRANSLATE bit is SET, this means the address on the
183  802.3 side does not directly convert to an 802.15.4 address.
184  To translate it, the remainder of the octet is used as an
185  index in a look-up table. This look-up table simply stores
186  the 4th, 5th, and 8th octet of the 802.15.4 address, and attaches
187  them to the remaining 5 bytes of the 802.3 address.
188 
189  In this way there can be 32 different 802.15.4 'prefixes',
190  requiring only 96 bytes of RAM in a storage table on the
191  802.3 to 802.15.4 bridge.
192 
193  Mulitcast addresses on 802.3 are mapped to broadcast addresses on
194  802.15.4 and vis-versa. Since IPv6 does not use 802.3 broadcast,
195  this code will drop all 802.3 broadcast packets. They are most
196  likely something unwanted, such as IPv4 packets that snuck in.
197 
198  \par Notes on how addresses are stored
199 
200  An 802.15.4 address will be reported for example as:
201 
202  0x8877665544332211
203 
204  Stored in the array as passed to these functions, it will be:
205  \verbatim
206  array[0] = 0x88;
207  array[1] = 0x77;
208  array[2] = 0x66;
209  etc.
210  \endverbatim
211 
212  An 802.3 address will be reported for example as:
213  02:43:53:35:45:45
214 
215  Stored in the array as passed to these functions, it will be:
216  \verbatim
217  array[0] = 0x02;
218  array[1] = 0x43;
219  array[2] = 0x53;
220  array[3] = 0x35
221  etc.
222  \endverbatim
223 */
224 #endif
225 
226 #include "uip.h"
227 #include "uip_arp.h" //For ethernet header structure
228 
229 #include "net/rime.h"
230 #include "sicslowpan.h"
231 #include "sicslow_ethernet.h"
232 #if !RF230BB
233 #include "zmac.h"
234 #include "frame.h"
235 #include "radio.h"
236 #endif
237 #include "rndis/rndis_protocol.h"
238 #include "rndis/rndis_task.h"
239 
240 #include <stdint.h>
241 #include <stdio.h>
242 #include <string.h>
243 
244 #define DEBUG 0
245 #if DEBUG
246 #define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
247 #else
248 #define PRINTF(...)
249 #endif
250 
251 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
252 #define ETHBUF(x) ((struct uip_eth_hdr *)x)
253 
254 //For little endian, such as our friend mr. AVR
255 #ifndef LSB
256 #define LSB(u16) (((uint8_t *)&(u16))[0]) //!< Least significant byte of \a u16.
257 #define MSB(u16) (((uint8_t *)&(u16))[1]) //!< Most significant byte of \a u16.
258 #endif
259 
260 static const uint64_t simple_trans_ethernet_addr = 0x3E3D3C3B3AF2ULL;
261 
262 #if UIP_CONF_IPV6_RPL
263 static uip_ipaddr_t last_sender;
264 #endif
265 
266 extern uint64_t usb_ethernet_addr;
267 
268 extern uint64_t macLongAddr;
269 
270 #if !RF230BB
271 extern void (*pinput)(const struct mac_driver *r);
272 void (*sicslowinput)(const struct mac_driver *r);
273 parsed_frame_t * parsed_frame;
274 #endif
275 usbstick_mode_t usbstick_mode;
276 
277 uint8_t mac_createSicslowpanLongAddr(uint8_t * ethernet, uip_lladdr_t * lowpan);
278 uint8_t mac_createEthernetAddr(uint8_t * ethernet, uip_lladdr_t * lowpan);
279 uint8_t mac_createDefaultEthernetAddr(uint8_t * ethernet);
280 void mac_ethhijack_nondata(const struct mac_driver *r);
281 void mac_ethhijack(const struct mac_driver *r);
282 
283 extern void (*sicslowmac_snifferhook)(const struct mac_driver *r);
284 
285 
286 //! Location of TRANSLATE (TR) bit in Ethernet address
287 #define TRANSLATE_BIT_MASK (1<<2)
288 //! Location of LOCAL (GL) bit in Ethernet address
289 #define LOCAL_BIT_MASK (1<<1)
290 //! Location of MULTICAST (MU) bit in Ethernet address
291 #define MULTICAST_BIT_MASK (1<<0)
292 
293 #define PREFIX_BUFFER_SIZE 32
294 
295 uint8_t prefixCounter;
296 uint8_t prefixBuffer[PREFIX_BUFFER_SIZE][3];
297 
298 /* 6lowpan max size + ethernet header size + 1 */
299 uint8_t raw_buf[127+ UIP_LLH_LEN +1];
300 
301 /**
302  * \brief Perform any setup needed
303  */
304 #if !RF230BB
305  struct mac_driver * pmac;
306 #endif
307 void mac_ethernetSetup(void)
308 {
309  usbstick_mode.sicslowpan = 1;
310  usbstick_mode.sendToRf = 1;
311  usbstick_mode.translate = 1;
312  usbstick_mode.debugOn= 1;
313  usbstick_mode.raw = 0;
314  usbstick_mode.sneeze=0;
315 
316 #if !RF230BB
317  sicslowinput = pinput;
318 
319  pmac = sicslowmac_get_driver();
320  pmac->set_receive_function(mac_ethhijack);
321  sicslowmac_snifferhook = mac_ethhijack_nondata;
322 #endif
323 }
324 
325 
326 /**
327  * \brief Take a packet received over the ethernet link, and send it
328  * out over 802.15.4
329  */
330 void mac_ethernetToLowpan(uint8_t * ethHeader)
331 {
332  //Dest address
333  uip_lladdr_t destAddr;
334  uip_lladdr_t *destAddrPtr = NULL;
335 
336  PRINTF("Packet type: 0x%04x\n\r", uip_ntohs(((struct uip_eth_hdr *) ethHeader)->type));
337 
338  //RUM doesn't support sending data
339  #if UIP_CONF_USE_RUM
340  return;
341  #endif
342 
343  /* In sniffer or sneezr mode we don't ever send anything */
344  if ((usbstick_mode.sendToRf == 0) || (usbstick_mode.sneeze != 0)) {
345  uip_len = 0;
346  return;
347  }
348 
349 
350  /* If not IPv6 we don't do anything. Disable ipv4 on the interface to prevent possible hangs from discovery packet flooding */
351  if (((struct uip_eth_hdr *) ethHeader)->type != UIP_HTONS(UIP_ETHTYPE_IPV6)) {
352  PRINTF("eth2low: Dropping packet w/type=0x%04x\n",uip_ntohs(((struct uip_eth_hdr *) ethHeader)->type));
353  // printf("!ipv6");
354 #if !RF230BB
355  usb_eth_stat.txbad++;
356 #endif
357  uip_len = 0;
358  return;
359  }
360 
361  /* IPv6 uses 33-33-xx-xx-xx-xx prefix for multicast ND stuff */
362  if ( (((struct uip_eth_hdr *) ethHeader)->dest.addr[0] == 0x33) &&
363  (((struct uip_eth_hdr *) ethHeader)->dest.addr[1] == 0x33) )
364  {
365  PRINTF("eth2low: Ethernet multicast packet received\n\r");
366  ;//Do Nothing
367  } else if ( (((struct uip_eth_hdr *) ethHeader)->dest.addr[0] == 0xFF) &&
368  (((struct uip_eth_hdr *) ethHeader)->dest.addr[1] == 0xFF) &&
369  (((struct uip_eth_hdr *) ethHeader)->dest.addr[2] == 0xFF) &&
370  (((struct uip_eth_hdr *) ethHeader)->dest.addr[3] == 0xFF) &&
371  (((struct uip_eth_hdr *) ethHeader)->dest.addr[4] == 0xFF) &&
372  (((struct uip_eth_hdr *) ethHeader)->dest.addr[5] == 0xFF) ) {
373  /* IPv6 does not use broadcast addresses, hence this should not happen */
374  PRINTF("eth2low: Dropping broadcast packet\n\r");
375 #if !RF230BB
376  usb_eth_stat.txbad++;
377 #endif
378  uip_len = 0;
379  return;
380  } else {
381 
382  /* Simple Address Translation */
383  if(memcmp((uint8_t *)&simple_trans_ethernet_addr, &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), 6) == 0) {
384 #if UIP_CONF_IPV6
385  //Addressed to us: make 802.15.4 address from IPv6 Address
386  destAddr.addr[0] = UIP_IP_BUF->destipaddr.u8[8] ^ 0x02;
387  destAddr.addr[1] = UIP_IP_BUF->destipaddr.u8[9];
388  destAddr.addr[2] = UIP_IP_BUF->destipaddr.u8[10];
389  destAddr.addr[3] = UIP_IP_BUF->destipaddr.u8[11];
390  destAddr.addr[4] = UIP_IP_BUF->destipaddr.u8[12];
391  destAddr.addr[5] = UIP_IP_BUF->destipaddr.u8[13];
392  destAddr.addr[6] = UIP_IP_BUF->destipaddr.u8[14];
393  destAddr.addr[7] = UIP_IP_BUF->destipaddr.u8[15];
394 #else
395  //Not intended to be functional, but allows ip4 build without errors.
396  destAddr.addr[0] = UIP_IP_BUF->destipaddr.u8[0] ^ 0x02;
397  destAddr.addr[1] = UIP_IP_BUF->destipaddr.u8[1];
398  destAddr.addr[2] = UIP_IP_BUF->destipaddr.u8[2];
399  destAddr.addr[3] = UIP_IP_BUF->destipaddr.u8[3];
400  destAddr.addr[4] = UIP_IP_BUF->destipaddr.u8[0];
401  destAddr.addr[5] = UIP_IP_BUF->destipaddr.u8[1];
402  destAddr.addr[6] = UIP_IP_BUF->destipaddr.u8[2];
403  destAddr.addr[7] = UIP_IP_BUF->destipaddr.u8[3];
404 
405 #endif
406 
407  destAddrPtr = &destAddr;
408  }
409 #if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
410  else {
411  //Not addressed to us
412  uip_len = 0;
413  return;
414  }
415 #else
416 
417  /* Complex Address Translation */
418  PRINTF("eth2low: Addressed packet received... ");
419  //Check this returns OK
420  if (mac_createSicslowpanLongAddr( &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), &destAddr) == 0) {
421  PRINTF(" translation failed\n\r");
422 #if !RF230BB
423  usb_eth_stat.txbad++;
424 #endif
425  uip_len = 0;
426  return;
427  }
428  PRINTF(" translated OK\n\r");
429  destAddrPtr = &destAddr;
430 #endif /* UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS */
431 
432 
433  }
434 
435  //Remove header from length before passing onward
436  uip_len -= UIP_LLH_LEN;
437 
438  //Some IP packets have link layer in them, need to change them around!
439  if (usbstick_mode.translate) {
440 #if DEBUG
441  uint8_t transReturn = mac_translateIPLinkLayer(ll_802154_type);
442  PRINTF("IPTranslation: returns %d\n\r", transReturn);
443 #else
444  mac_translateIPLinkLayer(ll_802154_type);
445 #endif
446  }
447 
448 #if UIP_CONF_IPV6
449 /* Send the packet to the uip6 stack if it exists, else send to 6lowpan */
450 #if UIP_CONF_IPV6_RPL
451 /* Save the destination address, to trap ponging it back to the interface */
452  uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr);
453  tcpip_input();
454 #else
455 // 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]);
456 // 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]);
457  tcpip_output(destAddrPtr);
458 #endif
459 #else /* UIP_CONF_IPV6 */
460  tcpip_output(); //Allow non-ipv6 builds (Hello World)
461 #endif /* UIP_CONF_IPV6 */
462 
463 #if !RF230BB
464  usb_eth_stat.txok++;
465 #endif
466  uip_len = 0;
467 
468 }
469 
470 
471 /**
472  * \brief Take a packet received over the 802.15.4 link, and send it
473  * out over ethernet, performing any translations needed.
474  */
476 {
477 #if !RF230BB
478  parsed_frame = sicslowmac_get_frame();
479 #endif
480 
481  //Setup generic ethernet stuff
482  ETHBUF(uip_buf)->type = uip_htons(UIP_ETHTYPE_IPV6);
483 
484  //Check for broadcast message
485 
486 #if RF230BB
487  if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) {
488 // if(rimeaddr_cmp((const rimeaddr_t *)destAddr, &rimeaddr_null)) {
489 #else
490  if( ( parsed_frame->fcf->destAddrMode == SHORTADDRMODE) &&
491  ( parsed_frame->dest_addr->addr16 == 0xffff) ) {
492 #endif
493  ETHBUF(uip_buf)->dest.addr[0] = 0x33;
494  ETHBUF(uip_buf)->dest.addr[1] = 0x33;
495 
496 #if UIP_CONF_IPV6
497  ETHBUF(uip_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
498  ETHBUF(uip_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
499  ETHBUF(uip_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
500  ETHBUF(uip_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
501 #else
502  //Not intended to be functional, but allows ip4 build without errors.
503  ETHBUF(uip_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[0];
504  ETHBUF(uip_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[1];
505  ETHBUF(uip_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[2];
506  ETHBUF(uip_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[3];
507 #endif
508  } else {
509  //Otherwise we have a real address
510  mac_createEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->dest.addr[0]),
511  (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
512  }
513 
514 #if !UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
515  //Source ethernet depends on node
517  (uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]),
518  (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)
519  ))
520 #endif
521 
522  {
523  mac_createDefaultEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]));
524  }
525 
526  //We only do address translation in network mode!
527  if (usbstick_mode.translate) {
528  //Some IP packets have link layer in them, need to change them around!
529  mac_translateIPLinkLayer(ll_8023_type);
530  }
531 
532 #if UIP_CONF_IPV6_RPL
533 /* We won't play ping-pong with the host! */
534  if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) {
535  PRINTF("siclow_ethernet: Destination off-link but no route\n");
536  uip_len=0;
537  return;
538  }
539 #endif
540 
541  PRINTF("Low2Eth: Sending packet to ethernet\n\r");
542 
543  uip_len += UIP_LLH_LEN;
544 
545  usb_eth_send(uip_buf, uip_len, 1);
546 #if !RF230BB
547  usb_eth_stat.rxok++;
548 #endif
549  uip_len = 0;
550 }
551 
552 /**
553  * \brief Translate IP packet's possible link-layer addresses, passing
554  * the message to the appropriate higher level function for this
555  * packet (aka: ICMP)
556  * \param target The target we want to end up with - either ll_8023_type
557  * for ethernet, or ll_802154_type for 802.15.4
558  * \return Returns how successful the translation was
559  * \retval 0 Addresses, if present, were translated.
560  * \retval <0 Negative return values indicate various errors, as defined
561  * by the higher level function.
562  */
563 int8_t mac_translateIPLinkLayer(lltype_t target)
564 {
565 
566 #if UIP_LLADDR_LEN == 8
567  if (UIP_IP_BUF->proto == UIP_PROTO_ICMP6) {
568  PRINTF("eth2low: ICMP Message detected\n\r");
569  return mac_translateIcmpLinkLayer(target);
570  }
571  return 0;
572 #else
573  return 1;
574 #endif
575 
576 }
577 
578 #include "net/uip-icmp6.h"
579 #include "net/uip-nd6.h"
580 
581 typedef struct {
582  uint8_t type;
583  uint8_t length;
584  uint8_t data[16];
585 } icmp_opts_t;
586 
587 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
588 #define UIP_ICMP_OPTS(x) ((icmp_opts_t *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN + x])
589 
590 void slide(uint8_t * data, uint8_t length, int16_t slide);
591 
592 /**
593  * \brief Translate the link-layer (L2) addresses in an ICMP packet.
594  * This will just be NA/NS/RA/RS packets currently.
595  * \param target The target we want to end up with - either ll_8023_type
596  * for ethernet, or ll_802154_type for 802.15.4
597  * \return Returns how successful the translation was
598  * \retval 0 Addresses, if present, were translated.
599  * \retval -1 ICMP message was unknown type, nothing done.
600  * \retval -2 ICMP Length does not make sense?
601  * \retval -3 Unknown 'target' type
602  */
603 int8_t mac_translateIcmpLinkLayer(lltype_t target)
604 {
605  uint16_t icmp_opt_offset = 0;
606  int16_t len = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0] << 8);
607 
608  uint16_t iplen;
609 
610  uint8_t i;
611 
612  int16_t sizechange;
613 
614  uint8_t llbuf[16];
615 
616  //Figure out offset to start of options
617  switch(UIP_ICMP_BUF->type) {
618  case ICMP6_NS:
619  case ICMP6_NA:
620  icmp_opt_offset = 24;
621  break;
622 
623  case ICMP6_RS:
624  icmp_opt_offset = 8;
625  break;
626 
627  case ICMP6_RA:
628  icmp_opt_offset = 16;
629  break;
630 
631  case ICMP6_REDIRECT:
632  icmp_opt_offset = 40;
633  break;
634 
635  /** Things without link-layer */
636  case ICMP6_DST_UNREACH:
638  case ICMP6_TIME_EXCEEDED:
639  case ICMP6_PARAM_PROB:
640  case ICMP6_ECHO_REQUEST:
641  case ICMP6_ECHO_REPLY:
642  return 0;
643  break;
644 
645  default:
646  return -1;
647  }
648 
649  //Figure out length of options
650  len -= icmp_opt_offset;
651 
652  //Sanity check
653  if (len < 8) return -2;
654 
655  //While we have options to do...
656  while (len >= 8){
657 
658  //If we have one of these, we have something useful!
659  if (((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_SLLAO) ||
660  ((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_TLLAO) ) {
661 
662  /* Shrinking the buffer may thrash things, so we store the old
663  link-layer address */
664  for(i = 0; i < (UIP_ICMP_OPTS(icmp_opt_offset)->length*8 - 2); i++) {
665  llbuf[i] = UIP_ICMP_OPTS(icmp_opt_offset)->data[i];
666  }
667 
668  //Shrink/grow buffer as needed
669  if (target == ll_802154_type) {
670  //Current is 802.3, Hence current link-layer option is 6 extra bytes
671  sizechange = 8;
672  slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 6, len - 6, sizechange);
673  } else if (target == ll_8023_type) {
674  /* Current is 802.15.4, Hence current link-layer option is 14 extra
675  * bytes.
676  * (Actual LL is 8 bytes, but total option length is in multiples of
677  * 8 Bytes, hence 8 + 2 = 10. Closest is 16 bytes, then 16 bytes for
678  * total optional length - 2 bytes for type + length leaves 14 )
679  */
680  sizechange = -8;
681  slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 14, len - 14, sizechange);
682  } else {
683  return -3; //Uh-oh!
684  }
685 
686  //Translate addresses
687  if (target == ll_802154_type) {
688  mac_createSicslowpanLongAddr(llbuf, (uip_lladdr_t *)UIP_ICMP_OPTS(icmp_opt_offset)->data);
689  } else {
690 #if !UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
691  if(!mac_createEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data, (uip_lladdr_t *)llbuf))
692 #endif
693  mac_createDefaultEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data);
694  }
695 
696  //Adjust the length
697  if (target == ll_802154_type) {
698  UIP_ICMP_OPTS(icmp_opt_offset)->length = 2;
699  } else {
700  UIP_ICMP_OPTS(icmp_opt_offset)->length = 1;
701  }
702 
703  //Adjust the IP header length, as well as uIP length
704  iplen = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0]<<8);
705  iplen += sizechange;
706  len += sizechange;
707 
708  UIP_IP_BUF->len[1] = (uint8_t)iplen;
709  UIP_IP_BUF->len[0] = (uint8_t)(iplen >> 8);
710 
711  uip_len += sizechange;
712 
713  //We broke ICMP checksum, be sure to fix that
714  UIP_ICMP_BUF->icmpchksum = 0;
715 #if UIP_CONF_IPV6 //allow non ipv6 builds
716  UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
717 #endif
718 
719  //Finally set up next run in while loop
720  len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
721  icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
722  } else {
723 
724  //Not an option we care about, ignore it
725  len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
726 
727  //This shouldn't happen!
728  if (UIP_ICMP_OPTS(icmp_opt_offset)->length == 0) {
729  PRINTF("Option in ND packet has length zero, error?\n\r");
730  len = 0;
731  }
732 
733  icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
734 
735  } //If ICMP_OPT is one we care about
736 
737  } //while(len >= 8)
738 
739  return 0;
740 
741 }
742 
743 
744 /**
745  * \brief Create a 802.15.4 long address from a 802.3 address
746  * \param ethernet Pointer to ethernet address
747  * \param lowpan Pointer to 802.15.4 address
748  */
749 uint8_t mac_createSicslowpanLongAddr(uint8_t * ethernet, uip_lladdr_t * lowpan)
750 {
751 #if UIP_CONF_AUTO_SUBSTITUTE_LOCAL_MAC_ADDR
752  //Special case - if the address is our address, we just copy over what we know to be
753  //our 802.15.4 address
754  if (memcmp((uint8_t *)&usb_ethernet_addr, ethernet, 6) == 0)
755  {
756  memcpy((uint8_t *)lowpan, &macLongAddr, UIP_LLADDR_LEN);
757  return 1;
758  }
759 #endif
760 
761 #if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
762 
763  //Easy does it!
764  lowpan->addr[0] = ethernet[0];
765  lowpan->addr[1] = ethernet[1];
766  lowpan->addr[2] = ethernet[2];
767  lowpan->addr[3] = 0xff;
768  lowpan->addr[4] = 0xfe;
769  lowpan->addr[5] = ethernet[3];
770  lowpan->addr[6] = ethernet[4];
771  lowpan->addr[7] = ethernet[5];
772 
773 #else //!UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
774 
775  uint8_t index;
776 
777 #if UIP_LLADDR_LEN == 8
778  //Check if translate bit is set, hence we have to look up the prefix
780  //Get top bits
781  index = ethernet[0] >> 3;
782 
783  //Copy over prefix
784  lowpan->addr[0] = prefixBuffer[index][0];
785  lowpan->addr[1] = prefixBuffer[index][1];
786  lowpan->addr[2] = prefixBuffer[index][2];
787  lowpan->addr[3] = ethernet[1];
788  lowpan->addr[4] = ethernet[2];
789 
790  //Check this is plausible...
791  if (index >= prefixCounter)
792  return 0;
793  } else {
794  lowpan->addr[0] = ethernet[0];
795  lowpan->addr[1] = ethernet[1];
796  lowpan->addr[2] = ethernet[2];
797  lowpan->addr[3] = 0xff;
798  lowpan->addr[4] = 0xfe;
799  }
800 
801  lowpan->addr[5] = ethernet[3];
802  lowpan->addr[6] = ethernet[4];
803  lowpan->addr[7] = ethernet[5];
804 
805 #else //UIP_LLADDR != 8
806  // Not sure when we would ever hit this case...
807  uint8_t i;
808  for(i = 0; i < UIP_LLADDR_LEN; i++) {
809  lowpan->addr[i] = ethernet[i];
810  }
811 #endif //UIP_LLADDR == 8
812 
813 #endif //UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
814 
815  return 1;
816 }
817 
818 
819 /**
820  * \brief Create a 802.3 address from a 802.15.4 long address
821  * \param ethernet Pointer to ethernet address
822  * \param lowpan Pointer to 802.15.4 address
823  */
824 uint8_t mac_createEthernetAddr(uint8_t * ethernet, uip_lladdr_t * lowpan)
825 {
826 #if UIP_CONF_AUTO_SUBSTITUTE_LOCAL_MAC_ADDR
827  //Special case - if the address is our address, we just copy over what we know to be
828  //our 802.3 address
829  if (memcmp((uint8_t *)&macLongAddr, (uint8_t *)lowpan, UIP_LLADDR_LEN) == 0) {
830  usb_eth_get_mac_address(ethernet);
831  return 1;
832  }
833 #endif
834 
835 #if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
836 
837  /** Just copy over 6 bytes **/
838  ethernet[0] = lowpan->addr[0];
839  ethernet[1] = lowpan->addr[1];
840  ethernet[2] = lowpan->addr[2];
841  ethernet[3] = lowpan->addr[5];
842  ethernet[4] = lowpan->addr[6];
843  ethernet[5] = lowpan->addr[7];
844 
845 #else //!UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
846 
847  uint8_t index = 0;
848  uint8_t i;
849 
850 #if UIP_LLADDR_LEN == 8
851 
852  //Check if we need to do anything:
853  if ((lowpan->addr[3] == 0xff) && (lowpan->addr[4] == 0xfe) &&
854  ((lowpan->addr[0] & TRANSLATE_BIT_MASK) == 0) &&
855  ((lowpan->addr[0] & MULTICAST_BIT_MASK) == 0) &&
856  (lowpan->addr[0] & LOCAL_BIT_MASK)) {
857 
858  /** Nope: just copy over 6 bytes **/
859  ethernet[0] = lowpan->addr[0];
860  ethernet[1] = lowpan->addr[1];
861  ethernet[2] = lowpan->addr[2];
862  ethernet[3] = lowpan->addr[5];
863  ethernet[4] = lowpan->addr[6];
864  ethernet[5] = lowpan->addr[7];
865 
866 
867  } else {
868 
869  /** Yes: need to store prefix **/
870  for (i = 0; i < prefixCounter; i++) {
871  //Check the current prefix - if it fails, check next one
872  if ((lowpan->addr[0] == prefixBuffer[i][0]) &&
873  (lowpan->addr[1] == prefixBuffer[i][1]) &&
874  (lowpan->addr[2] == prefixBuffer[i][2])) {
875  break;
876  }
877  }
878  index = i;
879 
880  if (index >= PREFIX_BUFFER_SIZE) {
881  // Overflow. Fall back to simple translation.
882  // TODO: Implement me!
883  ethernet[0] = lowpan->addr[0];
884  ethernet[1] = lowpan->addr[1];
885  ethernet[2] = lowpan->addr[2];
886  ethernet[3] = lowpan->addr[5];
887  ethernet[4] = lowpan->addr[6];
888  ethernet[5] = lowpan->addr[7];
889  return 0;
890  } else {
891  //Are we making a new one?
892  if (index == prefixCounter) {
893  prefixCounter++;
894  prefixBuffer[index][0] = lowpan->addr[0];
895  prefixBuffer[index][1] = lowpan->addr[1];
896  prefixBuffer[index][2] = lowpan->addr[2];
897  }
898 
899  //Create ethernet MAC address now
900  ethernet[0] = TRANSLATE_BIT_MASK | LOCAL_BIT_MASK | (index << 3);
901  ethernet[1] = lowpan->addr[3];
902  ethernet[2] = lowpan->addr[4];
903  ethernet[3] = lowpan->addr[5];
904  ethernet[4] = lowpan->addr[6];
905  ethernet[5] = lowpan->addr[7];
906  }
907  }
908 
909 #else //UIP_LLADDR_LEN != 8
910  // Not sure when we would ever hit this case...
911  //Create ethernet MAC address now
912  for(i = 0; i < UIP_LLADDR_LEN; i++) {
913  ethernet[i] = lowpan->addr[i];
914  }
915 #endif //UIP_LLADDR_LEN == 8
916 
917 #endif //UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
918 
919  return 1;
920 }
921 /**
922  * \brief Create a 802.3 address (default)
923  * \param ethernet Pointer to ethernet address
924  */
925 uint8_t mac_createDefaultEthernetAddr(uint8_t * ethernet)
926 {
927  memcpy(ethernet, &simple_trans_ethernet_addr, 6);
928  return 1;
929 }
930 /**
931  * \brief Slide the pointed to memory up a certain amount,
932  * growing/shrinking a buffer
933  * \param data Pointer to start of data buffer
934  * \param length Length of the data buffer
935  * \param slide How many bytes to slide the buffer up in memory (if +) or
936  * down in memory (if -)
937  */
938 void slide(uint8_t * data, uint8_t length, int16_t slide)
939 {
940  //Sanity checks
941  if (!length) return;
942  if (!slide) return;
943 
944  uint8_t i = 0;
945 
946  while(length) {
947  length--;
948 
949  //If we are sliding up, we do from the top of the buffer down
950  if (slide > 0) {
951  *(data + length + slide) = *(data + length);
952 
953  //If we are sliding down, we do from the bottom of the buffer up
954  } else {
955  *(data + slide + i) = *(data + i);
956  }
957 
958  i++;
959  }
960 }
961 
962 //#define ETHBUF(x) ((struct uip_eth_hdr *)x)
963 //#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
964 
965 void
966 mac_log_802_15_4_tx(const uint8_t* buffer, size_t total_len) {
967  if (usbstick_mode.raw != 0) {
968  uint8_t sendlen;
969 
970  static uint8_t raw_buf[127+ UIP_LLH_LEN +1];
971 
972  /* Get the raw frame */
973  memcpy(&raw_buf[UIP_LLH_LEN], buffer, total_len);
974  sendlen = total_len;
975 
976  /* Setup generic ethernet stuff */
977  ETHBUF(raw_buf)->type = uip_htons(0x809A); //UIP_ETHTYPE_802154 0x809A
978 
979  /* Check for broadcast message */
980  if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) {
981  ETHBUF(raw_buf)->dest.addr[0] = 0x33;
982  ETHBUF(raw_buf)->dest.addr[1] = 0x33;
983  ETHBUF(raw_buf)->dest.addr[2] = 0x00;
984  ETHBUF(raw_buf)->dest.addr[3] = 0x00;
985  ETHBUF(raw_buf)->dest.addr[4] = 0x80;
986  ETHBUF(raw_buf)->dest.addr[5] = 0x9A;
987 
988 /*
989  ETHBUF(raw_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
990  ETHBUF(raw_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
991  ETHBUF(raw_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
992  ETHBUF(raw_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
993 */
994  } else {
995  /* Otherwise we have a real address */
996  mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->dest.addr[0]),
997  (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
998  }
999 
1000 // mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]),(uip_lladdr_t *)&uip_lladdr.addr);
1001  mac_createDefaultEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]));
1002 
1003  sendlen += UIP_LLH_LEN;
1004  usb_eth_send(raw_buf, sendlen, 0);
1005  }
1006 }
1007 
1008 void
1009 mac_log_802_15_4_rx(const uint8_t* buf, size_t len) {
1010  if (usbstick_mode.raw != 0) {
1011  uint8_t sendlen;
1012 
1013  /* Get the raw frame */
1014  memcpy(&raw_buf[UIP_LLH_LEN], buf, len);
1015  sendlen = len;
1016 
1017  /* Setup generic ethernet stuff */
1018  ETHBUF(raw_buf)->type = uip_htons(0x809A); //UIP_ETHTYPE_802154 0x809A
1019 
1020  /* Check for broadcast message */
1021  if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) {
1022  ETHBUF(raw_buf)->dest.addr[0] = 0x33;
1023  ETHBUF(raw_buf)->dest.addr[1] = 0x33;
1024  ETHBUF(raw_buf)->dest.addr[2] = 0x00;
1025  ETHBUF(raw_buf)->dest.addr[3] = 0x00;
1026  ETHBUF(raw_buf)->dest.addr[4] = 0x80;
1027  ETHBUF(raw_buf)->dest.addr[5] = 0x9A;
1028 /*
1029  ETHBUF(raw_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
1030  ETHBUF(raw_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
1031  ETHBUF(raw_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
1032  ETHBUF(raw_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
1033 */
1034  } else {
1035  /* Otherwise we have a real address */
1036  mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->dest.addr[0]),
1037  (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
1038  }
1039 
1040 // mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]),(uip_lladdr_t *)&uip_lladdr.addr);
1041  mac_createDefaultEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]));
1042 
1043  sendlen += UIP_LLH_LEN;
1044  usb_eth_send(raw_buf, sendlen, 0);
1045  }
1046 }
1047 /* The rf230bb send driver may call this routine via RF230BB_HOOK_IS_SEND_ENABLED */
1048 bool
1049 mac_is_send_enabled(void) {
1050  if ((usbstick_mode.sendToRf == 0) || (usbstick_mode.sneeze != 0)) return 0;
1051  return 1;
1052 //return usbstick_mode.sendToRf;
1053 }
1054 
1055 /** @} */
1056 
1057 
1058 
1059 /** @} */
1060 
1061 
1062 #if !RF230BB
1063 /*--------------------------------------------------------------------*/
1064 /** \brief Process a received 6lowpan packet. Hijack function.
1065  * \param r The MAC layer
1066  *
1067  * The 6lowpan packet is put in packetbuf by the MAC. This routine calls
1068  * any other needed layers (either 6lowpan, or just raw ethernet dump)
1069  */
1070 void mac_ethhijack(const struct mac_driver *r)
1071 {
1072  if (usbstick_mode.raw) {
1073  mac_802154raw(r);
1074  }
1075 
1076  if (usbstick_mode.sicslowpan) {
1077 
1078 #if UIP_CONF_USE_RUM
1079  if (parsed_frame->payload[4]) { /* RUM 6lowpan frame type */
1080 #endif
1081  sicslowinput(r);
1082 #if UIP_CONF_USE_RUM
1083  }
1084 #endif
1085 
1086 
1087  }
1088 
1089 }
1090 
1091 void mac_ethhijack_nondata(const struct mac_driver *r)
1092 {
1093  if (usbstick_mode.raw)
1094  mac_802154raw(r);
1095 }
1096 
1097 
1098 /*--------------------------------------------------------------------*/
1099 /*--------------------------------------------------------------------*/
1100 /** \brief Logs a sent 6lowpan frame
1101  *
1102  * This routine passes a frame
1103  * directly to the ethernet layer without decompressing.
1104  */
1106 {
1107  mac_log_802_15_4_tx(frame_result->frame, frame_result->length);
1108 }
1109 
1110 
1111 /*--------------------------------------------------------------------*/
1112 /** \brief Process a received 6lowpan packet.
1113  * \param r The MAC layer
1114  *
1115  * The 6lowpan packet is put in packetbuf by the MAC. This routine passes
1116  * it directly to the ethernet layer without decompressing.
1117  */
1118 void mac_802154raw(const struct mac_driver *r) {
1119  mac_log_802_15_4_tx(radio_frame_data(), radio_frame_length());
1120 }
1121 
1122 #endif /* !RF230BB */
1123 
1124 
1125