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