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

ax25_std_in.c (11114B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *
      4 * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
      5 * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
      6 * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
      7 * Copyright (C) Hans-Joachim Hetscher DD8NE (dd8ne@bnv-bamberg.de)
      8 *
      9 * Most of this code is based on the SDL diagrams published in the 7th ARRL
     10 * Computer Networking Conference papers. The diagrams have mistakes in them,
     11 * but are mostly correct. Before you modify the code could you read the SDL
     12 * diagrams as the code is not obvious and probably very easy to break.
     13 */
     14#include <linux/errno.h>
     15#include <linux/types.h>
     16#include <linux/socket.h>
     17#include <linux/in.h>
     18#include <linux/kernel.h>
     19#include <linux/timer.h>
     20#include <linux/string.h>
     21#include <linux/sockios.h>
     22#include <linux/net.h>
     23#include <net/ax25.h>
     24#include <linux/inet.h>
     25#include <linux/netdevice.h>
     26#include <linux/skbuff.h>
     27#include <net/sock.h>
     28#include <net/tcp_states.h>
     29#include <linux/uaccess.h>
     30#include <linux/fcntl.h>
     31#include <linux/mm.h>
     32#include <linux/interrupt.h>
     33
     34/*
     35 *	State machine for state 1, Awaiting Connection State.
     36 *	The handling of the timer(s) is in file ax25_std_timer.c.
     37 *	Handling of state 0 and connection release is in ax25.c.
     38 */
     39static int ax25_std_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type)
     40{
     41	switch (frametype) {
     42	case AX25_SABM:
     43		ax25->modulus = AX25_MODULUS;
     44		ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
     45		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
     46		break;
     47
     48	case AX25_SABME:
     49		ax25->modulus = AX25_EMODULUS;
     50		ax25->window  = ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
     51		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
     52		break;
     53
     54	case AX25_DISC:
     55		ax25_send_control(ax25, AX25_DM, pf, AX25_RESPONSE);
     56		break;
     57
     58	case AX25_UA:
     59		if (pf) {
     60			ax25_calculate_rtt(ax25);
     61			ax25_stop_t1timer(ax25);
     62			ax25_start_t3timer(ax25);
     63			ax25_start_idletimer(ax25);
     64			ax25->vs      = 0;
     65			ax25->va      = 0;
     66			ax25->vr      = 0;
     67			ax25->state   = AX25_STATE_3;
     68			ax25->n2count = 0;
     69			if (ax25->sk != NULL) {
     70				bh_lock_sock(ax25->sk);
     71				ax25->sk->sk_state = TCP_ESTABLISHED;
     72				/* For WAIT_SABM connections we will produce an accept ready socket here */
     73				if (!sock_flag(ax25->sk, SOCK_DEAD))
     74					ax25->sk->sk_state_change(ax25->sk);
     75				bh_unlock_sock(ax25->sk);
     76			}
     77		}
     78		break;
     79
     80	case AX25_DM:
     81		if (pf) {
     82			if (ax25->modulus == AX25_MODULUS) {
     83				ax25_disconnect(ax25, ECONNREFUSED);
     84			} else {
     85				ax25->modulus = AX25_MODULUS;
     86				ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
     87			}
     88		}
     89		break;
     90
     91	default:
     92		break;
     93	}
     94
     95	return 0;
     96}
     97
     98/*
     99 *	State machine for state 2, Awaiting Release State.
    100 *	The handling of the timer(s) is in file ax25_std_timer.c
    101 *	Handling of state 0 and connection release is in ax25.c.
    102 */
    103static int ax25_std_state2_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type)
    104{
    105	switch (frametype) {
    106	case AX25_SABM:
    107	case AX25_SABME:
    108		ax25_send_control(ax25, AX25_DM, pf, AX25_RESPONSE);
    109		break;
    110
    111	case AX25_DISC:
    112		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
    113		ax25_disconnect(ax25, 0);
    114		break;
    115
    116	case AX25_DM:
    117	case AX25_UA:
    118		if (pf)
    119			ax25_disconnect(ax25, 0);
    120		break;
    121
    122	case AX25_I:
    123	case AX25_REJ:
    124	case AX25_RNR:
    125	case AX25_RR:
    126		if (pf) ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE);
    127		break;
    128
    129	default:
    130		break;
    131	}
    132
    133	return 0;
    134}
    135
    136/*
    137 *	State machine for state 3, Connected State.
    138 *	The handling of the timer(s) is in file ax25_std_timer.c
    139 *	Handling of state 0 and connection release is in ax25.c.
    140 */
    141static int ax25_std_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type)
    142{
    143	int queued = 0;
    144
    145	switch (frametype) {
    146	case AX25_SABM:
    147	case AX25_SABME:
    148		if (frametype == AX25_SABM) {
    149			ax25->modulus = AX25_MODULUS;
    150			ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
    151		} else {
    152			ax25->modulus = AX25_EMODULUS;
    153			ax25->window  = ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
    154		}
    155		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
    156		ax25_stop_t1timer(ax25);
    157		ax25_stop_t2timer(ax25);
    158		ax25_start_t3timer(ax25);
    159		ax25_start_idletimer(ax25);
    160		ax25->condition = 0x00;
    161		ax25->vs        = 0;
    162		ax25->va        = 0;
    163		ax25->vr        = 0;
    164		ax25_requeue_frames(ax25);
    165		break;
    166
    167	case AX25_DISC:
    168		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
    169		ax25_disconnect(ax25, 0);
    170		break;
    171
    172	case AX25_DM:
    173		ax25_disconnect(ax25, ECONNRESET);
    174		break;
    175
    176	case AX25_RR:
    177	case AX25_RNR:
    178		if (frametype == AX25_RR)
    179			ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
    180		else
    181			ax25->condition |= AX25_COND_PEER_RX_BUSY;
    182		if (type == AX25_COMMAND && pf)
    183			ax25_std_enquiry_response(ax25);
    184		if (ax25_validate_nr(ax25, nr)) {
    185			ax25_check_iframes_acked(ax25, nr);
    186		} else {
    187			ax25_std_nr_error_recovery(ax25);
    188			ax25->state = AX25_STATE_1;
    189		}
    190		break;
    191
    192	case AX25_REJ:
    193		ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
    194		if (type == AX25_COMMAND && pf)
    195			ax25_std_enquiry_response(ax25);
    196		if (ax25_validate_nr(ax25, nr)) {
    197			ax25_frames_acked(ax25, nr);
    198			ax25_calculate_rtt(ax25);
    199			ax25_stop_t1timer(ax25);
    200			ax25_start_t3timer(ax25);
    201			ax25_requeue_frames(ax25);
    202		} else {
    203			ax25_std_nr_error_recovery(ax25);
    204			ax25->state = AX25_STATE_1;
    205		}
    206		break;
    207
    208	case AX25_I:
    209		if (!ax25_validate_nr(ax25, nr)) {
    210			ax25_std_nr_error_recovery(ax25);
    211			ax25->state = AX25_STATE_1;
    212			break;
    213		}
    214		if (ax25->condition & AX25_COND_PEER_RX_BUSY) {
    215			ax25_frames_acked(ax25, nr);
    216		} else {
    217			ax25_check_iframes_acked(ax25, nr);
    218		}
    219		if (ax25->condition & AX25_COND_OWN_RX_BUSY) {
    220			if (pf) ax25_std_enquiry_response(ax25);
    221			break;
    222		}
    223		if (ns == ax25->vr) {
    224			ax25->vr = (ax25->vr + 1) % ax25->modulus;
    225			queued = ax25_rx_iframe(ax25, skb);
    226			if (ax25->condition & AX25_COND_OWN_RX_BUSY)
    227				ax25->vr = ns;	/* ax25->vr - 1 */
    228			ax25->condition &= ~AX25_COND_REJECT;
    229			if (pf) {
    230				ax25_std_enquiry_response(ax25);
    231			} else {
    232				if (!(ax25->condition & AX25_COND_ACK_PENDING)) {
    233					ax25->condition |= AX25_COND_ACK_PENDING;
    234					ax25_start_t2timer(ax25);
    235				}
    236			}
    237		} else {
    238			if (ax25->condition & AX25_COND_REJECT) {
    239				if (pf) ax25_std_enquiry_response(ax25);
    240			} else {
    241				ax25->condition |= AX25_COND_REJECT;
    242				ax25_send_control(ax25, AX25_REJ, pf, AX25_RESPONSE);
    243				ax25->condition &= ~AX25_COND_ACK_PENDING;
    244			}
    245		}
    246		break;
    247
    248	case AX25_FRMR:
    249	case AX25_ILLEGAL:
    250		ax25_std_establish_data_link(ax25);
    251		ax25->state = AX25_STATE_1;
    252		break;
    253
    254	default:
    255		break;
    256	}
    257
    258	return queued;
    259}
    260
    261/*
    262 *	State machine for state 4, Timer Recovery State.
    263 *	The handling of the timer(s) is in file ax25_std_timer.c
    264 *	Handling of state 0 and connection release is in ax25.c.
    265 */
    266static int ax25_std_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type)
    267{
    268	int queued = 0;
    269
    270	switch (frametype) {
    271	case AX25_SABM:
    272	case AX25_SABME:
    273		if (frametype == AX25_SABM) {
    274			ax25->modulus = AX25_MODULUS;
    275			ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
    276		} else {
    277			ax25->modulus = AX25_EMODULUS;
    278			ax25->window  = ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
    279		}
    280		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
    281		ax25_stop_t1timer(ax25);
    282		ax25_stop_t2timer(ax25);
    283		ax25_start_t3timer(ax25);
    284		ax25_start_idletimer(ax25);
    285		ax25->condition = 0x00;
    286		ax25->vs        = 0;
    287		ax25->va        = 0;
    288		ax25->vr        = 0;
    289		ax25->state     = AX25_STATE_3;
    290		ax25->n2count   = 0;
    291		ax25_requeue_frames(ax25);
    292		break;
    293
    294	case AX25_DISC:
    295		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
    296		ax25_disconnect(ax25, 0);
    297		break;
    298
    299	case AX25_DM:
    300		ax25_disconnect(ax25, ECONNRESET);
    301		break;
    302
    303	case AX25_RR:
    304	case AX25_RNR:
    305		if (frametype == AX25_RR)
    306			ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
    307		else
    308			ax25->condition |= AX25_COND_PEER_RX_BUSY;
    309		if (type == AX25_RESPONSE && pf) {
    310			ax25_stop_t1timer(ax25);
    311			ax25->n2count = 0;
    312			if (ax25_validate_nr(ax25, nr)) {
    313				ax25_frames_acked(ax25, nr);
    314				if (ax25->vs == ax25->va) {
    315					ax25_start_t3timer(ax25);
    316					ax25->state   = AX25_STATE_3;
    317				} else {
    318					ax25_requeue_frames(ax25);
    319				}
    320			} else {
    321				ax25_std_nr_error_recovery(ax25);
    322				ax25->state = AX25_STATE_1;
    323			}
    324			break;
    325		}
    326		if (type == AX25_COMMAND && pf)
    327			ax25_std_enquiry_response(ax25);
    328		if (ax25_validate_nr(ax25, nr)) {
    329			ax25_frames_acked(ax25, nr);
    330		} else {
    331			ax25_std_nr_error_recovery(ax25);
    332			ax25->state = AX25_STATE_1;
    333		}
    334		break;
    335
    336	case AX25_REJ:
    337		ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
    338		if (pf && type == AX25_RESPONSE) {
    339			ax25_stop_t1timer(ax25);
    340			ax25->n2count = 0;
    341			if (ax25_validate_nr(ax25, nr)) {
    342				ax25_frames_acked(ax25, nr);
    343				if (ax25->vs == ax25->va) {
    344					ax25_start_t3timer(ax25);
    345					ax25->state   = AX25_STATE_3;
    346				} else {
    347					ax25_requeue_frames(ax25);
    348				}
    349			} else {
    350				ax25_std_nr_error_recovery(ax25);
    351				ax25->state = AX25_STATE_1;
    352			}
    353			break;
    354		}
    355		if (type == AX25_COMMAND && pf)
    356			ax25_std_enquiry_response(ax25);
    357		if (ax25_validate_nr(ax25, nr)) {
    358			ax25_frames_acked(ax25, nr);
    359			ax25_requeue_frames(ax25);
    360		} else {
    361			ax25_std_nr_error_recovery(ax25);
    362			ax25->state = AX25_STATE_1;
    363		}
    364		break;
    365
    366	case AX25_I:
    367		if (!ax25_validate_nr(ax25, nr)) {
    368			ax25_std_nr_error_recovery(ax25);
    369			ax25->state = AX25_STATE_1;
    370			break;
    371		}
    372		ax25_frames_acked(ax25, nr);
    373		if (ax25->condition & AX25_COND_OWN_RX_BUSY) {
    374			if (pf)
    375				ax25_std_enquiry_response(ax25);
    376			break;
    377		}
    378		if (ns == ax25->vr) {
    379			ax25->vr = (ax25->vr + 1) % ax25->modulus;
    380			queued = ax25_rx_iframe(ax25, skb);
    381			if (ax25->condition & AX25_COND_OWN_RX_BUSY)
    382				ax25->vr = ns;	/* ax25->vr - 1 */
    383			ax25->condition &= ~AX25_COND_REJECT;
    384			if (pf) {
    385				ax25_std_enquiry_response(ax25);
    386			} else {
    387				if (!(ax25->condition & AX25_COND_ACK_PENDING)) {
    388					ax25->condition |= AX25_COND_ACK_PENDING;
    389					ax25_start_t2timer(ax25);
    390				}
    391			}
    392		} else {
    393			if (ax25->condition & AX25_COND_REJECT) {
    394				if (pf) ax25_std_enquiry_response(ax25);
    395			} else {
    396				ax25->condition |= AX25_COND_REJECT;
    397				ax25_send_control(ax25, AX25_REJ, pf, AX25_RESPONSE);
    398				ax25->condition &= ~AX25_COND_ACK_PENDING;
    399			}
    400		}
    401		break;
    402
    403	case AX25_FRMR:
    404	case AX25_ILLEGAL:
    405		ax25_std_establish_data_link(ax25);
    406		ax25->state = AX25_STATE_1;
    407		break;
    408
    409	default:
    410		break;
    411	}
    412
    413	return queued;
    414}
    415
    416/*
    417 *	Higher level upcall for a LAPB frame
    418 */
    419int ax25_std_frame_in(ax25_cb *ax25, struct sk_buff *skb, int type)
    420{
    421	int queued = 0, frametype, ns, nr, pf;
    422
    423	frametype = ax25_decode(ax25, skb, &ns, &nr, &pf);
    424
    425	switch (ax25->state) {
    426	case AX25_STATE_1:
    427		queued = ax25_std_state1_machine(ax25, skb, frametype, pf, type);
    428		break;
    429	case AX25_STATE_2:
    430		queued = ax25_std_state2_machine(ax25, skb, frametype, pf, type);
    431		break;
    432	case AX25_STATE_3:
    433		queued = ax25_std_state3_machine(ax25, skb, frametype, ns, nr, pf, type);
    434		break;
    435	case AX25_STATE_4:
    436		queued = ax25_std_state4_machine(ax25, skb, frametype, ns, nr, pf, type);
    437		break;
    438	}
    439
    440	ax25_kick(ax25);
    441
    442	return queued;
    443}