From patchwork Tue Feb 28 15:00:30 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: alex.bluesman.smirnov@gmail.com X-Patchwork-Id: 143459 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 025D3B6EE6 for ; Wed, 29 Feb 2012 01:06:14 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932071Ab2B1OGG (ORCPT ); Tue, 28 Feb 2012 09:06:06 -0500 Received: from mail-ey0-f174.google.com ([209.85.215.174]:35589 "EHLO mail-ey0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753994Ab2B1OGA (ORCPT ); Tue, 28 Feb 2012 09:06:00 -0500 Received: by mail-ey0-f174.google.com with SMTP id h12so2585014eaa.19 for ; Tue, 28 Feb 2012 06:05:59 -0800 (PST) Received-SPF: pass (google.com: domain of alex.bluesman.smirnov@gmail.com designates 10.14.39.195 as permitted sender) client-ip=10.14.39.195; Authentication-Results: mr.google.com; spf=pass (google.com: domain of alex.bluesman.smirnov@gmail.com designates 10.14.39.195 as permitted sender) smtp.mail=alex.bluesman.smirnov@gmail.com; dkim=pass header.i=alex.bluesman.smirnov@gmail.com Received: from mr.google.com ([10.14.39.195]) by 10.14.39.195 with SMTP id d43mr985982eeb.28.1330437959851 (num_hops = 1); Tue, 28 Feb 2012 06:05:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=ofww7oHv1oqi0eDyPS0E3bMIlS+O2ug7/nCKJTh+d00=; b=hSrd/o2rgrLTDOp5al87yCqxMIyljDXyq8aZPkc+LZq5kC7EI6A3XOHNGaGdViVes+ +H4T00OGmDDzOWpLUJTT5a2CZJUzgGWJoz/6S/Ve7hNDCBngzFwm66BX2PVcWr/I3HcT +d7PmMd92U6SmVJN8PYcjVO/3Tn3HESpATnpA= Received: by 10.14.39.195 with SMTP id d43mr738541eeb.28.1330437959717; Tue, 28 Feb 2012 06:05:59 -0800 (PST) Received: from localhost.localdomain ([91.213.169.4]) by mx.google.com with ESMTPS id v51sm70715974eef.2.2012.02.28.06.05.58 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 28 Feb 2012 06:05:59 -0800 (PST) From: Alexander Smirnov To: netdev@vger.kernel.org Cc: davem@davemloft.net, linux-zigbee-devel@lists.sourceforge.net, dbaryshkov@gmail.com, Alexander Smirnov Subject: [PATCH 11/13] mac802154: monitor device support Date: Tue, 28 Feb 2012 18:00:30 +0300 Message-Id: <1330441232-17650-12-git-send-email-alex.bluesman.smirnov@gmail.com> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1330441232-17650-1-git-send-email-alex.bluesman.smirnov@gmail.com> References: <1330441232-17650-1-git-send-email-alex.bluesman.smirnov@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Support for monitor device intended to capture all the network activity. This interface could be used by networks sniffers. Already supported by WireShark. Signed-off-by: Alexander Smirnov --- include/linux/if_arp.h | 1 + include/linux/nl802154.h | 16 ++++++ include/net/wpan-phy.h | 3 + net/mac802154/Makefile | 2 +- net/mac802154/ieee802154_dev.c | 5 ++- net/mac802154/mac802154.h | 5 ++ net/mac802154/monitor.c | 116 ++++++++++++++++++++++++++++++++++++++++ net/mac802154/rx.c | 1 + 8 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 net/mac802154/monitor.c diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h index 6d722f4..f0e69c6 100644 --- a/include/linux/if_arp.h +++ b/include/linux/if_arp.h @@ -87,6 +87,7 @@ #define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */ #define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */ #define ARPHRD_IEEE802154 804 +#define ARPHRD_IEEE802154_MONITOR 805 /* IEEE 802.15.4 network monitor */ #define ARPHRD_PHONET 820 /* PhoNet media type */ #define ARPHRD_PHONET_PIPE 821 /* PhoNet pipe header */ diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h index 2015ad2..9964c4f 100644 --- a/include/linux/nl802154.h +++ b/include/linux/nl802154.h @@ -129,6 +129,22 @@ enum { enum { __IEEE802154_DEV_INVALID = -1, + + /* + * TODO: + * + * Nowadays three device types supported by this stack at linux-zigbee + * project: WPAN = 0, MONITOR = 1 and SMAC = 2. + * + * Since this stack implementation exists many years, it's definitely + * bad idea to change the assigned values due to they are already used + * by third-party software like: iz-tools, wireshark... + * + * Currently only monitor device is added and initialized by '1' for + * compatibility. + */ + IEEE802154_DEV_MONITOR = 1, + __IEEE802154_DEV_MAX, }; diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h index 1437c90..d0fb1ed 100644 --- a/include/net/wpan-phy.h +++ b/include/net/wpan-phy.h @@ -24,6 +24,9 @@ #include #include +#define WPAN_NUM_PAGES 32 +#define WPAN_NUM_CHANNELS 27 + struct wpan_phy { struct mutex pib_lock; diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile index 6b348b0..ec1bd3f 100644 --- a/net/mac802154/Makefile +++ b/net/mac802154/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_MAC802154) += mac802154.o -mac802154-objs := ieee802154_dev.o rx.o tx.o mac_cmd.o mib.o +mac802154-objs := ieee802154_dev.o rx.o tx.o mac_cmd.o mib.o monitor.o diff --git a/net/mac802154/ieee802154_dev.c b/net/mac802154/ieee802154_dev.c index 44e0317..c3f52cf 100644 --- a/net/mac802154/ieee802154_dev.c +++ b/net/mac802154/ieee802154_dev.c @@ -131,8 +131,11 @@ mac802154_add_iface(struct wpan_phy *phy, const char *name, int type) struct net_device *dev; int err = -ENOMEM; - /* No devices is currently supported */ switch (type) { + case IEEE802154_DEV_MONITOR: + dev = alloc_netdev(sizeof(struct mac802154_sub_if_data), + name, mac802154_monitor_setup); + break; default: dev = NULL; err = -EINVAL; diff --git a/net/mac802154/mac802154.h b/net/mac802154/mac802154.h index 5c96b2d..38196f1 100644 --- a/net/mac802154/mac802154.h +++ b/net/mac802154/mac802154.h @@ -86,11 +86,16 @@ struct mac802154_sub_if_data { #define MAC802154_MAX_XMIT_ATTEMPTS 3 +#define MAC802154_CHAN_NONE (~(u8)0) + extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; int mac802154_slave_open(struct net_device *dev); int mac802154_slave_close(struct net_device *dev); +void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb); +void mac802154_monitor_setup(struct net_device *dev); + netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, u8 page, u8 chan); diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c new file mode 100644 index 0000000..137b868 --- /dev/null +++ b/net/mac802154/monitor.c @@ -0,0 +1,116 @@ +/* + * Copyright 2007, 2008, 2009 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Written by: + * Dmitry Eremin-Solenikov + * Sergey Lapin + * Maxim Gorbachyov + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mac802154.h" + +static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct mac802154_sub_if_data *priv; + u8 chan, page; + + priv = netdev_priv(dev); + + /* FIXME: locking */ + chan = priv->hw->phy->current_channel; + page = priv->hw->phy->current_page; + + if (chan == MAC802154_CHAN_NONE) /* not initialized */ + return NETDEV_TX_OK; + + BUG_ON(page >= WPAN_NUM_PAGES); + BUG_ON(chan >= WPAN_NUM_CHANNELS); + + skb->skb_iif = dev->ifindex; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + + return mac802154_tx(priv->hw, skb, page, chan); +} + + +void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb) +{ + struct sk_buff *skb2; + struct mac802154_sub_if_data *sdata; + u16 crc = crc_ccitt(0, skb->data, skb->len); + u8 *data; + + rcu_read_lock(); + list_for_each_entry_rcu(sdata, &priv->slaves, list) { + if (sdata->type != IEEE802154_DEV_MONITOR) + continue; + + skb2 = skb_clone(skb, GFP_ATOMIC); + skb2->dev = sdata->dev; + skb2->pkt_type = PACKET_HOST; + data = skb_put(skb2, 2); + data[0] = crc & 0xff; + data[1] = crc >> 8; + + if (in_interrupt()) + netif_rx(skb2); + else + netif_rx_ni(skb2); + } + rcu_read_unlock(); +} + +static const struct net_device_ops mac802154_monitor_ops = { + .ndo_open = mac802154_slave_open, + .ndo_stop = mac802154_slave_close, + .ndo_start_xmit = mac802154_monitor_xmit, +}; + +void mac802154_monitor_setup(struct net_device *dev) +{ + struct mac802154_sub_if_data *priv; + + dev->addr_len = 0; + dev->hard_header_len = 0; + dev->needed_tailroom = 2; /* FCS */ + dev->mtu = IEEE802154_MTU; + dev->tx_queue_len = 10; + dev->type = ARPHRD_IEEE802154_MONITOR; + dev->flags = IFF_NOARP | IFF_BROADCAST; + dev->watchdog_timeo = 0; + + dev->destructor = free_netdev; + dev->netdev_ops = &mac802154_monitor_ops; + dev->ml_priv = &mac802154_mlme_reduced; + + priv = netdev_priv(dev); + priv->type = IEEE802154_DEV_MONITOR; + + priv->chan = MAC802154_CHAN_NONE; /* not initialized */ + priv->page = 0; /* for compat */ +} diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 3446379..3a6836c 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -58,6 +58,7 @@ mac802154_subif_rx(struct ieee802154_dev *hw, struct sk_buff *skb, u8 lqi) skb_trim(skb, skb->len - 2); /* CRC */ } + mac802154_monitors_rx(priv, skb); out: dev_kfree_skb(skb); return;