~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/bluetooth/bnep/sock.c

Version: ~ [ linux-5.11 ] ~ [ linux-5.10.17 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.99 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.176 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.221 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.257 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.257 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp