RE: [PATCH v2 1/2] NFC: Add RAW Socket type for sniffing and implemented NCI sniffing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,
Sorry I sent to wrong mailing list. Please ignore!!

> -----Original Message-----
> From: linux-bluetooth-owner@xxxxxxxxxxxxxxx [mailto:linux-bluetooth-
> owner@xxxxxxxxxxxxxxx] On Behalf Of Hirenkumar Tandel
> Sent: Thursday, April 24, 2014 2:01 PM
> To: 'Samuel Ortiz'
> Cc: linux-bluetooth@xxxxxxxxxxxxxxx; Quinton Yuan
> Subject: [PATCH v2 1/2] NFC: Add RAW Socket type for sniffing and
> implemented NCI sniffing
> 
> 
> This patch introduces Socket with protocol: SOCKPROTO_RAW and type:
> SOCK_RAW.
> It implements NCI sniffing feature using RAW sniffing. Also modified
> macros for LLCP sniffing.
> 
> Signed-off-by: Hiren Tandel <hirent@xxxxxxxxxxx>
> Signed-off-by: Rahul Tank <rahult@xxxxxxxxxxx>
> ---
> v2: Use common set of macros for both LLCP & RAW. Also use common release,
>     recvmsg & destruct functions for both SOCK_SEQPACKET & SOCK_RAW types.
>     (Samuel Ortiz)
> 
>  include/net/nfc/nfc.h    |  3 ++
>  include/uapi/linux/nfc.h | 16 ++++++---  net/nfc/llcp_commands.c  |  2 +-
>  net/nfc/llcp_core.c      | 11 +++---
>  net/nfc/nci/core.c       |  9 +++++
>  net/nfc/nfc.h            |  6 ++++
>  net/nfc/rawsock.c        | 94
> +++++++++++++++++++++++++++++++++++++++++++++---
>  7 files changed, 126 insertions(+), 15 deletions(-)
> 
> diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index
> 2e8b40c..6c583e2 100644
> --- a/include/net/nfc/nfc.h
> +++ b/include/net/nfc/nfc.h
> @@ -264,4 +264,7 @@ int nfc_add_se(struct nfc_dev *dev, u32 se_idx, u16
> type);  int nfc_remove_se(struct nfc_dev *dev, u32 se_idx);  struct nfc_se
> *nfc_find_se(struct nfc_dev *dev, u32 se_idx);
> 
> +void nfc_send_to_raw_sock(struct nfc_dev *dev, struct sk_buff *skb,
> +			  u8 payload_type, u8 direction);
> +
>  #endif /* __NET_NFC_H */
> diff --git a/include/uapi/linux/nfc.h b/include/uapi/linux/nfc.h index
> 9789dc9..9b19b44 100644
> --- a/include/uapi/linux/nfc.h
> +++ b/include/uapi/linux/nfc.h
> @@ -273,11 +273,19 @@ struct sockaddr_nfc_llcp {
>   * First byte is the adapter index
>   * Second byte contains flags
>   *  - 0x01 - Direction (0=RX, 1=TX)
> - *  - 0x02-0x80 - Reserved
> + *  - 0x02-0x04 - Payload type (000=LLCP, 001=NCI, 010=HCI, 011=Digital,
> + *                              100=Proprietary)
> + *  - 0x05-0x80 - Reserved
>   **/
> -#define NFC_LLCP_RAW_HEADER_SIZE	2
> -#define NFC_LLCP_DIRECTION_RX		0x00
> -#define NFC_LLCP_DIRECTION_TX		0x01
> +#define NFC_RAW_HEADER_SIZE	2
> +#define NFC_DIRECTION_RX		0x00
> +#define NFC_DIRECTION_TX		0x01
> +
> +#define RAW_PAYLOAD_LLCP 0
> +#define RAW_PAYLOAD_NCI	1
> +#define RAW_PAYLOAD_HCI	2
> +#define RAW_PAYLOAD_DIGITAL	3
> +#define RAW_PAYLOAD_PROPRIETARY	4
> 
>  /* socket option names */
>  #define NFC_LLCP_RW		0
> diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c index
> bec6ed1..a3ad69a 100644
> --- a/net/nfc/llcp_commands.c
> +++ b/net/nfc/llcp_commands.c
> @@ -387,7 +387,7 @@ int nfc_llcp_send_symm(struct nfc_dev *dev)
> 
>  	__net_timestamp(skb);
> 
> -	nfc_llcp_send_to_raw_sock(local, skb, NFC_LLCP_DIRECTION_TX);
> +	nfc_llcp_send_to_raw_sock(local, skb, NFC_DIRECTION_TX);
> 
>  	return nfc_data_exchange(dev, local->target_idx, skb,
>  				 nfc_llcp_recv, local);
> diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c index
> 9d37ded..0518df8 100644
> --- a/net/nfc/llcp_core.c
> +++ b/net/nfc/llcp_core.c
> @@ -678,16 +678,17 @@ void nfc_llcp_send_to_raw_sock(struct nfc_llcp_local
> *local,
>  			continue;
> 
>  		if (skb_copy == NULL) {
> -			skb_copy = __pskb_copy(skb, NFC_LLCP_RAW_HEADER_SIZE,
> +			skb_copy = __pskb_copy(skb, NFC_RAW_HEADER_SIZE,
>  					       GFP_ATOMIC);
> 
>  			if (skb_copy == NULL)
>  				continue;
> 
> -			data = skb_push(skb_copy, NFC_LLCP_RAW_HEADER_SIZE);
> +			data = skb_push(skb_copy, NFC_RAW_HEADER_SIZE);
> 
>  			data[0] = local->dev ? local->dev->idx : 0xFF;
> -			data[1] = direction;
> +			data[1] = direction & 0x01;
> +			data[1] |= (RAW_PAYLOAD_LLCP << 1);
>  		}
> 
>  		nskb = skb_clone(skb_copy, GFP_ATOMIC); @@ -745,7 +746,7 @@
> static void nfc_llcp_tx_work(struct work_struct *work)
>  			__net_timestamp(skb);
> 
>  			nfc_llcp_send_to_raw_sock(local, skb,
> -						  NFC_LLCP_DIRECTION_TX);
> +						  NFC_DIRECTION_TX);
> 
>  			ret = nfc_data_exchange(local->dev, local->target_idx,
>  						skb, nfc_llcp_recv, local);
> @@ -1474,7 +1475,7 @@ static void nfc_llcp_rx_work(struct work_struct
> *work)
> 
>  	__net_timestamp(skb);
> 
> -	nfc_llcp_send_to_raw_sock(local, skb, NFC_LLCP_DIRECTION_RX);
> +	nfc_llcp_send_to_raw_sock(local, skb, NFC_DIRECTION_RX);
> 
>  	nfc_llcp_rx_skb(local, skb);
> 
> diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index
> 28d0762..6cc4652 100644
> --- a/net/nfc/nci/core.c
> +++ b/net/nfc/nci/core.c
> @@ -861,6 +861,10 @@ static int nci_send_frame(struct nci_dev *ndev,
> struct sk_buff *skb)
>  	/* Get rid of skb owner, prior to sending to the driver. */
>  	skb_orphan(skb);
> 
> +	/* Send copy to sniffer */
> +	nfc_send_to_raw_sock(ndev->nfc_dev, skb,
> +			     RAW_PAYLOAD_NCI, NFC_DIRECTION_TX);
> +
>  	return ndev->ops->send(ndev, skb);
>  }
> 
> @@ -935,6 +939,11 @@ static void nci_rx_work(struct work_struct *work)
>  	struct sk_buff *skb;
> 
>  	while ((skb = skb_dequeue(&ndev->rx_q))) {
> +
> +		/* Send copy to sniffer */
> +		nfc_send_to_raw_sock(ndev->nfc_dev, skb,
> +				     RAW_PAYLOAD_NCI, NFC_DIRECTION_RX);
> +
>  		/* Process frame */
>  		switch (nci_mt(skb->data)) {
>  		case NCI_MT_RSP_PKT:
> diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index 9d6e74f..88d6006 100644
> --- a/net/nfc/nfc.h
> +++ b/net/nfc/nfc.h
> @@ -40,6 +40,12 @@ struct nfc_rawsock {
>  	struct work_struct tx_work;
>  	bool tx_work_scheduled;
>  };
> +
> +struct nfc_sock_list {
> +	struct hlist_head head;
> +	rwlock_t          lock;
> +};
> +
>  #define nfc_rawsock(sk) ((struct nfc_rawsock *) sk)  #define
> to_rawsock_sk(_tx_work) \
>  	((struct sock *) container_of(_tx_work, struct nfc_rawsock,
> tx_work)) diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c index
> c27a6e8..8627c75 100644
> --- a/net/nfc/rawsock.c
> +++ b/net/nfc/rawsock.c
> @@ -27,6 +27,24 @@
> 
>  #include "nfc.h"
> 
> +static struct nfc_sock_list raw_sk_list = {
> +	.lock = __RW_LOCK_UNLOCKED(raw_sk_list.lock)
> +};
> +
> +void nfc_sock_link(struct nfc_sock_list *l, struct sock *sk) {
> +	write_lock(&l->lock);
> +	sk_add_node(sk, &l->head);
> +	write_unlock(&l->lock);
> +}
> +
> +void nfc_sock_unlink(struct nfc_sock_list *l, struct sock *sk) {
> +	write_lock(&l->lock);
> +	sk_del_node_init(sk);
> +	write_unlock(&l->lock);
> +}
> +
>  static void rawsock_write_queue_purge(struct sock *sk)  {
>  	pr_debug("sk=%p\n", sk);
> @@ -57,6 +75,9 @@ static int rawsock_release(struct socket *sock)
>  	if (!sk)
>  		return 0;
> 
> +	if (sock->type == SOCK_RAW)
> +		nfc_sock_unlink(&raw_sk_list, sk);
> +
>  	sock_orphan(sk);
>  	sock_put(sk);
> 
> @@ -275,6 +296,26 @@ static const struct proto_ops rawsock_ops = {
>  	.mmap           = sock_no_mmap,
>  };
> 
> +static const struct proto_ops rawsock_raw_ops = {
> +	.family         = PF_NFC,
> +	.owner          = THIS_MODULE,
> +	.release        = rawsock_release,
> +	.bind           = sock_no_bind,
> +	.connect        = sock_no_connect,
> +	.socketpair     = sock_no_socketpair,
> +	.accept         = sock_no_accept,
> +	.getname        = sock_no_getname,
> +	.poll           = datagram_poll,
> +	.ioctl          = sock_no_ioctl,
> +	.listen         = sock_no_listen,
> +	.shutdown       = sock_no_shutdown,
> +	.setsockopt     = sock_no_setsockopt,
> +	.getsockopt     = sock_no_getsockopt,
> +	.sendmsg        = sock_no_sendmsg,
> +	.recvmsg        = rawsock_recvmsg,
> +	.mmap           = sock_no_mmap,
> +};
> +
>  static void rawsock_destruct(struct sock *sk)  {
>  	pr_debug("sk=%p\n", sk);
> @@ -300,10 +341,13 @@ static int rawsock_create(struct net *net, struct
> socket *sock,
> 
>  	pr_debug("sock=%p\n", sock);
> 
> -	if (sock->type != SOCK_SEQPACKET)
> +	if ((sock->type != SOCK_SEQPACKET) && (sock->type != SOCK_RAW))
>  		return -ESOCKTNOSUPPORT;
> 
> -	sock->ops = &rawsock_ops;
> +	if (sock->type == SOCK_RAW)
> +		sock->ops = &rawsock_raw_ops;
> +	else
> +		sock->ops = &rawsock_ops;
> 
>  	sk = sk_alloc(net, PF_NFC, GFP_ATOMIC, nfc_proto->proto);
>  	if (!sk)
> @@ -313,13 +357,53 @@ static int rawsock_create(struct net *net, struct
> socket *sock,
>  	sk->sk_protocol = nfc_proto->id;
>  	sk->sk_destruct = rawsock_destruct;
>  	sock->state = SS_UNCONNECTED;
> -
> -	INIT_WORK(&nfc_rawsock(sk)->tx_work, rawsock_tx_work);
> -	nfc_rawsock(sk)->tx_work_scheduled = false;
> +	if (sock->type == SOCK_RAW)
> +		nfc_sock_link(&raw_sk_list, sk);
> +	else {
> +		INIT_WORK(&nfc_rawsock(sk)->tx_work, rawsock_tx_work);
> +		nfc_rawsock(sk)->tx_work_scheduled = false;
> +	}
> 
>  	return 0;
>  }
> 
> +void nfc_send_to_raw_sock(struct nfc_dev *dev, struct sk_buff *skb,
> +			  u8 payload_type, u8 direction)
> +{
> +	struct sk_buff *skb_copy = NULL, *nskb;
> +	struct sock *sk;
> +	u8 *data;
> +
> +	read_lock(&raw_sk_list.lock);
> +
> +	sk_for_each(sk, &raw_sk_list.head) {
> +		if (!skb_copy) {
> +			skb_copy = __pskb_copy(skb, NFC_RAW_HEADER_SIZE,
> +				     GFP_ATOMIC);
> +			if (!skb_copy)
> +				continue;
> +
> +			data = skb_push(skb_copy, NFC_RAW_HEADER_SIZE);
> +
> +			data[0] = dev ? dev->idx : 0xFF;
> +			data[1] = direction & 0x01;
> +			data[1] |= (payload_type << 1);
> +		}
> +
> +		nskb = skb_clone(skb_copy, GFP_ATOMIC);
> +		if (!nskb)
> +			continue;
> +
> +		if (sock_queue_rcv_skb(sk, nskb))
> +			kfree_skb(nskb);
> +	}
> +
> +	read_unlock(&raw_sk_list.lock);
> +
> +	kfree_skb(skb_copy);
> +}
> +EXPORT_SYMBOL(nfc_send_to_raw_sock);
> +
>  static struct proto rawsock_proto = {
>  	.name     = "NFC_RAW",
>  	.owner    = THIS_MODULE,
> --
> 1.8.1.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth"
> in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info
> at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux