ax25_ds_in.c (7031B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * 4 * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk) 5 * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de) 6 */ 7#include <linux/errno.h> 8#include <linux/types.h> 9#include <linux/socket.h> 10#include <linux/in.h> 11#include <linux/kernel.h> 12#include <linux/timer.h> 13#include <linux/string.h> 14#include <linux/sockios.h> 15#include <linux/net.h> 16#include <net/ax25.h> 17#include <linux/inet.h> 18#include <linux/netdevice.h> 19#include <linux/skbuff.h> 20#include <net/sock.h> 21#include <net/tcp_states.h> 22#include <linux/uaccess.h> 23#include <linux/fcntl.h> 24#include <linux/mm.h> 25#include <linux/interrupt.h> 26 27/* 28 * State machine for state 1, Awaiting Connection State. 29 * The handling of the timer(s) is in file ax25_ds_timer.c. 30 * Handling of state 0 and connection release is in ax25.c. 31 */ 32static int ax25_ds_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type) 33{ 34 switch (frametype) { 35 case AX25_SABM: 36 ax25->modulus = AX25_MODULUS; 37 ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW]; 38 ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE); 39 break; 40 41 case AX25_SABME: 42 ax25->modulus = AX25_EMODULUS; 43 ax25->window = ax25->ax25_dev->values[AX25_VALUES_EWINDOW]; 44 ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE); 45 break; 46 47 case AX25_DISC: 48 ax25_send_control(ax25, AX25_DM, pf, AX25_RESPONSE); 49 break; 50 51 case AX25_UA: 52 ax25_calculate_rtt(ax25); 53 ax25_stop_t1timer(ax25); 54 ax25_start_t3timer(ax25); 55 ax25_start_idletimer(ax25); 56 ax25->vs = 0; 57 ax25->va = 0; 58 ax25->vr = 0; 59 ax25->state = AX25_STATE_3; 60 ax25->n2count = 0; 61 if (ax25->sk != NULL) { 62 bh_lock_sock(ax25->sk); 63 ax25->sk->sk_state = TCP_ESTABLISHED; 64 /* 65 * For WAIT_SABM connections we will produce an accept 66 * ready socket here 67 */ 68 if (!sock_flag(ax25->sk, SOCK_DEAD)) 69 ax25->sk->sk_state_change(ax25->sk); 70 bh_unlock_sock(ax25->sk); 71 } 72 ax25_dama_on(ax25); 73 74 /* according to DK4EG's spec we are required to 75 * send a RR RESPONSE FINAL NR=0. 76 */ 77 78 ax25_std_enquiry_response(ax25); 79 break; 80 81 case AX25_DM: 82 if (pf) 83 ax25_disconnect(ax25, ECONNREFUSED); 84 break; 85 86 default: 87 if (pf) 88 ax25_send_control(ax25, AX25_SABM, AX25_POLLON, AX25_COMMAND); 89 break; 90 } 91 92 return 0; 93} 94 95/* 96 * State machine for state 2, Awaiting Release State. 97 * The handling of the timer(s) is in file ax25_ds_timer.c 98 * Handling of state 0 and connection release is in ax25.c. 99 */ 100static int ax25_ds_state2_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type) 101{ 102 switch (frametype) { 103 case AX25_SABM: 104 case AX25_SABME: 105 ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND); 106 ax25_dama_off(ax25); 107 break; 108 109 case AX25_DISC: 110 ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE); 111 ax25_dama_off(ax25); 112 ax25_disconnect(ax25, 0); 113 break; 114 115 case AX25_DM: 116 case AX25_UA: 117 if (pf) { 118 ax25_dama_off(ax25); 119 ax25_disconnect(ax25, 0); 120 } 121 break; 122 123 case AX25_I: 124 case AX25_REJ: 125 case AX25_RNR: 126 case AX25_RR: 127 if (pf) { 128 ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND); 129 ax25_dama_off(ax25); 130 } 131 break; 132 133 default: 134 break; 135 } 136 137 return 0; 138} 139 140/* 141 * State machine for state 3, Connected State. 142 * The handling of the timer(s) is in file ax25_timer.c 143 * Handling of state 0 and connection release is in ax25.c. 144 */ 145static int ax25_ds_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type) 146{ 147 int queued = 0; 148 149 switch (frametype) { 150 case AX25_SABM: 151 case AX25_SABME: 152 if (frametype == AX25_SABM) { 153 ax25->modulus = AX25_MODULUS; 154 ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW]; 155 } else { 156 ax25->modulus = AX25_EMODULUS; 157 ax25->window = ax25->ax25_dev->values[AX25_VALUES_EWINDOW]; 158 } 159 ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE); 160 ax25_stop_t1timer(ax25); 161 ax25_start_t3timer(ax25); 162 ax25_start_idletimer(ax25); 163 ax25->condition = 0x00; 164 ax25->vs = 0; 165 ax25->va = 0; 166 ax25->vr = 0; 167 ax25_requeue_frames(ax25); 168 ax25_dama_on(ax25); 169 break; 170 171 case AX25_DISC: 172 ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE); 173 ax25_dama_off(ax25); 174 ax25_disconnect(ax25, 0); 175 break; 176 177 case AX25_DM: 178 ax25_dama_off(ax25); 179 ax25_disconnect(ax25, ECONNRESET); 180 break; 181 182 case AX25_RR: 183 case AX25_RNR: 184 if (frametype == AX25_RR) 185 ax25->condition &= ~AX25_COND_PEER_RX_BUSY; 186 else 187 ax25->condition |= AX25_COND_PEER_RX_BUSY; 188 189 if (ax25_validate_nr(ax25, nr)) { 190 if (ax25_check_iframes_acked(ax25, nr)) 191 ax25->n2count=0; 192 if (type == AX25_COMMAND && pf) 193 ax25_ds_enquiry_response(ax25); 194 } else { 195 ax25_ds_nr_error_recovery(ax25); 196 ax25->state = AX25_STATE_1; 197 } 198 break; 199 200 case AX25_REJ: 201 ax25->condition &= ~AX25_COND_PEER_RX_BUSY; 202 203 if (ax25_validate_nr(ax25, nr)) { 204 if (ax25->va != nr) 205 ax25->n2count=0; 206 207 ax25_frames_acked(ax25, nr); 208 ax25_calculate_rtt(ax25); 209 ax25_stop_t1timer(ax25); 210 ax25_start_t3timer(ax25); 211 ax25_requeue_frames(ax25); 212 213 if (type == AX25_COMMAND && pf) 214 ax25_ds_enquiry_response(ax25); 215 } else { 216 ax25_ds_nr_error_recovery(ax25); 217 ax25->state = AX25_STATE_1; 218 } 219 break; 220 221 case AX25_I: 222 if (!ax25_validate_nr(ax25, nr)) { 223 ax25_ds_nr_error_recovery(ax25); 224 ax25->state = AX25_STATE_1; 225 break; 226 } 227 if (ax25->condition & AX25_COND_PEER_RX_BUSY) { 228 ax25_frames_acked(ax25, nr); 229 ax25->n2count = 0; 230 } else { 231 if (ax25_check_iframes_acked(ax25, nr)) 232 ax25->n2count = 0; 233 } 234 if (ax25->condition & AX25_COND_OWN_RX_BUSY) { 235 if (pf) ax25_ds_enquiry_response(ax25); 236 break; 237 } 238 if (ns == ax25->vr) { 239 ax25->vr = (ax25->vr + 1) % ax25->modulus; 240 queued = ax25_rx_iframe(ax25, skb); 241 if (ax25->condition & AX25_COND_OWN_RX_BUSY) 242 ax25->vr = ns; /* ax25->vr - 1 */ 243 ax25->condition &= ~AX25_COND_REJECT; 244 if (pf) { 245 ax25_ds_enquiry_response(ax25); 246 } else { 247 if (!(ax25->condition & AX25_COND_ACK_PENDING)) { 248 ax25->condition |= AX25_COND_ACK_PENDING; 249 ax25_start_t2timer(ax25); 250 } 251 } 252 } else { 253 if (ax25->condition & AX25_COND_REJECT) { 254 if (pf) ax25_ds_enquiry_response(ax25); 255 } else { 256 ax25->condition |= AX25_COND_REJECT; 257 ax25_ds_enquiry_response(ax25); 258 ax25->condition &= ~AX25_COND_ACK_PENDING; 259 } 260 } 261 break; 262 263 case AX25_FRMR: 264 case AX25_ILLEGAL: 265 ax25_ds_establish_data_link(ax25); 266 ax25->state = AX25_STATE_1; 267 break; 268 269 default: 270 break; 271 } 272 273 return queued; 274} 275 276/* 277 * Higher level upcall for a LAPB frame 278 */ 279int ax25_ds_frame_in(ax25_cb *ax25, struct sk_buff *skb, int type) 280{ 281 int queued = 0, frametype, ns, nr, pf; 282 283 frametype = ax25_decode(ax25, skb, &ns, &nr, &pf); 284 285 switch (ax25->state) { 286 case AX25_STATE_1: 287 queued = ax25_ds_state1_machine(ax25, skb, frametype, pf, type); 288 break; 289 case AX25_STATE_2: 290 queued = ax25_ds_state2_machine(ax25, skb, frametype, pf, type); 291 break; 292 case AX25_STATE_3: 293 queued = ax25_ds_state3_machine(ax25, skb, frametype, ns, nr, pf, type); 294 break; 295 } 296 297 return queued; 298}