171e36b1bSAlexander Aring /* 271e36b1bSAlexander Aring * IEEE802154.4 socket interface 371e36b1bSAlexander Aring * 471e36b1bSAlexander Aring * Copyright 2007, 2008 Siemens AG 571e36b1bSAlexander Aring * 671e36b1bSAlexander Aring * This program is free software; you can redistribute it and/or modify 771e36b1bSAlexander Aring * it under the terms of the GNU General Public License version 2 871e36b1bSAlexander Aring * as published by the Free Software Foundation. 971e36b1bSAlexander Aring * 1071e36b1bSAlexander Aring * This program is distributed in the hope that it will be useful, 1171e36b1bSAlexander Aring * but WITHOUT ANY WARRANTY; without even the implied warranty of 1271e36b1bSAlexander Aring * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1371e36b1bSAlexander Aring * GNU General Public License for more details. 1471e36b1bSAlexander Aring * 1571e36b1bSAlexander Aring * Written by: 1671e36b1bSAlexander Aring * Sergey Lapin <slapin@ossfans.org> 1771e36b1bSAlexander Aring * Maxim Gorbachyov <maxim.gorbachev@siemens.com> 1871e36b1bSAlexander Aring */ 1971e36b1bSAlexander Aring 2071e36b1bSAlexander Aring #include <linux/net.h> 2171e36b1bSAlexander Aring #include <linux/capability.h> 2271e36b1bSAlexander Aring #include <linux/module.h> 2371e36b1bSAlexander Aring #include <linux/if_arp.h> 2471e36b1bSAlexander Aring #include <linux/if.h> 2571e36b1bSAlexander Aring #include <linux/termios.h> /* For TIOCOUTQ/INQ */ 2671e36b1bSAlexander Aring #include <linux/list.h> 2771e36b1bSAlexander Aring #include <linux/slab.h> 2871e36b1bSAlexander Aring #include <net/datalink.h> 2971e36b1bSAlexander Aring #include <net/psnap.h> 3071e36b1bSAlexander Aring #include <net/sock.h> 3171e36b1bSAlexander Aring #include <net/tcp_states.h> 3271e36b1bSAlexander Aring #include <net/route.h> 3371e36b1bSAlexander Aring 3471e36b1bSAlexander Aring #include <net/af_ieee802154.h> 3571e36b1bSAlexander Aring #include <net/ieee802154_netdev.h> 3671e36b1bSAlexander Aring 3771e36b1bSAlexander Aring /* Utility function for families */ 3871e36b1bSAlexander Aring static struct net_device* 3971e36b1bSAlexander Aring ieee802154_get_dev(struct net *net, const struct ieee802154_addr *addr) 4071e36b1bSAlexander Aring { 4171e36b1bSAlexander Aring struct net_device *dev = NULL; 4271e36b1bSAlexander Aring struct net_device *tmp; 4371e36b1bSAlexander Aring __le16 pan_id, short_addr; 4471e36b1bSAlexander Aring u8 hwaddr[IEEE802154_ADDR_LEN]; 4571e36b1bSAlexander Aring 4671e36b1bSAlexander Aring switch (addr->mode) { 4771e36b1bSAlexander Aring case IEEE802154_ADDR_LONG: 4871e36b1bSAlexander Aring ieee802154_devaddr_to_raw(hwaddr, addr->extended_addr); 4971e36b1bSAlexander Aring rcu_read_lock(); 5071e36b1bSAlexander Aring dev = dev_getbyhwaddr_rcu(net, ARPHRD_IEEE802154, hwaddr); 5171e36b1bSAlexander Aring if (dev) 5271e36b1bSAlexander Aring dev_hold(dev); 5371e36b1bSAlexander Aring rcu_read_unlock(); 5471e36b1bSAlexander Aring break; 5571e36b1bSAlexander Aring case IEEE802154_ADDR_SHORT: 5671e36b1bSAlexander Aring if (addr->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST) || 5771e36b1bSAlexander Aring addr->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) || 5871e36b1bSAlexander Aring addr->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST)) 5971e36b1bSAlexander Aring break; 6071e36b1bSAlexander Aring 6171e36b1bSAlexander Aring rtnl_lock(); 6271e36b1bSAlexander Aring 6371e36b1bSAlexander Aring for_each_netdev(net, tmp) { 6471e36b1bSAlexander Aring if (tmp->type != ARPHRD_IEEE802154) 6571e36b1bSAlexander Aring continue; 6671e36b1bSAlexander Aring 67c947f7e1SAlexander Aring pan_id = tmp->ieee802154_ptr->pan_id; 68c947f7e1SAlexander Aring short_addr = tmp->ieee802154_ptr->short_addr; 6971e36b1bSAlexander Aring if (pan_id == addr->pan_id && 7071e36b1bSAlexander Aring short_addr == addr->short_addr) { 7171e36b1bSAlexander Aring dev = tmp; 7271e36b1bSAlexander Aring dev_hold(dev); 7371e36b1bSAlexander Aring break; 7471e36b1bSAlexander Aring } 7571e36b1bSAlexander Aring } 7671e36b1bSAlexander Aring 7771e36b1bSAlexander Aring rtnl_unlock(); 7871e36b1bSAlexander Aring break; 7971e36b1bSAlexander Aring default: 8071e36b1bSAlexander Aring pr_warn("Unsupported ieee802154 address type: %d\n", 8171e36b1bSAlexander Aring addr->mode); 8271e36b1bSAlexander Aring break; 8371e36b1bSAlexander Aring } 8471e36b1bSAlexander Aring 8571e36b1bSAlexander Aring return dev; 8671e36b1bSAlexander Aring } 8771e36b1bSAlexander Aring 8871e36b1bSAlexander Aring static int ieee802154_sock_release(struct socket *sock) 8971e36b1bSAlexander Aring { 9071e36b1bSAlexander Aring struct sock *sk = sock->sk; 9171e36b1bSAlexander Aring 9271e36b1bSAlexander Aring if (sk) { 9371e36b1bSAlexander Aring sock->sk = NULL; 9471e36b1bSAlexander Aring sk->sk_prot->close(sk, 0); 9571e36b1bSAlexander Aring } 9671e36b1bSAlexander Aring return 0; 9771e36b1bSAlexander Aring } 9871e36b1bSAlexander Aring 991b784140SYing Xue static int ieee802154_sock_sendmsg(struct socket *sock, struct msghdr *msg, 1001b784140SYing Xue size_t len) 10171e36b1bSAlexander Aring { 10271e36b1bSAlexander Aring struct sock *sk = sock->sk; 10371e36b1bSAlexander Aring 1041b784140SYing Xue return sk->sk_prot->sendmsg(sk, msg, len); 10571e36b1bSAlexander Aring } 10671e36b1bSAlexander Aring 10771e36b1bSAlexander Aring static int ieee802154_sock_bind(struct socket *sock, struct sockaddr *uaddr, 10871e36b1bSAlexander Aring int addr_len) 10971e36b1bSAlexander Aring { 11071e36b1bSAlexander Aring struct sock *sk = sock->sk; 11171e36b1bSAlexander Aring 11271e36b1bSAlexander Aring if (sk->sk_prot->bind) 11371e36b1bSAlexander Aring return sk->sk_prot->bind(sk, uaddr, addr_len); 11471e36b1bSAlexander Aring 11571e36b1bSAlexander Aring return sock_no_bind(sock, uaddr, addr_len); 11671e36b1bSAlexander Aring } 11771e36b1bSAlexander Aring 11871e36b1bSAlexander Aring static int ieee802154_sock_connect(struct socket *sock, struct sockaddr *uaddr, 11971e36b1bSAlexander Aring int addr_len, int flags) 12071e36b1bSAlexander Aring { 12171e36b1bSAlexander Aring struct sock *sk = sock->sk; 12271e36b1bSAlexander Aring 12371e36b1bSAlexander Aring if (addr_len < sizeof(uaddr->sa_family)) 12471e36b1bSAlexander Aring return -EINVAL; 12571e36b1bSAlexander Aring 12671e36b1bSAlexander Aring if (uaddr->sa_family == AF_UNSPEC) 12771e36b1bSAlexander Aring return sk->sk_prot->disconnect(sk, flags); 12871e36b1bSAlexander Aring 12971e36b1bSAlexander Aring return sk->sk_prot->connect(sk, uaddr, addr_len); 13071e36b1bSAlexander Aring } 13171e36b1bSAlexander Aring 13271e36b1bSAlexander Aring static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg, 13371e36b1bSAlexander Aring unsigned int cmd) 13471e36b1bSAlexander Aring { 13571e36b1bSAlexander Aring struct ifreq ifr; 13671e36b1bSAlexander Aring int ret = -ENOIOCTLCMD; 13771e36b1bSAlexander Aring struct net_device *dev; 13871e36b1bSAlexander Aring 13971e36b1bSAlexander Aring if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) 14071e36b1bSAlexander Aring return -EFAULT; 14171e36b1bSAlexander Aring 14271e36b1bSAlexander Aring ifr.ifr_name[IFNAMSIZ-1] = 0; 14371e36b1bSAlexander Aring 14471e36b1bSAlexander Aring dev_load(sock_net(sk), ifr.ifr_name); 14571e36b1bSAlexander Aring dev = dev_get_by_name(sock_net(sk), ifr.ifr_name); 14671e36b1bSAlexander Aring 14771e36b1bSAlexander Aring if (!dev) 14871e36b1bSAlexander Aring return -ENODEV; 14971e36b1bSAlexander Aring 15071e36b1bSAlexander Aring if (dev->type == ARPHRD_IEEE802154 && dev->netdev_ops->ndo_do_ioctl) 15171e36b1bSAlexander Aring ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd); 15271e36b1bSAlexander Aring 15371e36b1bSAlexander Aring if (!ret && copy_to_user(arg, &ifr, sizeof(struct ifreq))) 15471e36b1bSAlexander Aring ret = -EFAULT; 15571e36b1bSAlexander Aring dev_put(dev); 15671e36b1bSAlexander Aring 15771e36b1bSAlexander Aring return ret; 15871e36b1bSAlexander Aring } 15971e36b1bSAlexander Aring 16071e36b1bSAlexander Aring static int ieee802154_sock_ioctl(struct socket *sock, unsigned int cmd, 16171e36b1bSAlexander Aring unsigned long arg) 16271e36b1bSAlexander Aring { 16371e36b1bSAlexander Aring struct sock *sk = sock->sk; 16471e36b1bSAlexander Aring 16571e36b1bSAlexander Aring switch (cmd) { 16671e36b1bSAlexander Aring case SIOCGSTAMP: 16771e36b1bSAlexander Aring return sock_get_timestamp(sk, (struct timeval __user *)arg); 16871e36b1bSAlexander Aring case SIOCGSTAMPNS: 16971e36b1bSAlexander Aring return sock_get_timestampns(sk, (struct timespec __user *)arg); 17071e36b1bSAlexander Aring case SIOCGIFADDR: 17171e36b1bSAlexander Aring case SIOCSIFADDR: 17271e36b1bSAlexander Aring return ieee802154_dev_ioctl(sk, (struct ifreq __user *)arg, 17371e36b1bSAlexander Aring cmd); 17471e36b1bSAlexander Aring default: 17571e36b1bSAlexander Aring if (!sk->sk_prot->ioctl) 17671e36b1bSAlexander Aring return -ENOIOCTLCMD; 17771e36b1bSAlexander Aring return sk->sk_prot->ioctl(sk, cmd, arg); 17871e36b1bSAlexander Aring } 17971e36b1bSAlexander Aring } 18071e36b1bSAlexander Aring 18171e36b1bSAlexander Aring /* RAW Sockets (802.15.4 created in userspace) */ 18271e36b1bSAlexander Aring static HLIST_HEAD(raw_head); 18371e36b1bSAlexander Aring static DEFINE_RWLOCK(raw_lock); 18471e36b1bSAlexander Aring 185086c653fSCraig Gallek static int raw_hash(struct sock *sk) 18671e36b1bSAlexander Aring { 18771e36b1bSAlexander Aring write_lock_bh(&raw_lock); 18871e36b1bSAlexander Aring sk_add_node(sk, &raw_head); 18971e36b1bSAlexander Aring sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); 19071e36b1bSAlexander Aring write_unlock_bh(&raw_lock); 191086c653fSCraig Gallek 192086c653fSCraig Gallek return 0; 19371e36b1bSAlexander Aring } 19471e36b1bSAlexander Aring 19571e36b1bSAlexander Aring static void raw_unhash(struct sock *sk) 19671e36b1bSAlexander Aring { 19771e36b1bSAlexander Aring write_lock_bh(&raw_lock); 19871e36b1bSAlexander Aring if (sk_del_node_init(sk)) 19971e36b1bSAlexander Aring sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); 20071e36b1bSAlexander Aring write_unlock_bh(&raw_lock); 20171e36b1bSAlexander Aring } 20271e36b1bSAlexander Aring 20371e36b1bSAlexander Aring static void raw_close(struct sock *sk, long timeout) 20471e36b1bSAlexander Aring { 20571e36b1bSAlexander Aring sk_common_release(sk); 20671e36b1bSAlexander Aring } 20771e36b1bSAlexander Aring 20871e36b1bSAlexander Aring static int raw_bind(struct sock *sk, struct sockaddr *_uaddr, int len) 20971e36b1bSAlexander Aring { 21071e36b1bSAlexander Aring struct ieee802154_addr addr; 21171e36b1bSAlexander Aring struct sockaddr_ieee802154 *uaddr = (struct sockaddr_ieee802154 *)_uaddr; 21271e36b1bSAlexander Aring int err = 0; 21371e36b1bSAlexander Aring struct net_device *dev = NULL; 21471e36b1bSAlexander Aring 21571e36b1bSAlexander Aring if (len < sizeof(*uaddr)) 21671e36b1bSAlexander Aring return -EINVAL; 21771e36b1bSAlexander Aring 21871e36b1bSAlexander Aring uaddr = (struct sockaddr_ieee802154 *)_uaddr; 21971e36b1bSAlexander Aring if (uaddr->family != AF_IEEE802154) 22071e36b1bSAlexander Aring return -EINVAL; 22171e36b1bSAlexander Aring 22271e36b1bSAlexander Aring lock_sock(sk); 22371e36b1bSAlexander Aring 22471e36b1bSAlexander Aring ieee802154_addr_from_sa(&addr, &uaddr->addr); 22571e36b1bSAlexander Aring dev = ieee802154_get_dev(sock_net(sk), &addr); 22671e36b1bSAlexander Aring if (!dev) { 22771e36b1bSAlexander Aring err = -ENODEV; 22871e36b1bSAlexander Aring goto out; 22971e36b1bSAlexander Aring } 23071e36b1bSAlexander Aring 23171e36b1bSAlexander Aring sk->sk_bound_dev_if = dev->ifindex; 23271e36b1bSAlexander Aring sk_dst_reset(sk); 23371e36b1bSAlexander Aring 23471e36b1bSAlexander Aring dev_put(dev); 23571e36b1bSAlexander Aring out: 23671e36b1bSAlexander Aring release_sock(sk); 23771e36b1bSAlexander Aring 23871e36b1bSAlexander Aring return err; 23971e36b1bSAlexander Aring } 24071e36b1bSAlexander Aring 24171e36b1bSAlexander Aring static int raw_connect(struct sock *sk, struct sockaddr *uaddr, 24271e36b1bSAlexander Aring int addr_len) 24371e36b1bSAlexander Aring { 24471e36b1bSAlexander Aring return -ENOTSUPP; 24571e36b1bSAlexander Aring } 24671e36b1bSAlexander Aring 24771e36b1bSAlexander Aring static int raw_disconnect(struct sock *sk, int flags) 24871e36b1bSAlexander Aring { 24971e36b1bSAlexander Aring return 0; 25071e36b1bSAlexander Aring } 25171e36b1bSAlexander Aring 2521b784140SYing Xue static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) 25371e36b1bSAlexander Aring { 25471e36b1bSAlexander Aring struct net_device *dev; 25571e36b1bSAlexander Aring unsigned int mtu; 25671e36b1bSAlexander Aring struct sk_buff *skb; 25771e36b1bSAlexander Aring int hlen, tlen; 25871e36b1bSAlexander Aring int err; 25971e36b1bSAlexander Aring 26071e36b1bSAlexander Aring if (msg->msg_flags & MSG_OOB) { 26171e36b1bSAlexander Aring pr_debug("msg->msg_flags = 0x%x\n", msg->msg_flags); 26271e36b1bSAlexander Aring return -EOPNOTSUPP; 26371e36b1bSAlexander Aring } 26471e36b1bSAlexander Aring 26571e36b1bSAlexander Aring lock_sock(sk); 26671e36b1bSAlexander Aring if (!sk->sk_bound_dev_if) 26771e36b1bSAlexander Aring dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154); 26871e36b1bSAlexander Aring else 26971e36b1bSAlexander Aring dev = dev_get_by_index(sock_net(sk), sk->sk_bound_dev_if); 27071e36b1bSAlexander Aring release_sock(sk); 27171e36b1bSAlexander Aring 27271e36b1bSAlexander Aring if (!dev) { 27371e36b1bSAlexander Aring pr_debug("no dev\n"); 27471e36b1bSAlexander Aring err = -ENXIO; 27571e36b1bSAlexander Aring goto out; 27671e36b1bSAlexander Aring } 27771e36b1bSAlexander Aring 278b40988c4SAlexander Aring mtu = IEEE802154_MTU; 27971e36b1bSAlexander Aring pr_debug("name = %s, mtu = %u\n", dev->name, mtu); 28071e36b1bSAlexander Aring 28171e36b1bSAlexander Aring if (size > mtu) { 2825b5e0928SAlexey Dobriyan pr_debug("size = %zu, mtu = %u\n", size, mtu); 283c032705eSLennert Buytenhek err = -EMSGSIZE; 28471e36b1bSAlexander Aring goto out_dev; 28571e36b1bSAlexander Aring } 28671e36b1bSAlexander Aring 28771e36b1bSAlexander Aring hlen = LL_RESERVED_SPACE(dev); 28871e36b1bSAlexander Aring tlen = dev->needed_tailroom; 28971e36b1bSAlexander Aring skb = sock_alloc_send_skb(sk, hlen + tlen + size, 29071e36b1bSAlexander Aring msg->msg_flags & MSG_DONTWAIT, &err); 29171e36b1bSAlexander Aring if (!skb) 29271e36b1bSAlexander Aring goto out_dev; 29371e36b1bSAlexander Aring 29471e36b1bSAlexander Aring skb_reserve(skb, hlen); 29571e36b1bSAlexander Aring 29671e36b1bSAlexander Aring skb_reset_mac_header(skb); 29771e36b1bSAlexander Aring skb_reset_network_header(skb); 29871e36b1bSAlexander Aring 29971e36b1bSAlexander Aring err = memcpy_from_msg(skb_put(skb, size), msg, size); 30071e36b1bSAlexander Aring if (err < 0) 30171e36b1bSAlexander Aring goto out_skb; 30271e36b1bSAlexander Aring 30371e36b1bSAlexander Aring skb->dev = dev; 30471e36b1bSAlexander Aring skb->protocol = htons(ETH_P_IEEE802154); 30571e36b1bSAlexander Aring 30671e36b1bSAlexander Aring err = dev_queue_xmit(skb); 30771e36b1bSAlexander Aring if (err > 0) 30871e36b1bSAlexander Aring err = net_xmit_errno(err); 30971e36b1bSAlexander Aring 310a611c58bSLin Zhang dev_put(dev); 311a611c58bSLin Zhang 31271e36b1bSAlexander Aring return err ?: size; 31371e36b1bSAlexander Aring 31471e36b1bSAlexander Aring out_skb: 31571e36b1bSAlexander Aring kfree_skb(skb); 31671e36b1bSAlexander Aring out_dev: 31771e36b1bSAlexander Aring dev_put(dev); 31871e36b1bSAlexander Aring out: 31971e36b1bSAlexander Aring return err; 32071e36b1bSAlexander Aring } 32171e36b1bSAlexander Aring 3221b784140SYing Xue static int raw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, 3231b784140SYing Xue int noblock, int flags, int *addr_len) 32471e36b1bSAlexander Aring { 32571e36b1bSAlexander Aring size_t copied = 0; 32671e36b1bSAlexander Aring int err = -EOPNOTSUPP; 32771e36b1bSAlexander Aring struct sk_buff *skb; 32871e36b1bSAlexander Aring 32971e36b1bSAlexander Aring skb = skb_recv_datagram(sk, flags, noblock, &err); 33071e36b1bSAlexander Aring if (!skb) 33171e36b1bSAlexander Aring goto out; 33271e36b1bSAlexander Aring 33371e36b1bSAlexander Aring copied = skb->len; 33471e36b1bSAlexander Aring if (len < copied) { 33571e36b1bSAlexander Aring msg->msg_flags |= MSG_TRUNC; 33671e36b1bSAlexander Aring copied = len; 33771e36b1bSAlexander Aring } 33871e36b1bSAlexander Aring 33971e36b1bSAlexander Aring err = skb_copy_datagram_msg(skb, 0, msg, copied); 34071e36b1bSAlexander Aring if (err) 34171e36b1bSAlexander Aring goto done; 34271e36b1bSAlexander Aring 34371e36b1bSAlexander Aring sock_recv_ts_and_drops(msg, sk, skb); 34471e36b1bSAlexander Aring 34571e36b1bSAlexander Aring if (flags & MSG_TRUNC) 34671e36b1bSAlexander Aring copied = skb->len; 34771e36b1bSAlexander Aring done: 34871e36b1bSAlexander Aring skb_free_datagram(sk, skb); 34971e36b1bSAlexander Aring out: 35071e36b1bSAlexander Aring if (err) 35171e36b1bSAlexander Aring return err; 35271e36b1bSAlexander Aring return copied; 35371e36b1bSAlexander Aring } 35471e36b1bSAlexander Aring 35571e36b1bSAlexander Aring static int raw_rcv_skb(struct sock *sk, struct sk_buff *skb) 35671e36b1bSAlexander Aring { 35771e36b1bSAlexander Aring skb = skb_share_check(skb, GFP_ATOMIC); 35871e36b1bSAlexander Aring if (!skb) 35971e36b1bSAlexander Aring return NET_RX_DROP; 36071e36b1bSAlexander Aring 36171e36b1bSAlexander Aring if (sock_queue_rcv_skb(sk, skb) < 0) { 36271e36b1bSAlexander Aring kfree_skb(skb); 36371e36b1bSAlexander Aring return NET_RX_DROP; 36471e36b1bSAlexander Aring } 36571e36b1bSAlexander Aring 36671e36b1bSAlexander Aring return NET_RX_SUCCESS; 36771e36b1bSAlexander Aring } 36871e36b1bSAlexander Aring 36971e36b1bSAlexander Aring static void ieee802154_raw_deliver(struct net_device *dev, struct sk_buff *skb) 37071e36b1bSAlexander Aring { 37171e36b1bSAlexander Aring struct sock *sk; 37271e36b1bSAlexander Aring 37371e36b1bSAlexander Aring read_lock(&raw_lock); 37471e36b1bSAlexander Aring sk_for_each(sk, &raw_head) { 37571e36b1bSAlexander Aring bh_lock_sock(sk); 37671e36b1bSAlexander Aring if (!sk->sk_bound_dev_if || 37771e36b1bSAlexander Aring sk->sk_bound_dev_if == dev->ifindex) { 37871e36b1bSAlexander Aring struct sk_buff *clone; 37971e36b1bSAlexander Aring 38071e36b1bSAlexander Aring clone = skb_clone(skb, GFP_ATOMIC); 38171e36b1bSAlexander Aring if (clone) 38271e36b1bSAlexander Aring raw_rcv_skb(sk, clone); 38371e36b1bSAlexander Aring } 38471e36b1bSAlexander Aring bh_unlock_sock(sk); 38571e36b1bSAlexander Aring } 38671e36b1bSAlexander Aring read_unlock(&raw_lock); 38771e36b1bSAlexander Aring } 38871e36b1bSAlexander Aring 38971e36b1bSAlexander Aring static int raw_getsockopt(struct sock *sk, int level, int optname, 39071e36b1bSAlexander Aring char __user *optval, int __user *optlen) 39171e36b1bSAlexander Aring { 39271e36b1bSAlexander Aring return -EOPNOTSUPP; 39371e36b1bSAlexander Aring } 39471e36b1bSAlexander Aring 39571e36b1bSAlexander Aring static int raw_setsockopt(struct sock *sk, int level, int optname, 39671e36b1bSAlexander Aring char __user *optval, unsigned int optlen) 39771e36b1bSAlexander Aring { 39871e36b1bSAlexander Aring return -EOPNOTSUPP; 39971e36b1bSAlexander Aring } 40071e36b1bSAlexander Aring 40171e36b1bSAlexander Aring static struct proto ieee802154_raw_prot = { 40271e36b1bSAlexander Aring .name = "IEEE-802.15.4-RAW", 40371e36b1bSAlexander Aring .owner = THIS_MODULE, 40471e36b1bSAlexander Aring .obj_size = sizeof(struct sock), 40571e36b1bSAlexander Aring .close = raw_close, 40671e36b1bSAlexander Aring .bind = raw_bind, 40771e36b1bSAlexander Aring .sendmsg = raw_sendmsg, 40871e36b1bSAlexander Aring .recvmsg = raw_recvmsg, 40971e36b1bSAlexander Aring .hash = raw_hash, 41071e36b1bSAlexander Aring .unhash = raw_unhash, 41171e36b1bSAlexander Aring .connect = raw_connect, 41271e36b1bSAlexander Aring .disconnect = raw_disconnect, 41371e36b1bSAlexander Aring .getsockopt = raw_getsockopt, 41471e36b1bSAlexander Aring .setsockopt = raw_setsockopt, 41571e36b1bSAlexander Aring }; 41671e36b1bSAlexander Aring 41771e36b1bSAlexander Aring static const struct proto_ops ieee802154_raw_ops = { 41871e36b1bSAlexander Aring .family = PF_IEEE802154, 41971e36b1bSAlexander Aring .owner = THIS_MODULE, 42071e36b1bSAlexander Aring .release = ieee802154_sock_release, 42171e36b1bSAlexander Aring .bind = ieee802154_sock_bind, 42271e36b1bSAlexander Aring .connect = ieee802154_sock_connect, 42371e36b1bSAlexander Aring .socketpair = sock_no_socketpair, 42471e36b1bSAlexander Aring .accept = sock_no_accept, 42571e36b1bSAlexander Aring .getname = sock_no_getname, 426a11e1d43SLinus Torvalds .poll = datagram_poll, 42771e36b1bSAlexander Aring .ioctl = ieee802154_sock_ioctl, 42871e36b1bSAlexander Aring .listen = sock_no_listen, 42971e36b1bSAlexander Aring .shutdown = sock_no_shutdown, 43071e36b1bSAlexander Aring .setsockopt = sock_common_setsockopt, 43171e36b1bSAlexander Aring .getsockopt = sock_common_getsockopt, 43271e36b1bSAlexander Aring .sendmsg = ieee802154_sock_sendmsg, 43371e36b1bSAlexander Aring .recvmsg = sock_common_recvmsg, 43471e36b1bSAlexander Aring .mmap = sock_no_mmap, 43571e36b1bSAlexander Aring .sendpage = sock_no_sendpage, 43671e36b1bSAlexander Aring #ifdef CONFIG_COMPAT 43771e36b1bSAlexander Aring .compat_setsockopt = compat_sock_common_setsockopt, 43871e36b1bSAlexander Aring .compat_getsockopt = compat_sock_common_getsockopt, 43971e36b1bSAlexander Aring #endif 44071e36b1bSAlexander Aring }; 44171e36b1bSAlexander Aring 44271e36b1bSAlexander Aring /* DGRAM Sockets (802.15.4 dataframes) */ 44371e36b1bSAlexander Aring static HLIST_HEAD(dgram_head); 44471e36b1bSAlexander Aring static DEFINE_RWLOCK(dgram_lock); 44571e36b1bSAlexander Aring 44671e36b1bSAlexander Aring struct dgram_sock { 44771e36b1bSAlexander Aring struct sock sk; 44871e36b1bSAlexander Aring 44971e36b1bSAlexander Aring struct ieee802154_addr src_addr; 45071e36b1bSAlexander Aring struct ieee802154_addr dst_addr; 45171e36b1bSAlexander Aring 45271e36b1bSAlexander Aring unsigned int bound:1; 45371e36b1bSAlexander Aring unsigned int connected:1; 45471e36b1bSAlexander Aring unsigned int want_ack:1; 45571e36b1bSAlexander Aring unsigned int secen:1; 45671e36b1bSAlexander Aring unsigned int secen_override:1; 45771e36b1bSAlexander Aring unsigned int seclevel:3; 45871e36b1bSAlexander Aring unsigned int seclevel_override:1; 45971e36b1bSAlexander Aring }; 46071e36b1bSAlexander Aring 46171e36b1bSAlexander Aring static inline struct dgram_sock *dgram_sk(const struct sock *sk) 46271e36b1bSAlexander Aring { 46371e36b1bSAlexander Aring return container_of(sk, struct dgram_sock, sk); 46471e36b1bSAlexander Aring } 46571e36b1bSAlexander Aring 466086c653fSCraig Gallek static int dgram_hash(struct sock *sk) 46771e36b1bSAlexander Aring { 46871e36b1bSAlexander Aring write_lock_bh(&dgram_lock); 46971e36b1bSAlexander Aring sk_add_node(sk, &dgram_head); 47071e36b1bSAlexander Aring sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); 47171e36b1bSAlexander Aring write_unlock_bh(&dgram_lock); 472086c653fSCraig Gallek 473086c653fSCraig Gallek return 0; 47471e36b1bSAlexander Aring } 47571e36b1bSAlexander Aring 47671e36b1bSAlexander Aring static void dgram_unhash(struct sock *sk) 47771e36b1bSAlexander Aring { 47871e36b1bSAlexander Aring write_lock_bh(&dgram_lock); 47971e36b1bSAlexander Aring if (sk_del_node_init(sk)) 48071e36b1bSAlexander Aring sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); 48171e36b1bSAlexander Aring write_unlock_bh(&dgram_lock); 48271e36b1bSAlexander Aring } 48371e36b1bSAlexander Aring 48471e36b1bSAlexander Aring static int dgram_init(struct sock *sk) 48571e36b1bSAlexander Aring { 48671e36b1bSAlexander Aring struct dgram_sock *ro = dgram_sk(sk); 48771e36b1bSAlexander Aring 48871e36b1bSAlexander Aring ro->want_ack = 1; 48971e36b1bSAlexander Aring return 0; 49071e36b1bSAlexander Aring } 49171e36b1bSAlexander Aring 49271e36b1bSAlexander Aring static void dgram_close(struct sock *sk, long timeout) 49371e36b1bSAlexander Aring { 49471e36b1bSAlexander Aring sk_common_release(sk); 49571e36b1bSAlexander Aring } 49671e36b1bSAlexander Aring 49771e36b1bSAlexander Aring static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len) 49871e36b1bSAlexander Aring { 49971e36b1bSAlexander Aring struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr; 50071e36b1bSAlexander Aring struct ieee802154_addr haddr; 50171e36b1bSAlexander Aring struct dgram_sock *ro = dgram_sk(sk); 50271e36b1bSAlexander Aring int err = -EINVAL; 50371e36b1bSAlexander Aring struct net_device *dev; 50471e36b1bSAlexander Aring 50571e36b1bSAlexander Aring lock_sock(sk); 50671e36b1bSAlexander Aring 50771e36b1bSAlexander Aring ro->bound = 0; 50871e36b1bSAlexander Aring 50971e36b1bSAlexander Aring if (len < sizeof(*addr)) 51071e36b1bSAlexander Aring goto out; 51171e36b1bSAlexander Aring 51271e36b1bSAlexander Aring if (addr->family != AF_IEEE802154) 51371e36b1bSAlexander Aring goto out; 51471e36b1bSAlexander Aring 51571e36b1bSAlexander Aring ieee802154_addr_from_sa(&haddr, &addr->addr); 51671e36b1bSAlexander Aring dev = ieee802154_get_dev(sock_net(sk), &haddr); 51771e36b1bSAlexander Aring if (!dev) { 51871e36b1bSAlexander Aring err = -ENODEV; 51971e36b1bSAlexander Aring goto out; 52071e36b1bSAlexander Aring } 52171e36b1bSAlexander Aring 52271e36b1bSAlexander Aring if (dev->type != ARPHRD_IEEE802154) { 52371e36b1bSAlexander Aring err = -ENODEV; 52471e36b1bSAlexander Aring goto out_put; 52571e36b1bSAlexander Aring } 52671e36b1bSAlexander Aring 52771e36b1bSAlexander Aring ro->src_addr = haddr; 52871e36b1bSAlexander Aring 52971e36b1bSAlexander Aring ro->bound = 1; 53071e36b1bSAlexander Aring err = 0; 53171e36b1bSAlexander Aring out_put: 53271e36b1bSAlexander Aring dev_put(dev); 53371e36b1bSAlexander Aring out: 53471e36b1bSAlexander Aring release_sock(sk); 53571e36b1bSAlexander Aring 53671e36b1bSAlexander Aring return err; 53771e36b1bSAlexander Aring } 53871e36b1bSAlexander Aring 53971e36b1bSAlexander Aring static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg) 54071e36b1bSAlexander Aring { 54171e36b1bSAlexander Aring switch (cmd) { 54271e36b1bSAlexander Aring case SIOCOUTQ: 54371e36b1bSAlexander Aring { 54471e36b1bSAlexander Aring int amount = sk_wmem_alloc_get(sk); 54571e36b1bSAlexander Aring 54671e36b1bSAlexander Aring return put_user(amount, (int __user *)arg); 54771e36b1bSAlexander Aring } 54871e36b1bSAlexander Aring 54971e36b1bSAlexander Aring case SIOCINQ: 55071e36b1bSAlexander Aring { 55171e36b1bSAlexander Aring struct sk_buff *skb; 55271e36b1bSAlexander Aring unsigned long amount; 55371e36b1bSAlexander Aring 55471e36b1bSAlexander Aring amount = 0; 55571e36b1bSAlexander Aring spin_lock_bh(&sk->sk_receive_queue.lock); 55671e36b1bSAlexander Aring skb = skb_peek(&sk->sk_receive_queue); 55771e36b1bSAlexander Aring if (skb) { 55871e36b1bSAlexander Aring /* We will only return the amount 55971e36b1bSAlexander Aring * of this packet since that is all 56071e36b1bSAlexander Aring * that will be read. 56171e36b1bSAlexander Aring */ 56271e36b1bSAlexander Aring amount = skb->len - ieee802154_hdr_length(skb); 56371e36b1bSAlexander Aring } 56471e36b1bSAlexander Aring spin_unlock_bh(&sk->sk_receive_queue.lock); 56571e36b1bSAlexander Aring return put_user(amount, (int __user *)arg); 56671e36b1bSAlexander Aring } 56771e36b1bSAlexander Aring } 56871e36b1bSAlexander Aring 56971e36b1bSAlexander Aring return -ENOIOCTLCMD; 57071e36b1bSAlexander Aring } 57171e36b1bSAlexander Aring 57271e36b1bSAlexander Aring /* FIXME: autobind */ 57371e36b1bSAlexander Aring static int dgram_connect(struct sock *sk, struct sockaddr *uaddr, 57471e36b1bSAlexander Aring int len) 57571e36b1bSAlexander Aring { 57671e36b1bSAlexander Aring struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr; 57771e36b1bSAlexander Aring struct dgram_sock *ro = dgram_sk(sk); 57871e36b1bSAlexander Aring int err = 0; 57971e36b1bSAlexander Aring 58071e36b1bSAlexander Aring if (len < sizeof(*addr)) 58171e36b1bSAlexander Aring return -EINVAL; 58271e36b1bSAlexander Aring 58371e36b1bSAlexander Aring if (addr->family != AF_IEEE802154) 58471e36b1bSAlexander Aring return -EINVAL; 58571e36b1bSAlexander Aring 58671e36b1bSAlexander Aring lock_sock(sk); 58771e36b1bSAlexander Aring 58871e36b1bSAlexander Aring if (!ro->bound) { 58971e36b1bSAlexander Aring err = -ENETUNREACH; 59071e36b1bSAlexander Aring goto out; 59171e36b1bSAlexander Aring } 59271e36b1bSAlexander Aring 59371e36b1bSAlexander Aring ieee802154_addr_from_sa(&ro->dst_addr, &addr->addr); 59471e36b1bSAlexander Aring ro->connected = 1; 59571e36b1bSAlexander Aring 59671e36b1bSAlexander Aring out: 59771e36b1bSAlexander Aring release_sock(sk); 59871e36b1bSAlexander Aring return err; 59971e36b1bSAlexander Aring } 60071e36b1bSAlexander Aring 60171e36b1bSAlexander Aring static int dgram_disconnect(struct sock *sk, int flags) 60271e36b1bSAlexander Aring { 60371e36b1bSAlexander Aring struct dgram_sock *ro = dgram_sk(sk); 60471e36b1bSAlexander Aring 60571e36b1bSAlexander Aring lock_sock(sk); 60671e36b1bSAlexander Aring ro->connected = 0; 60771e36b1bSAlexander Aring release_sock(sk); 60871e36b1bSAlexander Aring 60971e36b1bSAlexander Aring return 0; 61071e36b1bSAlexander Aring } 61171e36b1bSAlexander Aring 6121b784140SYing Xue static int dgram_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) 61371e36b1bSAlexander Aring { 61471e36b1bSAlexander Aring struct net_device *dev; 61571e36b1bSAlexander Aring unsigned int mtu; 61671e36b1bSAlexander Aring struct sk_buff *skb; 61771e36b1bSAlexander Aring struct ieee802154_mac_cb *cb; 61871e36b1bSAlexander Aring struct dgram_sock *ro = dgram_sk(sk); 61971e36b1bSAlexander Aring struct ieee802154_addr dst_addr; 62071e36b1bSAlexander Aring int hlen, tlen; 62171e36b1bSAlexander Aring int err; 62271e36b1bSAlexander Aring 62371e36b1bSAlexander Aring if (msg->msg_flags & MSG_OOB) { 62471e36b1bSAlexander Aring pr_debug("msg->msg_flags = 0x%x\n", msg->msg_flags); 62571e36b1bSAlexander Aring return -EOPNOTSUPP; 62671e36b1bSAlexander Aring } 62771e36b1bSAlexander Aring 62871e36b1bSAlexander Aring if (!ro->connected && !msg->msg_name) 62971e36b1bSAlexander Aring return -EDESTADDRREQ; 63071e36b1bSAlexander Aring else if (ro->connected && msg->msg_name) 63171e36b1bSAlexander Aring return -EISCONN; 63271e36b1bSAlexander Aring 63371e36b1bSAlexander Aring if (!ro->bound) 63471e36b1bSAlexander Aring dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154); 63571e36b1bSAlexander Aring else 63671e36b1bSAlexander Aring dev = ieee802154_get_dev(sock_net(sk), &ro->src_addr); 63771e36b1bSAlexander Aring 63871e36b1bSAlexander Aring if (!dev) { 63971e36b1bSAlexander Aring pr_debug("no dev\n"); 64071e36b1bSAlexander Aring err = -ENXIO; 64171e36b1bSAlexander Aring goto out; 64271e36b1bSAlexander Aring } 643b40988c4SAlexander Aring mtu = IEEE802154_MTU; 64471e36b1bSAlexander Aring pr_debug("name = %s, mtu = %u\n", dev->name, mtu); 64571e36b1bSAlexander Aring 64671e36b1bSAlexander Aring if (size > mtu) { 6475b5e0928SAlexey Dobriyan pr_debug("size = %zu, mtu = %u\n", size, mtu); 64871e36b1bSAlexander Aring err = -EMSGSIZE; 64971e36b1bSAlexander Aring goto out_dev; 65071e36b1bSAlexander Aring } 65171e36b1bSAlexander Aring 65271e36b1bSAlexander Aring hlen = LL_RESERVED_SPACE(dev); 65371e36b1bSAlexander Aring tlen = dev->needed_tailroom; 65471e36b1bSAlexander Aring skb = sock_alloc_send_skb(sk, hlen + tlen + size, 65571e36b1bSAlexander Aring msg->msg_flags & MSG_DONTWAIT, 65671e36b1bSAlexander Aring &err); 65771e36b1bSAlexander Aring if (!skb) 65871e36b1bSAlexander Aring goto out_dev; 65971e36b1bSAlexander Aring 66071e36b1bSAlexander Aring skb_reserve(skb, hlen); 66171e36b1bSAlexander Aring 66271e36b1bSAlexander Aring skb_reset_network_header(skb); 66371e36b1bSAlexander Aring 66471e36b1bSAlexander Aring cb = mac_cb_init(skb); 66571e36b1bSAlexander Aring cb->type = IEEE802154_FC_TYPE_DATA; 66671e36b1bSAlexander Aring cb->ackreq = ro->want_ack; 66771e36b1bSAlexander Aring 66871e36b1bSAlexander Aring if (msg->msg_name) { 66971e36b1bSAlexander Aring DECLARE_SOCKADDR(struct sockaddr_ieee802154*, 67071e36b1bSAlexander Aring daddr, msg->msg_name); 67171e36b1bSAlexander Aring 67271e36b1bSAlexander Aring ieee802154_addr_from_sa(&dst_addr, &daddr->addr); 67371e36b1bSAlexander Aring } else { 67471e36b1bSAlexander Aring dst_addr = ro->dst_addr; 67571e36b1bSAlexander Aring } 67671e36b1bSAlexander Aring 67771e36b1bSAlexander Aring cb->secen = ro->secen; 67871e36b1bSAlexander Aring cb->secen_override = ro->secen_override; 67971e36b1bSAlexander Aring cb->seclevel = ro->seclevel; 68071e36b1bSAlexander Aring cb->seclevel_override = ro->seclevel_override; 68171e36b1bSAlexander Aring 682838b83d6SAlexander Aring err = wpan_dev_hard_header(skb, dev, &dst_addr, 68371e36b1bSAlexander Aring ro->bound ? &ro->src_addr : NULL, size); 68471e36b1bSAlexander Aring if (err < 0) 68571e36b1bSAlexander Aring goto out_skb; 68671e36b1bSAlexander Aring 68771e36b1bSAlexander Aring err = memcpy_from_msg(skb_put(skb, size), msg, size); 68871e36b1bSAlexander Aring if (err < 0) 68971e36b1bSAlexander Aring goto out_skb; 69071e36b1bSAlexander Aring 69171e36b1bSAlexander Aring skb->dev = dev; 69271e36b1bSAlexander Aring skb->protocol = htons(ETH_P_IEEE802154); 69371e36b1bSAlexander Aring 69471e36b1bSAlexander Aring err = dev_queue_xmit(skb); 69571e36b1bSAlexander Aring if (err > 0) 69671e36b1bSAlexander Aring err = net_xmit_errno(err); 69771e36b1bSAlexander Aring 698a611c58bSLin Zhang dev_put(dev); 699a611c58bSLin Zhang 70071e36b1bSAlexander Aring return err ?: size; 70171e36b1bSAlexander Aring 70271e36b1bSAlexander Aring out_skb: 70371e36b1bSAlexander Aring kfree_skb(skb); 70471e36b1bSAlexander Aring out_dev: 70571e36b1bSAlexander Aring dev_put(dev); 70671e36b1bSAlexander Aring out: 70771e36b1bSAlexander Aring return err; 70871e36b1bSAlexander Aring } 70971e36b1bSAlexander Aring 7101b784140SYing Xue static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, 7111b784140SYing Xue int noblock, int flags, int *addr_len) 71271e36b1bSAlexander Aring { 71371e36b1bSAlexander Aring size_t copied = 0; 71471e36b1bSAlexander Aring int err = -EOPNOTSUPP; 71571e36b1bSAlexander Aring struct sk_buff *skb; 71671e36b1bSAlexander Aring DECLARE_SOCKADDR(struct sockaddr_ieee802154 *, saddr, msg->msg_name); 71771e36b1bSAlexander Aring 71871e36b1bSAlexander Aring skb = skb_recv_datagram(sk, flags, noblock, &err); 71971e36b1bSAlexander Aring if (!skb) 72071e36b1bSAlexander Aring goto out; 72171e36b1bSAlexander Aring 72271e36b1bSAlexander Aring copied = skb->len; 72371e36b1bSAlexander Aring if (len < copied) { 72471e36b1bSAlexander Aring msg->msg_flags |= MSG_TRUNC; 72571e36b1bSAlexander Aring copied = len; 72671e36b1bSAlexander Aring } 72771e36b1bSAlexander Aring 72871e36b1bSAlexander Aring /* FIXME: skip headers if necessary ?! */ 72971e36b1bSAlexander Aring err = skb_copy_datagram_msg(skb, 0, msg, copied); 73071e36b1bSAlexander Aring if (err) 73171e36b1bSAlexander Aring goto done; 73271e36b1bSAlexander Aring 73371e36b1bSAlexander Aring sock_recv_ts_and_drops(msg, sk, skb); 73471e36b1bSAlexander Aring 73571e36b1bSAlexander Aring if (saddr) { 7368a70cefaSLennert Buytenhek /* Clear the implicit padding in struct sockaddr_ieee802154 7378a70cefaSLennert Buytenhek * (16 bits between 'family' and 'addr') and in struct 7388a70cefaSLennert Buytenhek * ieee802154_addr_sa (16 bits at the end of the structure). 7398a70cefaSLennert Buytenhek */ 7408a70cefaSLennert Buytenhek memset(saddr, 0, sizeof(*saddr)); 7418a70cefaSLennert Buytenhek 74271e36b1bSAlexander Aring saddr->family = AF_IEEE802154; 74371e36b1bSAlexander Aring ieee802154_addr_to_sa(&saddr->addr, &mac_cb(skb)->source); 74471e36b1bSAlexander Aring *addr_len = sizeof(*saddr); 74571e36b1bSAlexander Aring } 74671e36b1bSAlexander Aring 74771e36b1bSAlexander Aring if (flags & MSG_TRUNC) 74871e36b1bSAlexander Aring copied = skb->len; 74971e36b1bSAlexander Aring done: 75071e36b1bSAlexander Aring skb_free_datagram(sk, skb); 75171e36b1bSAlexander Aring out: 75271e36b1bSAlexander Aring if (err) 75371e36b1bSAlexander Aring return err; 75471e36b1bSAlexander Aring return copied; 75571e36b1bSAlexander Aring } 75671e36b1bSAlexander Aring 75771e36b1bSAlexander Aring static int dgram_rcv_skb(struct sock *sk, struct sk_buff *skb) 75871e36b1bSAlexander Aring { 75971e36b1bSAlexander Aring skb = skb_share_check(skb, GFP_ATOMIC); 76071e36b1bSAlexander Aring if (!skb) 76171e36b1bSAlexander Aring return NET_RX_DROP; 76271e36b1bSAlexander Aring 76371e36b1bSAlexander Aring if (sock_queue_rcv_skb(sk, skb) < 0) { 76471e36b1bSAlexander Aring kfree_skb(skb); 76571e36b1bSAlexander Aring return NET_RX_DROP; 76671e36b1bSAlexander Aring } 76771e36b1bSAlexander Aring 76871e36b1bSAlexander Aring return NET_RX_SUCCESS; 76971e36b1bSAlexander Aring } 77071e36b1bSAlexander Aring 77171e36b1bSAlexander Aring static inline bool 77271e36b1bSAlexander Aring ieee802154_match_sock(__le64 hw_addr, __le16 pan_id, __le16 short_addr, 77371e36b1bSAlexander Aring struct dgram_sock *ro) 77471e36b1bSAlexander Aring { 77571e36b1bSAlexander Aring if (!ro->bound) 77671e36b1bSAlexander Aring return true; 77771e36b1bSAlexander Aring 77871e36b1bSAlexander Aring if (ro->src_addr.mode == IEEE802154_ADDR_LONG && 77971e36b1bSAlexander Aring hw_addr == ro->src_addr.extended_addr) 78071e36b1bSAlexander Aring return true; 78171e36b1bSAlexander Aring 78271e36b1bSAlexander Aring if (ro->src_addr.mode == IEEE802154_ADDR_SHORT && 78371e36b1bSAlexander Aring pan_id == ro->src_addr.pan_id && 78471e36b1bSAlexander Aring short_addr == ro->src_addr.short_addr) 78571e36b1bSAlexander Aring return true; 78671e36b1bSAlexander Aring 78771e36b1bSAlexander Aring return false; 78871e36b1bSAlexander Aring } 78971e36b1bSAlexander Aring 79071e36b1bSAlexander Aring static int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb) 79171e36b1bSAlexander Aring { 79271e36b1bSAlexander Aring struct sock *sk, *prev = NULL; 79371e36b1bSAlexander Aring int ret = NET_RX_SUCCESS; 79471e36b1bSAlexander Aring __le16 pan_id, short_addr; 79571e36b1bSAlexander Aring __le64 hw_addr; 79671e36b1bSAlexander Aring 79771e36b1bSAlexander Aring /* Data frame processing */ 79871e36b1bSAlexander Aring BUG_ON(dev->type != ARPHRD_IEEE802154); 79971e36b1bSAlexander Aring 800c947f7e1SAlexander Aring pan_id = dev->ieee802154_ptr->pan_id; 801c947f7e1SAlexander Aring short_addr = dev->ieee802154_ptr->short_addr; 802c947f7e1SAlexander Aring hw_addr = dev->ieee802154_ptr->extended_addr; 80371e36b1bSAlexander Aring 80471e36b1bSAlexander Aring read_lock(&dgram_lock); 80571e36b1bSAlexander Aring sk_for_each(sk, &dgram_head) { 80671e36b1bSAlexander Aring if (ieee802154_match_sock(hw_addr, pan_id, short_addr, 80771e36b1bSAlexander Aring dgram_sk(sk))) { 80871e36b1bSAlexander Aring if (prev) { 80971e36b1bSAlexander Aring struct sk_buff *clone; 81071e36b1bSAlexander Aring 81171e36b1bSAlexander Aring clone = skb_clone(skb, GFP_ATOMIC); 81271e36b1bSAlexander Aring if (clone) 81371e36b1bSAlexander Aring dgram_rcv_skb(prev, clone); 81471e36b1bSAlexander Aring } 81571e36b1bSAlexander Aring 81671e36b1bSAlexander Aring prev = sk; 81771e36b1bSAlexander Aring } 81871e36b1bSAlexander Aring } 81971e36b1bSAlexander Aring 82071e36b1bSAlexander Aring if (prev) { 82171e36b1bSAlexander Aring dgram_rcv_skb(prev, skb); 82271e36b1bSAlexander Aring } else { 82371e36b1bSAlexander Aring kfree_skb(skb); 82471e36b1bSAlexander Aring ret = NET_RX_DROP; 82571e36b1bSAlexander Aring } 82671e36b1bSAlexander Aring read_unlock(&dgram_lock); 82771e36b1bSAlexander Aring 82871e36b1bSAlexander Aring return ret; 82971e36b1bSAlexander Aring } 83071e36b1bSAlexander Aring 83171e36b1bSAlexander Aring static int dgram_getsockopt(struct sock *sk, int level, int optname, 83271e36b1bSAlexander Aring char __user *optval, int __user *optlen) 83371e36b1bSAlexander Aring { 83471e36b1bSAlexander Aring struct dgram_sock *ro = dgram_sk(sk); 83571e36b1bSAlexander Aring 83671e36b1bSAlexander Aring int val, len; 83771e36b1bSAlexander Aring 83871e36b1bSAlexander Aring if (level != SOL_IEEE802154) 83971e36b1bSAlexander Aring return -EOPNOTSUPP; 84071e36b1bSAlexander Aring 84171e36b1bSAlexander Aring if (get_user(len, optlen)) 84271e36b1bSAlexander Aring return -EFAULT; 84371e36b1bSAlexander Aring 84471e36b1bSAlexander Aring len = min_t(unsigned int, len, sizeof(int)); 84571e36b1bSAlexander Aring 84671e36b1bSAlexander Aring switch (optname) { 84771e36b1bSAlexander Aring case WPAN_WANTACK: 84871e36b1bSAlexander Aring val = ro->want_ack; 84971e36b1bSAlexander Aring break; 85071e36b1bSAlexander Aring case WPAN_SECURITY: 85171e36b1bSAlexander Aring if (!ro->secen_override) 85271e36b1bSAlexander Aring val = WPAN_SECURITY_DEFAULT; 85371e36b1bSAlexander Aring else if (ro->secen) 85471e36b1bSAlexander Aring val = WPAN_SECURITY_ON; 85571e36b1bSAlexander Aring else 85671e36b1bSAlexander Aring val = WPAN_SECURITY_OFF; 85771e36b1bSAlexander Aring break; 85871e36b1bSAlexander Aring case WPAN_SECURITY_LEVEL: 85971e36b1bSAlexander Aring if (!ro->seclevel_override) 86071e36b1bSAlexander Aring val = WPAN_SECURITY_LEVEL_DEFAULT; 86171e36b1bSAlexander Aring else 86271e36b1bSAlexander Aring val = ro->seclevel; 86371e36b1bSAlexander Aring break; 86471e36b1bSAlexander Aring default: 86571e36b1bSAlexander Aring return -ENOPROTOOPT; 86671e36b1bSAlexander Aring } 86771e36b1bSAlexander Aring 86871e36b1bSAlexander Aring if (put_user(len, optlen)) 86971e36b1bSAlexander Aring return -EFAULT; 87071e36b1bSAlexander Aring if (copy_to_user(optval, &val, len)) 87171e36b1bSAlexander Aring return -EFAULT; 87271e36b1bSAlexander Aring return 0; 87371e36b1bSAlexander Aring } 87471e36b1bSAlexander Aring 87571e36b1bSAlexander Aring static int dgram_setsockopt(struct sock *sk, int level, int optname, 87671e36b1bSAlexander Aring char __user *optval, unsigned int optlen) 87771e36b1bSAlexander Aring { 87871e36b1bSAlexander Aring struct dgram_sock *ro = dgram_sk(sk); 87971e36b1bSAlexander Aring struct net *net = sock_net(sk); 88071e36b1bSAlexander Aring int val; 88171e36b1bSAlexander Aring int err = 0; 88271e36b1bSAlexander Aring 88371e36b1bSAlexander Aring if (optlen < sizeof(int)) 88471e36b1bSAlexander Aring return -EINVAL; 88571e36b1bSAlexander Aring 88671e36b1bSAlexander Aring if (get_user(val, (int __user *)optval)) 88771e36b1bSAlexander Aring return -EFAULT; 88871e36b1bSAlexander Aring 88971e36b1bSAlexander Aring lock_sock(sk); 89071e36b1bSAlexander Aring 89171e36b1bSAlexander Aring switch (optname) { 89271e36b1bSAlexander Aring case WPAN_WANTACK: 89371e36b1bSAlexander Aring ro->want_ack = !!val; 89471e36b1bSAlexander Aring break; 89571e36b1bSAlexander Aring case WPAN_SECURITY: 89671e36b1bSAlexander Aring if (!ns_capable(net->user_ns, CAP_NET_ADMIN) && 89771e36b1bSAlexander Aring !ns_capable(net->user_ns, CAP_NET_RAW)) { 89871e36b1bSAlexander Aring err = -EPERM; 89971e36b1bSAlexander Aring break; 90071e36b1bSAlexander Aring } 90171e36b1bSAlexander Aring 90271e36b1bSAlexander Aring switch (val) { 90371e36b1bSAlexander Aring case WPAN_SECURITY_DEFAULT: 90471e36b1bSAlexander Aring ro->secen_override = 0; 90571e36b1bSAlexander Aring break; 90671e36b1bSAlexander Aring case WPAN_SECURITY_ON: 90771e36b1bSAlexander Aring ro->secen_override = 1; 90871e36b1bSAlexander Aring ro->secen = 1; 90971e36b1bSAlexander Aring break; 91071e36b1bSAlexander Aring case WPAN_SECURITY_OFF: 91171e36b1bSAlexander Aring ro->secen_override = 1; 91271e36b1bSAlexander Aring ro->secen = 0; 91371e36b1bSAlexander Aring break; 91471e36b1bSAlexander Aring default: 91571e36b1bSAlexander Aring err = -EINVAL; 91671e36b1bSAlexander Aring break; 91771e36b1bSAlexander Aring } 91871e36b1bSAlexander Aring break; 91971e36b1bSAlexander Aring case WPAN_SECURITY_LEVEL: 92071e36b1bSAlexander Aring if (!ns_capable(net->user_ns, CAP_NET_ADMIN) && 92171e36b1bSAlexander Aring !ns_capable(net->user_ns, CAP_NET_RAW)) { 92271e36b1bSAlexander Aring err = -EPERM; 92371e36b1bSAlexander Aring break; 92471e36b1bSAlexander Aring } 92571e36b1bSAlexander Aring 92671e36b1bSAlexander Aring if (val < WPAN_SECURITY_LEVEL_DEFAULT || 92771e36b1bSAlexander Aring val > IEEE802154_SCF_SECLEVEL_ENC_MIC128) { 92871e36b1bSAlexander Aring err = -EINVAL; 92971e36b1bSAlexander Aring } else if (val == WPAN_SECURITY_LEVEL_DEFAULT) { 93071e36b1bSAlexander Aring ro->seclevel_override = 0; 93171e36b1bSAlexander Aring } else { 93271e36b1bSAlexander Aring ro->seclevel_override = 1; 93371e36b1bSAlexander Aring ro->seclevel = val; 93471e36b1bSAlexander Aring } 93571e36b1bSAlexander Aring break; 93671e36b1bSAlexander Aring default: 93771e36b1bSAlexander Aring err = -ENOPROTOOPT; 93871e36b1bSAlexander Aring break; 93971e36b1bSAlexander Aring } 94071e36b1bSAlexander Aring 94171e36b1bSAlexander Aring release_sock(sk); 94271e36b1bSAlexander Aring return err; 94371e36b1bSAlexander Aring } 94471e36b1bSAlexander Aring 94571e36b1bSAlexander Aring static struct proto ieee802154_dgram_prot = { 94671e36b1bSAlexander Aring .name = "IEEE-802.15.4-MAC", 94771e36b1bSAlexander Aring .owner = THIS_MODULE, 94871e36b1bSAlexander Aring .obj_size = sizeof(struct dgram_sock), 94971e36b1bSAlexander Aring .init = dgram_init, 95071e36b1bSAlexander Aring .close = dgram_close, 95171e36b1bSAlexander Aring .bind = dgram_bind, 95271e36b1bSAlexander Aring .sendmsg = dgram_sendmsg, 95371e36b1bSAlexander Aring .recvmsg = dgram_recvmsg, 95471e36b1bSAlexander Aring .hash = dgram_hash, 95571e36b1bSAlexander Aring .unhash = dgram_unhash, 95671e36b1bSAlexander Aring .connect = dgram_connect, 95771e36b1bSAlexander Aring .disconnect = dgram_disconnect, 95871e36b1bSAlexander Aring .ioctl = dgram_ioctl, 95971e36b1bSAlexander Aring .getsockopt = dgram_getsockopt, 96071e36b1bSAlexander Aring .setsockopt = dgram_setsockopt, 96171e36b1bSAlexander Aring }; 96271e36b1bSAlexander Aring 96371e36b1bSAlexander Aring static const struct proto_ops ieee802154_dgram_ops = { 96471e36b1bSAlexander Aring .family = PF_IEEE802154, 96571e36b1bSAlexander Aring .owner = THIS_MODULE, 96671e36b1bSAlexander Aring .release = ieee802154_sock_release, 96771e36b1bSAlexander Aring .bind = ieee802154_sock_bind, 96871e36b1bSAlexander Aring .connect = ieee802154_sock_connect, 96971e36b1bSAlexander Aring .socketpair = sock_no_socketpair, 97071e36b1bSAlexander Aring .accept = sock_no_accept, 97171e36b1bSAlexander Aring .getname = sock_no_getname, 972a11e1d43SLinus Torvalds .poll = datagram_poll, 97371e36b1bSAlexander Aring .ioctl = ieee802154_sock_ioctl, 97471e36b1bSAlexander Aring .listen = sock_no_listen, 97571e36b1bSAlexander Aring .shutdown = sock_no_shutdown, 97671e36b1bSAlexander Aring .setsockopt = sock_common_setsockopt, 97771e36b1bSAlexander Aring .getsockopt = sock_common_getsockopt, 97871e36b1bSAlexander Aring .sendmsg = ieee802154_sock_sendmsg, 97971e36b1bSAlexander Aring .recvmsg = sock_common_recvmsg, 98071e36b1bSAlexander Aring .mmap = sock_no_mmap, 98171e36b1bSAlexander Aring .sendpage = sock_no_sendpage, 98271e36b1bSAlexander Aring #ifdef CONFIG_COMPAT 98371e36b1bSAlexander Aring .compat_setsockopt = compat_sock_common_setsockopt, 98471e36b1bSAlexander Aring .compat_getsockopt = compat_sock_common_getsockopt, 98571e36b1bSAlexander Aring #endif 98671e36b1bSAlexander Aring }; 98771e36b1bSAlexander Aring 98871e36b1bSAlexander Aring /* Create a socket. Initialise the socket, blank the addresses 98971e36b1bSAlexander Aring * set the state. 99071e36b1bSAlexander Aring */ 99171e36b1bSAlexander Aring static int ieee802154_create(struct net *net, struct socket *sock, 99271e36b1bSAlexander Aring int protocol, int kern) 99371e36b1bSAlexander Aring { 99471e36b1bSAlexander Aring struct sock *sk; 99571e36b1bSAlexander Aring int rc; 99671e36b1bSAlexander Aring struct proto *proto; 99771e36b1bSAlexander Aring const struct proto_ops *ops; 99871e36b1bSAlexander Aring 99971e36b1bSAlexander Aring if (!net_eq(net, &init_net)) 100071e36b1bSAlexander Aring return -EAFNOSUPPORT; 100171e36b1bSAlexander Aring 100271e36b1bSAlexander Aring switch (sock->type) { 100371e36b1bSAlexander Aring case SOCK_RAW: 100471e36b1bSAlexander Aring proto = &ieee802154_raw_prot; 100571e36b1bSAlexander Aring ops = &ieee802154_raw_ops; 100671e36b1bSAlexander Aring break; 100771e36b1bSAlexander Aring case SOCK_DGRAM: 100871e36b1bSAlexander Aring proto = &ieee802154_dgram_prot; 100971e36b1bSAlexander Aring ops = &ieee802154_dgram_ops; 101071e36b1bSAlexander Aring break; 101171e36b1bSAlexander Aring default: 101271e36b1bSAlexander Aring rc = -ESOCKTNOSUPPORT; 101371e36b1bSAlexander Aring goto out; 101471e36b1bSAlexander Aring } 101571e36b1bSAlexander Aring 101671e36b1bSAlexander Aring rc = -ENOMEM; 101711aa9c28SEric W. Biederman sk = sk_alloc(net, PF_IEEE802154, GFP_KERNEL, proto, kern); 101871e36b1bSAlexander Aring if (!sk) 101971e36b1bSAlexander Aring goto out; 102071e36b1bSAlexander Aring rc = 0; 102171e36b1bSAlexander Aring 102271e36b1bSAlexander Aring sock->ops = ops; 102371e36b1bSAlexander Aring 102471e36b1bSAlexander Aring sock_init_data(sock, sk); 102571e36b1bSAlexander Aring /* FIXME: sk->sk_destruct */ 102671e36b1bSAlexander Aring sk->sk_family = PF_IEEE802154; 102771e36b1bSAlexander Aring 102871e36b1bSAlexander Aring /* Checksums on by default */ 102971e36b1bSAlexander Aring sock_set_flag(sk, SOCK_ZAPPED); 103071e36b1bSAlexander Aring 1031086c653fSCraig Gallek if (sk->sk_prot->hash) { 1032086c653fSCraig Gallek rc = sk->sk_prot->hash(sk); 1033086c653fSCraig Gallek if (rc) { 1034086c653fSCraig Gallek sk_common_release(sk); 1035086c653fSCraig Gallek goto out; 1036086c653fSCraig Gallek } 1037086c653fSCraig Gallek } 103871e36b1bSAlexander Aring 103971e36b1bSAlexander Aring if (sk->sk_prot->init) { 104071e36b1bSAlexander Aring rc = sk->sk_prot->init(sk); 104171e36b1bSAlexander Aring if (rc) 104271e36b1bSAlexander Aring sk_common_release(sk); 104371e36b1bSAlexander Aring } 104471e36b1bSAlexander Aring out: 104571e36b1bSAlexander Aring return rc; 104671e36b1bSAlexander Aring } 104771e36b1bSAlexander Aring 104871e36b1bSAlexander Aring static const struct net_proto_family ieee802154_family_ops = { 104971e36b1bSAlexander Aring .family = PF_IEEE802154, 105071e36b1bSAlexander Aring .create = ieee802154_create, 105171e36b1bSAlexander Aring .owner = THIS_MODULE, 105271e36b1bSAlexander Aring }; 105371e36b1bSAlexander Aring 105471e36b1bSAlexander Aring static int ieee802154_rcv(struct sk_buff *skb, struct net_device *dev, 105571e36b1bSAlexander Aring struct packet_type *pt, struct net_device *orig_dev) 105671e36b1bSAlexander Aring { 105771e36b1bSAlexander Aring if (!netif_running(dev)) 105871e36b1bSAlexander Aring goto drop; 105971e36b1bSAlexander Aring pr_debug("got frame, type %d, dev %p\n", dev->type, dev); 106071e36b1bSAlexander Aring #ifdef DEBUG 106171e36b1bSAlexander Aring print_hex_dump_bytes("ieee802154_rcv ", 106271e36b1bSAlexander Aring DUMP_PREFIX_NONE, skb->data, skb->len); 106371e36b1bSAlexander Aring #endif 106471e36b1bSAlexander Aring 106571e36b1bSAlexander Aring if (!net_eq(dev_net(dev), &init_net)) 106671e36b1bSAlexander Aring goto drop; 106771e36b1bSAlexander Aring 106871e36b1bSAlexander Aring ieee802154_raw_deliver(dev, skb); 106971e36b1bSAlexander Aring 107071e36b1bSAlexander Aring if (dev->type != ARPHRD_IEEE802154) 107171e36b1bSAlexander Aring goto drop; 107271e36b1bSAlexander Aring 107371e36b1bSAlexander Aring if (skb->pkt_type != PACKET_OTHERHOST) 107471e36b1bSAlexander Aring return ieee802154_dgram_deliver(dev, skb); 107571e36b1bSAlexander Aring 107671e36b1bSAlexander Aring drop: 107771e36b1bSAlexander Aring kfree_skb(skb); 107871e36b1bSAlexander Aring return NET_RX_DROP; 107971e36b1bSAlexander Aring } 108071e36b1bSAlexander Aring 108171e36b1bSAlexander Aring static struct packet_type ieee802154_packet_type = { 108271e36b1bSAlexander Aring .type = htons(ETH_P_IEEE802154), 108371e36b1bSAlexander Aring .func = ieee802154_rcv, 108471e36b1bSAlexander Aring }; 108571e36b1bSAlexander Aring 108671e36b1bSAlexander Aring static int __init af_ieee802154_init(void) 108771e36b1bSAlexander Aring { 108871e36b1bSAlexander Aring int rc = -EINVAL; 108971e36b1bSAlexander Aring 109071e36b1bSAlexander Aring rc = proto_register(&ieee802154_raw_prot, 1); 109171e36b1bSAlexander Aring if (rc) 109271e36b1bSAlexander Aring goto out; 109371e36b1bSAlexander Aring 109471e36b1bSAlexander Aring rc = proto_register(&ieee802154_dgram_prot, 1); 109571e36b1bSAlexander Aring if (rc) 109671e36b1bSAlexander Aring goto err_dgram; 109771e36b1bSAlexander Aring 109871e36b1bSAlexander Aring /* Tell SOCKET that we are alive */ 109971e36b1bSAlexander Aring rc = sock_register(&ieee802154_family_ops); 110071e36b1bSAlexander Aring if (rc) 110171e36b1bSAlexander Aring goto err_sock; 110271e36b1bSAlexander Aring dev_add_pack(&ieee802154_packet_type); 110371e36b1bSAlexander Aring 110471e36b1bSAlexander Aring rc = 0; 110571e36b1bSAlexander Aring goto out; 110671e36b1bSAlexander Aring 110771e36b1bSAlexander Aring err_sock: 110871e36b1bSAlexander Aring proto_unregister(&ieee802154_dgram_prot); 110971e36b1bSAlexander Aring err_dgram: 111071e36b1bSAlexander Aring proto_unregister(&ieee802154_raw_prot); 111171e36b1bSAlexander Aring out: 111271e36b1bSAlexander Aring return rc; 111371e36b1bSAlexander Aring } 111471e36b1bSAlexander Aring 111571e36b1bSAlexander Aring static void __exit af_ieee802154_remove(void) 111671e36b1bSAlexander Aring { 111771e36b1bSAlexander Aring dev_remove_pack(&ieee802154_packet_type); 111871e36b1bSAlexander Aring sock_unregister(PF_IEEE802154); 111971e36b1bSAlexander Aring proto_unregister(&ieee802154_dgram_prot); 112071e36b1bSAlexander Aring proto_unregister(&ieee802154_raw_prot); 112171e36b1bSAlexander Aring } 112271e36b1bSAlexander Aring 112371e36b1bSAlexander Aring module_init(af_ieee802154_init); 112471e36b1bSAlexander Aring module_exit(af_ieee802154_remove); 112571e36b1bSAlexander Aring 112671e36b1bSAlexander Aring MODULE_LICENSE("GPL"); 112771e36b1bSAlexander Aring MODULE_ALIAS_NETPROTO(PF_IEEE802154); 1128