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