^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) BNEP implementation for Linux Bluetooth stack (BlueZ).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) Copyright (C) 2001-2002 Inventel Systemes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) Written 2001-2002 by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) David Libault <david.libault@inventel.fr>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) it under the terms of the GNU General Public License version 2 as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) published by the Free Software Foundation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) SOFTWARE IS DISCLAIMED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "bnep.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static struct bt_sock_list bnep_sk_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) .lock = __RW_LOCK_UNLOCKED(bnep_sk_list.lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static int bnep_sock_release(struct socket *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) BT_DBG("sock %p sk %p", sock, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (!sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) bt_sock_unlink(&bnep_sk_list, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) sock_orphan(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static int do_bnep_sock_ioctl(struct socket *sock, unsigned int cmd, void __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct bnep_connlist_req cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct bnep_connadd_req ca;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct bnep_conndel_req cd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct bnep_conninfo ci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct socket *nsock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) __u32 supp_feat = BIT(BNEP_SETUP_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) BT_DBG("cmd %x arg %p", cmd, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) case BNEPCONNADD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (!capable(CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (copy_from_user(&ca, argp, sizeof(ca)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) nsock = sockfd_lookup(ca.sock, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (!nsock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (nsock->sk->sk_state != BT_CONNECTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) sockfd_put(nsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return -EBADFD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ca.device[sizeof(ca.device)-1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) err = bnep_add_connection(&ca, nsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (copy_to_user(argp, &ca, sizeof(ca)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) sockfd_put(nsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) case BNEPCONNDEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (!capable(CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (copy_from_user(&cd, argp, sizeof(cd)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return bnep_del_connection(&cd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) case BNEPGETCONNLIST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (copy_from_user(&cl, argp, sizeof(cl)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (cl.cnum <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) err = bnep_get_connlist(&cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (!err && copy_to_user(argp, &cl, sizeof(cl)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) case BNEPGETCONNINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (copy_from_user(&ci, argp, sizeof(ci)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) err = bnep_get_conninfo(&ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (!err && copy_to_user(argp, &ci, sizeof(ci)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) case BNEPGETSUPPFEAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (copy_to_user(argp, &supp_feat, sizeof(supp_feat)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return do_bnep_sock_ioctl(sock, cmd, (void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) void __user *argp = compat_ptr(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (cmd == BNEPGETCONNLIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct bnep_connlist_req cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) unsigned __user *p = argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) u32 uci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (get_user(cl.cnum, p) || get_user(uci, p + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) cl.ci = compat_ptr(uci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (cl.cnum <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) err = bnep_get_connlist(&cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (!err && put_user(cl.cnum, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return do_bnep_sock_ioctl(sock, cmd, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static const struct proto_ops bnep_sock_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) .family = PF_BLUETOOTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .release = bnep_sock_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .ioctl = bnep_sock_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .compat_ioctl = bnep_sock_compat_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) .bind = sock_no_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .getname = sock_no_getname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) .sendmsg = sock_no_sendmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) .recvmsg = sock_no_recvmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) .listen = sock_no_listen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) .shutdown = sock_no_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .connect = sock_no_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .socketpair = sock_no_socketpair,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .accept = sock_no_accept,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .mmap = sock_no_mmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static struct proto bnep_proto = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .name = "BNEP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .obj_size = sizeof(struct bt_sock)
^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 bnep_sock_create(struct net *net, struct socket *sock, int protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int kern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) BT_DBG("sock %p", sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (sock->type != SOCK_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return -ESOCKTNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, kern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (!sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) sock_init_data(sock, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) sock->ops = &bnep_sock_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) sock->state = SS_UNCONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) sock_reset_flag(sk, SOCK_ZAPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) sk->sk_protocol = protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) sk->sk_state = BT_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) bt_sock_link(&bnep_sk_list, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static const struct net_proto_family bnep_sock_family_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .family = PF_BLUETOOTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .create = bnep_sock_create
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) int __init bnep_sock_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) err = proto_register(&bnep_proto, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) err = bt_sock_register(BTPROTO_BNEP, &bnep_sock_family_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) BT_ERR("Can't register BNEP socket");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) err = bt_procfs_init(&init_net, "bnep", &bnep_sk_list, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) BT_ERR("Failed to create BNEP proc file");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) bt_sock_unregister(BTPROTO_BNEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) BT_INFO("BNEP socket layer initialized");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) proto_unregister(&bnep_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) void __exit bnep_sock_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) bt_procfs_cleanup(&init_net, "bnep");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) bt_sock_unregister(BTPROTO_BNEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) proto_unregister(&bnep_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }