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 */ 39 static 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 */ 103 static 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 */ 141 static 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 */ 266 static 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 */ 419 int 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 } 444
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.