ioctl.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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 - sk_wmem_alloc_get(sk),
  55. (int __user *) argp) ? -EFAULT : 0;
  56. goto done;
  57. case SIOCINQ:
  58. {
  59. struct sk_buff *skb;
  60. if (sock->state != SS_CONNECTED) {
  61. error = -EINVAL;
  62. goto done;
  63. }
  64. skb = skb_peek(&sk->sk_receive_queue);
  65. error = put_user(skb ? skb->len : 0,
  66. (int __user *)argp) ? -EFAULT : 0;
  67. goto done;
  68. }
  69. case SIOCGSTAMP: /* borrowed from IP */
  70. #ifdef CONFIG_COMPAT
  71. if (compat)
  72. error = compat_sock_get_timestamp(sk, argp);
  73. else
  74. #endif
  75. error = sock_get_timestamp(sk, argp);
  76. goto done;
  77. case SIOCGSTAMPNS: /* borrowed from IP */
  78. #ifdef CONFIG_COMPAT
  79. if (compat)
  80. error = compat_sock_get_timestampns(sk, argp);
  81. else
  82. #endif
  83. error = sock_get_timestampns(sk, argp);
  84. goto done;
  85. case ATM_SETSC:
  86. if (net_ratelimit())
  87. printk(KERN_WARNING "ATM_SETSC is obsolete; used by %s:%d\n",
  88. current->comm, task_pid_nr(current));
  89. error = 0;
  90. goto done;
  91. case ATMSIGD_CTRL:
  92. if (!capable(CAP_NET_ADMIN)) {
  93. error = -EPERM;
  94. goto done;
  95. }
  96. /*
  97. * The user/kernel protocol for exchanging signalling
  98. * info uses kernel pointers as opaque references,
  99. * so the holder of the file descriptor can scribble
  100. * on the kernel... so we should make sure that we
  101. * have the same privileges that /proc/kcore needs
  102. */
  103. if (!capable(CAP_SYS_RAWIO)) {
  104. error = -EPERM;
  105. goto done;
  106. }
  107. #ifdef CONFIG_COMPAT
  108. /* WTF? I don't even want to _think_ about making this
  109. work for 32-bit userspace. TBH I don't really want
  110. to think about it at all. dwmw2. */
  111. if (compat) {
  112. if (net_ratelimit())
  113. printk(KERN_WARNING "32-bit task cannot be atmsigd\n");
  114. error = -EINVAL;
  115. goto done;
  116. }
  117. #endif
  118. error = sigd_attach(vcc);
  119. if (!error)
  120. sock->state = SS_CONNECTED;
  121. goto done;
  122. case ATM_SETBACKEND:
  123. case ATM_NEWBACKENDIF:
  124. {
  125. atm_backend_t backend;
  126. error = get_user(backend, (atm_backend_t __user *) argp);
  127. if (error)
  128. goto done;
  129. switch (backend) {
  130. case ATM_BACKEND_PPP:
  131. request_module("pppoatm");
  132. break;
  133. case ATM_BACKEND_BR2684:
  134. request_module("br2684");
  135. break;
  136. }
  137. }
  138. break;
  139. case ATMMPC_CTRL:
  140. case ATMMPC_DATA:
  141. request_module("mpoa");
  142. break;
  143. case ATMARPD_CTRL:
  144. request_module("clip");
  145. break;
  146. case ATMLEC_CTRL:
  147. request_module("lec");
  148. break;
  149. }
  150. error = -ENOIOCTLCMD;
  151. mutex_lock(&ioctl_mutex);
  152. list_for_each(pos, &ioctl_list) {
  153. struct atm_ioctl * ic = list_entry(pos, struct atm_ioctl, list);
  154. if (try_module_get(ic->owner)) {
  155. error = ic->ioctl(sock, cmd, arg);
  156. module_put(ic->owner);
  157. if (error != -ENOIOCTLCMD)
  158. break;
  159. }
  160. }
  161. mutex_unlock(&ioctl_mutex);
  162. if (error != -ENOIOCTLCMD)
  163. goto done;
  164. error = atm_dev_ioctl(cmd, argp, compat);
  165. done:
  166. return error;
  167. }
  168. int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
  169. {
  170. return do_vcc_ioctl(sock, cmd, arg, 0);
  171. }
  172. #ifdef CONFIG_COMPAT
  173. int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
  174. {
  175. return do_vcc_ioctl(sock, cmd, arg, 1);
  176. }
  177. #endif