• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/net/
1/*
2 *  ==FILEVERSION 980319==
3 *
4 * ppp_deflate.c - interface the zlib procedures for Deflate compression
5 * and decompression (as used by gzip) to the PPP code.
6 * This version is for use with Linux kernel 1.3.X.
7 *
8 * Copyright (c) 1994 The Australian National University.
9 * All rights reserved.
10 *
11 * Permission to use, copy, modify, and distribute this software and its
12 * documentation is hereby granted, provided that the above copyright
13 * notice appears in all copies.  This software is provided without any
14 * warranty, express or implied. The Australian National University
15 * makes no representations about the suitability of this software for
16 * any purpose.
17 *
18 * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
19 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
20 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
21 * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY
22 * OF SUCH DAMAGE.
23 *
24 * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
26 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
27 * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
28 * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
29 * OR MODIFICATIONS.
30 *
31 * From: deflate.c,v 1.1 1996/01/18 03:17:48 paulus Exp
32 */
33
34#include <linux/module.h>
35#include <linux/slab.h>
36#include <linux/vmalloc.h>
37#include <linux/init.h>
38#include <linux/string.h>
39
40#include <linux/ppp_defs.h>
41#include <linux/ppp-comp.h>
42
43#include <linux/zlib.h>
44
45/*
46 * State for a Deflate (de)compressor.
47 */
48struct ppp_deflate_state {
49    int		seqno;
50    int		w_size;
51    int		unit;
52    int		mru;
53    int		debug;
54    z_stream	strm;
55    struct compstat stats;
56};
57
58#define DEFLATE_OVHD	2		/* Deflate overhead/packet */
59
60static void	*z_comp_alloc(unsigned char *options, int opt_len);
61static void	*z_decomp_alloc(unsigned char *options, int opt_len);
62static void	z_comp_free(void *state);
63static void	z_decomp_free(void *state);
64static int	z_comp_init(void *state, unsigned char *options,
65				 int opt_len,
66				 int unit, int hdrlen, int debug);
67static int	z_decomp_init(void *state, unsigned char *options,
68				   int opt_len,
69				   int unit, int hdrlen, int mru, int debug);
70static int	z_compress(void *state, unsigned char *rptr,
71				unsigned char *obuf,
72				int isize, int osize);
73static void	z_incomp(void *state, unsigned char *ibuf, int icnt);
74static int	z_decompress(void *state, unsigned char *ibuf,
75				int isize, unsigned char *obuf, int osize);
76static void	z_comp_reset(void *state);
77static void	z_decomp_reset(void *state);
78static void	z_comp_stats(void *state, struct compstat *stats);
79
80/**
81 *	z_comp_free - free the memory used by a compressor
82 *	@arg:	pointer to the private state for the compressor.
83 */
84static void z_comp_free(void *arg)
85{
86	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
87
88	if (state) {
89		zlib_deflateEnd(&state->strm);
90		vfree(state->strm.workspace);
91		kfree(state);
92	}
93}
94
95/**
96 *	z_comp_alloc - allocate space for a compressor.
97 *	@options: pointer to CCP option data
98 *	@opt_len: length of the CCP option at @options.
99 *
100 *	The @options pointer points to the a buffer containing the
101 *	CCP option data for the compression being negotiated.  It is
102 *	formatted according to RFC1979, and describes the window
103 *	size that the peer is requesting that we use in compressing
104 *	data to be sent to it.
105 *
106 *	Returns the pointer to the private state for the compressor,
107 *	or NULL if we could not allocate enough memory.
108 */
109static void *z_comp_alloc(unsigned char *options, int opt_len)
110{
111	struct ppp_deflate_state *state;
112	int w_size;
113
114	if (opt_len != CILEN_DEFLATE ||
115	    (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) ||
116	    options[1] != CILEN_DEFLATE ||
117	    DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL ||
118	    options[3] != DEFLATE_CHK_SEQUENCE)
119		return NULL;
120	w_size = DEFLATE_SIZE(options[2]);
121	if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
122		return NULL;
123
124	state = kzalloc(sizeof(*state),
125						     GFP_KERNEL);
126	if (state == NULL)
127		return NULL;
128
129	state->strm.next_in   = NULL;
130	state->w_size         = w_size;
131	state->strm.workspace = vmalloc(zlib_deflate_workspacesize());
132	if (state->strm.workspace == NULL)
133		goto out_free;
134
135	if (zlib_deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION,
136			 DEFLATE_METHOD_VAL, -w_size, 8, Z_DEFAULT_STRATEGY)
137	    != Z_OK)
138		goto out_free;
139	return (void *) state;
140
141out_free:
142	z_comp_free(state);
143	return NULL;
144}
145
146/**
147 *	z_comp_init - initialize a previously-allocated compressor.
148 *	@arg:	pointer to the private state for the compressor
149 *	@options: pointer to the CCP option data describing the
150 *		compression that was negotiated with the peer
151 *	@opt_len: length of the CCP option data at @options
152 *	@unit:	PPP unit number for diagnostic messages
153 *	@hdrlen: ignored (present for backwards compatibility)
154 *	@debug:	debug flag; if non-zero, debug messages are printed.
155 *
156 *	The CCP options described by @options must match the options
157 *	specified when the compressor was allocated.  The compressor
158 *	history is reset.  Returns 0 for failure (CCP options don't
159 *	match) or 1 for success.
160 */
161static int z_comp_init(void *arg, unsigned char *options, int opt_len,
162		       int unit, int hdrlen, int debug)
163{
164	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
165
166	if (opt_len < CILEN_DEFLATE ||
167	    (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) ||
168	    options[1] != CILEN_DEFLATE ||
169	    DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL ||
170	    DEFLATE_SIZE(options[2]) != state->w_size ||
171	    options[3] != DEFLATE_CHK_SEQUENCE)
172		return 0;
173
174	state->seqno = 0;
175	state->unit  = unit;
176	state->debug = debug;
177
178	zlib_deflateReset(&state->strm);
179
180	return 1;
181}
182
183/**
184 *	z_comp_reset - reset a previously-allocated compressor.
185 *	@arg:	pointer to private state for the compressor.
186 *
187 *	This clears the history for the compressor and makes it
188 *	ready to start emitting a new compressed stream.
189 */
190static void z_comp_reset(void *arg)
191{
192	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
193
194	state->seqno = 0;
195	zlib_deflateReset(&state->strm);
196}
197
198/**
199 *	z_compress - compress a PPP packet with Deflate compression.
200 *	@arg:	pointer to private state for the compressor
201 *	@rptr:	uncompressed packet (input)
202 *	@obuf:	compressed packet (output)
203 *	@isize:	size of uncompressed packet
204 *	@osize:	space available at @obuf
205 *
206 *	Returns the length of the compressed packet, or 0 if the
207 *	packet is incompressible.
208 */
209static int z_compress(void *arg, unsigned char *rptr, unsigned char *obuf,
210	       int isize, int osize)
211{
212	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
213	int r, proto, off, olen, oavail;
214	unsigned char *wptr;
215
216	/*
217	 * Check that the protocol is in the range we handle.
218	 */
219	proto = PPP_PROTOCOL(rptr);
220	if (proto > 0x3fff || proto == 0xfd || proto == 0xfb)
221		return 0;
222
223	/* Don't generate compressed packets which are larger than
224	   the uncompressed packet. */
225	if (osize > isize)
226		osize = isize;
227
228	wptr = obuf;
229
230	/*
231	 * Copy over the PPP header and store the 2-byte sequence number.
232	 */
233	wptr[0] = PPP_ADDRESS(rptr);
234	wptr[1] = PPP_CONTROL(rptr);
235	wptr[2] = PPP_COMP >> 8;
236	wptr[3] = PPP_COMP;
237	wptr += PPP_HDRLEN;
238	wptr[0] = state->seqno >> 8;
239	wptr[1] = state->seqno;
240	wptr += DEFLATE_OVHD;
241	olen = PPP_HDRLEN + DEFLATE_OVHD;
242	state->strm.next_out = wptr;
243	state->strm.avail_out = oavail = osize - olen;
244	++state->seqno;
245
246	off = (proto > 0xff) ? 2 : 3;	/* skip 1st proto byte if 0 */
247	rptr += off;
248	state->strm.next_in = rptr;
249	state->strm.avail_in = (isize - off);
250
251	for (;;) {
252		r = zlib_deflate(&state->strm, Z_PACKET_FLUSH);
253		if (r != Z_OK) {
254			if (state->debug)
255				printk(KERN_ERR
256				       "z_compress: deflate returned %d\n", r);
257			break;
258		}
259		if (state->strm.avail_out == 0) {
260			olen += oavail;
261			state->strm.next_out = NULL;
262			state->strm.avail_out = oavail = 1000000;
263		} else {
264			break;		/* all done */
265		}
266	}
267	olen += oavail - state->strm.avail_out;
268
269	/*
270	 * See if we managed to reduce the size of the packet.
271	 */
272	if (olen < isize) {
273		state->stats.comp_bytes += olen;
274		state->stats.comp_packets++;
275	} else {
276		state->stats.inc_bytes += isize;
277		state->stats.inc_packets++;
278		olen = 0;
279	}
280	state->stats.unc_bytes += isize;
281	state->stats.unc_packets++;
282
283	return olen;
284}
285
286/**
287 *	z_comp_stats - return compression statistics for a compressor
288 *		or decompressor.
289 *	@arg:	pointer to private space for the (de)compressor
290 *	@stats:	pointer to a struct compstat to receive the result.
291 */
292static void z_comp_stats(void *arg, struct compstat *stats)
293{
294	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
295
296	*stats = state->stats;
297}
298
299/**
300 *	z_decomp_free - Free the memory used by a decompressor.
301 *	@arg:	pointer to private space for the decompressor.
302 */
303static void z_decomp_free(void *arg)
304{
305	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
306
307	if (state) {
308		zlib_inflateEnd(&state->strm);
309		kfree(state->strm.workspace);
310		kfree(state);
311	}
312}
313
314/**
315 *	z_decomp_alloc - allocate space for a decompressor.
316 *	@options: pointer to CCP option data
317 *	@opt_len: length of the CCP option at @options.
318 *
319 *	The @options pointer points to the a buffer containing the
320 *	CCP option data for the compression being negotiated.  It is
321 *	formatted according to RFC1979, and describes the window
322 *	size that we are requesting the peer to use in compressing
323 *	data to be sent to us.
324 *
325 *	Returns the pointer to the private state for the decompressor,
326 *	or NULL if we could not allocate enough memory.
327 */
328static void *z_decomp_alloc(unsigned char *options, int opt_len)
329{
330	struct ppp_deflate_state *state;
331	int w_size;
332
333	if (opt_len != CILEN_DEFLATE ||
334	    (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) ||
335	    options[1] != CILEN_DEFLATE ||
336	    DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL ||
337	    options[3] != DEFLATE_CHK_SEQUENCE)
338		return NULL;
339	w_size = DEFLATE_SIZE(options[2]);
340	if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
341		return NULL;
342
343	state = kzalloc(sizeof(*state), GFP_KERNEL);
344	if (state == NULL)
345		return NULL;
346
347	state->w_size         = w_size;
348	state->strm.next_out  = NULL;
349	state->strm.workspace = kmalloc(zlib_inflate_workspacesize(),
350					GFP_KERNEL|__GFP_REPEAT);
351	if (state->strm.workspace == NULL)
352		goto out_free;
353
354	if (zlib_inflateInit2(&state->strm, -w_size) != Z_OK)
355		goto out_free;
356	return (void *) state;
357
358out_free:
359	z_decomp_free(state);
360	return NULL;
361}
362
363/**
364 *	z_decomp_init - initialize a previously-allocated decompressor.
365 *	@arg:	pointer to the private state for the decompressor
366 *	@options: pointer to the CCP option data describing the
367 *		compression that was negotiated with the peer
368 *	@opt_len: length of the CCP option data at @options
369 *	@unit:	PPP unit number for diagnostic messages
370 *	@hdrlen: ignored (present for backwards compatibility)
371 *	@mru:	maximum length of decompressed packets
372 *	@debug:	debug flag; if non-zero, debug messages are printed.
373 *
374 *	The CCP options described by @options must match the options
375 *	specified when the decompressor was allocated.  The decompressor
376 *	history is reset.  Returns 0 for failure (CCP options don't
377 *	match) or 1 for success.
378 */
379static int z_decomp_init(void *arg, unsigned char *options, int opt_len,
380			 int unit, int hdrlen, int mru, int debug)
381{
382	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
383
384	if (opt_len < CILEN_DEFLATE ||
385	    (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) ||
386	    options[1] != CILEN_DEFLATE ||
387	    DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL ||
388	    DEFLATE_SIZE(options[2]) != state->w_size ||
389	    options[3] != DEFLATE_CHK_SEQUENCE)
390		return 0;
391
392	state->seqno = 0;
393	state->unit  = unit;
394	state->debug = debug;
395	state->mru   = mru;
396
397	zlib_inflateReset(&state->strm);
398
399	return 1;
400}
401
402/**
403 *	z_decomp_reset - reset a previously-allocated decompressor.
404 *	@arg:	pointer to private state for the decompressor.
405 *
406 *	This clears the history for the decompressor and makes it
407 *	ready to receive a new compressed stream.
408 */
409static void z_decomp_reset(void *arg)
410{
411	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
412
413	state->seqno = 0;
414	zlib_inflateReset(&state->strm);
415}
416
417/**
418 *	z_decompress - decompress a Deflate-compressed packet.
419 *	@arg:	pointer to private state for the decompressor
420 *	@ibuf:	pointer to input (compressed) packet data
421 *	@isize:	length of input packet
422 *	@obuf:	pointer to space for output (decompressed) packet
423 *	@osize:	amount of space available at @obuf
424 *
425 * Because of patent problems, we return DECOMP_ERROR for errors
426 * found by inspecting the input data and for system problems, but
427 * DECOMP_FATALERROR for any errors which could possibly be said to
428 * be being detected "after" decompression.  For DECOMP_ERROR,
429 * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
430 * infringing a patent of Motorola's if we do, so we take CCP down
431 * instead.
432 *
433 * Given that the frame has the correct sequence number and a good FCS,
434 * errors such as invalid codes in the input most likely indicate a
435 * bug, so we return DECOMP_FATALERROR for them in order to turn off
436 * compression, even though they are detected by inspecting the input.
437 */
438static int z_decompress(void *arg, unsigned char *ibuf, int isize,
439		 unsigned char *obuf, int osize)
440{
441	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
442	int olen, seq, r;
443	int decode_proto, overflow;
444	unsigned char overflow_buf[1];
445
446	if (isize <= PPP_HDRLEN + DEFLATE_OVHD) {
447		if (state->debug)
448			printk(KERN_DEBUG "z_decompress%d: short pkt (%d)\n",
449			       state->unit, isize);
450		return DECOMP_ERROR;
451	}
452
453	/* Check the sequence number. */
454	seq = (ibuf[PPP_HDRLEN] << 8) + ibuf[PPP_HDRLEN+1];
455	if (seq != (state->seqno & 0xffff)) {
456		if (state->debug)
457			printk(KERN_DEBUG "z_decompress%d: bad seq # %d, expected %d\n",
458			       state->unit, seq, state->seqno & 0xffff);
459		return DECOMP_ERROR;
460	}
461	++state->seqno;
462
463	/*
464	 * Fill in the first part of the PPP header.  The protocol field
465	 * comes from the decompressed data.
466	 */
467	obuf[0] = PPP_ADDRESS(ibuf);
468	obuf[1] = PPP_CONTROL(ibuf);
469	obuf[2] = 0;
470
471	/*
472	 * Set up to call inflate.  We set avail_out to 1 initially so we can
473	 * look at the first byte of the output and decide whether we have
474	 * a 1-byte or 2-byte protocol field.
475	 */
476	state->strm.next_in = ibuf + PPP_HDRLEN + DEFLATE_OVHD;
477	state->strm.avail_in = isize - (PPP_HDRLEN + DEFLATE_OVHD);
478	state->strm.next_out = obuf + 3;
479	state->strm.avail_out = 1;
480	decode_proto = 1;
481	overflow = 0;
482
483	/*
484	 * Call inflate, supplying more input or output as needed.
485	 */
486	for (;;) {
487		r = zlib_inflate(&state->strm, Z_PACKET_FLUSH);
488		if (r != Z_OK) {
489			if (state->debug)
490				printk(KERN_DEBUG "z_decompress%d: inflate returned %d (%s)\n",
491				       state->unit, r, (state->strm.msg? state->strm.msg: ""));
492			return DECOMP_FATALERROR;
493		}
494		if (state->strm.avail_out != 0)
495			break;		/* all done */
496		if (decode_proto) {
497			state->strm.avail_out = osize - PPP_HDRLEN;
498			if ((obuf[3] & 1) == 0) {
499				/* 2-byte protocol field */
500				obuf[2] = obuf[3];
501				--state->strm.next_out;
502				++state->strm.avail_out;
503			}
504			decode_proto = 0;
505		} else if (!overflow) {
506			/*
507			 * We've filled up the output buffer; the only way to
508			 * find out whether inflate has any more characters
509			 * left is to give it another byte of output space.
510			 */
511			state->strm.next_out = overflow_buf;
512			state->strm.avail_out = 1;
513			overflow = 1;
514		} else {
515			if (state->debug)
516				printk(KERN_DEBUG "z_decompress%d: ran out of mru\n",
517				       state->unit);
518			return DECOMP_FATALERROR;
519		}
520	}
521
522	if (decode_proto) {
523		if (state->debug)
524			printk(KERN_DEBUG "z_decompress%d: didn't get proto\n",
525			       state->unit);
526		return DECOMP_ERROR;
527	}
528
529	olen = osize + overflow - state->strm.avail_out;
530	state->stats.unc_bytes += olen;
531	state->stats.unc_packets++;
532	state->stats.comp_bytes += isize;
533	state->stats.comp_packets++;
534
535	return olen;
536}
537
538/**
539 *	z_incomp - add incompressible input data to the history.
540 *	@arg:	pointer to private state for the decompressor
541 *	@ibuf:	pointer to input packet data
542 *	@icnt:	length of input data.
543 */
544static void z_incomp(void *arg, unsigned char *ibuf, int icnt)
545{
546	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
547	int proto, r;
548
549	/*
550	 * Check that the protocol is one we handle.
551	 */
552	proto = PPP_PROTOCOL(ibuf);
553	if (proto > 0x3fff || proto == 0xfd || proto == 0xfb)
554		return;
555
556	++state->seqno;
557
558	/*
559	 * We start at the either the 1st or 2nd byte of the protocol field,
560	 * depending on whether the protocol value is compressible.
561	 */
562	state->strm.next_in = ibuf + 3;
563	state->strm.avail_in = icnt - 3;
564	if (proto > 0xff) {
565		--state->strm.next_in;
566		++state->strm.avail_in;
567	}
568
569	r = zlib_inflateIncomp(&state->strm);
570	if (r != Z_OK) {
571		/* gak! */
572		if (state->debug) {
573			printk(KERN_DEBUG "z_incomp%d: inflateIncomp returned %d (%s)\n",
574			       state->unit, r, (state->strm.msg? state->strm.msg: ""));
575		}
576		return;
577	}
578
579	/*
580	 * Update stats.
581	 */
582	state->stats.inc_bytes += icnt;
583	state->stats.inc_packets++;
584	state->stats.unc_bytes += icnt;
585	state->stats.unc_packets++;
586}
587
588/*************************************************************
589 * Module interface table
590 *************************************************************/
591
592/* These are in ppp_generic.c */
593extern int  ppp_register_compressor   (struct compressor *cp);
594extern void ppp_unregister_compressor (struct compressor *cp);
595
596/*
597 * Procedures exported to if_ppp.c.
598 */
599static struct compressor ppp_deflate = {
600	.compress_proto =	CI_DEFLATE,
601	.comp_alloc =		z_comp_alloc,
602	.comp_free =		z_comp_free,
603	.comp_init =		z_comp_init,
604	.comp_reset =		z_comp_reset,
605	.compress =		z_compress,
606	.comp_stat =		z_comp_stats,
607	.decomp_alloc =		z_decomp_alloc,
608	.decomp_free =		z_decomp_free,
609	.decomp_init =		z_decomp_init,
610	.decomp_reset =		z_decomp_reset,
611	.decompress =		z_decompress,
612	.incomp =		z_incomp,
613	.decomp_stat =		z_comp_stats,
614	.owner =		THIS_MODULE
615};
616
617static struct compressor ppp_deflate_draft = {
618	.compress_proto =	CI_DEFLATE_DRAFT,
619	.comp_alloc =		z_comp_alloc,
620	.comp_free =		z_comp_free,
621	.comp_init =		z_comp_init,
622	.comp_reset =		z_comp_reset,
623	.compress =		z_compress,
624	.comp_stat =		z_comp_stats,
625	.decomp_alloc =		z_decomp_alloc,
626	.decomp_free =		z_decomp_free,
627	.decomp_init =		z_decomp_init,
628	.decomp_reset =		z_decomp_reset,
629	.decompress =		z_decompress,
630	.incomp =		z_incomp,
631	.decomp_stat =		z_comp_stats,
632	.owner =		THIS_MODULE
633};
634
635static int __init deflate_init(void)
636{
637        int answer = ppp_register_compressor(&ppp_deflate);
638        if (answer == 0)
639                printk(KERN_INFO
640		       "PPP Deflate Compression module registered\n");
641	ppp_register_compressor(&ppp_deflate_draft);
642        return answer;
643}
644
645static void __exit deflate_cleanup(void)
646{
647	ppp_unregister_compressor(&ppp_deflate);
648	ppp_unregister_compressor(&ppp_deflate_draft);
649}
650
651module_init(deflate_init);
652module_exit(deflate_cleanup);
653MODULE_LICENSE("Dual BSD/GPL");
654MODULE_ALIAS("ppp-compress-" __stringify(CI_DEFLATE));
655MODULE_ALIAS("ppp-compress-" __stringify(CI_DEFLATE_DRAFT));
656