Phonet: deliver broadcast packets to broadcast sockets
[linux-2.6.git] / net / phonet / socket.c
1 /*
2  * File: socket.c
3  *
4  * Phonet sockets
5  *
6  * Copyright (C) 2008 Nokia Corporation.
7  *
8  * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
9  * Original author: Sakari Ailus <sakari.ailus@nokia.com>
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * version 2 as published by the Free Software Foundation.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23  * 02110-1301 USA
24  */
25
26 #include <linux/kernel.h>
27 #include <linux/net.h>
28 #include <linux/poll.h>
29 #include <net/sock.h>
30 #include <net/tcp_states.h>
31
32 #include <linux/phonet.h>
33 #include <net/phonet/phonet.h>
34 #include <net/phonet/pep.h>
35 #include <net/phonet/pn_dev.h>
36
37 static int pn_socket_release(struct socket *sock)
38 {
39         struct sock *sk = sock->sk;
40
41         if (sk) {
42                 sock->sk = NULL;
43                 sk->sk_prot->close(sk, 0);
44         }
45         return 0;
46 }
47
48 static struct  {
49         struct hlist_head hlist;
50         spinlock_t lock;
51 } pnsocks = {
52         .hlist = HLIST_HEAD_INIT,
53         .lock = __SPIN_LOCK_UNLOCKED(pnsocks.lock),
54 };
55
56 /*
57  * Find address based on socket address, match only certain fields.
58  * Also grab sock if it was found. Remember to sock_put it later.
59  */
60 struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *spn)
61 {
62         struct hlist_node *node;
63         struct sock *sknode;
64         struct sock *rval = NULL;
65         u16 obj = pn_sockaddr_get_object(spn);
66         u8 res = spn->spn_resource;
67
68         spin_lock_bh(&pnsocks.lock);
69
70         sk_for_each(sknode, node, &pnsocks.hlist) {
71                 struct pn_sock *pn = pn_sk(sknode);
72                 BUG_ON(!pn->sobject); /* unbound socket */
73
74                 if (!net_eq(sock_net(sknode), net))
75                         continue;
76                 if (pn_port(obj)) {
77                         /* Look up socket by port */
78                         if (pn_port(pn->sobject) != pn_port(obj))
79                                 continue;
80                 } else {
81                         /* If port is zero, look up by resource */
82                         if (pn->resource != res)
83                                 continue;
84                 }
85                 if (pn_addr(pn->sobject)
86                  && pn_addr(pn->sobject) != pn_addr(obj))
87                         continue;
88
89                 rval = sknode;
90                 sock_hold(sknode);
91                 break;
92         }
93
94         spin_unlock_bh(&pnsocks.lock);
95
96         return rval;
97 }
98
99 /* Deliver a broadcast packet (only in bottom-half) */
100 void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb)
101 {
102         struct hlist_node *node;
103         struct sock *sknode;
104
105         spin_lock(&pnsocks.lock);
106         sk_for_each(sknode, node, &pnsocks.hlist) {
107                 struct sk_buff *clone;
108
109                 if (!net_eq(sock_net(sknode), net))
110                         continue;
111                 if (!sock_flag(sknode, SOCK_BROADCAST))
112                         continue;
113
114                 clone = skb_clone(skb, GFP_ATOMIC);
115                 if (clone)
116                         sk_receive_skb(sknode, clone, 0);
117         }
118         spin_unlock(&pnsocks.lock);
119 }
120
121 void pn_sock_hash(struct sock *sk)
122 {
123         spin_lock_bh(&pnsocks.lock);
124         sk_add_node(sk, &pnsocks.hlist);
125         spin_unlock_bh(&pnsocks.lock);
126 }
127 EXPORT_SYMBOL(pn_sock_hash);
128
129 void pn_sock_unhash(struct sock *sk)
130 {
131         spin_lock_bh(&pnsocks.lock);
132         sk_del_node_init(sk);
133         spin_unlock_bh(&pnsocks.lock);
134 }
135 EXPORT_SYMBOL(pn_sock_unhash);
136
137 static DEFINE_MUTEX(port_mutex);
138
139 static int pn_socket_bind(struct socket *sock, struct sockaddr *addr, int len)
140 {
141         struct sock *sk = sock->sk;
142         struct pn_sock *pn = pn_sk(sk);
143         struct sockaddr_pn *spn = (struct sockaddr_pn *)addr;
144         int err;
145         u16 handle;
146         u8 saddr;
147
148         if (sk->sk_prot->bind)
149                 return sk->sk_prot->bind(sk, addr, len);
150
151         if (len < sizeof(struct sockaddr_pn))
152                 return -EINVAL;
153         if (spn->spn_family != AF_PHONET)
154                 return -EAFNOSUPPORT;
155
156         handle = pn_sockaddr_get_object((struct sockaddr_pn *)addr);
157         saddr = pn_addr(handle);
158         if (saddr && phonet_address_lookup(sock_net(sk), saddr))
159                 return -EADDRNOTAVAIL;
160
161         lock_sock(sk);
162         if (sk->sk_state != TCP_CLOSE || pn_port(pn->sobject)) {
163                 err = -EINVAL; /* attempt to rebind */
164                 goto out;
165         }
166         WARN_ON(sk_hashed(sk));
167         mutex_lock(&port_mutex);
168         err = sk->sk_prot->get_port(sk, pn_port(handle));
169         if (err)
170                 goto out_port;
171
172         /* get_port() sets the port, bind() sets the address if applicable */
173         pn->sobject = pn_object(saddr, pn_port(pn->sobject));
174         pn->resource = spn->spn_resource;
175
176         /* Enable RX on the socket */
177         sk->sk_prot->hash(sk);
178 out_port:
179         mutex_unlock(&port_mutex);
180 out:
181         release_sock(sk);
182         return err;
183 }
184
185 static int pn_socket_autobind(struct socket *sock)
186 {
187         struct sockaddr_pn sa;
188         int err;
189
190         memset(&sa, 0, sizeof(sa));
191         sa.spn_family = AF_PHONET;
192         err = pn_socket_bind(sock, (struct sockaddr *)&sa,
193                                 sizeof(struct sockaddr_pn));
194         if (err != -EINVAL)
195                 return err;
196         BUG_ON(!pn_port(pn_sk(sock->sk)->sobject));
197         return 0; /* socket was already bound */
198 }
199
200 static int pn_socket_accept(struct socket *sock, struct socket *newsock,
201                                 int flags)
202 {
203         struct sock *sk = sock->sk;
204         struct sock *newsk;
205         int err;
206
207         newsk = sk->sk_prot->accept(sk, flags, &err);
208         if (!newsk)
209                 return err;
210
211         lock_sock(newsk);
212         sock_graft(newsk, newsock);
213         newsock->state = SS_CONNECTED;
214         release_sock(newsk);
215         return 0;
216 }
217
218 static int pn_socket_getname(struct socket *sock, struct sockaddr *addr,
219                                 int *sockaddr_len, int peer)
220 {
221         struct sock *sk = sock->sk;
222         struct pn_sock *pn = pn_sk(sk);
223
224         memset(addr, 0, sizeof(struct sockaddr_pn));
225         addr->sa_family = AF_PHONET;
226         if (!peer) /* Race with bind() here is userland's problem. */
227                 pn_sockaddr_set_object((struct sockaddr_pn *)addr,
228                                         pn->sobject);
229
230         *sockaddr_len = sizeof(struct sockaddr_pn);
231         return 0;
232 }
233
234 static unsigned int pn_socket_poll(struct file *file, struct socket *sock,
235                                         poll_table *wait)
236 {
237         struct sock *sk = sock->sk;
238         struct pep_sock *pn = pep_sk(sk);
239         unsigned int mask = 0;
240
241         poll_wait(file, &sock->wait, wait);
242
243         switch (sk->sk_state) {
244         case TCP_LISTEN:
245                 return hlist_empty(&pn->ackq) ? 0 : POLLIN;
246         case TCP_CLOSE:
247                 return POLLERR;
248         }
249
250         if (!skb_queue_empty(&sk->sk_receive_queue))
251                 mask |= POLLIN | POLLRDNORM;
252         if (!skb_queue_empty(&pn->ctrlreq_queue))
253                 mask |= POLLPRI;
254         if (!mask && sk->sk_state == TCP_CLOSE_WAIT)
255                 return POLLHUP;
256
257         if (sk->sk_state == TCP_ESTABLISHED && atomic_read(&pn->tx_credits))
258                 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
259
260         return mask;
261 }
262
263 static int pn_socket_ioctl(struct socket *sock, unsigned int cmd,
264                                 unsigned long arg)
265 {
266         struct sock *sk = sock->sk;
267         struct pn_sock *pn = pn_sk(sk);
268
269         if (cmd == SIOCPNGETOBJECT) {
270                 struct net_device *dev;
271                 u16 handle;
272                 u8 saddr;
273
274                 if (get_user(handle, (__u16 __user *)arg))
275                         return -EFAULT;
276
277                 lock_sock(sk);
278                 if (sk->sk_bound_dev_if)
279                         dev = dev_get_by_index(sock_net(sk),
280                                                 sk->sk_bound_dev_if);
281                 else
282                         dev = phonet_device_get(sock_net(sk));
283                 if (dev && (dev->flags & IFF_UP))
284                         saddr = phonet_address_get(dev, pn_addr(handle));
285                 else
286                         saddr = PN_NO_ADDR;
287                 release_sock(sk);
288
289                 if (dev)
290                         dev_put(dev);
291                 if (saddr == PN_NO_ADDR)
292                         return -EHOSTUNREACH;
293
294                 handle = pn_object(saddr, pn_port(pn->sobject));
295                 return put_user(handle, (__u16 __user *)arg);
296         }
297
298         return sk->sk_prot->ioctl(sk, cmd, arg);
299 }
300
301 static int pn_socket_listen(struct socket *sock, int backlog)
302 {
303         struct sock *sk = sock->sk;
304         int err = 0;
305
306         if (sock->state != SS_UNCONNECTED)
307                 return -EINVAL;
308         if (pn_socket_autobind(sock))
309                 return -ENOBUFS;
310
311         lock_sock(sk);
312         if (sk->sk_state != TCP_CLOSE) {
313                 err = -EINVAL;
314                 goto out;
315         }
316
317         sk->sk_state = TCP_LISTEN;
318         sk->sk_ack_backlog = 0;
319         sk->sk_max_ack_backlog = backlog;
320 out:
321         release_sock(sk);
322         return err;
323 }
324
325 static int pn_socket_sendmsg(struct kiocb *iocb, struct socket *sock,
326                                 struct msghdr *m, size_t total_len)
327 {
328         struct sock *sk = sock->sk;
329
330         if (pn_socket_autobind(sock))
331                 return -EAGAIN;
332
333         return sk->sk_prot->sendmsg(iocb, sk, m, total_len);
334 }
335
336 const struct proto_ops phonet_dgram_ops = {
337         .family         = AF_PHONET,
338         .owner          = THIS_MODULE,
339         .release        = pn_socket_release,
340         .bind           = pn_socket_bind,
341         .connect        = sock_no_connect,
342         .socketpair     = sock_no_socketpair,
343         .accept         = sock_no_accept,
344         .getname        = pn_socket_getname,
345         .poll           = datagram_poll,
346         .ioctl          = pn_socket_ioctl,
347         .listen         = sock_no_listen,
348         .shutdown       = sock_no_shutdown,
349         .setsockopt     = sock_no_setsockopt,
350         .getsockopt     = sock_no_getsockopt,
351 #ifdef CONFIG_COMPAT
352         .compat_setsockopt = sock_no_setsockopt,
353         .compat_getsockopt = sock_no_getsockopt,
354 #endif
355         .sendmsg        = pn_socket_sendmsg,
356         .recvmsg        = sock_common_recvmsg,
357         .mmap           = sock_no_mmap,
358         .sendpage       = sock_no_sendpage,
359 };
360
361 const struct proto_ops phonet_stream_ops = {
362         .family         = AF_PHONET,
363         .owner          = THIS_MODULE,
364         .release        = pn_socket_release,
365         .bind           = pn_socket_bind,
366         .connect        = sock_no_connect,
367         .socketpair     = sock_no_socketpair,
368         .accept         = pn_socket_accept,
369         .getname        = pn_socket_getname,
370         .poll           = pn_socket_poll,
371         .ioctl          = pn_socket_ioctl,
372         .listen         = pn_socket_listen,
373         .shutdown       = sock_no_shutdown,
374         .setsockopt     = sock_common_setsockopt,
375         .getsockopt     = sock_common_getsockopt,
376 #ifdef CONFIG_COMPAT
377         .compat_setsockopt = compat_sock_common_setsockopt,
378         .compat_getsockopt = compat_sock_common_getsockopt,
379 #endif
380         .sendmsg        = pn_socket_sendmsg,
381         .recvmsg        = sock_common_recvmsg,
382         .mmap           = sock_no_mmap,
383         .sendpage       = sock_no_sendpage,
384 };
385 EXPORT_SYMBOL(phonet_stream_ops);
386
387 /* allocate port for a socket */
388 int pn_sock_get_port(struct sock *sk, unsigned short sport)
389 {
390         static int port_cur;
391         struct net *net = sock_net(sk);
392         struct pn_sock *pn = pn_sk(sk);
393         struct sockaddr_pn try_sa;
394         struct sock *tmpsk;
395
396         memset(&try_sa, 0, sizeof(struct sockaddr_pn));
397         try_sa.spn_family = AF_PHONET;
398         WARN_ON(!mutex_is_locked(&port_mutex));
399         if (!sport) {
400                 /* search free port */
401                 int port, pmin, pmax;
402
403                 phonet_get_local_port_range(&pmin, &pmax);
404                 for (port = pmin; port <= pmax; port++) {
405                         port_cur++;
406                         if (port_cur < pmin || port_cur > pmax)
407                                 port_cur = pmin;
408
409                         pn_sockaddr_set_port(&try_sa, port_cur);
410                         tmpsk = pn_find_sock_by_sa(net, &try_sa);
411                         if (tmpsk == NULL) {
412                                 sport = port_cur;
413                                 goto found;
414                         } else
415                                 sock_put(tmpsk);
416                 }
417         } else {
418                 /* try to find specific port */
419                 pn_sockaddr_set_port(&try_sa, sport);
420                 tmpsk = pn_find_sock_by_sa(net, &try_sa);
421                 if (tmpsk == NULL)
422                         /* No sock there! We can use that port... */
423                         goto found;
424                 else
425                         sock_put(tmpsk);
426         }
427         /* the port must be in use already */
428         return -EADDRINUSE;
429
430 found:
431         pn->sobject = pn_object(pn_addr(pn->sobject), sport);
432         return 0;
433 }
434 EXPORT_SYMBOL(pn_sock_get_port);
435
436 #ifdef CONFIG_PROC_FS
437 static struct sock *pn_sock_get_idx(struct seq_file *seq, loff_t pos)
438 {
439         struct net *net = seq_file_net(seq);
440         struct hlist_node *node;
441         struct sock *sknode;
442
443         sk_for_each(sknode, node, &pnsocks.hlist) {
444                 if (!net_eq(net, sock_net(sknode)))
445                         continue;
446                 if (!pos)
447                         return sknode;
448                 pos--;
449         }
450         return NULL;
451 }
452
453 static struct sock *pn_sock_get_next(struct seq_file *seq, struct sock *sk)
454 {
455         struct net *net = seq_file_net(seq);
456
457         do
458                 sk = sk_next(sk);
459         while (sk && !net_eq(net, sock_net(sk)));
460
461         return sk;
462 }
463
464 static void *pn_sock_seq_start(struct seq_file *seq, loff_t *pos)
465         __acquires(pnsocks.lock)
466 {
467         spin_lock_bh(&pnsocks.lock);
468         return *pos ? pn_sock_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
469 }
470
471 static void *pn_sock_seq_next(struct seq_file *seq, void *v, loff_t *pos)
472 {
473         struct sock *sk;
474
475         if (v == SEQ_START_TOKEN)
476                 sk = pn_sock_get_idx(seq, 0);
477         else
478                 sk = pn_sock_get_next(seq, v);
479         (*pos)++;
480         return sk;
481 }
482
483 static void pn_sock_seq_stop(struct seq_file *seq, void *v)
484         __releases(pnsocks.lock)
485 {
486         spin_unlock_bh(&pnsocks.lock);
487 }
488
489 static int pn_sock_seq_show(struct seq_file *seq, void *v)
490 {
491         int len;
492
493         if (v == SEQ_START_TOKEN)
494                 seq_printf(seq, "%s%n", "pt  loc  rem rs st tx_queue rx_queue "
495                         "  uid inode ref pointer drops", &len);
496         else {
497                 struct sock *sk = v;
498                 struct pn_sock *pn = pn_sk(sk);
499
500                 seq_printf(seq, "%2d %04X:%04X:%02X %02X %08X:%08X %5d %lu "
501                         "%d %p %d%n",
502                         sk->sk_protocol, pn->sobject, 0, pn->resource,
503                         sk->sk_state,
504                         sk_wmem_alloc_get(sk), sk_rmem_alloc_get(sk),
505                         sock_i_uid(sk), sock_i_ino(sk),
506                         atomic_read(&sk->sk_refcnt), sk,
507                         atomic_read(&sk->sk_drops), &len);
508         }
509         seq_printf(seq, "%*s\n", 127 - len, "");
510         return 0;
511 }
512
513 static const struct seq_operations pn_sock_seq_ops = {
514         .start = pn_sock_seq_start,
515         .next = pn_sock_seq_next,
516         .stop = pn_sock_seq_stop,
517         .show = pn_sock_seq_show,
518 };
519
520 static int pn_sock_open(struct inode *inode, struct file *file)
521 {
522         return seq_open_net(inode, file, &pn_sock_seq_ops,
523                                 sizeof(struct seq_net_private));
524 }
525
526 const struct file_operations pn_sock_seq_fops = {
527         .owner = THIS_MODULE,
528         .open = pn_sock_open,
529         .read = seq_read,
530         .llseek = seq_lseek,
531         .release = seq_release_net,
532 };
533 #endif