linux/net/atm/ioctl.c
<<
>>
Prefs
   1/* ATM ioctl handling */
   2
   3/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
   4/* 2003 John Levon  <levon@movementarian.org> */
   5
   6
   7#include <linux/module.h>
   8#include <linux/kmod.h>
   9#include <linux/net.h>          /* struct socket, struct proto_ops */
  10#include <linux/atm.h>          /* ATM stuff */
  11#include <linux/atmdev.h>
  12#include <linux/atmclip.h>      /* CLIP_*ENCAP */
  13#include <linux/atmarp.h>       /* manifest constants */
  14#include <linux/capability.h>
  15#include <linux/sonet.h>        /* for ioctls */
  16#include <linux/atmsvc.h>
  17#include <linux/atmmpc.h>
  18#include <net/atmclip.h>
  19#include <linux/atmlec.h>
  20#include <linux/mutex.h>
  21#include <asm/ioctls.h>
  22
  23#include "resources.h"
  24#include "signaling.h"          /* for WAITING and sigd_attach */
  25#include "common.h"
  26
  27
  28static DEFINE_MUTEX(ioctl_mutex);
  29static LIST_HEAD(ioctl_list);
  30
  31
  32void register_atm_ioctl(struct atm_ioctl *ioctl)
  33{
  34        mutex_lock(&ioctl_mutex);
  35        list_add_tail(&ioctl->list, &ioctl_list);
  36        mutex_unlock(&ioctl_mutex);
  37}
  38
  39void deregister_atm_ioctl(struct atm_ioctl *ioctl)
  40{
  41        mutex_lock(&ioctl_mutex);
  42        list_del(&ioctl->list);
  43        mutex_unlock(&ioctl_mutex);
  44}
  45
  46EXPORT_SYMBOL(register_atm_ioctl);
  47EXPORT_SYMBOL(deregister_atm_ioctl);
  48
  49int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
  50{
  51        struct sock *sk = sock->sk;
  52        struct atm_vcc *vcc;
  53        int error;
  54        struct list_head * pos;
  55        void __user *argp = (void __user *)arg;
  56
  57        vcc = ATM_SD(sock);
  58        switch (cmd) {
  59                case SIOCOUTQ:
  60                        if (sock->state != SS_CONNECTED ||
  61                            !test_bit(ATM_VF_READY, &vcc->flags)) {
  62                                error =  -EINVAL;
  63                                goto done;
  64                        }
  65                        error = put_user(sk->sk_sndbuf -
  66                                         atomic_read(&sk->sk_wmem_alloc),
  67                                         (int __user *) argp) ? -EFAULT : 0;
  68                        goto done;
  69                case SIOCINQ:
  70                        {
  71                                struct sk_buff *skb;
  72
  73                                if (sock->state != SS_CONNECTED) {
  74                                        error = -EINVAL;
  75                                        goto done;
  76                                }
  77                                skb = skb_peek(&sk->sk_receive_queue);
  78                                error = put_user(skb ? skb->len : 0,
  79                                                 (int __user *)argp) ? -EFAULT : 0;
  80                                goto done;
  81                        }
  82                case SIOCGSTAMP: /* borrowed from IP */
  83                        error = sock_get_timestamp(sk, argp);
  84                        goto done;
  85                case SIOCGSTAMPNS: /* borrowed from IP */
  86                        error = sock_get_timestampns(sk, argp);
  87                        goto done;
  88                case ATM_SETSC:
  89                        printk(KERN_WARNING "ATM_SETSC is obsolete\n");
  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 privledges that /proc/kcore needs
 103                         */
 104                        if (!capable(CAP_SYS_RAWIO)) {
 105                                error = -EPERM;
 106                                goto done;
 107                        }
 108                        error = sigd_attach(vcc);
 109                        if (!error)
 110                                sock->state = SS_CONNECTED;
 111                        goto done;
 112                case ATM_SETBACKEND:
 113                case ATM_NEWBACKENDIF:
 114                        {
 115                                atm_backend_t backend;
 116                                error = get_user(backend, (atm_backend_t __user *) argp);
 117                                if (error)
 118                                        goto done;
 119                                switch (backend) {
 120                                        case ATM_BACKEND_PPP:
 121                                                request_module("pppoatm");
 122                                                break;
 123                                        case ATM_BACKEND_BR2684:
 124                                                request_module("br2684");
 125                                                break;
 126                                }
 127                        }
 128                        break;
 129                case ATMMPC_CTRL:
 130                case ATMMPC_DATA:
 131                        request_module("mpoa");
 132                        break;
 133                case ATMARPD_CTRL:
 134                        request_module("clip");
 135                        break;
 136                case ATMLEC_CTRL:
 137                        request_module("lec");
 138                        break;
 139        }
 140
 141        error = -ENOIOCTLCMD;
 142
 143        mutex_lock(&ioctl_mutex);
 144        list_for_each(pos, &ioctl_list) {
 145                struct atm_ioctl * ic = list_entry(pos, struct atm_ioctl, list);
 146                if (try_module_get(ic->owner)) {
 147                        error = ic->ioctl(sock, cmd, arg);
 148                        module_put(ic->owner);
 149                        if (error != -ENOIOCTLCMD)
 150                                break;
 151                }
 152        }
 153        mutex_unlock(&ioctl_mutex);
 154
 155        if (error != -ENOIOCTLCMD)
 156                goto done;
 157
 158        error = atm_dev_ioctl(cmd, argp);
 159
 160done:
 161        return error;
 162}
 163
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.