ioctl.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /* ATM ioctl handling */
  2. /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
  3. /* 2003 John Levon <levon@movementarian.org> */
  4. #include <linux/module.h>
  5. #include <linux/kmod.h>
  6. #include <linux/net.h> /* struct socket, struct proto_ops */
  7. #include <linux/atm.h> /* ATM stuff */
  8. #include <linux/atmdev.h>
  9. #include <linux/atmclip.h> /* CLIP_*ENCAP */
  10. #include <linux/atmarp.h> /* manifest constants */
  11. #include <linux/capability.h>
  12. #include <linux/sonet.h> /* for ioctls */
  13. #include <linux/atmsvc.h>
  14. #include <linux/atmmpc.h>
  15. #include <net/atmclip.h>
  16. #include <linux/atmlec.h>
  17. #include <linux/mutex.h>
  18. #include <asm/ioctls.h>
  19. #include <net/compat.h>
  20. #include "resources.h"
  21. #include "signaling.h" /* for WAITING and sigd_attach */
  22. #include "common.h"
  23. static DEFINE_MUTEX(ioctl_mutex);
  24. static LIST_HEAD(ioctl_list);
  25. void register_atm_ioctl(struct atm_ioctl *ioctl)
  26. {
  27. mutex_lock(&ioctl_mutex);
  28. list_add_tail(&ioctl->list, &ioctl_list);
  29. mutex_unlock(&ioctl_mutex);
  30. }
  31. void deregister_atm_ioctl(struct atm_ioctl *ioctl)
  32. {
  33. mutex_lock(&ioctl_mutex);
  34. list_del(&ioctl->list);
  35. mutex_unlock(&ioctl_mutex);
  36. }
  37. EXPORT_SYMBOL(register_atm_ioctl);
  38. EXPORT_SYMBOL(deregister_atm_ioctl);
  39. static int do_vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg, int compat)
  40. {
  41. struct sock *sk = sock->sk;
  42. struct atm_vcc *vcc;
  43. int error;
  44. struct list_head * pos;
  45. void __user *argp = (void __user *)arg;
  46. vcc = ATM_SD(sock);
  47. switch (cmd) {
  48. case SIOCOUTQ:
  49. if (sock->state != SS_CONNECTED ||
  50. !test_bit(ATM_VF_READY, &vcc->flags)) {
  51. error = -EINVAL;
  52. goto done;
  53. }
  54. error = put_user(sk->sk_sndbuf -
  55. atomic_read(&sk->sk_wmem_alloc),
  56. (int __user *) argp) ? -EFAULT : 0;
  57. goto done;
  58. case SIOCINQ:
  59. {
  60. struct sk_buff *skb;
  61. if (sock->state != SS_CONNECTED) {
  62. error = -EINVAL;
  63. goto done;
  64. }
  65. skb = skb_peek(&sk->sk_receive_queue);
  66. error = put_user(skb ? skb->len : 0,
  67. (int __user *)argp) ? -EFAULT : 0;
  68. goto done;
  69. }
  70. case SIOCGSTAMP: /* borrowed from IP */
  71. #ifdef CONFIG_COMPAT
  72. if (compat)
  73. error = compat_sock_get_timestamp(sk, argp);
  74. else
  75. #endif
  76. error = sock_get_timestamp(sk, argp);
  77. goto done;
  78. case SIOCGSTAMPNS: /* borrowed from IP */
  79. #ifdef CONFIG_COMPAT
  80. if (compat)
  81. error = compat_sock_get_timestampns(sk, argp);
  82. else
  83. #endif
  84. error = sock_get_timestampns(sk, argp);
  85. goto done;
  86. case ATM_SETSC:
  87. if (net_ratelimit())
  88. printk(KERN_WARNING "ATM_SETSC is obsolete; used by %s:%d\n",
  89. current->comm, task_pid_nr(current));
  90. error = 0;
  91. goto done;
  92. case ATMSIGD_CTRL:
  93. if (!capable(CAP_NET_ADMIN)) {
  94. error = -EPERM;
  95. goto done;
  96. }
  97. /*
  98. * The user/kernel protocol for exchanging signalling
  99. * info uses kernel pointers as opaque references,
  100. * so the holder of the file descriptor can scribble
  101. * on the kernel... so we should make sure that we
  102. * have the same privileges that /proc/kcore needs
  103. */
  104. if (!capable(CAP_SYS_RAWIO)) {
  105. error = -EPERM;
  106. goto done;
  107. }
  108. #ifdef CONFIG_COMPAT
  109. /* WTF? I don't even want to _think_ about making this
  110. work for 32-bit userspace. TBH I don't really want
  111. to think about it at all. dwmw2. */
  112. if (compat) {
  113. if (net_ratelimit())
  114. printk(KERN_WARNING "32-bit task cannot be atmsigd\n");
  115. error = -EINVAL;
  116. goto done;
  117. }
  118. #endif
  119. error = sigd_attach(vcc);
  120. if (!error)
  121. sock->state = SS_CONNECTED;
  122. goto done;
  123. case ATM_SETBACKEND:
  124. case ATM_NEWBACKENDIF:
  125. {
  126. atm_backend_t backend;
  127. error = get_user(backend, (atm_backend_t __user *) argp);
  128. if (error)
  129. goto done;
  130. switch (backend) {
  131. case ATM_BACKEND_PPP:
  132. request_module("pppoatm");
  133. break;
  134. case ATM_BACKEND_BR2684:
  135. request_module("br2684");
  136. break;
  137. }
  138. }
  139. break;
  140. case ATMMPC_CTRL:
  141. case ATMMPC_DATA:
  142. request_module("mpoa");
  143. break;
  144. case ATMARPD_CTRL:
  145. request_module("clip");
  146. break;
  147. case ATMLEC_CTRL:
  148. request_module("lec");
  149. break;
  150. }
  151. error = -ENOIOCTLCMD;
  152. mutex_lock(&ioctl_mutex);
  153. list_for_each(pos, &ioctl_list) {
  154. struct atm_ioctl * ic = list_entry(pos, struct atm_ioctl, list);
  155. if (try_module_get(ic->owner)) {
  156. error = ic->ioctl(sock, cmd, arg);
  157. module_put(ic->owner);
  158. if (error != -ENOIOCTLCMD)
  159. break;
  160. }
  161. }
  162. mutex_unlock(&ioctl_mutex);
  163. if (error != -ENOIOCTLCMD)
  164. goto done;
  165. error = atm_dev_ioctl(cmd, argp, compat);
  166. done:
  167. return error;
  168. }
  169. int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
  170. {
  171. return do_vcc_ioctl(sock, cmd, arg, 0);
  172. }
  173. #ifdef CONFIG_COMPAT
  174. int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
  175. {
  176. return do_vcc_ioctl(sock, cmd, arg, 1);
  177. }
  178. #endif