24 #include <linux/netdevice.h>
25 #include <linux/module.h>
26 #include <linux/if_arp.h>
40 if (
unlikely(!pskb_may_pull(skb, 1)))
49 static inline int mac802154_fetch_skb_u16(
struct sk_buff *skb,
u16 *val)
51 if (
unlikely(!pskb_may_pull(skb, 2)))
54 *val = skb->
data[0] | (skb->
data[1] << 8);
60 static inline void mac802154_haddr_copy_swap(
u8 *
dest,
const u8 *
src)
64 dest[IEEE802154_ADDR_LEN - i - 1] = src[i];
94 "Using DEBUGing ioctl SIOCSIFADDR isn't recommened!\n");
115 static int mac802154_wpan_mac_addr(
struct net_device *dev,
void *
p)
119 if (netif_running(dev))
128 static int mac802154_header_create(
struct sk_buff *skb,
150 head[pos++] = mac_cb(skb)->seq;
151 fc = mac_cb_type(skb);
176 head[pos++] = daddr->
pan_id & 0xff;
177 head[pos++] = daddr->
pan_id >> 8;
183 mac802154_haddr_copy_swap(head + pos, daddr->
hwaddr);
196 head[pos++] = saddr->
pan_id & 0xff;
197 head[pos++] = saddr->
pan_id >> 8;
204 mac802154_haddr_copy_swap(head + pos, saddr->
hwaddr);
219 mac802154_header_parse(
const struct sk_buff *skb,
unsigned char *haddr)
221 const u8 *
hdr = skb_mac_header(skb);
222 const u8 *
tail = skb_tail_pointer(skb);
230 fc = hdr[0] | (hdr[1] << 8);
243 if (fc & IEEE802154_FC_INTRA_PAN) {
246 addr->
pan_id = hdr[0] | (hdr[1] << 8);
256 if (fc & IEEE802154_FC_INTRA_PAN) {
259 addr->
pan_id = hdr[0] | (hdr[1] << 8);
277 if (!(fc & IEEE802154_FC_INTRA_PAN)) {
280 addr->
pan_id = hdr[0] | (hdr[1] << 8);
287 mac802154_haddr_copy_swap(addr->
hwaddr, hdr);
291 if (!(fc & IEEE802154_FC_INTRA_PAN)) {
294 addr->
pan_id = hdr[0] | (hdr[1] << 8);
321 priv = netdev_priv(dev);
334 dev->
stats.tx_packets++;
340 static struct header_ops mac802154_header_ops = {
341 .create = mac802154_header_create,
342 .parse = mac802154_header_parse,
348 .ndo_start_xmit = mac802154_wpan_xmit,
349 .ndo_do_ioctl = mac802154_wpan_ioctl,
350 .ndo_set_mac_address = mac802154_wpan_mac_addr,
373 priv = netdev_priv(dev);
396 pr_debug(
"getting packet via slave interface %s\n", sdata->
dev->name);
400 switch (mac_cb(skb)->
da.addr_type) {
410 if (mac_cb(skb)->
da.pan_id != sdata->
pan_id &&
413 else if (!
memcmp(mac_cb(skb)->
da.hwaddr, sdata->
dev->dev_addr,
420 if (mac_cb(skb)->
da.pan_id != sdata->
pan_id &&
423 else if (mac_cb(skb)->
da.short_addr == sdata->
short_addr)
425 else if (mac_cb(skb)->
da.short_addr ==
439 sdata->
dev->stats.rx_packets++;
440 sdata->
dev->stats.rx_bytes += skb->
len;
442 switch (mac_cb_type(skb)) {
444 return mac802154_process_data(sdata->
dev, skb);
446 pr_warning(
"ieee802154: bad frame received (type = %d)\n",
453 static int mac802154_parse_frame_start(
struct sk_buff *skb)
458 if (mac802154_fetch_skb_u16(skb, &fc) ||
459 mac802154_fetch_skb_u8(skb, &(mac_cb(skb)->seq)))
462 pr_debug(
"fc: %04x dsn: %02x\n", fc, head[2]);
468 if (fc & IEEE802154_FC_INTRA_PAN)
472 if (mac802154_fetch_skb_u16(skb, &(mac_cb(skb)->
da.pan_id)))
476 if (mac_cb_is_intrapan(skb))
477 mac_cb(skb)->sa.pan_id = mac_cb(skb)->da.pan_id;
479 pr_debug(
"dest PAN addr: %04x\n", mac_cb(skb)->
da.pan_id);
482 u16 *
da = &(mac_cb(skb)->da.short_addr);
484 if (mac802154_fetch_skb_u16(skb, da))
487 pr_debug(
"destination address is short: %04x\n",
488 mac_cb(skb)->da.short_addr);
493 mac802154_haddr_copy_swap(mac_cb(skb)->da.hwaddr,
497 pr_debug(
"destination address is hardware\n");
503 if (!(mac_cb_is_intrapan(skb))) {
504 u16 *sa_pan = &(mac_cb(skb)->sa.pan_id);
506 if (mac802154_fetch_skb_u16(skb, sa_pan))
510 pr_debug(
"source PAN addr: %04x\n", mac_cb(skb)->da.pan_id);
513 u16 *sa = &(mac_cb(skb)->sa.short_addr);
515 if (mac802154_fetch_skb_u16(skb, sa))
518 pr_debug(
"source address is short: %04x\n",
519 mac_cb(skb)->sa.short_addr);
524 mac802154_haddr_copy_swap(mac_cb(skb)->sa.hwaddr,
528 pr_debug(
"source address is hardware\n");
543 ret = mac802154_parse_frame_start(skb);
550 list_for_each_entry_rcu(sdata, &priv->
slaves,
list) {
556 mac802154_subif_frame(sdata, sskb);