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 * 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/fcntl.h> 30#include <linux/mm.h> 31#include <linux/interrupt.h> 32#include <net/rose.h> 33 34/* 35 * State machine for state 1, Awaiting Call Accepted State. 36 * The handling of the timer(s) is in file rose_timer.c. 37 * Handling of state 0 and connection release is in af_rose.c. 38 */ 39static int rose_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype) 40{ 41 struct rose_sock *rose = rose_sk(sk); 42 43 switch (frametype) { 44 case ROSE_CALL_ACCEPTED: 45 rose_stop_timer(sk); 46 rose_start_idletimer(sk); 47 rose->condition = 0x00; 48 rose->vs = 0; 49 rose->va = 0; 50 rose->vr = 0; 51 rose->vl = 0; 52 rose->state = ROSE_STATE_3; 53 sk->sk_state = TCP_ESTABLISHED; 54 if (!sock_flag(sk, SOCK_DEAD)) 55 sk->sk_state_change(sk); 56 break; 57 58 case ROSE_CLEAR_REQUEST: 59 rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION); 60 rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]); 61 rose->neighbour->use--; 62 break; 63 64 default: 65 break; 66 } 67 68 return 0; 69} 70 71/* 72 * State machine for state 2, Awaiting Clear Confirmation State. 73 * The handling of the timer(s) is in file rose_timer.c 74 * Handling of state 0 and connection release is in af_rose.c. 75 */ 76static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int frametype) 77{ 78 struct rose_sock *rose = rose_sk(sk); 79 80 switch (frametype) { 81 case ROSE_CLEAR_REQUEST: 82 rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION); 83 rose_disconnect(sk, 0, skb->data[3], skb->data[4]); 84 rose->neighbour->use--; 85 break; 86 87 case ROSE_CLEAR_CONFIRMATION: 88 rose_disconnect(sk, 0, -1, -1); 89 rose->neighbour->use--; 90 break; 91 92 default: 93 break; 94 } 95 96 return 0; 97} 98 99/* 100 * State machine for state 3, Connected State. 101 * The handling of the timer(s) is in file rose_timer.c 102 * Handling of state 0 and connection release is in af_rose.c. 103 */ 104static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype, int ns, int nr, int q, int d, int m) 105{ 106 struct rose_sock *rose = rose_sk(sk); 107 int queued = 0; 108 109 switch (frametype) { 110 case ROSE_RESET_REQUEST: 111 rose_stop_timer(sk); 112 rose_start_idletimer(sk); 113 rose_write_internal(sk, ROSE_RESET_CONFIRMATION); 114 rose->condition = 0x00; 115 rose->vs = 0; 116 rose->vr = 0; 117 rose->va = 0; 118 rose->vl = 0; 119 rose_requeue_frames(sk); 120 break; 121 122 case ROSE_CLEAR_REQUEST: 123 rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION); 124 rose_disconnect(sk, 0, skb->data[3], skb->data[4]); 125 rose->neighbour->use--; 126 break; 127 128 case ROSE_RR: 129 case ROSE_RNR: 130 if (!rose_validate_nr(sk, nr)) { 131 rose_write_internal(sk, ROSE_RESET_REQUEST); 132 rose->condition = 0x00; 133 rose->vs = 0; 134 rose->vr = 0; 135 rose->va = 0; 136 rose->vl = 0; 137 rose->state = ROSE_STATE_4; 138 rose_start_t2timer(sk); 139 rose_stop_idletimer(sk); 140 } else { 141 rose_frames_acked(sk, nr); 142 if (frametype == ROSE_RNR) { 143 rose->condition |= ROSE_COND_PEER_RX_BUSY; 144 } else { 145 rose->condition &= ~ROSE_COND_PEER_RX_BUSY; 146 } 147 } 148 break; 149 150 case ROSE_DATA: /* XXX */ 151 rose->condition &= ~ROSE_COND_PEER_RX_BUSY; 152 if (!rose_validate_nr(sk, nr)) { 153 rose_write_internal(sk, ROSE_RESET_REQUEST); 154 rose->condition = 0x00; 155 rose->vs = 0; 156 rose->vr = 0; 157 rose->va = 0; 158 rose->vl = 0; 159 rose->state = ROSE_STATE_4; 160 rose_start_t2timer(sk); 161 rose_stop_idletimer(sk); 162 break; 163 } 164 rose_frames_acked(sk, nr); 165 if (ns == rose->vr) { 166 rose_start_idletimer(sk); 167 if (sock_queue_rcv_skb(sk, skb) == 0) { 168 rose->vr = (rose->vr + 1) % ROSE_MODULUS; 169 queued = 1; 170 } else { 171 /* Should never happen ! */ 172 rose_write_internal(sk, ROSE_RESET_REQUEST); 173 rose->condition = 0x00; 174 rose->vs = 0; 175 rose->vr = 0; 176 rose->va = 0; 177 rose->vl = 0; 178 rose->state = ROSE_STATE_4; 179 rose_start_t2timer(sk); 180 rose_stop_idletimer(sk); 181 break; 182 } 183 if (atomic_read(&sk->sk_rmem_alloc) > 184 (sk->sk_rcvbuf >> 1)) 185 rose->condition |= ROSE_COND_OWN_RX_BUSY; 186 } 187 /* 188 * If the window is full, ack the frame, else start the 189 * acknowledge hold back timer. 190 */ 191 if (((rose->vl + sysctl_rose_window_size) % ROSE_MODULUS) == rose->vr) { 192 rose->condition &= ~ROSE_COND_ACK_PENDING; 193 rose_stop_timer(sk); 194 rose_enquiry_response(sk); 195 } else { 196 rose->condition |= ROSE_COND_ACK_PENDING; 197 rose_start_hbtimer(sk); 198 } 199 break; 200 201 default: 202 printk(KERN_WARNING "ROSE: unknown %02X in state 3\n", frametype); 203 break; 204 } 205 206 return queued; 207} 208 209/* 210 * State machine for state 4, Awaiting Reset Confirmation State. 211 * The handling of the timer(s) is in file rose_timer.c 212 * Handling of state 0 and connection release is in af_rose.c. 213 */ 214static int rose_state4_machine(struct sock *sk, struct sk_buff *skb, int frametype) 215{ 216 struct rose_sock *rose = rose_sk(sk); 217 218 switch (frametype) { 219 case ROSE_RESET_REQUEST: 220 rose_write_internal(sk, ROSE_RESET_CONFIRMATION); 221 case ROSE_RESET_CONFIRMATION: 222 rose_stop_timer(sk); 223 rose_start_idletimer(sk); 224 rose->condition = 0x00; 225 rose->va = 0; 226 rose->vr = 0; 227 rose->vs = 0; 228 rose->vl = 0; 229 rose->state = ROSE_STATE_3; 230 rose_requeue_frames(sk); 231 break; 232 233 case ROSE_CLEAR_REQUEST: 234 rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION); 235 rose_disconnect(sk, 0, skb->data[3], skb->data[4]); 236 rose->neighbour->use--; 237 break; 238 239 default: 240 break; 241 } 242 243 return 0; 244} 245 246/* 247 * State machine for state 5, Awaiting Call Acceptance State. 248 * The handling of the timer(s) is in file rose_timer.c 249 * Handling of state 0 and connection release is in af_rose.c. 250 */ 251static int rose_state5_machine(struct sock *sk, struct sk_buff *skb, int frametype) 252{ 253 if (frametype == ROSE_CLEAR_REQUEST) { 254 rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION); 255 rose_disconnect(sk, 0, skb->data[3], skb->data[4]); 256 rose_sk(sk)->neighbour->use--; 257 } 258 259 return 0; 260} 261 262/* Higher level upcall for a LAPB frame */ 263int rose_process_rx_frame(struct sock *sk, struct sk_buff *skb) 264{ 265 struct rose_sock *rose = rose_sk(sk); 266 int queued = 0, frametype, ns, nr, q, d, m; 267 268 if (rose->state == ROSE_STATE_0) 269 return 0; 270 271 frametype = rose_decode(skb, &ns, &nr, &q, &d, &m); 272 273 switch (rose->state) { 274 case ROSE_STATE_1: 275 queued = rose_state1_machine(sk, skb, frametype); 276 break; 277 case ROSE_STATE_2: 278 queued = rose_state2_machine(sk, skb, frametype); 279 break; 280 case ROSE_STATE_3: 281 queued = rose_state3_machine(sk, skb, frametype, ns, nr, q, d, m); 282 break; 283 case ROSE_STATE_4: 284 queued = rose_state4_machine(sk, skb, frametype); 285 break; 286 case ROSE_STATE_5: 287 queued = rose_state5_machine(sk, skb, frametype); 288 break; 289 } 290 291 rose_kick(sk); 292 293 return queued; 294} 295