cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hdlc_raw.c (2490B)


      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
     22static int raw_ioctl(struct net_device *dev, struct if_settings *ifs);
     23
     24static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev)
     25{
     26	return cpu_to_be16(ETH_P_IP);
     27}
     28
     29static struct hdlc_proto proto = {
     30	.type_trans	= raw_type_trans,
     31	.ioctl		= raw_ioctl,
     32	.module		= THIS_MODULE,
     33};
     34
     35
     36static int raw_ioctl(struct net_device *dev, struct if_settings *ifs)
     37{
     38	raw_hdlc_proto __user *raw_s = ifs->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 (ifs->type) {
     45	case IF_GET_PROTO:
     46		if (dev_to_hdlc(dev)->proto != &proto)
     47			return -EINVAL;
     48		ifs->type = IF_PROTO_HDLC;
     49		if (ifs->size < size) {
     50			ifs->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
     93static int __init hdlc_raw_init(void)
     94{
     95	register_hdlc_protocol(&proto);
     96	return 0;
     97}
     98
     99
    100
    101static void __exit hdlc_raw_exit(void)
    102{
    103	unregister_hdlc_protocol(&proto);
    104}
    105
    106
    107module_init(hdlc_raw_init);
    108module_exit(hdlc_raw_exit);
    109
    110MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
    111MODULE_DESCRIPTION("Raw HDLC protocol support for generic HDLC");
    112MODULE_LICENSE("GPL v2");