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