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/gfp.h> 27 #include <linux/kernel.h> 28 #include <linux/net.h> 29 #include <linux/poll.h> 30 #include <net/sock.h> 31 #include <net/tcp_states.h> 32 33 #include <linux/phonet.h> 34 #include <net/phonet/phonet.h> 35 #include <net/phonet/pep.h> 36 #include <net/phonet/pn_dev.h> 37 38 static int pn_socket_release(struct socket *sock) 39 { 40 struct sock *sk = sock->sk; 41 42 if (sk) { 43 sock->sk = NULL; 44 sk->sk_prot->close(sk, 0); 45 } 46 return 0; 47 } 48 49 #define PN_HASHSIZE 16 50 #define PN_HASHMASK (PN_HASHSIZE-1) 51 52 53 static struct { 54 struct hlist_head hlist[PN_HASHSIZE]; 55 struct mutex lock; 56 } pnsocks; 57 58 void __init pn_sock_init(void) 59 { 60 unsigned i; 61 62 for (i = 0; i < PN_HASHSIZE; i++) 63 INIT_HLIST_HEAD(pnsocks.hlist + i); 64 mutex_init(&pnsocks.lock); 65 } 66 67 static struct hlist_head *pn_hash_list(u16 obj) 68 { 69 return pnsocks.hlist + (obj & PN_HASHMASK); 70 } 71 72 /* 73 * Find address based on socket address, match only certain fields. 74 * Also grab sock if it was found. Remember to sock_put it later. 75 */ 76 struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *spn) 77 { 78 struct hlist_node *node; 79 struct sock *sknode; 80 struct sock *rval = NULL; 81 u16 obj = pn_sockaddr_get_object(spn); 82 u8 res = spn->spn_resource; 83 struct hlist_head *hlist = pn_hash_list(obj); 84 85 rcu_read_lock(); 86 sk_for_each_rcu(sknode, node, hlist) { 87 struct pn_sock *pn = pn_sk(sknode); 88 BUG_ON(!pn->sobject); /* unbound socket */ 89 90 if (!net_eq(sock_net(sknode), net)) 91 continue; 92 if (pn_port(obj)) { 93 /* Look up socket by port */ 94 if (pn_port(pn->sobject) != pn_port(obj)) 95 continue; 96 } else { 97 /* If port is zero, look up by resource */ 98 if (pn->resource != res) 99 continue; 100 } 101 if (pn_addr(pn->sobject) && 102 pn_addr(pn->sobject) != pn_addr(obj)) 103 continue; 104 105 rval = sknode; 106 sock_hold(sknode); 107 break; 108 } 109 rcu_read_unlock(); 110 111 return rval; 112 } 113 114 /* Deliver a broadcast packet (only in bottom-half) */ 115 void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb) 116 { 117 struct hlist_head *hlist = pnsocks.hlist; 118 unsigned h; 119 120 rcu_read_lock(); 121 for (h = 0; h < PN_HASHSIZE; h++) { 122 struct hlist_node *node; 123 struct sock *sknode; 124 125 sk_for_each(sknode, node, hlist) { 126 struct sk_buff *clone; 127 128 if (!net_eq(sock_net(sknode), net)) 129 continue; 130 if (!sock_flag(sknode, SOCK_BROADCAST)) 131 continue; 132 133 clone = skb_clone(skb, GFP_ATOMIC); 134 if (clone) { 135 sock_hold(sknode); 136 sk_receive_skb(sknode, clone, 0); 137 } 138 } 139 hlist++; 140 } 141 rcu_read_unlock(); 142 } 143 144 void pn_sock_hash(struct sock *sk) 145 { 146 struct hlist_head *hlist = pn_hash_list(pn_sk(sk)->sobject); 147 148 mutex_lock(&pnsocks.lock); 149 sk_add_node_rcu(sk, hlist); 150 mutex_unlock(&pnsocks.lock); 151 } 152 EXPORT_SYMBOL(pn_sock_hash); 153 154 void pn_sock_unhash(struct sock *sk) 155 { 156 mutex_lock(&pnsocks.lock); 157 sk_del_node_init_rcu(sk); 158 mutex_unlock(&pnsocks.lock); 159 pn_sock_unbind_all_res(sk); 160 synchronize_rcu(); 161 } 162 EXPORT_SYMBOL(pn_sock_unhash); 163 164 static DEFINE_MUTEX(port_mutex); 165 166 static int pn_socket_bind(struct socket *sock, struct sockaddr *addr, int len) 167 { 168 struct sock *sk = sock->sk; 169 struct pn_sock *pn = pn_sk(sk); 170 struct sockaddr_pn *spn = (struct sockaddr_pn *)addr; 171 int err; 172 u16 handle; 173 u8 saddr; 174 175 if (sk->sk_prot->bind) 176 return sk->sk_prot->bind(sk, addr, len); 177 178 if (len < sizeof(struct sockaddr_pn)) 179 return -EINVAL; 180 if (spn->spn_family != AF_PHONET) 181 return -EAFNOSUPPORT; 182 183 handle = pn_sockaddr_get_object((struct sockaddr_pn *)addr); 184 saddr = pn_addr(handle); 185 if (saddr && phonet_address_lookup(sock_net(sk), saddr)) 186 return -EADDRNOTAVAIL; 187 188 lock_sock(sk); 189 if (sk->sk_state != TCP_CLOSE || pn_port(pn->sobject)) { 190 err = -EINVAL; /* attempt to rebind */ 191 goto out; 192 } 193 WARN_ON(sk_hashed(sk)); 194 mutex_lock(&port_mutex); 195 err = sk->sk_prot->get_port(sk, pn_port(handle)); 196 if (err) 197 goto out_port; 198 199 /* get_port() sets the port, bind() sets the address if applicable */ 200 pn->sobject = pn_object(saddr, pn_port(pn->sobject)); 201 pn->resource = spn->spn_resource; 202 203 /* Enable RX on the socket */ 204 sk->sk_prot->hash(sk); 205 out_port: 206 mutex_unlock(&port_mutex); 207 out: 208 release_sock(sk); 209 return err; 210 } 211 212 static int pn_socket_autobind(struct socket *sock) 213 { 214 struct sockaddr_pn sa; 215 int err; 216 217 memset(&sa, 0, sizeof(sa)); 218 sa.spn_family = AF_PHONET; 219 err = pn_socket_bind(sock, (struct sockaddr *)&sa, 220 sizeof(struct sockaddr_pn)); 221 if (err != -EINVAL) 222 return err; 223 BUG_ON(!pn_port(pn_sk(sock->sk)->sobject)); 224 return 0; /* socket was already bound */ 225 } 226 227 static int pn_socket_connect(struct socket *sock, struct sockaddr *addr, 228 int len, int flags) 229 { 230 struct sock *sk = sock->sk; 231 struct pn_sock *pn = pn_sk(sk); 232 struct sockaddr_pn *spn = (struct sockaddr_pn *)addr; 233 struct task_struct *tsk = current; 234 long timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); 235 int err; 236 237 if (pn_socket_autobind(sock)) 238 return -ENOBUFS; 239 if (len < sizeof(struct sockaddr_pn)) 240 return -EINVAL; 241 if (spn->spn_family != AF_PHONET) 242 return -EAFNOSUPPORT; 243 244 lock_sock(sk); 245 246 switch (sock->state) { 247 case SS_UNCONNECTED: 248 if (sk->sk_state != TCP_CLOSE) { 249 err = -EISCONN; 250 goto out; 251 } 252 break; 253 case SS_CONNECTING: 254 err = -EALREADY; 255 goto out; 256 default: 257 err = -EISCONN; 258 goto out; 259 } 260 261 pn->dobject = pn_sockaddr_get_object(spn); 262 pn->resource = pn_sockaddr_get_resource(spn); 263 sock->state = SS_CONNECTING; 264 265 err = sk->sk_prot->connect(sk, addr, len); 266 if (err) { 267 sock->state = SS_UNCONNECTED; 268 pn->dobject = 0; 269 goto out; 270 } 271 272 while (sk->sk_state == TCP_SYN_SENT) { 273 DEFINE_WAIT(wait); 274 275 if (!timeo) { 276 err = -EINPROGRESS; 277 goto out; 278 } 279 if (signal_pending(tsk)) { 280 err = sock_intr_errno(timeo); 281 goto out; 282 } 283 284 prepare_to_wait_exclusive(sk_sleep(sk), &wait, 285 TASK_INTERRUPTIBLE); 286 release_sock(sk); 287 timeo = schedule_timeout(timeo); 288 lock_sock(sk); 289 finish_wait(sk_sleep(sk), &wait); 290 } 291 292 if ((1 << sk->sk_state) & (TCPF_SYN_RECV|TCPF_ESTABLISHED)) 293 err = 0; 294 else if (sk->sk_state == TCP_CLOSE_WAIT) 295 err = -ECONNRESET; 296 else 297 err = -ECONNREFUSED; 298 sock->state = err ? SS_UNCONNECTED : SS_CONNECTED; 299 out: 300 release_sock(sk); 301 return err; 302 } 303 304 static int pn_socket_accept(struct socket *sock, struct socket *newsock, 305 int flags) 306 { 307 struct sock *sk = sock->sk; 308 struct sock *newsk; 309 int err; 310 311 if (unlikely(sk->sk_state != TCP_LISTEN)) 312 return -EINVAL; 313 314 newsk = sk->sk_prot->accept(sk, flags, &err); 315 if (!newsk) 316 return err; 317 318 lock_sock(newsk); 319 sock_graft(newsk, newsock); 320 newsock->state = SS_CONNECTED; 321 release_sock(newsk); 322 return 0; 323 } 324 325 static int pn_socket_getname(struct socket *sock, struct sockaddr *addr, 326 int *sockaddr_len, int peer) 327 { 328 struct sock *sk = sock->sk; 329 struct pn_sock *pn = pn_sk(sk); 330 331 memset(addr, 0, sizeof(struct sockaddr_pn)); 332 addr->sa_family = AF_PHONET; 333 if (!peer) /* Race with bind() here is userland's problem. */ 334 pn_sockaddr_set_object((struct sockaddr_pn *)addr, 335 pn->sobject); 336 337 *sockaddr_len = sizeof(struct sockaddr_pn); 338 return 0; 339 } 340 341 static unsigned int pn_socket_poll(struct file *file, struct socket *sock, 342 poll_table *wait) 343 { 344 struct sock *sk = sock->sk; 345 struct pep_sock *pn = pep_sk(sk); 346 unsigned int mask = 0; 347 348 poll_wait(file, sk_sleep(sk), wait); 349 350 if (sk->sk_state == TCP_CLOSE) 351 return POLLERR; 352 if (!skb_queue_empty(&sk->sk_receive_queue)) 353 mask |= POLLIN | POLLRDNORM; 354 if (!skb_queue_empty(&pn->ctrlreq_queue)) 355 mask |= POLLPRI; 356 if (!mask && sk->sk_state == TCP_CLOSE_WAIT) 357 return POLLHUP; 358 359 if (sk->sk_state == TCP_ESTABLISHED && 360 atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf && 361 atomic_read(&pn->tx_credits)) 362 mask |= POLLOUT | POLLWRNORM | POLLWRBAND; 363 364 return mask; 365 } 366 367 static int pn_socket_ioctl(struct socket *sock, unsigned int cmd, 368 unsigned long arg) 369 { 370 struct sock *sk = sock->sk; 371 struct pn_sock *pn = pn_sk(sk); 372 373 if (cmd == SIOCPNGETOBJECT) { 374 struct net_device *dev; 375 u16 handle; 376 u8 saddr; 377 378 if (get_user(handle, (__u16 __user *)arg)) 379 return -EFAULT; 380 381 lock_sock(sk); 382 if (sk->sk_bound_dev_if) 383 dev = dev_get_by_index(sock_net(sk), 384 sk->sk_bound_dev_if); 385 else 386 dev = phonet_device_get(sock_net(sk)); 387 if (dev && (dev->flags & IFF_UP)) 388 saddr = phonet_address_get(dev, pn_addr(handle)); 389 else 390 saddr = PN_NO_ADDR; 391 release_sock(sk); 392 393 if (dev) 394 dev_put(dev); 395 if (saddr == PN_NO_ADDR) 396 return -EHOSTUNREACH; 397 398 handle = pn_object(saddr, pn_port(pn->sobject)); 399 return put_user(handle, (__u16 __user *)arg); 400 } 401 402 return sk->sk_prot->ioctl(sk, cmd, arg); 403 } 404 405 static int pn_socket_listen(struct socket *sock, int backlog) 406 { 407 struct sock *sk = sock->sk; 408 int err = 0; 409 410 if (pn_socket_autobind(sock)) 411 return -ENOBUFS; 412 413 lock_sock(sk); 414 if (sock->state != SS_UNCONNECTED) { 415 err = -EINVAL; 416 goto out; 417 } 418 419 if (sk->sk_state != TCP_LISTEN) { 420 sk->sk_state = TCP_LISTEN; 421 sk->sk_ack_backlog = 0; 422 } 423 sk->sk_max_ack_backlog = backlog; 424 out: 425 release_sock(sk); 426 return err; 427 } 428 429 static int pn_socket_sendmsg(struct kiocb *iocb, struct socket *sock, 430 struct msghdr *m, size_t total_len) 431 { 432 struct sock *sk = sock->sk; 433 434 if (pn_socket_autobind(sock)) 435 return -EAGAIN; 436 437 return sk->sk_prot->sendmsg(iocb, sk, m, total_len); 438 } 439 440 const struct proto_ops phonet_dgram_ops = { 441 .family = AF_PHONET, 442 .owner = THIS_MODULE, 443 .release = pn_socket_release, 444 .bind = pn_socket_bind, 445 .connect = sock_no_connect, 446 .socketpair = sock_no_socketpair, 447 .accept = sock_no_accept, 448 .getname = pn_socket_getname, 449 .poll = datagram_poll, 450 .ioctl = pn_socket_ioctl, 451 .listen = sock_no_listen, 452 .shutdown = sock_no_shutdown, 453 .setsockopt = sock_no_setsockopt, 454 .getsockopt = sock_no_getsockopt, 455 #ifdef CONFIG_COMPAT 456 .compat_setsockopt = sock_no_setsockopt, 457 .compat_getsockopt = sock_no_getsockopt, 458 #endif 459 .sendmsg = pn_socket_sendmsg, 460 .recvmsg = sock_common_recvmsg, 461 .mmap = sock_no_mmap, 462 .sendpage = sock_no_sendpage, 463 }; 464 465 const struct proto_ops phonet_stream_ops = { 466 .family = AF_PHONET, 467 .owner = THIS_MODULE, 468 .release = pn_socket_release, 469 .bind = pn_socket_bind, 470 .connect = pn_socket_connect, 471 .socketpair = sock_no_socketpair, 472 .accept = pn_socket_accept, 473 .getname = pn_socket_getname, 474 .poll = pn_socket_poll, 475 .ioctl = pn_socket_ioctl, 476 .listen = pn_socket_listen, 477 .shutdown = sock_no_shutdown, 478 .setsockopt = sock_common_setsockopt, 479 .getsockopt = sock_common_getsockopt, 480 #ifdef CONFIG_COMPAT 481 .compat_setsockopt = compat_sock_common_setsockopt, 482 .compat_getsockopt = compat_sock_common_getsockopt, 483 #endif 484 .sendmsg = pn_socket_sendmsg, 485 .recvmsg = sock_common_recvmsg, 486 .mmap = sock_no_mmap, 487 .sendpage = sock_no_sendpage, 488 }; 489 EXPORT_SYMBOL(phonet_stream_ops); 490 491 /* allocate port for a socket */ 492 int pn_sock_get_port(struct sock *sk, unsigned short sport) 493 { 494 static int port_cur; 495 struct net *net = sock_net(sk); 496 struct pn_sock *pn = pn_sk(sk); 497 struct sockaddr_pn try_sa; 498 struct sock *tmpsk; 499 500 memset(&try_sa, 0, sizeof(struct sockaddr_pn)); 501 try_sa.spn_family = AF_PHONET; 502 WARN_ON(!mutex_is_locked(&port_mutex)); 503 if (!sport) { 504 /* search free port */ 505 int port, pmin, pmax; 506 507 phonet_get_local_port_range(&pmin, &pmax); 508 for (port = pmin; port <= pmax; port++) { 509 port_cur++; 510 if (port_cur < pmin || port_cur > pmax) 511 port_cur = pmin; 512 513 pn_sockaddr_set_port(&try_sa, port_cur); 514 tmpsk = pn_find_sock_by_sa(net, &try_sa); 515 if (tmpsk == NULL) { 516 sport = port_cur; 517 goto found; 518 } else 519 sock_put(tmpsk); 520 } 521 } else { 522 /* try to find specific port */ 523 pn_sockaddr_set_port(&try_sa, sport); 524 tmpsk = pn_find_sock_by_sa(net, &try_sa); 525 if (tmpsk == NULL) 526 /* No sock there! We can use that port... */ 527 goto found; 528 else 529 sock_put(tmpsk); 530 } 531 /* the port must be in use already */ 532 return -EADDRINUSE; 533 534 found: 535 pn->sobject = pn_object(pn_addr(pn->sobject), sport); 536 return 0; 537 } 538 EXPORT_SYMBOL(pn_sock_get_port); 539 540 #ifdef CONFIG_PROC_FS 541 static struct sock *pn_sock_get_idx(struct seq_file *seq, loff_t pos) 542 { 543 struct net *net = seq_file_net(seq); 544 struct hlist_head *hlist = pnsocks.hlist; 545 struct hlist_node *node; 546 struct sock *sknode; 547 unsigned h; 548 549 for (h = 0; h < PN_HASHSIZE; h++) { 550 sk_for_each_rcu(sknode, node, hlist) { 551 if (!net_eq(net, sock_net(sknode))) 552 continue; 553 if (!pos) 554 return sknode; 555 pos--; 556 } 557 hlist++; 558 } 559 return NULL; 560 } 561 562 static struct sock *pn_sock_get_next(struct seq_file *seq, struct sock *sk) 563 { 564 struct net *net = seq_file_net(seq); 565 566 do 567 sk = sk_next(sk); 568 while (sk && !net_eq(net, sock_net(sk))); 569 570 return sk; 571 } 572 573 static void *pn_sock_seq_start(struct seq_file *seq, loff_t *pos) 574 __acquires(rcu) 575 { 576 rcu_read_lock(); 577 return *pos ? pn_sock_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; 578 } 579 580 static void *pn_sock_seq_next(struct seq_file *seq, void *v, loff_t *pos) 581 { 582 struct sock *sk; 583 584 if (v == SEQ_START_TOKEN) 585 sk = pn_sock_get_idx(seq, 0); 586 else 587 sk = pn_sock_get_next(seq, v); 588 (*pos)++; 589 return sk; 590 } 591 592 static void pn_sock_seq_stop(struct seq_file *seq, void *v) 593 __releases(rcu) 594 { 595 rcu_read_unlock(); 596 } 597 598 static int pn_sock_seq_show(struct seq_file *seq, void *v) 599 { 600 int len; 601 602 if (v == SEQ_START_TOKEN) 603 seq_printf(seq, "%s%n", "pt loc rem rs st tx_queue rx_queue " 604 " uid inode ref pointer drops", &len); 605 else { 606 struct sock *sk = v; 607 struct pn_sock *pn = pn_sk(sk); 608 609 seq_printf(seq, "%2d %04X:%04X:%02X %02X %08X:%08X %5d %lu " 610 "%d %pK %d%n", 611 sk->sk_protocol, pn->sobject, pn->dobject, 612 pn->resource, sk->sk_state, 613 sk_wmem_alloc_get(sk), sk_rmem_alloc_get(sk), 614 sock_i_uid(sk), sock_i_ino(sk), 615 atomic_read(&sk->sk_refcnt), sk, 616 atomic_read(&sk->sk_drops), &len); 617 } 618 seq_printf(seq, "%*s\n", 127 - len, ""); 619 return 0; 620 } 621 622 static const struct seq_operations pn_sock_seq_ops = { 623 .start = pn_sock_seq_start, 624 .next = pn_sock_seq_next, 625 .stop = pn_sock_seq_stop, 626 .show = pn_sock_seq_show, 627 }; 628 629 static int pn_sock_open(struct inode *inode, struct file *file) 630 { 631 return seq_open_net(inode, file, &pn_sock_seq_ops, 632 sizeof(struct seq_net_private)); 633 } 634 635 const struct file_operations pn_sock_seq_fops = { 636 .owner = THIS_MODULE, 637 .open = pn_sock_open, 638 .read = seq_read, 639 .llseek = seq_lseek, 640 .release = seq_release_net, 641 }; 642 #endif 643 644 static struct { 645 struct sock *sk[256]; 646 } pnres; 647 648 /* 649 * Find and hold socket based on resource. 650 */ 651 struct sock *pn_find_sock_by_res(struct net *net, u8 res) 652 { 653 struct sock *sk; 654 655 if (!net_eq(net, &init_net)) 656 return NULL; 657 658 rcu_read_lock(); 659 sk = rcu_dereference(pnres.sk[res]); 660 if (sk) 661 sock_hold(sk); 662 rcu_read_unlock(); 663 return sk; 664 } 665 666 static DEFINE_MUTEX(resource_mutex); 667 668 int pn_sock_bind_res(struct sock *sk, u8 res) 669 { 670 int ret = -EADDRINUSE; 671 672 if (!net_eq(sock_net(sk), &init_net)) 673 return -ENOIOCTLCMD; 674 if (!capable(CAP_SYS_ADMIN)) 675 return -EPERM; 676 if (pn_socket_autobind(sk->sk_socket)) 677 return -EAGAIN; 678 679 mutex_lock(&resource_mutex); 680 if (pnres.sk[res] == NULL) { 681 sock_hold(sk); 682 rcu_assign_pointer(pnres.sk[res], sk); 683 ret = 0; 684 } 685 mutex_unlock(&resource_mutex); 686 return ret; 687 } 688 689 int pn_sock_unbind_res(struct sock *sk, u8 res) 690 { 691 int ret = -ENOENT; 692 693 if (!capable(CAP_SYS_ADMIN)) 694 return -EPERM; 695 696 mutex_lock(&resource_mutex); 697 if (pnres.sk[res] == sk) { 698 rcu_assign_pointer(pnres.sk[res], NULL); 699 ret = 0; 700 } 701 mutex_unlock(&resource_mutex); 702 703 if (ret == 0) { 704 synchronize_rcu(); 705 sock_put(sk); 706 } 707 return ret; 708 } 709 710 void pn_sock_unbind_all_res(struct sock *sk) 711 { 712 unsigned res, match = 0; 713 714 mutex_lock(&resource_mutex); 715 for (res = 0; res < 256; res++) { 716 if (pnres.sk[res] == sk) { 717 rcu_assign_pointer(pnres.sk[res], NULL); 718 match++; 719 } 720 } 721 mutex_unlock(&resource_mutex); 722 723 while (match > 0) { 724 __sock_put(sk); 725 match--; 726 } 727 /* Caller is responsible for RCU sync before final sock_put() */ 728 } 729 730 #ifdef CONFIG_PROC_FS 731 static struct sock **pn_res_get_idx(struct seq_file *seq, loff_t pos) 732 { 733 struct net *net = seq_file_net(seq); 734 unsigned i; 735 736 if (!net_eq(net, &init_net)) 737 return NULL; 738 739 for (i = 0; i < 256; i++) { 740 if (pnres.sk[i] == NULL) 741 continue; 742 if (!pos) 743 return pnres.sk + i; 744 pos--; 745 } 746 return NULL; 747 } 748 749 static struct sock **pn_res_get_next(struct seq_file *seq, struct sock **sk) 750 { 751 struct net *net = seq_file_net(seq); 752 unsigned i; 753 754 BUG_ON(!net_eq(net, &init_net)); 755 756 for (i = (sk - pnres.sk) + 1; i < 256; i++) 757 if (pnres.sk[i]) 758 return pnres.sk + i; 759 return NULL; 760 } 761 762 static void *pn_res_seq_start(struct seq_file *seq, loff_t *pos) 763 __acquires(resource_mutex) 764 { 765 mutex_lock(&resource_mutex); 766 return *pos ? pn_res_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; 767 } 768 769 static void *pn_res_seq_next(struct seq_file *seq, void *v, loff_t *pos) 770 { 771 struct sock **sk; 772 773 if (v == SEQ_START_TOKEN) 774 sk = pn_res_get_idx(seq, 0); 775 else 776 sk = pn_res_get_next(seq, v); 777 (*pos)++; 778 return sk; 779 } 780 781 static void pn_res_seq_stop(struct seq_file *seq, void *v) 782 __releases(resource_mutex) 783 { 784 mutex_unlock(&resource_mutex); 785 } 786 787 static int pn_res_seq_show(struct seq_file *seq, void *v) 788 { 789 int len; 790 791 if (v == SEQ_START_TOKEN) 792 seq_printf(seq, "%s%n", "rs uid inode", &len); 793 else { 794 struct sock **psk = v; 795 struct sock *sk = *psk; 796 797 seq_printf(seq, "%02X %5d %lu%n", 798 (int) (psk - pnres.sk), sock_i_uid(sk), 799 sock_i_ino(sk), &len); 800 } 801 seq_printf(seq, "%*s\n", 63 - len, ""); 802 return 0; 803 } 804 805 static const struct seq_operations pn_res_seq_ops = { 806 .start = pn_res_seq_start, 807 .next = pn_res_seq_next, 808 .stop = pn_res_seq_stop, 809 .show = pn_res_seq_show, 810 }; 811 812 static int pn_res_open(struct inode *inode, struct file *file) 813 { 814 return seq_open_net(inode, file, &pn_res_seq_ops, 815 sizeof(struct seq_net_private)); 816 } 817 818 const struct file_operations pn_res_seq_fops = { 819 .owner = THIS_MODULE, 820 .open = pn_res_open, 821 .read = seq_read, 822 .llseek = seq_lseek, 823 .release = seq_release_net, 824 }; 825 #endif 826