1 /*
2  *	X.25 Packet Layer release 002
3  *
4  *	This is ALPHA test software. This code may break your machine, randomly fail to work with new
5  *	releases, misbehave and/or generally screw up. It might even work.
6  *
7  *	This code REQUIRES 2.1.15 or higher
8  *
9  *	This module:
10  *		This module is free software; you can redistribute it and/or
11  *		modify it under the terms of the GNU General Public License
12  *		as published by the Free Software Foundation; either version
13  *		2 of the License, or (at your option) any later version.
14  *
15  *	History
16  *	X.25 001	Jonathan Naylor	  Started coding.
17  *	X.25 002	Jonathan Naylor	  Centralised disconnection processing.
18  *	mar/20/00	Daniela Squassoni Disabling/enabling of facilities
19  *					  negotiation.
20  *	jun/24/01	Arnaldo C. Melo	  use skb_queue_purge, cleanups
21  */
22 
23 #include <linux/errno.h>
24 #include <linux/types.h>
25 #include <linux/socket.h>
26 #include <linux/in.h>
27 #include <linux/kernel.h>
28 #include <linux/sched.h>
29 #include <linux/timer.h>
30 #include <linux/string.h>
31 #include <linux/sockios.h>
32 #include <linux/net.h>
33 #include <linux/inet.h>
34 #include <linux/netdevice.h>
35 #include <linux/skbuff.h>
36 #include <net/sock.h>
37 #include <asm/segment.h>
38 #include <asm/system.h>
39 #include <linux/fcntl.h>
40 #include <linux/mm.h>
41 #include <linux/interrupt.h>
42 #include <net/x25.h>
43 
44 /*
45  *	This routine purges all of the queues of frames.
46  */
x25_clear_queues(struct sock * sk)47 void x25_clear_queues(struct sock *sk)
48 {
49 	skb_queue_purge(&sk->write_queue);
50 	skb_queue_purge(&sk->protinfo.x25->ack_queue);
51 	skb_queue_purge(&sk->protinfo.x25->interrupt_in_queue);
52 	skb_queue_purge(&sk->protinfo.x25->interrupt_out_queue);
53 	skb_queue_purge(&sk->protinfo.x25->fragment_queue);
54 }
55 
56 
57 /*
58  * This routine purges the input queue of those frames that have been
59  * acknowledged. This replaces the boxes labelled "V(a) <- N(r)" on the
60  * SDL diagram.
61 */
x25_frames_acked(struct sock * sk,unsigned short nr)62 void x25_frames_acked(struct sock *sk, unsigned short nr)
63 {
64 	struct sk_buff *skb;
65 	int modulus = sk->protinfo.x25->neighbour->extended ? X25_EMODULUS :
66 							      X25_SMODULUS;
67 
68 	/*
69 	 * Remove all the ack-ed frames from the ack queue.
70 	 */
71 	if (sk->protinfo.x25->va != nr)
72 		while (skb_peek(&sk->protinfo.x25->ack_queue) != NULL &&
73 		       sk->protinfo.x25->va != nr) {
74 			skb = skb_dequeue(&sk->protinfo.x25->ack_queue);
75 			kfree_skb(skb);
76 			sk->protinfo.x25->va = (sk->protinfo.x25->va + 1) %
77 						modulus;
78 		}
79 }
80 
x25_requeue_frames(struct sock * sk)81 void x25_requeue_frames(struct sock *sk)
82 {
83 	struct sk_buff *skb, *skb_prev = NULL;
84 
85 	/*
86 	 * Requeue all the un-ack-ed frames on the output queue to be picked
87 	 * up by x25_kick. This arrangement handles the possibility of an empty
88 	 * output queue.
89 	 */
90 	while ((skb = skb_dequeue(&sk->protinfo.x25->ack_queue)) != NULL) {
91 		if (skb_prev == NULL)
92 			skb_queue_head(&sk->write_queue, skb);
93 		else
94 			skb_append(skb_prev, skb);
95 		skb_prev = skb;
96 	}
97 }
98 
99 /*
100  *	Validate that the value of nr is between va and vs. Return true or
101  *	false for testing.
102  */
x25_validate_nr(struct sock * sk,unsigned short nr)103 int x25_validate_nr(struct sock *sk, unsigned short nr)
104 {
105 	unsigned short vc = sk->protinfo.x25->va;
106 	int modulus = sk->protinfo.x25->neighbour->extended ? X25_EMODULUS :
107 							      X25_SMODULUS;
108 
109 	while (vc != sk->protinfo.x25->vs) {
110 		if (nr == vc) return 1;
111 		vc = (vc + 1) % modulus;
112 	}
113 
114 	return nr == sk->protinfo.x25->vs ? 1 : 0;
115 }
116 
117 /*
118  *  This routine is called when the packet layer internally generates a
119  *  control frame.
120  */
x25_write_internal(struct sock * sk,int frametype)121 void x25_write_internal(struct sock *sk, int frametype)
122 {
123 	struct sk_buff *skb;
124 	unsigned char  *dptr;
125 	unsigned char  facilities[X25_MAX_FAC_LEN];
126 	unsigned char  addresses[1 + X25_ADDR_LEN];
127 	unsigned char  lci1, lci2;
128 	int len;
129 
130 	/*
131 	 *	Default safe frame size.
132 	 */
133 	len = X25_MAX_L2_LEN + X25_EXT_MIN_LEN;
134 
135 	/*
136 	 *	Adjust frame size.
137 	 */
138 	switch (frametype) {
139 		case X25_CALL_REQUEST:
140 			len += 1 + X25_ADDR_LEN + X25_MAX_FAC_LEN +
141 			       X25_MAX_CUD_LEN;
142 			break;
143 		case X25_CALL_ACCEPTED:
144 			len += 1 + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN;
145 			break;
146 		case X25_CLEAR_REQUEST:
147 		case X25_RESET_REQUEST:
148 			len += 2;
149 			break;
150 		case X25_RR:
151 		case X25_RNR:
152 		case X25_REJ:
153 		case X25_CLEAR_CONFIRMATION:
154 		case X25_INTERRUPT_CONFIRMATION:
155 		case X25_RESET_CONFIRMATION:
156 			break;
157 		default:
158 			printk(KERN_ERR "X.25: invalid frame type %02X\n",
159 			       frametype);
160 			return;
161 	}
162 
163 	if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
164 		return;
165 
166 	/*
167 	 *	Space for Ethernet and 802.2 LLC headers.
168 	 */
169 	skb_reserve(skb, X25_MAX_L2_LEN);
170 
171 	/*
172 	 *	Make space for the GFI and LCI, and fill them in.
173 	 */
174 	dptr = skb_put(skb, 2);
175 
176 	lci1 = (sk->protinfo.x25->lci >> 8) & 0x0F;
177 	lci2 = (sk->protinfo.x25->lci >> 0) & 0xFF;
178 
179 	if (sk->protinfo.x25->neighbour->extended) {
180 		*dptr++ = lci1 | X25_GFI_EXTSEQ;
181 		*dptr++ = lci2;
182 	} else {
183 		*dptr++ = lci1 | X25_GFI_STDSEQ;
184 		*dptr++ = lci2;
185 	}
186 
187 	/*
188 	 *	Now fill in the frame type specific information.
189 	 */
190 	switch (frametype) {
191 
192 		case X25_CALL_REQUEST:
193 			dptr    = skb_put(skb, 1);
194 			*dptr++ = X25_CALL_REQUEST;
195 			len     = x25_addr_aton(addresses, &sk->protinfo.x25->dest_addr, &sk->protinfo.x25->source_addr);
196 			dptr    = skb_put(skb, len);
197 			memcpy(dptr, addresses, len);
198 			len     = x25_create_facilities(facilities, &sk->protinfo.x25->facilities, sk->protinfo.x25->neighbour->global_facil_mask);
199 			dptr    = skb_put(skb, len);
200 			memcpy(dptr, facilities, len);
201 			dptr = skb_put(skb, sk->protinfo.x25->calluserdata.cudlength);
202 			memcpy(dptr, sk->protinfo.x25->calluserdata.cuddata, sk->protinfo.x25->calluserdata.cudlength);
203 			sk->protinfo.x25->calluserdata.cudlength = 0;
204 			break;
205 
206 		case X25_CALL_ACCEPTED:
207 			dptr    = skb_put(skb, 2);
208 			*dptr++ = X25_CALL_ACCEPTED;
209 			*dptr++ = 0x00;		/* Address lengths */
210 			len     = x25_create_facilities(facilities, &sk->protinfo.x25->facilities, sk->protinfo.x25->vc_facil_mask);
211 			dptr    = skb_put(skb, len);
212 			memcpy(dptr, facilities, len);
213 			dptr = skb_put(skb, sk->protinfo.x25->calluserdata.cudlength);
214 			memcpy(dptr, sk->protinfo.x25->calluserdata.cuddata, sk->protinfo.x25->calluserdata.cudlength);
215 			sk->protinfo.x25->calluserdata.cudlength = 0;
216 			break;
217 
218 		case X25_CLEAR_REQUEST:
219 		case X25_RESET_REQUEST:
220 			dptr    = skb_put(skb, 3);
221 			*dptr++ = frametype;
222 			*dptr++ = 0x00;		/* XXX */
223 			*dptr++ = 0x00;		/* XXX */
224 			break;
225 
226 		case X25_RR:
227 		case X25_RNR:
228 		case X25_REJ:
229 			if (sk->protinfo.x25->neighbour->extended) {
230 				dptr     = skb_put(skb, 2);
231 				*dptr++  = frametype;
232 				*dptr++  = (sk->protinfo.x25->vr << 1) & 0xFE;
233 			} else {
234 				dptr     = skb_put(skb, 1);
235 				*dptr    = frametype;
236 				*dptr++ |= (sk->protinfo.x25->vr << 5) & 0xE0;
237 			}
238 			break;
239 
240 		case X25_CLEAR_CONFIRMATION:
241 		case X25_INTERRUPT_CONFIRMATION:
242 		case X25_RESET_CONFIRMATION:
243 			dptr  = skb_put(skb, 1);
244 			*dptr = frametype;
245 			break;
246 	}
247 
248 	x25_transmit_link(skb, sk->protinfo.x25->neighbour);
249 }
250 
251 /*
252  *	Unpick the contents of the passed X.25 Packet Layer frame.
253  */
x25_decode(struct sock * sk,struct sk_buff * skb,int * ns,int * nr,int * q,int * d,int * m)254 int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q,
255 	       int *d, int *m)
256 {
257 	unsigned char *frame = skb->data;
258 
259 	*ns = *nr = *q = *d = *m = 0;
260 
261 	switch (frame[2]) {
262 		case X25_CALL_REQUEST:
263 		case X25_CALL_ACCEPTED:
264 		case X25_CLEAR_REQUEST:
265 		case X25_CLEAR_CONFIRMATION:
266 		case X25_INTERRUPT:
267 		case X25_INTERRUPT_CONFIRMATION:
268 		case X25_RESET_REQUEST:
269 		case X25_RESET_CONFIRMATION:
270 		case X25_RESTART_REQUEST:
271 		case X25_RESTART_CONFIRMATION:
272 		case X25_REGISTRATION_REQUEST:
273 		case X25_REGISTRATION_CONFIRMATION:
274 		case X25_DIAGNOSTIC:
275 			return frame[2];
276 	}
277 
278 	if (sk->protinfo.x25->neighbour->extended) {
279 		if (frame[2] == X25_RR  ||
280 		    frame[2] == X25_RNR ||
281 		    frame[2] == X25_REJ) {
282 			*nr = (frame[3] >> 1) & 0x7F;
283 			return frame[2];
284 		}
285 	} else {
286 		if ((frame[2] & 0x1F) == X25_RR  ||
287 		    (frame[2] & 0x1F) == X25_RNR ||
288 		    (frame[2] & 0x1F) == X25_REJ) {
289 			*nr = (frame[2] >> 5) & 0x07;
290 			return frame[2] & 0x1F;
291 		}
292 	}
293 
294 	if (sk->protinfo.x25->neighbour->extended) {
295 		if ((frame[2] & 0x01) == X25_DATA) {
296 			*q  = (frame[0] & X25_Q_BIT) == X25_Q_BIT;
297 			*d  = (frame[0] & X25_D_BIT) == X25_D_BIT;
298 			*m  = (frame[3] & X25_EXT_M_BIT) == X25_EXT_M_BIT;
299 			*nr = (frame[3] >> 1) & 0x7F;
300 			*ns = (frame[2] >> 1) & 0x7F;
301 			return X25_DATA;
302 		}
303 	} else {
304 		if ((frame[2] & 0x01) == X25_DATA) {
305 			*q  = (frame[0] & X25_Q_BIT) == X25_Q_BIT;
306 			*d  = (frame[0] & X25_D_BIT) == X25_D_BIT;
307 			*m  = (frame[2] & X25_STD_M_BIT) == X25_STD_M_BIT;
308 			*nr = (frame[2] >> 5) & 0x07;
309 			*ns = (frame[2] >> 1) & 0x07;
310 			return X25_DATA;
311 		}
312 	}
313 
314 	printk(KERN_DEBUG "X.25: invalid PLP frame %02X %02X %02X\n",
315 	       frame[0], frame[1], frame[2]);
316 
317 	return X25_ILLEGAL;
318 }
319 
x25_disconnect(struct sock * sk,int reason,unsigned char cause,unsigned char diagnostic)320 void x25_disconnect(struct sock *sk, int reason, unsigned char cause,
321 		    unsigned char diagnostic)
322 {
323 	x25_clear_queues(sk);
324 	x25_stop_timer(sk);
325 
326 	sk->protinfo.x25->lci   = 0;
327 	sk->protinfo.x25->state = X25_STATE_0;
328 
329 	sk->protinfo.x25->causediag.cause      = cause;
330 	sk->protinfo.x25->causediag.diagnostic = diagnostic;
331 
332 	sk->state     = TCP_CLOSE;
333 	sk->err       = reason;
334 	sk->shutdown |= SEND_SHUTDOWN;
335 
336 	if (!sk->dead)
337 		sk->state_change(sk);
338 
339 	sk->dead = 1;
340 }
341 
342 /*
343  * Clear an own-rx-busy condition and tell the peer about this, provided
344  * that there is a significant amount of free receive buffer space available.
345  */
x25_check_rbuf(struct sock * sk)346 void x25_check_rbuf(struct sock *sk)
347 {
348 	if (atomic_read(&sk->rmem_alloc) < (sk->rcvbuf / 2) &&
349 	    (sk->protinfo.x25->condition & X25_COND_OWN_RX_BUSY)) {
350 		sk->protinfo.x25->condition &= ~X25_COND_OWN_RX_BUSY;
351 		sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING;
352 		sk->protinfo.x25->vl         = sk->protinfo.x25->vr;
353 		x25_write_internal(sk, X25_RR);
354 		x25_stop_timer(sk);
355 	}
356 }
357