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