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

rose_dev.c (2994B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *
      4 * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
      5 */
      6#include <linux/module.h>
      7#include <linux/proc_fs.h>
      8#include <linux/kernel.h>
      9#include <linux/interrupt.h>
     10#include <linux/fs.h>
     11#include <linux/types.h>
     12#include <linux/sysctl.h>
     13#include <linux/string.h>
     14#include <linux/socket.h>
     15#include <linux/errno.h>
     16#include <linux/fcntl.h>
     17#include <linux/in.h>
     18#include <linux/if_ether.h>
     19#include <linux/slab.h>
     20
     21#include <asm/io.h>
     22
     23#include <linux/inet.h>
     24#include <linux/netdevice.h>
     25#include <linux/etherdevice.h>
     26#include <linux/if_arp.h>
     27#include <linux/skbuff.h>
     28
     29#include <net/ip.h>
     30#include <net/arp.h>
     31
     32#include <net/ax25.h>
     33#include <net/rose.h>
     34
     35static int rose_header(struct sk_buff *skb, struct net_device *dev,
     36		       unsigned short type,
     37		       const void *daddr, const void *saddr, unsigned int len)
     38{
     39	unsigned char *buff = skb_push(skb, ROSE_MIN_LEN + 2);
     40
     41	if (daddr)
     42		memcpy(buff + 7, daddr, dev->addr_len);
     43
     44	*buff++ = ROSE_GFI | ROSE_Q_BIT;
     45	*buff++ = 0x00;
     46	*buff++ = ROSE_DATA;
     47	*buff++ = 0x7F;
     48	*buff++ = AX25_P_IP;
     49
     50	if (daddr != NULL)
     51		return 37;
     52
     53	return -37;
     54}
     55
     56static int rose_set_mac_address(struct net_device *dev, void *addr)
     57{
     58	struct sockaddr *sa = addr;
     59	int err;
     60
     61	if (!memcmp(dev->dev_addr, sa->sa_data, dev->addr_len))
     62		return 0;
     63
     64	if (dev->flags & IFF_UP) {
     65		err = rose_add_loopback_node((rose_address *)sa->sa_data);
     66		if (err)
     67			return err;
     68
     69		rose_del_loopback_node((const rose_address *)dev->dev_addr);
     70	}
     71
     72	dev_addr_set(dev, sa->sa_data);
     73
     74	return 0;
     75}
     76
     77static int rose_open(struct net_device *dev)
     78{
     79	int err;
     80
     81	err = rose_add_loopback_node((const rose_address *)dev->dev_addr);
     82	if (err)
     83		return err;
     84
     85	netif_start_queue(dev);
     86
     87	return 0;
     88}
     89
     90static int rose_close(struct net_device *dev)
     91{
     92	netif_stop_queue(dev);
     93	rose_del_loopback_node((const rose_address *)dev->dev_addr);
     94	return 0;
     95}
     96
     97static netdev_tx_t rose_xmit(struct sk_buff *skb, struct net_device *dev)
     98{
     99	struct net_device_stats *stats = &dev->stats;
    100	unsigned int len = skb->len;
    101
    102	if (!netif_running(dev)) {
    103		printk(KERN_ERR "ROSE: rose_xmit - called when iface is down\n");
    104		return NETDEV_TX_BUSY;
    105	}
    106
    107	if (!rose_route_frame(skb, NULL)) {
    108		dev_kfree_skb(skb);
    109		stats->tx_errors++;
    110		return NETDEV_TX_OK;
    111	}
    112
    113	stats->tx_packets++;
    114	stats->tx_bytes += len;
    115	return NETDEV_TX_OK;
    116}
    117
    118static const struct header_ops rose_header_ops = {
    119	.create	= rose_header,
    120};
    121
    122static const struct net_device_ops rose_netdev_ops = {
    123	.ndo_open		= rose_open,
    124	.ndo_stop		= rose_close,
    125	.ndo_start_xmit		= rose_xmit,
    126	.ndo_set_mac_address    = rose_set_mac_address,
    127};
    128
    129void rose_setup(struct net_device *dev)
    130{
    131	dev->mtu		= ROSE_MAX_PACKET_SIZE - 2;
    132	dev->netdev_ops		= &rose_netdev_ops;
    133
    134	dev->header_ops		= &rose_header_ops;
    135	dev->hard_header_len	= AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN;
    136	dev->addr_len		= ROSE_ADDR_LEN;
    137	dev->type		= ARPHRD_ROSE;
    138
    139	/* New-style flags. */
    140	dev->flags		= IFF_NOARP;
    141}