xref: /openbmc/linux/net/ax25/ax25_ds_in.c (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
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