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

rfc1201.c (16163B)


      1/*
      2 * Linux ARCnet driver - RFC1201 (standard) packet encapsulation
      3 *
      4 * Written 1994-1999 by Avery Pennarun.
      5 * Derived from skeleton.c by Donald Becker.
      6 *
      7 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
      8 *  for sponsoring the further development of this driver.
      9 *
     10 * **********************
     11 *
     12 * The original copyright of skeleton.c was as follows:
     13 *
     14 * skeleton.c Written 1993 by Donald Becker.
     15 * Copyright 1993 United States Government as represented by the
     16 * Director, National Security Agency.  This software may only be used
     17 * and distributed according to the terms of the GNU General Public License as
     18 * modified by SRC, incorporated herein by reference.
     19 *
     20 * **********************
     21 *
     22 * For more details, see drivers/net/arcnet.c
     23 *
     24 * **********************
     25 */
     26
     27#define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
     28
     29#include <linux/gfp.h>
     30#include <linux/module.h>
     31#include <linux/init.h>
     32#include <linux/if_arp.h>
     33#include <linux/netdevice.h>
     34#include <linux/skbuff.h>
     35
     36#include "arcdevice.h"
     37
     38MODULE_LICENSE("GPL");
     39
     40static __be16 type_trans(struct sk_buff *skb, struct net_device *dev);
     41static void rx(struct net_device *dev, int bufnum,
     42	       struct archdr *pkthdr, int length);
     43static int build_header(struct sk_buff *skb, struct net_device *dev,
     44			unsigned short type, uint8_t daddr);
     45static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
     46		      int bufnum);
     47static int continue_tx(struct net_device *dev, int bufnum);
     48
     49static struct ArcProto rfc1201_proto = {
     50	.suffix		= 'a',
     51	.mtu		= 1500,	/* could be more, but some receivers can't handle it... */
     52	.is_ip          = 1,    /* This is for sending IP and ARP packages */
     53	.rx		= rx,
     54	.build_header	= build_header,
     55	.prepare_tx	= prepare_tx,
     56	.continue_tx	= continue_tx,
     57	.ack_tx         = NULL
     58};
     59
     60static int __init arcnet_rfc1201_init(void)
     61{
     62	pr_info("%s\n", "RFC1201 \"standard\" (`a') encapsulation support loaded");
     63
     64	arc_proto_map[ARC_P_IP]
     65	    = arc_proto_map[ARC_P_IPV6]
     66	    = arc_proto_map[ARC_P_ARP]
     67	    = arc_proto_map[ARC_P_RARP]
     68	    = arc_proto_map[ARC_P_IPX]
     69	    = arc_proto_map[ARC_P_NOVELL_EC]
     70	    = &rfc1201_proto;
     71
     72	/* if someone else already owns the broadcast, we won't take it */
     73	if (arc_bcast_proto == arc_proto_default)
     74		arc_bcast_proto = &rfc1201_proto;
     75
     76	return 0;
     77}
     78
     79static void __exit arcnet_rfc1201_exit(void)
     80{
     81	arcnet_unregister_proto(&rfc1201_proto);
     82}
     83
     84module_init(arcnet_rfc1201_init);
     85module_exit(arcnet_rfc1201_exit);
     86
     87/* Determine a packet's protocol ID.
     88 *
     89 * With ARCnet we have to convert everything to Ethernet-style stuff.
     90 */
     91static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
     92{
     93	struct archdr *pkt = (struct archdr *)skb->data;
     94	struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
     95	int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
     96
     97	/* Pull off the arcnet header. */
     98	skb_reset_mac_header(skb);
     99	skb_pull(skb, hdr_size);
    100
    101	if (pkt->hard.dest == 0) {
    102		skb->pkt_type = PACKET_BROADCAST;
    103	} else if (dev->flags & IFF_PROMISC) {
    104		/* if we're not sending to ourselves :) */
    105		if (pkt->hard.dest != dev->dev_addr[0])
    106			skb->pkt_type = PACKET_OTHERHOST;
    107	}
    108	/* now return the protocol number */
    109	switch (soft->proto) {
    110	case ARC_P_IP:
    111		return htons(ETH_P_IP);
    112	case ARC_P_IPV6:
    113		return htons(ETH_P_IPV6);
    114	case ARC_P_ARP:
    115		return htons(ETH_P_ARP);
    116	case ARC_P_RARP:
    117		return htons(ETH_P_RARP);
    118
    119	case ARC_P_IPX:
    120	case ARC_P_NOVELL_EC:
    121		return htons(ETH_P_802_3);
    122	default:
    123		dev->stats.rx_errors++;
    124		dev->stats.rx_crc_errors++;
    125		return 0;
    126	}
    127
    128	return htons(ETH_P_IP);
    129}
    130
    131/* packet receiver */
    132static void rx(struct net_device *dev, int bufnum,
    133	       struct archdr *pkthdr, int length)
    134{
    135	struct arcnet_local *lp = netdev_priv(dev);
    136	struct sk_buff *skb;
    137	struct archdr *pkt = pkthdr;
    138	struct arc_rfc1201 *soft = &pkthdr->soft.rfc1201;
    139	int saddr = pkt->hard.source, ofs;
    140	struct Incoming *in = &lp->rfc1201.incoming[saddr];
    141
    142	arc_printk(D_DURING, dev, "it's an RFC1201 packet (length=%d)\n",
    143		   length);
    144
    145	if (length >= MinTU)
    146		ofs = 512 - length;
    147	else
    148		ofs = 256 - length;
    149
    150	if (soft->split_flag == 0xFF) {		/* Exception Packet */
    151		if (length >= 4 + RFC1201_HDR_SIZE) {
    152			arc_printk(D_DURING, dev, "compensating for exception packet\n");
    153		} else {
    154			arc_printk(D_EXTRA, dev, "short RFC1201 exception packet from %02Xh",
    155				   saddr);
    156			return;
    157		}
    158
    159		/* skip over 4-byte junkola */
    160		length -= 4;
    161		ofs += 4;
    162		lp->hw.copy_from_card(dev, bufnum, 512 - length,
    163				      soft, sizeof(pkt->soft));
    164	}
    165	if (!soft->split_flag) {	/* not split */
    166		arc_printk(D_RX, dev, "incoming is not split (splitflag=%d)\n",
    167			   soft->split_flag);
    168
    169		if (in->skb) {	/* already assembling one! */
    170			arc_printk(D_EXTRA, dev, "aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)\n",
    171				   in->sequence, soft->split_flag,
    172				   soft->sequence);
    173			lp->rfc1201.aborted_seq = soft->sequence;
    174			dev_kfree_skb_irq(in->skb);
    175			dev->stats.rx_errors++;
    176			dev->stats.rx_missed_errors++;
    177			in->skb = NULL;
    178		}
    179		in->sequence = soft->sequence;
    180
    181		skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
    182		if (!skb) {
    183			dev->stats.rx_dropped++;
    184			return;
    185		}
    186		skb_put(skb, length + ARC_HDR_SIZE);
    187		skb->dev = dev;
    188
    189		pkt = (struct archdr *)skb->data;
    190		soft = &pkt->soft.rfc1201;
    191
    192		/* up to sizeof(pkt->soft) has already
    193		 * been copied from the card
    194		 */
    195		memcpy(pkt, pkthdr, sizeof(struct archdr));
    196		if (length > sizeof(pkt->soft))
    197			lp->hw.copy_from_card(dev, bufnum,
    198					      ofs + sizeof(pkt->soft),
    199					      pkt->soft.raw + sizeof(pkt->soft),
    200					      length - sizeof(pkt->soft));
    201
    202		/* ARP packets have problems when sent from some DOS systems:
    203		 * the source address is always 0!
    204		 * So we take the hardware source addr (which is impossible
    205		 * to fumble) and insert it ourselves.
    206		 */
    207		if (soft->proto == ARC_P_ARP) {
    208			struct arphdr *arp = (struct arphdr *)soft->payload;
    209
    210			/* make sure addresses are the right length */
    211			if (arp->ar_hln == 1 && arp->ar_pln == 4) {
    212				uint8_t *cptr = (uint8_t *)arp + sizeof(struct arphdr);
    213
    214				if (!*cptr) {	/* is saddr = 00? */
    215					arc_printk(D_EXTRA, dev,
    216						   "ARP source address was 00h, set to %02Xh\n",
    217						   saddr);
    218					dev->stats.rx_crc_errors++;
    219					*cptr = saddr;
    220				} else {
    221					arc_printk(D_DURING, dev, "ARP source address (%Xh) is fine.\n",
    222						   *cptr);
    223				}
    224			} else {
    225				arc_printk(D_NORMAL, dev, "funny-shaped ARP packet. (%Xh, %Xh)\n",
    226					   arp->ar_hln, arp->ar_pln);
    227				dev->stats.rx_errors++;
    228				dev->stats.rx_crc_errors++;
    229			}
    230		}
    231		if (BUGLVL(D_SKB))
    232			arcnet_dump_skb(dev, skb, "rx");
    233
    234		skb->protocol = type_trans(skb, dev);
    235		netif_rx(skb);
    236	} else {		/* split packet */
    237		/* NOTE: MSDOS ARP packet correction should only need to
    238		 * apply to unsplit packets, since ARP packets are so short.
    239		 *
    240		 * My interpretation of the RFC1201 document is that if a
    241		 * packet is received out of order, the entire assembly
    242		 * process should be aborted.
    243		 *
    244		 * The RFC also mentions "it is possible for successfully
    245		 * received packets to be retransmitted." As of 0.40 all
    246		 * previously received packets are allowed, not just the
    247		 * most recent one.
    248		 *
    249		 * We allow multiple assembly processes, one for each
    250		 * ARCnet card possible on the network.
    251		 * Seems rather like a waste of memory, but there's no
    252		 * other way to be reliable.
    253		 */
    254
    255		arc_printk(D_RX, dev, "packet is split (splitflag=%d, seq=%d)\n",
    256			   soft->split_flag, in->sequence);
    257
    258		if (in->skb && in->sequence != soft->sequence) {
    259			arc_printk(D_EXTRA, dev, "wrong seq number (saddr=%d, expected=%d, seq=%d, splitflag=%d)\n",
    260				   saddr, in->sequence, soft->sequence,
    261				   soft->split_flag);
    262			dev_kfree_skb_irq(in->skb);
    263			in->skb = NULL;
    264			dev->stats.rx_errors++;
    265			dev->stats.rx_missed_errors++;
    266			in->lastpacket = in->numpackets = 0;
    267		}
    268		if (soft->split_flag & 1) {	/* first packet in split */
    269			arc_printk(D_RX, dev, "brand new splitpacket (splitflag=%d)\n",
    270				   soft->split_flag);
    271			if (in->skb) {	/* already assembling one! */
    272				arc_printk(D_EXTRA, dev, "aborting previous (seq=%d) assembly (splitflag=%d, seq=%d)\n",
    273					   in->sequence, soft->split_flag,
    274					   soft->sequence);
    275				dev->stats.rx_errors++;
    276				dev->stats.rx_missed_errors++;
    277				dev_kfree_skb_irq(in->skb);
    278			}
    279			in->sequence = soft->sequence;
    280			in->numpackets = ((unsigned)soft->split_flag >> 1) + 2;
    281			in->lastpacket = 1;
    282
    283			if (in->numpackets > 16) {
    284				arc_printk(D_EXTRA, dev, "incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
    285					   soft->split_flag);
    286				lp->rfc1201.aborted_seq = soft->sequence;
    287				dev->stats.rx_errors++;
    288				dev->stats.rx_length_errors++;
    289				return;
    290			}
    291			in->skb = skb = alloc_skb(508 * in->numpackets + ARC_HDR_SIZE,
    292						  GFP_ATOMIC);
    293			if (!skb) {
    294				arc_printk(D_NORMAL, dev, "(split) memory squeeze, dropping packet.\n");
    295				lp->rfc1201.aborted_seq = soft->sequence;
    296				dev->stats.rx_dropped++;
    297				return;
    298			}
    299			skb->dev = dev;
    300			pkt = (struct archdr *)skb->data;
    301			soft = &pkt->soft.rfc1201;
    302
    303			memcpy(pkt, pkthdr, ARC_HDR_SIZE + RFC1201_HDR_SIZE);
    304			skb_put(skb, ARC_HDR_SIZE + RFC1201_HDR_SIZE);
    305
    306			soft->split_flag = 0;	/* end result won't be split */
    307		} else {	/* not first packet */
    308			int packetnum = ((unsigned)soft->split_flag >> 1) + 1;
    309
    310			/* if we're not assembling, there's no point trying to
    311			 * continue.
    312			 */
    313			if (!in->skb) {
    314				if (lp->rfc1201.aborted_seq != soft->sequence) {
    315					arc_printk(D_EXTRA, dev, "can't continue split without starting first! (splitflag=%d, seq=%d, aborted=%d)\n",
    316						   soft->split_flag,
    317						   soft->sequence,
    318						   lp->rfc1201.aborted_seq);
    319					dev->stats.rx_errors++;
    320					dev->stats.rx_missed_errors++;
    321				}
    322				return;
    323			}
    324			in->lastpacket++;
    325			/* if not the right flag */
    326			if (packetnum != in->lastpacket) {
    327				/* harmless duplicate? ignore. */
    328				if (packetnum <= in->lastpacket - 1) {
    329					arc_printk(D_EXTRA, dev, "duplicate splitpacket ignored! (splitflag=%d)\n",
    330						   soft->split_flag);
    331					dev->stats.rx_errors++;
    332					dev->stats.rx_frame_errors++;
    333					return;
    334				}
    335				/* "bad" duplicate, kill reassembly */
    336				arc_printk(D_EXTRA, dev, "out-of-order splitpacket, reassembly (seq=%d) aborted (splitflag=%d, seq=%d)\n",
    337					   in->sequence, soft->split_flag,
    338					   soft->sequence);
    339				lp->rfc1201.aborted_seq = soft->sequence;
    340				dev_kfree_skb_irq(in->skb);
    341				in->skb = NULL;
    342				dev->stats.rx_errors++;
    343				dev->stats.rx_missed_errors++;
    344				in->lastpacket = in->numpackets = 0;
    345				return;
    346			}
    347			pkt = (struct archdr *)in->skb->data;
    348			soft = &pkt->soft.rfc1201;
    349		}
    350
    351		skb = in->skb;
    352
    353		lp->hw.copy_from_card(dev, bufnum, ofs + RFC1201_HDR_SIZE,
    354				      skb->data + skb->len,
    355				      length - RFC1201_HDR_SIZE);
    356		skb_put(skb, length - RFC1201_HDR_SIZE);
    357
    358		/* are we done? */
    359		if (in->lastpacket == in->numpackets) {
    360			in->skb = NULL;
    361			in->lastpacket = in->numpackets = 0;
    362
    363			arc_printk(D_SKB_SIZE, dev, "skb: received %d bytes from %02X (unsplit)\n",
    364				   skb->len, pkt->hard.source);
    365			arc_printk(D_SKB_SIZE, dev, "skb: received %d bytes from %02X (split)\n",
    366				   skb->len, pkt->hard.source);
    367			if (BUGLVL(D_SKB))
    368				arcnet_dump_skb(dev, skb, "rx");
    369
    370			skb->protocol = type_trans(skb, dev);
    371			netif_rx(skb);
    372		}
    373	}
    374}
    375
    376/* Create the ARCnet hard/soft headers for RFC1201. */
    377static int build_header(struct sk_buff *skb, struct net_device *dev,
    378			unsigned short type, uint8_t daddr)
    379{
    380	struct arcnet_local *lp = netdev_priv(dev);
    381	int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
    382	struct archdr *pkt = skb_push(skb, hdr_size);
    383	struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
    384
    385	/* set the protocol ID according to RFC1201 */
    386	switch (type) {
    387	case ETH_P_IP:
    388		soft->proto = ARC_P_IP;
    389		break;
    390	case ETH_P_IPV6:
    391		soft->proto = ARC_P_IPV6;
    392		break;
    393	case ETH_P_ARP:
    394		soft->proto = ARC_P_ARP;
    395		break;
    396	case ETH_P_RARP:
    397		soft->proto = ARC_P_RARP;
    398		break;
    399	case ETH_P_IPX:
    400	case ETH_P_802_3:
    401	case ETH_P_802_2:
    402		soft->proto = ARC_P_IPX;
    403		break;
    404	case ETH_P_ATALK:
    405		soft->proto = ARC_P_ATALK;
    406		break;
    407	default:
    408		arc_printk(D_NORMAL, dev, "RFC1201: I don't understand protocol %d (%Xh)\n",
    409			   type, type);
    410		dev->stats.tx_errors++;
    411		dev->stats.tx_aborted_errors++;
    412		return 0;
    413	}
    414
    415	/* Set the source hardware address.
    416	 *
    417	 * This is pretty pointless for most purposes, but it can help in
    418	 * debugging.  ARCnet does not allow us to change the source address
    419	 * in the actual packet sent.
    420	 */
    421	pkt->hard.source = *dev->dev_addr;
    422
    423	soft->sequence = htons(lp->rfc1201.sequence++);
    424	soft->split_flag = 0;	/* split packets are done elsewhere */
    425
    426	/* see linux/net/ethernet/eth.c to see where I got the following */
    427
    428	if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
    429		/* FIXME: fill in the last byte of the dest ipaddr here
    430		 * to better comply with RFC1051 in "noarp" mode.
    431		 * For now, always broadcasting will probably at least get
    432		 * packets sent out :)
    433		 */
    434		pkt->hard.dest = 0;
    435		return hdr_size;
    436	}
    437	/* otherwise, drop in the dest address */
    438	pkt->hard.dest = daddr;
    439	return hdr_size;
    440}
    441
    442static void load_pkt(struct net_device *dev, struct arc_hardware *hard,
    443		     struct arc_rfc1201 *soft, int softlen, int bufnum)
    444{
    445	struct arcnet_local *lp = netdev_priv(dev);
    446	int ofs;
    447
    448	/* assume length <= XMTU: someone should have handled that by now. */
    449
    450	if (softlen > MinTU) {
    451		hard->offset[0] = 0;
    452		hard->offset[1] = ofs = 512 - softlen;
    453	} else if (softlen > MTU) {	/* exception packet - add an extra header */
    454		struct arc_rfc1201 excsoft;
    455
    456		excsoft.proto = soft->proto;
    457		excsoft.split_flag = 0xff;
    458		excsoft.sequence = htons(0xffff);
    459
    460		hard->offset[0] = 0;
    461		ofs = 512 - softlen;
    462		hard->offset[1] = ofs - RFC1201_HDR_SIZE;
    463		lp->hw.copy_to_card(dev, bufnum, ofs - RFC1201_HDR_SIZE,
    464				    &excsoft, RFC1201_HDR_SIZE);
    465	} else {
    466		hard->offset[0] = ofs = 256 - softlen;
    467	}
    468
    469	lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
    470	lp->hw.copy_to_card(dev, bufnum, ofs, soft, softlen);
    471
    472	lp->lastload_dest = hard->dest;
    473}
    474
    475static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
    476		      int bufnum)
    477{
    478	struct arcnet_local *lp = netdev_priv(dev);
    479	const int maxsegsize = XMTU - RFC1201_HDR_SIZE;
    480	struct Outgoing *out;
    481
    482	arc_printk(D_DURING, dev, "prepare_tx: txbufs=%d/%d/%d\n",
    483		   lp->next_tx, lp->cur_tx, bufnum);
    484
    485	/* hard header is not included in packet length */
    486	length -= ARC_HDR_SIZE;
    487	pkt->soft.rfc1201.split_flag = 0;
    488
    489	/* need to do a split packet? */
    490	if (length > XMTU) {
    491		out = &lp->outgoing;
    492
    493		out->length = length - RFC1201_HDR_SIZE;
    494		out->dataleft = lp->outgoing.length;
    495		out->numsegs = (out->dataleft + maxsegsize - 1) / maxsegsize;
    496		out->segnum = 0;
    497
    498		arc_printk(D_DURING, dev, "rfc1201 prep_tx: ready for %d-segment split (%d bytes, seq=%d)\n",
    499			   out->numsegs, out->length,
    500			   pkt->soft.rfc1201.sequence);
    501
    502		return 0;	/* not done */
    503	}
    504	/* just load the packet into the buffers and send it off */
    505	load_pkt(dev, &pkt->hard, &pkt->soft.rfc1201, length, bufnum);
    506
    507	return 1;		/* done */
    508}
    509
    510static int continue_tx(struct net_device *dev, int bufnum)
    511{
    512	struct arcnet_local *lp = netdev_priv(dev);
    513	struct Outgoing *out = &lp->outgoing;
    514	struct arc_hardware *hard = &out->pkt->hard;
    515	struct arc_rfc1201 *soft = &out->pkt->soft.rfc1201, *newsoft;
    516	int maxsegsize = XMTU - RFC1201_HDR_SIZE;
    517	int seglen;
    518
    519	arc_printk(D_DURING, dev,
    520		   "rfc1201 continue_tx: loading segment %d(+1) of %d (seq=%d)\n",
    521		   out->segnum, out->numsegs, soft->sequence);
    522
    523	/* the "new" soft header comes right before the data chunk */
    524	newsoft = (struct arc_rfc1201 *)
    525	    (out->pkt->soft.raw + out->length - out->dataleft);
    526
    527	if (!out->segnum)	/* first packet; newsoft == soft */
    528		newsoft->split_flag = ((out->numsegs - 2) << 1) | 1;
    529	else {
    530		newsoft->split_flag = out->segnum << 1;
    531		newsoft->proto = soft->proto;
    532		newsoft->sequence = soft->sequence;
    533	}
    534
    535	seglen = maxsegsize;
    536	if (seglen > out->dataleft)
    537		seglen = out->dataleft;
    538	out->dataleft -= seglen;
    539
    540	load_pkt(dev, hard, newsoft, seglen + RFC1201_HDR_SIZE, bufnum);
    541
    542	out->segnum++;
    543	if (out->segnum >= out->numsegs)
    544		return 1;
    545	else
    546		return 0;
    547}