root/drivers/net/wan/hdlc_raw.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. raw_type_trans
  2. raw_ioctl
  3. mod_init
  4. mod_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Generic HDLC support routines for Linux
   4  * HDLC support
   5  *
   6  * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
   7  */
   8 
   9 #include <linux/errno.h>
  10 #include <linux/hdlc.h>
  11 #include <linux/if_arp.h>
  12 #include <linux/inetdevice.h>
  13 #include <linux/init.h>
  14 #include <linux/kernel.h>
  15 #include <linux/module.h>
  16 #include <linux/pkt_sched.h>
  17 #include <linux/poll.h>
  18 #include <linux/rtnetlink.h>
  19 #include <linux/skbuff.h>
  20 
  21 
  22 static int raw_ioctl(struct net_device *dev, struct ifreq *ifr);
  23 
  24 static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev)
  25 {
  26         return cpu_to_be16(ETH_P_IP);
  27 }
  28 
  29 static struct hdlc_proto proto = {
  30         .type_trans     = raw_type_trans,
  31         .ioctl          = raw_ioctl,
  32         .module         = THIS_MODULE,
  33 };
  34 
  35 
  36 static int raw_ioctl(struct net_device *dev, struct ifreq *ifr)
  37 {
  38         raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc;
  39         const size_t size = sizeof(raw_hdlc_proto);
  40         raw_hdlc_proto new_settings;
  41         hdlc_device *hdlc = dev_to_hdlc(dev);
  42         int result;
  43 
  44         switch (ifr->ifr_settings.type) {
  45         case IF_GET_PROTO:
  46                 if (dev_to_hdlc(dev)->proto != &proto)
  47                         return -EINVAL;
  48                 ifr->ifr_settings.type = IF_PROTO_HDLC;
  49                 if (ifr->ifr_settings.size < size) {
  50                         ifr->ifr_settings.size = size; /* data size wanted */
  51                         return -ENOBUFS;
  52                 }
  53                 if (copy_to_user(raw_s, hdlc->state, size))
  54                         return -EFAULT;
  55                 return 0;
  56 
  57         case IF_PROTO_HDLC:
  58                 if (!capable(CAP_NET_ADMIN))
  59                         return -EPERM;
  60 
  61                 if (dev->flags & IFF_UP)
  62                         return -EBUSY;
  63 
  64                 if (copy_from_user(&new_settings, raw_s, size))
  65                         return -EFAULT;
  66 
  67                 if (new_settings.encoding == ENCODING_DEFAULT)
  68                         new_settings.encoding = ENCODING_NRZ;
  69 
  70                 if (new_settings.parity == PARITY_DEFAULT)
  71                         new_settings.parity = PARITY_CRC16_PR1_CCITT;
  72 
  73                 result = hdlc->attach(dev, new_settings.encoding,
  74                                       new_settings.parity);
  75                 if (result)
  76                         return result;
  77 
  78                 result = attach_hdlc_protocol(dev, &proto,
  79                                               sizeof(raw_hdlc_proto));
  80                 if (result)
  81                         return result;
  82                 memcpy(hdlc->state, &new_settings, size);
  83                 dev->type = ARPHRD_RAWHDLC;
  84                 call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
  85                 netif_dormant_off(dev);
  86                 return 0;
  87         }
  88 
  89         return -EINVAL;
  90 }
  91 
  92 
  93 static int __init mod_init(void)
  94 {
  95         register_hdlc_protocol(&proto);
  96         return 0;
  97 }
  98 
  99 
 100 
 101 static void __exit mod_exit(void)
 102 {
 103         unregister_hdlc_protocol(&proto);
 104 }
 105 
 106 
 107 module_init(mod_init);
 108 module_exit(mod_exit);
 109 
 110 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
 111 MODULE_DESCRIPTION("Raw HDLC protocol support for generic HDLC");
 112 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */