^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * IEEE802154.4 socket interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2007, 2008 Siemens AG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Written by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Sergey Lapin <slapin@ossfans.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/net.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/if.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/termios.h> /* For TIOCOUTQ/INQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/socket.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <net/datalink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <net/psnap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <net/tcp_states.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <net/route.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <net/af_ieee802154.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <net/ieee802154_netdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* Utility function for families */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static struct net_device*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) ieee802154_get_dev(struct net *net, const struct ieee802154_addr *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct net_device *dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct net_device *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) __le16 pan_id, short_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) u8 hwaddr[IEEE802154_ADDR_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) switch (addr->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) case IEEE802154_ADDR_LONG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) ieee802154_devaddr_to_raw(hwaddr, addr->extended_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) dev = dev_getbyhwaddr_rcu(net, ARPHRD_IEEE802154, hwaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) dev_hold(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) case IEEE802154_ADDR_SHORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (addr->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) addr->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) addr->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) for_each_netdev(net, tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (tmp->type != ARPHRD_IEEE802154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) pan_id = tmp->ieee802154_ptr->pan_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) short_addr = tmp->ieee802154_ptr->short_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (pan_id == addr->pan_id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) short_addr == addr->short_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) dev = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) dev_hold(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) pr_warn("Unsupported ieee802154 address type: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) addr->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static int ieee802154_sock_release(struct socket *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) sock->sk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) sk->sk_prot->close(sk, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static int ieee802154_sock_sendmsg(struct socket *sock, struct msghdr *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return sk->sk_prot->sendmsg(sk, msg, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static int ieee802154_sock_bind(struct socket *sock, struct sockaddr *uaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) int addr_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (sk->sk_prot->bind)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return sk->sk_prot->bind(sk, uaddr, addr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return sock_no_bind(sock, uaddr, addr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static int ieee802154_sock_connect(struct socket *sock, struct sockaddr *uaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int addr_len, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (addr_len < sizeof(uaddr->sa_family))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (uaddr->sa_family == AF_UNSPEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return sk->sk_prot->disconnect(sk, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return sk->sk_prot->connect(sk, uaddr, addr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct ifreq ifr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int ret = -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ifr.ifr_name[IFNAMSIZ-1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) dev_load(sock_net(sk), ifr.ifr_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) dev = dev_get_by_name(sock_net(sk), ifr.ifr_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (dev->type == ARPHRD_IEEE802154 && dev->netdev_ops->ndo_do_ioctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (!ret && copy_to_user(arg, &ifr, sizeof(struct ifreq)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) dev_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static int ieee802154_sock_ioctl(struct socket *sock, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) case SIOCGIFADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) case SIOCSIFADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return ieee802154_dev_ioctl(sk, (struct ifreq __user *)arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (!sk->sk_prot->ioctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return sk->sk_prot->ioctl(sk, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* RAW Sockets (802.15.4 created in userspace) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static HLIST_HEAD(raw_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static DEFINE_RWLOCK(raw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static int raw_hash(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) write_lock_bh(&raw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) sk_add_node(sk, &raw_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) write_unlock_bh(&raw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static void raw_unhash(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) write_lock_bh(&raw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (sk_del_node_init(sk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) write_unlock_bh(&raw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static void raw_close(struct sock *sk, long timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) sk_common_release(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static int raw_bind(struct sock *sk, struct sockaddr *_uaddr, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct ieee802154_addr addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct sockaddr_ieee802154 *uaddr = (struct sockaddr_ieee802154 *)_uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct net_device *dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (len < sizeof(*uaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) uaddr = (struct sockaddr_ieee802154 *)_uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (uaddr->family != AF_IEEE802154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ieee802154_addr_from_sa(&addr, &uaddr->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) dev = ieee802154_get_dev(sock_net(sk), &addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) sk->sk_bound_dev_if = dev->ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) sk_dst_reset(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) dev_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static int raw_connect(struct sock *sk, struct sockaddr *uaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int addr_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int raw_disconnect(struct sock *sk, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) unsigned int mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) int hlen, tlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (msg->msg_flags & MSG_OOB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) pr_debug("msg->msg_flags = 0x%x\n", msg->msg_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (!sk->sk_bound_dev_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) dev = dev_get_by_index(sock_net(sk), sk->sk_bound_dev_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) pr_debug("no dev\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) err = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) mtu = IEEE802154_MTU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) pr_debug("name = %s, mtu = %u\n", dev->name, mtu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (size > mtu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) pr_debug("size = %zu, mtu = %u\n", size, mtu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) err = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) goto out_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) hlen = LL_RESERVED_SPACE(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) tlen = dev->needed_tailroom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) skb = sock_alloc_send_skb(sk, hlen + tlen + size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) msg->msg_flags & MSG_DONTWAIT, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) goto out_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) skb_reserve(skb, hlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) skb_reset_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) err = memcpy_from_msg(skb_put(skb, size), msg, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) goto out_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) skb->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) skb->protocol = htons(ETH_P_IEEE802154);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) err = dev_queue_xmit(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (err > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) err = net_xmit_errno(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) dev_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return err ?: size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) out_skb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) out_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) dev_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static int raw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) int noblock, int flags, int *addr_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) size_t copied = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) int err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) skb = skb_recv_datagram(sk, flags, noblock, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) copied = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (len < copied) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) msg->msg_flags |= MSG_TRUNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) copied = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) err = skb_copy_datagram_msg(skb, 0, msg, copied);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) sock_recv_ts_and_drops(msg, sk, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (flags & MSG_TRUNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) copied = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) skb_free_datagram(sk, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static int raw_rcv_skb(struct sock *sk, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) skb = skb_share_check(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (sock_queue_rcv_skb(sk, skb) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return NET_RX_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) static void ieee802154_raw_deliver(struct net_device *dev, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) read_lock(&raw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) sk_for_each(sk, &raw_head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) bh_lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (!sk->sk_bound_dev_if ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) sk->sk_bound_dev_if == dev->ifindex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct sk_buff *clone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) clone = skb_clone(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (clone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) raw_rcv_skb(sk, clone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) bh_unlock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) read_unlock(&raw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static int raw_getsockopt(struct sock *sk, int level, int optname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) char __user *optval, int __user *optlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static int raw_setsockopt(struct sock *sk, int level, int optname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) sockptr_t optval, unsigned int optlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static struct proto ieee802154_raw_prot = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) .name = "IEEE-802.15.4-RAW",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .obj_size = sizeof(struct sock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .close = raw_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) .bind = raw_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) .sendmsg = raw_sendmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) .recvmsg = raw_recvmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) .hash = raw_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) .unhash = raw_unhash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) .connect = raw_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) .disconnect = raw_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) .getsockopt = raw_getsockopt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) .setsockopt = raw_setsockopt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static const struct proto_ops ieee802154_raw_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) .family = PF_IEEE802154,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) .release = ieee802154_sock_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) .bind = ieee802154_sock_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) .connect = ieee802154_sock_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .socketpair = sock_no_socketpair,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) .accept = sock_no_accept,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) .getname = sock_no_getname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) .poll = datagram_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .ioctl = ieee802154_sock_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) .gettstamp = sock_gettstamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .listen = sock_no_listen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) .shutdown = sock_no_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) .setsockopt = sock_common_setsockopt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) .getsockopt = sock_common_getsockopt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) .sendmsg = ieee802154_sock_sendmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) .recvmsg = sock_common_recvmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) .mmap = sock_no_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .sendpage = sock_no_sendpage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* DGRAM Sockets (802.15.4 dataframes) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) static HLIST_HEAD(dgram_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static DEFINE_RWLOCK(dgram_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct dgram_sock {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct sock sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct ieee802154_addr src_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct ieee802154_addr dst_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) unsigned int bound:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) unsigned int connected:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) unsigned int want_ack:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) unsigned int want_lqi:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) unsigned int secen:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) unsigned int secen_override:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) unsigned int seclevel:3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) unsigned int seclevel_override:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static inline struct dgram_sock *dgram_sk(const struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return container_of(sk, struct dgram_sock, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static int dgram_hash(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) write_lock_bh(&dgram_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) sk_add_node(sk, &dgram_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) write_unlock_bh(&dgram_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static void dgram_unhash(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) write_lock_bh(&dgram_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (sk_del_node_init(sk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) write_unlock_bh(&dgram_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static int dgram_init(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct dgram_sock *ro = dgram_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ro->want_ack = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ro->want_lqi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) static void dgram_close(struct sock *sk, long timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) sk_common_release(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct ieee802154_addr haddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct dgram_sock *ro = dgram_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) int err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ro->bound = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (len < sizeof(*addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (addr->family != AF_IEEE802154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) ieee802154_addr_from_sa(&haddr, &addr->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) dev = ieee802154_get_dev(sock_net(sk), &haddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (dev->type != ARPHRD_IEEE802154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ro->src_addr = haddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ro->bound = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) dev_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) case SIOCOUTQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) int amount = sk_wmem_alloc_get(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return put_user(amount, (int __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) case SIOCINQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) unsigned long amount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) amount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) spin_lock_bh(&sk->sk_receive_queue.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) skb = skb_peek(&sk->sk_receive_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) /* We will only return the amount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * of this packet since that is all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * that will be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) amount = skb->len - ieee802154_hdr_length(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) spin_unlock_bh(&sk->sk_receive_queue.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return put_user(amount, (int __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /* FIXME: autobind */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static int dgram_connect(struct sock *sk, struct sockaddr *uaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct dgram_sock *ro = dgram_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (len < sizeof(*addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (addr->family != AF_IEEE802154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (!ro->bound) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) err = -ENETUNREACH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) ieee802154_addr_from_sa(&ro->dst_addr, &addr->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) ro->connected = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) static int dgram_disconnect(struct sock *sk, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct dgram_sock *ro = dgram_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) ro->connected = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) static int dgram_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) unsigned int mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) struct ieee802154_mac_cb *cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) struct dgram_sock *ro = dgram_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) struct ieee802154_addr dst_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) int hlen, tlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (msg->msg_flags & MSG_OOB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) pr_debug("msg->msg_flags = 0x%x\n", msg->msg_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (!ro->connected && !msg->msg_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return -EDESTADDRREQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) else if (ro->connected && msg->msg_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return -EISCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (!ro->bound)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) dev = ieee802154_get_dev(sock_net(sk), &ro->src_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) pr_debug("no dev\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) err = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) mtu = IEEE802154_MTU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) pr_debug("name = %s, mtu = %u\n", dev->name, mtu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (size > mtu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) pr_debug("size = %zu, mtu = %u\n", size, mtu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) err = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) goto out_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) hlen = LL_RESERVED_SPACE(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) tlen = dev->needed_tailroom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) skb = sock_alloc_send_skb(sk, hlen + tlen + size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) msg->msg_flags & MSG_DONTWAIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) goto out_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) skb_reserve(skb, hlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) cb = mac_cb_init(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) cb->type = IEEE802154_FC_TYPE_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) cb->ackreq = ro->want_ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (msg->msg_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) DECLARE_SOCKADDR(struct sockaddr_ieee802154*,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) daddr, msg->msg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) ieee802154_addr_from_sa(&dst_addr, &daddr->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) dst_addr = ro->dst_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) cb->secen = ro->secen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) cb->secen_override = ro->secen_override;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) cb->seclevel = ro->seclevel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) cb->seclevel_override = ro->seclevel_override;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) err = wpan_dev_hard_header(skb, dev, &dst_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) ro->bound ? &ro->src_addr : NULL, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) goto out_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) err = memcpy_from_msg(skb_put(skb, size), msg, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) goto out_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) skb->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) skb->protocol = htons(ETH_P_IEEE802154);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) err = dev_queue_xmit(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (err > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) err = net_xmit_errno(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) dev_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return err ?: size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) out_skb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) out_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) dev_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) int noblock, int flags, int *addr_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) size_t copied = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) int err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct dgram_sock *ro = dgram_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) DECLARE_SOCKADDR(struct sockaddr_ieee802154 *, saddr, msg->msg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) skb = skb_recv_datagram(sk, flags, noblock, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) copied = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (len < copied) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) msg->msg_flags |= MSG_TRUNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) copied = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) /* FIXME: skip headers if necessary ?! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) err = skb_copy_datagram_msg(skb, 0, msg, copied);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) sock_recv_ts_and_drops(msg, sk, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (saddr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) /* Clear the implicit padding in struct sockaddr_ieee802154
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * (16 bits between 'family' and 'addr') and in struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * ieee802154_addr_sa (16 bits at the end of the structure).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) memset(saddr, 0, sizeof(*saddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) saddr->family = AF_IEEE802154;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) ieee802154_addr_to_sa(&saddr->addr, &mac_cb(skb)->source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) *addr_len = sizeof(*saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (ro->want_lqi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) err = put_cmsg(msg, SOL_IEEE802154, WPAN_WANTLQI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) sizeof(uint8_t), &(mac_cb(skb)->lqi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (flags & MSG_TRUNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) copied = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) skb_free_datagram(sk, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) static int dgram_rcv_skb(struct sock *sk, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) skb = skb_share_check(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (sock_queue_rcv_skb(sk, skb) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return NET_RX_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) static inline bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) ieee802154_match_sock(__le64 hw_addr, __le16 pan_id, __le16 short_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) struct dgram_sock *ro)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (!ro->bound)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (ro->src_addr.mode == IEEE802154_ADDR_LONG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) hw_addr == ro->src_addr.extended_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (ro->src_addr.mode == IEEE802154_ADDR_SHORT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) pan_id == ro->src_addr.pan_id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) short_addr == ro->src_addr.short_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) static int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) struct sock *sk, *prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) int ret = NET_RX_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) __le16 pan_id, short_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) __le64 hw_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /* Data frame processing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) BUG_ON(dev->type != ARPHRD_IEEE802154);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) pan_id = dev->ieee802154_ptr->pan_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) short_addr = dev->ieee802154_ptr->short_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) hw_addr = dev->ieee802154_ptr->extended_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) read_lock(&dgram_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) sk_for_each(sk, &dgram_head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (ieee802154_match_sock(hw_addr, pan_id, short_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) dgram_sk(sk))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (prev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) struct sk_buff *clone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) clone = skb_clone(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) if (clone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) dgram_rcv_skb(prev, clone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) prev = sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (prev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) dgram_rcv_skb(prev, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) ret = NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) read_unlock(&dgram_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) static int dgram_getsockopt(struct sock *sk, int level, int optname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) char __user *optval, int __user *optlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) struct dgram_sock *ro = dgram_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) int val, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (level != SOL_IEEE802154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (get_user(len, optlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) len = min_t(unsigned int, len, sizeof(int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) switch (optname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) case WPAN_WANTACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) val = ro->want_ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) case WPAN_WANTLQI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) val = ro->want_lqi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) case WPAN_SECURITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (!ro->secen_override)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) val = WPAN_SECURITY_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) else if (ro->secen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) val = WPAN_SECURITY_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) val = WPAN_SECURITY_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) case WPAN_SECURITY_LEVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (!ro->seclevel_override)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) val = WPAN_SECURITY_LEVEL_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) val = ro->seclevel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return -ENOPROTOOPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (put_user(len, optlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (copy_to_user(optval, &val, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) static int dgram_setsockopt(struct sock *sk, int level, int optname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) sockptr_t optval, unsigned int optlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) struct dgram_sock *ro = dgram_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) struct net *net = sock_net(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (optlen < sizeof(int))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (copy_from_sockptr(&val, optval, sizeof(int)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) switch (optname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) case WPAN_WANTACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) ro->want_ack = !!val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) case WPAN_WANTLQI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) ro->want_lqi = !!val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) case WPAN_SECURITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (!ns_capable(net->user_ns, CAP_NET_ADMIN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) !ns_capable(net->user_ns, CAP_NET_RAW)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) err = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) case WPAN_SECURITY_DEFAULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) ro->secen_override = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) case WPAN_SECURITY_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) ro->secen_override = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) ro->secen = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) case WPAN_SECURITY_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) ro->secen_override = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) ro->secen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) case WPAN_SECURITY_LEVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (!ns_capable(net->user_ns, CAP_NET_ADMIN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) !ns_capable(net->user_ns, CAP_NET_RAW)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) err = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (val < WPAN_SECURITY_LEVEL_DEFAULT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) val > IEEE802154_SCF_SECLEVEL_ENC_MIC128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) } else if (val == WPAN_SECURITY_LEVEL_DEFAULT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) ro->seclevel_override = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) ro->seclevel_override = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) ro->seclevel = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) err = -ENOPROTOOPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) static struct proto ieee802154_dgram_prot = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) .name = "IEEE-802.15.4-MAC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) .obj_size = sizeof(struct dgram_sock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) .init = dgram_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) .close = dgram_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) .bind = dgram_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) .sendmsg = dgram_sendmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) .recvmsg = dgram_recvmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) .hash = dgram_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) .unhash = dgram_unhash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) .connect = dgram_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) .disconnect = dgram_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) .ioctl = dgram_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) .getsockopt = dgram_getsockopt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) .setsockopt = dgram_setsockopt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) static const struct proto_ops ieee802154_dgram_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) .family = PF_IEEE802154,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) .release = ieee802154_sock_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) .bind = ieee802154_sock_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) .connect = ieee802154_sock_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) .socketpair = sock_no_socketpair,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) .accept = sock_no_accept,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) .getname = sock_no_getname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) .poll = datagram_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) .ioctl = ieee802154_sock_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) .gettstamp = sock_gettstamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) .listen = sock_no_listen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) .shutdown = sock_no_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) .setsockopt = sock_common_setsockopt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) .getsockopt = sock_common_getsockopt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) .sendmsg = ieee802154_sock_sendmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) .recvmsg = sock_common_recvmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) .mmap = sock_no_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) .sendpage = sock_no_sendpage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) static void ieee802154_sock_destruct(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) skb_queue_purge(&sk->sk_receive_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) /* Create a socket. Initialise the socket, blank the addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) * set the state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) static int ieee802154_create(struct net *net, struct socket *sock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) int protocol, int kern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) struct proto *proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) const struct proto_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (!net_eq(net, &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) return -EAFNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) switch (sock->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) case SOCK_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (!capable(CAP_NET_RAW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) proto = &ieee802154_raw_prot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) ops = &ieee802154_raw_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) case SOCK_DGRAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) proto = &ieee802154_dgram_prot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) ops = &ieee802154_dgram_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) rc = -ESOCKTNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) sk = sk_alloc(net, PF_IEEE802154, GFP_KERNEL, proto, kern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (!sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) sock->ops = ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) sock_init_data(sock, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) sk->sk_destruct = ieee802154_sock_destruct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) sk->sk_family = PF_IEEE802154;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) /* Checksums on by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) sock_set_flag(sk, SOCK_ZAPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (sk->sk_prot->hash) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) rc = sk->sk_prot->hash(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) sk_common_release(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) if (sk->sk_prot->init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) rc = sk->sk_prot->init(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) sk_common_release(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) static const struct net_proto_family ieee802154_family_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) .family = PF_IEEE802154,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) .create = ieee802154_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) static int ieee802154_rcv(struct sk_buff *skb, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) struct packet_type *pt, struct net_device *orig_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (!netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) pr_debug("got frame, type %d, dev %p\n", dev->type, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) print_hex_dump_bytes("ieee802154_rcv ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) DUMP_PREFIX_NONE, skb->data, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (!net_eq(dev_net(dev), &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) ieee802154_raw_deliver(dev, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (dev->type != ARPHRD_IEEE802154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (skb->pkt_type != PACKET_OTHERHOST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) return ieee802154_dgram_deliver(dev, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) static struct packet_type ieee802154_packet_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) .type = htons(ETH_P_IEEE802154),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) .func = ieee802154_rcv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) static int __init af_ieee802154_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) rc = proto_register(&ieee802154_raw_prot, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) rc = proto_register(&ieee802154_dgram_prot, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) goto err_dgram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) /* Tell SOCKET that we are alive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) rc = sock_register(&ieee802154_family_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) goto err_sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) dev_add_pack(&ieee802154_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) err_sock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) proto_unregister(&ieee802154_dgram_prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) err_dgram:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) proto_unregister(&ieee802154_raw_prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) static void __exit af_ieee802154_remove(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) dev_remove_pack(&ieee802154_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) sock_unregister(PF_IEEE802154);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) proto_unregister(&ieee802154_dgram_prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) proto_unregister(&ieee802154_raw_prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) module_init(af_ieee802154_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) module_exit(af_ieee802154_remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) MODULE_ALIAS_NETPROTO(PF_IEEE802154);