18e87d14255acffeee36873de226dc25c11b5f46dYOSHIFUJI Hideaki/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BNEP implementation for Linux Bluetooth stack (BlueZ). 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Copyright (C) 2001-2002 Inventel Systemes 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Written 2001-2002 by 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds David Libault <david.libault@inventel.fr> 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com> 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds This program is free software; you can redistribute it and/or modify 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds it under the terms of the GNU General Public License version 2 as 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds published by the Free Software Foundation; 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 178e87d14255acffeee36873de226dc25c11b5f46dYOSHIFUJI Hideaki CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 188e87d14255acffeee36873de226dc25c11b5f46dYOSHIFUJI Hideaki WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 198e87d14255acffeee36873de226dc25c11b5f46dYOSHIFUJI Hideaki ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 228e87d14255acffeee36873de226dc25c11b5f46dYOSHIFUJI Hideaki ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 238e87d14255acffeee36873de226dc25c11b5f46dYOSHIFUJI Hideaki COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SOFTWARE IS DISCLAIMED. 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 278c520a59927a5600973782505dbb750d985057c4Gustavo Padovan#include <linux/export.h> 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/file.h> 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "bnep.h" 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3277cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATOstatic struct bt_sock_list bnep_sk_list = { 3377cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO .lock = __RW_LOCK_UNLOCKED(bnep_sk_list.lock) 3477cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO}; 3577cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int bnep_sock_release(struct socket *sock) 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sock *sk = sock->sk; 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BT_DBG("sock %p sk %p", sock, sk); 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!sk) 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4577cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO bt_sock_unlink(&bnep_sk_list, sk); 4677cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sock_orphan(sk); 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sock_put(sk); 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bnep_connlist_req cl; 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bnep_connadd_req ca; 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bnep_conndel_req cd; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bnep_conninfo ci; 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct socket *nsock; 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __user *argp = (void __user *)arg; 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BT_DBG("cmd %x arg %lx", cmd, arg); 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case BNEPCONNADD: 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!capable(CAP_NET_ADMIN)) 67bf5b30b8a4416de04f1ac1196281ddb318669464Zhao Hongjiang return -EPERM; 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_from_user(&ca, argp, sizeof(ca))) 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 718e87d14255acffeee36873de226dc25c11b5f46dYOSHIFUJI Hideaki 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nsock = sockfd_lookup(ca.sock, &err); 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!nsock) 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nsock->sk->sk_state != BT_CONNECTED) { 7767b23219ce2f78352b0c566a472ff16c1b0fea9aJulia Lawall sockfd_put(nsock); 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EBADFD; 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8043629f8f5ea32a998d06d1bb41eefa0e821ff573Vasiliy Kulikov ca.device[sizeof(ca.device)-1] = 0; 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = bnep_add_connection(&ca, nsock); 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!err) { 848e87d14255acffeee36873de226dc25c11b5f46dYOSHIFUJI Hideaki if (copy_to_user(argp, &ca, sizeof(ca))) 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = -EFAULT; 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 8767b23219ce2f78352b0c566a472ff16c1b0fea9aJulia Lawall sockfd_put(nsock); 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 908e87d14255acffeee36873de226dc25c11b5f46dYOSHIFUJI Hideaki 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case BNEPCONNDEL: 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!capable(CAP_NET_ADMIN)) 93bf5b30b8a4416de04f1ac1196281ddb318669464Zhao Hongjiang return -EPERM; 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_from_user(&cd, argp, sizeof(cd))) 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 978e87d14255acffeee36873de226dc25c11b5f46dYOSHIFUJI Hideaki 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return bnep_del_connection(&cd); 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case BNEPGETCONNLIST: 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_from_user(&cl, argp, sizeof(cl))) 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cl.cnum <= 0) 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 1068e87d14255acffeee36873de226dc25c11b5f46dYOSHIFUJI Hideaki 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = bnep_get_connlist(&cl); 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!err && copy_to_user(argp, &cl, sizeof(cl))) 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case BNEPGETCONNINFO: 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_from_user(&ci, argp, sizeof(ci))) 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = bnep_get_conninfo(&ci); 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!err && copy_to_user(argp, &ci, sizeof(ci))) 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 130e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann#ifdef CONFIG_COMPAT 131e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmannstatic int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 132e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann{ 133e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann if (cmd == BNEPGETCONNLIST) { 134e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann struct bnep_connlist_req cl; 135816a11d5ced501d368fabe09172f3d62744e8b53Johan Hedberg u32 uci; 136e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann int err; 137e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann 138816a11d5ced501d368fabe09172f3d62744e8b53Johan Hedberg if (get_user(cl.cnum, (u32 __user *) arg) || 139e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann get_user(uci, (u32 __user *) (arg + 4))) 140e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann return -EFAULT; 141e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann 142e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann cl.ci = compat_ptr(uci); 143e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann 144e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann if (cl.cnum <= 0) 145e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann return -EINVAL; 1468e87d14255acffeee36873de226dc25c11b5f46dYOSHIFUJI Hideaki 147e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann err = bnep_get_connlist(&cl); 148e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann 149816a11d5ced501d368fabe09172f3d62744e8b53Johan Hedberg if (!err && put_user(cl.cnum, (u32 __user *) arg)) 150e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann err = -EFAULT; 151e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann 152e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann return err; 153e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann } 154e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann 155e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann return bnep_sock_ioctl(sock, cmd, arg); 156e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann} 157e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann#endif 158e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann 15990ddc4f0470427df306f308ad03db6b6b21644b8Eric Dumazetstatic const struct proto_ops bnep_sock_ops = { 160e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .family = PF_BLUETOOTH, 161e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .owner = THIS_MODULE, 162e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .release = bnep_sock_release, 163e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .ioctl = bnep_sock_ioctl, 164e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann#ifdef CONFIG_COMPAT 165e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .compat_ioctl = bnep_sock_compat_ioctl, 166e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann#endif 167e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .bind = sock_no_bind, 168e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .getname = sock_no_getname, 169e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .sendmsg = sock_no_sendmsg, 170e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .recvmsg = sock_no_recvmsg, 171e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .poll = sock_no_poll, 172e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .listen = sock_no_listen, 173e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .shutdown = sock_no_shutdown, 174e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .setsockopt = sock_no_setsockopt, 175e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .getsockopt = sock_no_getsockopt, 176e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .connect = sock_no_connect, 177e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .socketpair = sock_no_socketpair, 178e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .accept = sock_no_accept, 179e9c5702e3c5558dade169949abd730173e87ef9cMarcel Holtmann .mmap = sock_no_mmap 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct proto bnep_proto = { 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "BNEP", 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .obj_size = sizeof(struct bt_sock) 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1883f378b684453f2a028eda463ce383370545d9cc9Eric Parisstatic int bnep_sock_create(struct net *net, struct socket *sock, int protocol, 1893f378b684453f2a028eda463ce383370545d9cc9Eric Paris int kern) 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sock *sk; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BT_DBG("sock %p", sock); 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sock->type != SOCK_RAW) 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ESOCKTNOSUPPORT; 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1986257ff2177ff02d7f260a7a501876aa41cb9a9f6Pavel Emelyanov sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto); 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!sk) 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sock_init_data(sock, sk); 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sock->ops = &bnep_sock_ops; 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sock->state = SS_UNCONNECTED; 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sock_reset_flag(sk, SOCK_ZAPPED); 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sk->sk_protocol = protocol; 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sk->sk_state = BT_OPEN; 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21377cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO bt_sock_link(&bnep_sk_list, sk); 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 217ec1b4cf74c81bfd0fbe5bf62bafc86c45917e72fStephen Hemmingerstatic const struct net_proto_family bnep_sock_family_ops = { 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .family = PF_BLUETOOTH, 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .create = bnep_sock_create 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint __init bnep_sock_init(void) 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = proto_register(&bnep_proto, 0); 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err < 0) 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = bt_sock_register(BTPROTO_BNEP, &bnep_sock_family_ops); 23277cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO if (err < 0) { 23377cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO BT_ERR("Can't register BNEP socket"); 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto error; 23577cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO } 23677cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO 237b03166152f6da91cec8b66837b309dd3923ea536Al Viro err = bt_procfs_init(&init_net, "bnep", &bnep_sk_list, NULL); 23877cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO if (err < 0) { 23977cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO BT_ERR("Failed to create BNEP proc file"); 24077cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO bt_sock_unregister(BTPROTO_BNEP); 24177cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO goto error; 24277cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO } 24377cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO 24477cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO BT_INFO("BNEP socket layer initialized"); 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldserror: 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds proto_unregister(&bnep_proto); 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 253a4e2acf01a7e5fcd960fc332335ca10313641f4bTobias Klauservoid __exit bnep_sock_cleanup(void) 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 25577cf5585a31fdad48c16ddae9be154f5afe22c1cMasatake YAMATO bt_procfs_cleanup(&init_net, "bnep"); 2565e9d7f868f04106139a58212b860dcdc268ad3afDavid Herrmann bt_sock_unregister(BTPROTO_BNEP); 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds proto_unregister(&bnep_proto); 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 259