This source file includes following definitions.
- bnep_sock_release
- do_bnep_sock_ioctl
- bnep_sock_ioctl
- bnep_sock_compat_ioctl
- bnep_sock_create
- bnep_sock_init
- bnep_sock_cleanup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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 do_bnep_sock_ioctl(struct socket *sock, unsigned int cmd, void __user *argp)
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 __u32 supp_feat = BIT(BNEP_SETUP_RESPONSE);
60 int err;
61
62 BT_DBG("cmd %x arg %p", cmd, argp);
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 case BNEPGETSUPPFEAT:
124 if (copy_to_user(argp, &supp_feat, sizeof(supp_feat)))
125 return -EFAULT;
126
127 return 0;
128
129 default:
130 return -EINVAL;
131 }
132
133 return 0;
134 }
135
136 static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
137 {
138 return do_bnep_sock_ioctl(sock, cmd, (void __user *)arg);
139 }
140
141 #ifdef CONFIG_COMPAT
142 static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
143 {
144 void __user *argp = compat_ptr(arg);
145 if (cmd == BNEPGETCONNLIST) {
146 struct bnep_connlist_req cl;
147 unsigned __user *p = argp;
148 u32 uci;
149 int err;
150
151 if (get_user(cl.cnum, p) || get_user(uci, p + 1))
152 return -EFAULT;
153
154 cl.ci = compat_ptr(uci);
155
156 if (cl.cnum <= 0)
157 return -EINVAL;
158
159 err = bnep_get_connlist(&cl);
160
161 if (!err && put_user(cl.cnum, p))
162 err = -EFAULT;
163
164 return err;
165 }
166
167 return do_bnep_sock_ioctl(sock, cmd, argp);
168 }
169 #endif
170
171 static const struct proto_ops bnep_sock_ops = {
172 .family = PF_BLUETOOTH,
173 .owner = THIS_MODULE,
174 .release = bnep_sock_release,
175 .ioctl = bnep_sock_ioctl,
176 #ifdef CONFIG_COMPAT
177 .compat_ioctl = bnep_sock_compat_ioctl,
178 #endif
179 .bind = sock_no_bind,
180 .getname = sock_no_getname,
181 .sendmsg = sock_no_sendmsg,
182 .recvmsg = sock_no_recvmsg,
183 .listen = sock_no_listen,
184 .shutdown = sock_no_shutdown,
185 .setsockopt = sock_no_setsockopt,
186 .getsockopt = sock_no_getsockopt,
187 .connect = sock_no_connect,
188 .socketpair = sock_no_socketpair,
189 .accept = sock_no_accept,
190 .mmap = sock_no_mmap
191 };
192
193 static struct proto bnep_proto = {
194 .name = "BNEP",
195 .owner = THIS_MODULE,
196 .obj_size = sizeof(struct bt_sock)
197 };
198
199 static int bnep_sock_create(struct net *net, struct socket *sock, int protocol,
200 int kern)
201 {
202 struct sock *sk;
203
204 BT_DBG("sock %p", sock);
205
206 if (sock->type != SOCK_RAW)
207 return -ESOCKTNOSUPPORT;
208
209 sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, kern);
210 if (!sk)
211 return -ENOMEM;
212
213 sock_init_data(sock, sk);
214
215 sock->ops = &bnep_sock_ops;
216
217 sock->state = SS_UNCONNECTED;
218
219 sock_reset_flag(sk, SOCK_ZAPPED);
220
221 sk->sk_protocol = protocol;
222 sk->sk_state = BT_OPEN;
223
224 bt_sock_link(&bnep_sk_list, sk);
225 return 0;
226 }
227
228 static const struct net_proto_family bnep_sock_family_ops = {
229 .family = PF_BLUETOOTH,
230 .owner = THIS_MODULE,
231 .create = bnep_sock_create
232 };
233
234 int __init bnep_sock_init(void)
235 {
236 int err;
237
238 err = proto_register(&bnep_proto, 0);
239 if (err < 0)
240 return err;
241
242 err = bt_sock_register(BTPROTO_BNEP, &bnep_sock_family_ops);
243 if (err < 0) {
244 BT_ERR("Can't register BNEP socket");
245 goto error;
246 }
247
248 err = bt_procfs_init(&init_net, "bnep", &bnep_sk_list, NULL);
249 if (err < 0) {
250 BT_ERR("Failed to create BNEP proc file");
251 bt_sock_unregister(BTPROTO_BNEP);
252 goto error;
253 }
254
255 BT_INFO("BNEP socket layer initialized");
256
257 return 0;
258
259 error:
260 proto_unregister(&bnep_proto);
261 return err;
262 }
263
264 void __exit bnep_sock_cleanup(void)
265 {
266 bt_procfs_cleanup(&init_net, "bnep");
267 bt_sock_unregister(BTPROTO_BNEP);
268 proto_unregister(&bnep_proto);
269 }