1/*
2 * IEEE802154.4 socket interface
3 *
4 * Copyright 2007, 2008 Siemens AG
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Written by:
20 * Sergey Lapin <slapin@ossfans.org>
21 * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
22 */
23
24#include <linux/net.h>
25#include <linux/capability.h>
26#include <linux/module.h>
27#include <linux/if_arp.h>
28#include <linux/if.h>
29#include <linux/termios.h>	/* For TIOCOUTQ/INQ */
30#include <linux/list.h>
31#include <linux/slab.h>
32#include <net/datalink.h>
33#include <net/psnap.h>
34#include <net/sock.h>
35#include <net/tcp_states.h>
36#include <net/route.h>
37
38#include <net/af_ieee802154.h>
39#include <net/ieee802154_netdev.h>
40
41#include "af802154.h"
42
43/* Utility function for families */
44struct net_device*
45ieee802154_get_dev(struct net *net, const struct ieee802154_addr *addr)
46{
47	struct net_device *dev = NULL;
48	struct net_device *tmp;
49	__le16 pan_id, short_addr;
50	u8 hwaddr[IEEE802154_ADDR_LEN];
51
52	switch (addr->mode) {
53	case IEEE802154_ADDR_LONG:
54		ieee802154_devaddr_to_raw(hwaddr, addr->extended_addr);
55		rcu_read_lock();
56		dev = dev_getbyhwaddr_rcu(net, ARPHRD_IEEE802154, hwaddr);
57		if (dev)
58			dev_hold(dev);
59		rcu_read_unlock();
60		break;
61	case IEEE802154_ADDR_SHORT:
62		if (addr->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST) ||
63		    addr->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) ||
64		    addr->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST))
65			break;
66
67		rtnl_lock();
68
69		for_each_netdev(net, tmp) {
70			if (tmp->type != ARPHRD_IEEE802154)
71				continue;
72
73			pan_id = ieee802154_mlme_ops(tmp)->get_pan_id(tmp);
74			short_addr =
75				ieee802154_mlme_ops(tmp)->get_short_addr(tmp);
76
77			if (pan_id == addr->pan_id &&
78			    short_addr == addr->short_addr) {
79				dev = tmp;
80				dev_hold(dev);
81				break;
82			}
83		}
84
85		rtnl_unlock();
86		break;
87	default:
88		pr_warn("Unsupported ieee802154 address type: %d\n",
89			addr->mode);
90		break;
91	}
92
93	return dev;
94}
95
96static int ieee802154_sock_release(struct socket *sock)
97{
98	struct sock *sk = sock->sk;
99
100	if (sk) {
101		sock->sk = NULL;
102		sk->sk_prot->close(sk, 0);
103	}
104	return 0;
105}
106static int ieee802154_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
107				   struct msghdr *msg, size_t len)
108{
109	struct sock *sk = sock->sk;
110
111	return sk->sk_prot->sendmsg(iocb, sk, msg, len);
112}
113
114static int ieee802154_sock_bind(struct socket *sock, struct sockaddr *uaddr,
115				int addr_len)
116{
117	struct sock *sk = sock->sk;
118
119	if (sk->sk_prot->bind)
120		return sk->sk_prot->bind(sk, uaddr, addr_len);
121
122	return sock_no_bind(sock, uaddr, addr_len);
123}
124
125static int ieee802154_sock_connect(struct socket *sock, struct sockaddr *uaddr,
126				   int addr_len, int flags)
127{
128	struct sock *sk = sock->sk;
129
130	if (addr_len < sizeof(uaddr->sa_family))
131		return -EINVAL;
132
133	if (uaddr->sa_family == AF_UNSPEC)
134		return sk->sk_prot->disconnect(sk, flags);
135
136	return sk->sk_prot->connect(sk, uaddr, addr_len);
137}
138
139static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg,
140				unsigned int cmd)
141{
142	struct ifreq ifr;
143	int ret = -ENOIOCTLCMD;
144	struct net_device *dev;
145
146	if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
147		return -EFAULT;
148
149	ifr.ifr_name[IFNAMSIZ-1] = 0;
150
151	dev_load(sock_net(sk), ifr.ifr_name);
152	dev = dev_get_by_name(sock_net(sk), ifr.ifr_name);
153
154	if (!dev)
155		return -ENODEV;
156
157	if (dev->type == ARPHRD_IEEE802154 && dev->netdev_ops->ndo_do_ioctl)
158		ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd);
159
160	if (!ret && copy_to_user(arg, &ifr, sizeof(struct ifreq)))
161		ret = -EFAULT;
162	dev_put(dev);
163
164	return ret;
165}
166
167static int ieee802154_sock_ioctl(struct socket *sock, unsigned int cmd,
168				 unsigned long arg)
169{
170	struct sock *sk = sock->sk;
171
172	switch (cmd) {
173	case SIOCGSTAMP:
174		return sock_get_timestamp(sk, (struct timeval __user *)arg);
175	case SIOCGSTAMPNS:
176		return sock_get_timestampns(sk, (struct timespec __user *)arg);
177	case SIOCGIFADDR:
178	case SIOCSIFADDR:
179		return ieee802154_dev_ioctl(sk, (struct ifreq __user *)arg,
180				cmd);
181	default:
182		if (!sk->sk_prot->ioctl)
183			return -ENOIOCTLCMD;
184		return sk->sk_prot->ioctl(sk, cmd, arg);
185	}
186}
187
188static const struct proto_ops ieee802154_raw_ops = {
189	.family		   = PF_IEEE802154,
190	.owner		   = THIS_MODULE,
191	.release	   = ieee802154_sock_release,
192	.bind		   = ieee802154_sock_bind,
193	.connect	   = ieee802154_sock_connect,
194	.socketpair	   = sock_no_socketpair,
195	.accept		   = sock_no_accept,
196	.getname	   = sock_no_getname,
197	.poll		   = datagram_poll,
198	.ioctl		   = ieee802154_sock_ioctl,
199	.listen		   = sock_no_listen,
200	.shutdown	   = sock_no_shutdown,
201	.setsockopt	   = sock_common_setsockopt,
202	.getsockopt	   = sock_common_getsockopt,
203	.sendmsg	   = ieee802154_sock_sendmsg,
204	.recvmsg	   = sock_common_recvmsg,
205	.mmap		   = sock_no_mmap,
206	.sendpage	   = sock_no_sendpage,
207#ifdef CONFIG_COMPAT
208	.compat_setsockopt = compat_sock_common_setsockopt,
209	.compat_getsockopt = compat_sock_common_getsockopt,
210#endif
211};
212
213static const struct proto_ops ieee802154_dgram_ops = {
214	.family		   = PF_IEEE802154,
215	.owner		   = THIS_MODULE,
216	.release	   = ieee802154_sock_release,
217	.bind		   = ieee802154_sock_bind,
218	.connect	   = ieee802154_sock_connect,
219	.socketpair	   = sock_no_socketpair,
220	.accept		   = sock_no_accept,
221	.getname	   = sock_no_getname,
222	.poll		   = datagram_poll,
223	.ioctl		   = ieee802154_sock_ioctl,
224	.listen		   = sock_no_listen,
225	.shutdown	   = sock_no_shutdown,
226	.setsockopt	   = sock_common_setsockopt,
227	.getsockopt	   = sock_common_getsockopt,
228	.sendmsg	   = ieee802154_sock_sendmsg,
229	.recvmsg	   = sock_common_recvmsg,
230	.mmap		   = sock_no_mmap,
231	.sendpage	   = sock_no_sendpage,
232#ifdef CONFIG_COMPAT
233	.compat_setsockopt = compat_sock_common_setsockopt,
234	.compat_getsockopt = compat_sock_common_getsockopt,
235#endif
236};
237
238
239/* Create a socket. Initialise the socket, blank the addresses
240 * set the state.
241 */
242static int ieee802154_create(struct net *net, struct socket *sock,
243			     int protocol, int kern)
244{
245	struct sock *sk;
246	int rc;
247	struct proto *proto;
248	const struct proto_ops *ops;
249
250	if (!net_eq(net, &init_net))
251		return -EAFNOSUPPORT;
252
253	switch (sock->type) {
254	case SOCK_RAW:
255		proto = &ieee802154_raw_prot;
256		ops = &ieee802154_raw_ops;
257		break;
258	case SOCK_DGRAM:
259		proto = &ieee802154_dgram_prot;
260		ops = &ieee802154_dgram_ops;
261		break;
262	default:
263		rc = -ESOCKTNOSUPPORT;
264		goto out;
265	}
266
267	rc = -ENOMEM;
268	sk = sk_alloc(net, PF_IEEE802154, GFP_KERNEL, proto);
269	if (!sk)
270		goto out;
271	rc = 0;
272
273	sock->ops = ops;
274
275	sock_init_data(sock, sk);
276	/* FIXME: sk->sk_destruct */
277	sk->sk_family = PF_IEEE802154;
278
279	/* Checksums on by default */
280	sock_set_flag(sk, SOCK_ZAPPED);
281
282	if (sk->sk_prot->hash)
283		sk->sk_prot->hash(sk);
284
285	if (sk->sk_prot->init) {
286		rc = sk->sk_prot->init(sk);
287		if (rc)
288			sk_common_release(sk);
289	}
290out:
291	return rc;
292}
293
294static const struct net_proto_family ieee802154_family_ops = {
295	.family		= PF_IEEE802154,
296	.create		= ieee802154_create,
297	.owner		= THIS_MODULE,
298};
299
300static int ieee802154_rcv(struct sk_buff *skb, struct net_device *dev,
301			  struct packet_type *pt, struct net_device *orig_dev)
302{
303	if (!netif_running(dev))
304		goto drop;
305	pr_debug("got frame, type %d, dev %p\n", dev->type, dev);
306#ifdef DEBUG
307	print_hex_dump_bytes("ieee802154_rcv ",
308			     DUMP_PREFIX_NONE, skb->data, skb->len);
309#endif
310
311	if (!net_eq(dev_net(dev), &init_net))
312		goto drop;
313
314	ieee802154_raw_deliver(dev, skb);
315
316	if (dev->type != ARPHRD_IEEE802154)
317		goto drop;
318
319	if (skb->pkt_type != PACKET_OTHERHOST)
320		return ieee802154_dgram_deliver(dev, skb);
321
322drop:
323	kfree_skb(skb);
324	return NET_RX_DROP;
325}
326
327
328static struct packet_type ieee802154_packet_type = {
329	.type = htons(ETH_P_IEEE802154),
330	.func = ieee802154_rcv,
331};
332
333static int __init af_ieee802154_init(void)
334{
335	int rc = -EINVAL;
336
337	rc = proto_register(&ieee802154_raw_prot, 1);
338	if (rc)
339		goto out;
340
341	rc = proto_register(&ieee802154_dgram_prot, 1);
342	if (rc)
343		goto err_dgram;
344
345	/* Tell SOCKET that we are alive */
346	rc = sock_register(&ieee802154_family_ops);
347	if (rc)
348		goto err_sock;
349	dev_add_pack(&ieee802154_packet_type);
350
351	rc = 0;
352	goto out;
353
354err_sock:
355	proto_unregister(&ieee802154_dgram_prot);
356err_dgram:
357	proto_unregister(&ieee802154_raw_prot);
358out:
359	return rc;
360}
361static void __exit af_ieee802154_remove(void)
362{
363	dev_remove_pack(&ieee802154_packet_type);
364	sock_unregister(PF_IEEE802154);
365	proto_unregister(&ieee802154_dgram_prot);
366	proto_unregister(&ieee802154_raw_prot);
367}
368
369module_init(af_ieee802154_init);
370module_exit(af_ieee802154_remove);
371
372MODULE_LICENSE("GPL");
373MODULE_ALIAS_NETPROTO(PF_IEEE802154);
374