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_in.c (7534B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *
      4 * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
      5 *
      6 * Most of this code is based on the SDL diagrams published in the 7th ARRL
      7 * Computer Networking Conference papers. The diagrams have mistakes in them,
      8 * but are mostly correct. Before you modify the code could you read the SDL
      9 * diagrams as the code is not obvious and probably very easy to break.
     10 */
     11#include <linux/errno.h>
     12#include <linux/filter.h>
     13#include <linux/types.h>
     14#include <linux/socket.h>
     15#include <linux/in.h>
     16#include <linux/kernel.h>
     17#include <linux/timer.h>
     18#include <linux/string.h>
     19#include <linux/sockios.h>
     20#include <linux/net.h>
     21#include <net/ax25.h>
     22#include <linux/inet.h>
     23#include <linux/netdevice.h>
     24#include <linux/skbuff.h>
     25#include <net/sock.h>
     26#include <net/tcp_states.h>
     27#include <linux/fcntl.h>
     28#include <linux/mm.h>
     29#include <linux/interrupt.h>
     30#include <net/rose.h>
     31
     32/*
     33 * State machine for state 1, Awaiting Call Accepted State.
     34 * The handling of the timer(s) is in file rose_timer.c.
     35 * Handling of state 0 and connection release is in af_rose.c.
     36 */
     37static int rose_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype)
     38{
     39	struct rose_sock *rose = rose_sk(sk);
     40
     41	switch (frametype) {
     42	case ROSE_CALL_ACCEPTED:
     43		rose_stop_timer(sk);
     44		rose_start_idletimer(sk);
     45		rose->condition = 0x00;
     46		rose->vs        = 0;
     47		rose->va        = 0;
     48		rose->vr        = 0;
     49		rose->vl        = 0;
     50		rose->state     = ROSE_STATE_3;
     51		sk->sk_state	= TCP_ESTABLISHED;
     52		if (!sock_flag(sk, SOCK_DEAD))
     53			sk->sk_state_change(sk);
     54		break;
     55
     56	case ROSE_CLEAR_REQUEST:
     57		rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
     58		rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
     59		rose->neighbour->use--;
     60		break;
     61
     62	default:
     63		break;
     64	}
     65
     66	return 0;
     67}
     68
     69/*
     70 * State machine for state 2, Awaiting Clear Confirmation State.
     71 * The handling of the timer(s) is in file rose_timer.c
     72 * Handling of state 0 and connection release is in af_rose.c.
     73 */
     74static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int frametype)
     75{
     76	struct rose_sock *rose = rose_sk(sk);
     77
     78	switch (frametype) {
     79	case ROSE_CLEAR_REQUEST:
     80		rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
     81		rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
     82		rose->neighbour->use--;
     83		break;
     84
     85	case ROSE_CLEAR_CONFIRMATION:
     86		rose_disconnect(sk, 0, -1, -1);
     87		rose->neighbour->use--;
     88		break;
     89
     90	default:
     91		break;
     92	}
     93
     94	return 0;
     95}
     96
     97/*
     98 * State machine for state 3, Connected State.
     99 * The handling of the timer(s) is in file rose_timer.c
    100 * Handling of state 0 and connection release is in af_rose.c.
    101 */
    102static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype, int ns, int nr, int q, int d, int m)
    103{
    104	struct rose_sock *rose = rose_sk(sk);
    105	int queued = 0;
    106
    107	switch (frametype) {
    108	case ROSE_RESET_REQUEST:
    109		rose_stop_timer(sk);
    110		rose_start_idletimer(sk);
    111		rose_write_internal(sk, ROSE_RESET_CONFIRMATION);
    112		rose->condition = 0x00;
    113		rose->vs        = 0;
    114		rose->vr        = 0;
    115		rose->va        = 0;
    116		rose->vl        = 0;
    117		rose_requeue_frames(sk);
    118		break;
    119
    120	case ROSE_CLEAR_REQUEST:
    121		rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
    122		rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
    123		rose->neighbour->use--;
    124		break;
    125
    126	case ROSE_RR:
    127	case ROSE_RNR:
    128		if (!rose_validate_nr(sk, nr)) {
    129			rose_write_internal(sk, ROSE_RESET_REQUEST);
    130			rose->condition = 0x00;
    131			rose->vs        = 0;
    132			rose->vr        = 0;
    133			rose->va        = 0;
    134			rose->vl        = 0;
    135			rose->state     = ROSE_STATE_4;
    136			rose_start_t2timer(sk);
    137			rose_stop_idletimer(sk);
    138		} else {
    139			rose_frames_acked(sk, nr);
    140			if (frametype == ROSE_RNR) {
    141				rose->condition |= ROSE_COND_PEER_RX_BUSY;
    142			} else {
    143				rose->condition &= ~ROSE_COND_PEER_RX_BUSY;
    144			}
    145		}
    146		break;
    147
    148	case ROSE_DATA:	/* XXX */
    149		rose->condition &= ~ROSE_COND_PEER_RX_BUSY;
    150		if (!rose_validate_nr(sk, nr)) {
    151			rose_write_internal(sk, ROSE_RESET_REQUEST);
    152			rose->condition = 0x00;
    153			rose->vs        = 0;
    154			rose->vr        = 0;
    155			rose->va        = 0;
    156			rose->vl        = 0;
    157			rose->state     = ROSE_STATE_4;
    158			rose_start_t2timer(sk);
    159			rose_stop_idletimer(sk);
    160			break;
    161		}
    162		rose_frames_acked(sk, nr);
    163		if (ns == rose->vr) {
    164			rose_start_idletimer(sk);
    165			if (sk_filter_trim_cap(sk, skb, ROSE_MIN_LEN) == 0 &&
    166			    __sock_queue_rcv_skb(sk, skb) == 0) {
    167				rose->vr = (rose->vr + 1) % ROSE_MODULUS;
    168				queued = 1;
    169			} else {
    170				/* Should never happen ! */
    171				rose_write_internal(sk, ROSE_RESET_REQUEST);
    172				rose->condition = 0x00;
    173				rose->vs        = 0;
    174				rose->vr        = 0;
    175				rose->va        = 0;
    176				rose->vl        = 0;
    177				rose->state     = ROSE_STATE_4;
    178				rose_start_t2timer(sk);
    179				rose_stop_idletimer(sk);
    180				break;
    181			}
    182			if (atomic_read(&sk->sk_rmem_alloc) >
    183			    (sk->sk_rcvbuf >> 1))
    184				rose->condition |= ROSE_COND_OWN_RX_BUSY;
    185		}
    186		/*
    187		 * If the window is full, ack the frame, else start the
    188		 * acknowledge hold back timer.
    189		 */
    190		if (((rose->vl + sysctl_rose_window_size) % ROSE_MODULUS) == rose->vr) {
    191			rose->condition &= ~ROSE_COND_ACK_PENDING;
    192			rose_stop_timer(sk);
    193			rose_enquiry_response(sk);
    194		} else {
    195			rose->condition |= ROSE_COND_ACK_PENDING;
    196			rose_start_hbtimer(sk);
    197		}
    198		break;
    199
    200	default:
    201		printk(KERN_WARNING "ROSE: unknown %02X in state 3\n", frametype);
    202		break;
    203	}
    204
    205	return queued;
    206}
    207
    208/*
    209 * State machine for state 4, Awaiting Reset Confirmation State.
    210 * The handling of the timer(s) is in file rose_timer.c
    211 * Handling of state 0 and connection release is in af_rose.c.
    212 */
    213static int rose_state4_machine(struct sock *sk, struct sk_buff *skb, int frametype)
    214{
    215	struct rose_sock *rose = rose_sk(sk);
    216
    217	switch (frametype) {
    218	case ROSE_RESET_REQUEST:
    219		rose_write_internal(sk, ROSE_RESET_CONFIRMATION);
    220		fallthrough;
    221	case ROSE_RESET_CONFIRMATION:
    222		rose_stop_timer(sk);
    223		rose_start_idletimer(sk);
    224		rose->condition = 0x00;
    225		rose->va        = 0;
    226		rose->vr        = 0;
    227		rose->vs        = 0;
    228		rose->vl        = 0;
    229		rose->state     = ROSE_STATE_3;
    230		rose_requeue_frames(sk);
    231		break;
    232
    233	case ROSE_CLEAR_REQUEST:
    234		rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
    235		rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
    236		rose->neighbour->use--;
    237		break;
    238
    239	default:
    240		break;
    241	}
    242
    243	return 0;
    244}
    245
    246/*
    247 * State machine for state 5, Awaiting Call Acceptance State.
    248 * The handling of the timer(s) is in file rose_timer.c
    249 * Handling of state 0 and connection release is in af_rose.c.
    250 */
    251static int rose_state5_machine(struct sock *sk, struct sk_buff *skb, int frametype)
    252{
    253	if (frametype == ROSE_CLEAR_REQUEST) {
    254		rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
    255		rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
    256		rose_sk(sk)->neighbour->use--;
    257	}
    258
    259	return 0;
    260}
    261
    262/* Higher level upcall for a LAPB frame */
    263int rose_process_rx_frame(struct sock *sk, struct sk_buff *skb)
    264{
    265	struct rose_sock *rose = rose_sk(sk);
    266	int queued = 0, frametype, ns, nr, q, d, m;
    267
    268	if (rose->state == ROSE_STATE_0)
    269		return 0;
    270
    271	frametype = rose_decode(skb, &ns, &nr, &q, &d, &m);
    272
    273	switch (rose->state) {
    274	case ROSE_STATE_1:
    275		queued = rose_state1_machine(sk, skb, frametype);
    276		break;
    277	case ROSE_STATE_2:
    278		queued = rose_state2_machine(sk, skb, frametype);
    279		break;
    280	case ROSE_STATE_3:
    281		queued = rose_state3_machine(sk, skb, frametype, ns, nr, q, d, m);
    282		break;
    283	case ROSE_STATE_4:
    284		queued = rose_state4_machine(sk, skb, frametype);
    285		break;
    286	case ROSE_STATE_5:
    287		queued = rose_state5_machine(sk, skb, frametype);
    288		break;
    289	}
    290
    291	rose_kick(sk);
    292
    293	return queued;
    294}