/*
 * BSD compression module
 *
 * Patched version for ISDN syncPPP written 1997/1998 by Michael Hipp
 * The whole module is now SKB based.
 *
 */

/*
 * Update: The Berkeley copyright was changed, and the change
 * is retroactive to all "true" BSD software (ie everything
 * from UCB as opposed to other peoples code that just carried
 * the same license). The new copyright doesn't clash with the
 * GPL, so the module-only restriction has been removed..
 */

/*
 * Original copyright notice:
 *
 * Copyright (c) 1985, 1986 The Regents of the University of California.
 * All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * James A. Woods, derived from original work by Spencer Thomas
 * and Joseph Orost.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/errno.h>
#include <linux/string.h>	/* used in new tty drivers */
#include <linux/signal.h>	/* used in new tty drivers */
#include <linux/bitops.h>

#include <asm/byteorder.h>
#include <asm/types.h>

#include <linux/if.h>

#include <linux/if_ether.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/inet.h>
#include <linux/ioctl.h>
#include <linux/vmalloc.h>

#include <linux/ppp_defs.h>

#include <linux/isdn.h>
#include <linux/isdn_ppp.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/if_arp.h>
#include <linux/ppp-comp.h>

#include "isdn_ppp.h"

MODULE_DESCRIPTION("ISDN4Linux: BSD Compression for PPP over ISDN");
MODULE_LICENSE("Dual BSD/GPL");

#define BSD_VERSION(x)	((x) >> 5)
#define BSD_NBITS(x)	((x) & 0x1F)

#define BSD_CURRENT_VERSION	1

#define DEBUG 1

/*
 * A dictionary for doing BSD compress.
 */

struct bsd_dict {
	u32 fcode;
	u16 codem1;		/* output of hash table -1 */
	u16 cptr;		/* map code to hash table entry */
};

struct bsd_db {
	int            totlen;		/* length of this structure */
	unsigned int   hsize;		/* size of the hash table */
	unsigned char  hshift;		/* used in hash function */
	unsigned char  n_bits;		/* current bits/code */
	unsigned char  maxbits;		/* maximum bits/code */
	unsigned char  debug;		/* non-zero if debug desired */
	unsigned char  unit;		/* ppp unit number */
	u16 seqno;			/* sequence # of next packet */
	unsigned int   mru;		/* size of receive (decompress) bufr */
	unsigned int   maxmaxcode;	/* largest valid code */
	unsigned int   max_ent;		/* largest code in use */
	unsigned int   in_count;	/* uncompressed bytes, aged */
	unsigned int   bytes_out;	/* compressed bytes, aged */
	unsigned int   ratio;		/* recent compression ratio */
	unsigned int   checkpoint;	/* when to next check the ratio */
	unsigned int   clear_count;	/* times dictionary cleared */
	unsigned int   incomp_count;	/* incompressible packets */
	unsigned int   incomp_bytes;	/* incompressible bytes */
	unsigned int   uncomp_count;	/* uncompressed packets */
	unsigned int   uncomp_bytes;	/* uncompressed bytes */
	unsigned int   comp_count;	/* compressed packets */
	unsigned int   comp_bytes;	/* compressed bytes */
	unsigned short  *lens;		/* array of lengths of codes */
	struct bsd_dict *dict;		/* dictionary */
	int xmit;
};

#define BSD_OVHD	2		/* BSD compress overhead/packet */
#define MIN_BSD_BITS	9
#define BSD_INIT_BITS	MIN_BSD_BITS
#define MAX_BSD_BITS	15

/*
 * the next two codes should not be changed lightly, as they must not
 * lie within the contiguous general code space.
 */
#define CLEAR	256			/* table clear output code */
#define FIRST	257			/* first free entry */
#define LAST	255

#define MAXCODE(b)	((1 << (b)) - 1)
#define BADCODEM1	MAXCODE(MAX_BSD_BITS)

#define BSD_HASH(prefix, suffix, hshift) ((((unsigned long)(suffix)) << (hshift)) \
					  ^ (unsigned long)(prefix))
#define BSD_KEY(prefix, suffix)		((((unsigned long)(suffix)) << 16) \
					 + (unsigned long)(prefix))

#define CHECK_GAP	10000		/* Ratio check interval */

#define RATIO_SCALE_LOG	8
#define RATIO_SCALE	(1 << RATIO_SCALE_LOG)
#define RATIO_MAX	(0x7fffffff >> RATIO_SCALE_LOG)

/*
 * clear the dictionary
 */

static void bsd_clear(struct bsd_db *db)
{
	db->clear_count++;
	db->max_ent      = FIRST - 1;
	db->n_bits       = BSD_INIT_BITS;
	db->bytes_out    = 0;
	db->in_count     = 0;
	db->incomp_count = 0;
	db->ratio	     = 0;
	db->checkpoint   = CHECK_GAP;
}

/*
 * If the dictionary is full, then see if it is time to reset it.
 *
 * Compute the compression ratio using fixed-point arithmetic
 * with 8 fractional bits.
 *
 * Since we have an infinite stream instead of a single file,
 * watch only the local compression ratio.
 *
 * Since both peers must reset the dictionary at the same time even in
 * the absence of CLEAR codes (while packets are incompressible), they
 * must compute the same ratio.
 */
static int bsd_check(struct bsd_db *db)	/* 1=output CLEAR */
{
	unsigned int new_ratio;

	if (db->in_count >= db->checkpoint)
	{
		/* age the ratio by limiting the size of the counts */
		if (db->in_count >= RATIO_MAX || db->bytes_out >= RATIO_MAX)
		{
			db->in_count  -= (db->in_count  >> 2);
			db->bytes_out -= (db->bytes_out >> 2);
		}

		db->checkpoint = db->in_count + CHECK_GAP;

		if (db->max_ent >= db->maxmaxcode)
		{
			/* Reset the dictionary only if the ratio is worse,
			 * or if it looks as if it has been poisoned
			 * by incompressible data.
			 *
			 * This does not overflow, because
			 *	db->in_count <= RATIO_MAX.
			 */

			new_ratio = db->in_count << RATIO_SCALE_LOG;
			if (db->bytes_out != 0)
			{
				new_ratio /= db->bytes_out;
			}

			if (new_ratio < db->ratio || new_ratio < 1 * RATIO_SCALE)
			{
				bsd_clear(db);
				return 1;
			}
			db->ratio = new_ratio;
		}
	}
	return 0;
}

/*
 * Return statistics.
 */

static void bsd_stats(void *state, struct compstat *stats)
{
	struct bsd_db *db = (struct bsd_db *) state;

	stats->unc_bytes    = db->uncomp_bytes;
	stats->unc_packets  = db->uncomp_count;
	stats->comp_bytes   = db->comp_bytes;
	stats->comp_packets = db->comp_count;
	stats->inc_bytes    = db->incomp_bytes;
	stats->inc_packets  = db->incomp_count;
	stats->in_count     = db->in_count;
	stats->bytes_out    = db->bytes_out;
}

/*
 * Reset state, as on a CCP ResetReq.
 */
static void bsd_reset(void *state, unsigned char code, unsigned char id,
		      unsigned char *data, unsigned len,
		      struct isdn_ppp_resetparams *rsparm)
{
	struct bsd_db *db = (struct bsd_db *) state;

	bsd_clear(db);
	db->seqno       = 0;
	db->clear_count = 0;
}

/*
 * Release the compression structure
 */
static void bsd_free(void *state)
{
	struct bsd_db *db = (struct bsd_db *) state;

	if (db) {
		/*
		 * Release the dictionary
		 */
		vfree(db->dict);
		db->dict = NULL;

		/*
		 * Release the string buffer
		 */
		vfree(db->lens);
		db->lens = NULL;

		/*
		 * Finally release the structure itself.
		 */
		kfree(db);
	}
}


/*
 * Allocate space for a (de) compressor.
 */
static void *bsd_alloc(struct isdn_ppp_comp_data *data)
{
	int bits;
	unsigned int hsize, hshift, maxmaxcode;
	struct bsd_db *db;
	int decomp;

	static unsigned int htab[][2] = {
		{ 5003 , 4 } , { 5003 , 4 } , { 5003 , 4 } , { 5003 , 4 } ,
		{ 9001 , 5 } , { 18013 , 6 } , { 35023 , 7 } , { 69001 , 8 }
	};

	if (data->optlen != 1 || data->num != CI_BSD_COMPRESS
	    || BSD_VERSION(data->options[0]) != BSD_CURRENT_VERSION)
		return NULL;

	bits = BSD_NBITS(data->options[0]);

	if (bits < 9 || bits > 15)
		return NULL;

	hsize = htab[bits - 9][0];
	hshift = htab[bits - 9][1];

	/*
	 * Allocate the main control structure for this instance.
	 */
	maxmaxcode = MAXCODE(bits);
	db = kzalloc(sizeof(struct bsd_db), GFP_KERNEL);
	if (!db)
		return NULL;

	db->xmit = data->flags & IPPP_COMP_FLAG_XMIT;
	decomp = db->xmit ? 0 : 1;

	/*
	 * Allocate space for the dictionary. This may be more than one page in
	 * length.
	 */
	db->dict = vmalloc(array_size(hsize, sizeof(struct bsd_dict)));
	if (!db->dict) {
		bsd_free(db);
		return NULL;
	}

	/*
	 * If this is the compression buffer then there is no length data.
	 * For decompression, the length information is needed as well.
	 */
	if (!decomp)
		db->lens = NULL;
	else {
		db->lens = vmalloc(array_size(sizeof(db->lens[0]),
					      maxmaxcode + 1));
		if (!db->lens) {
			bsd_free(db);
			return (NULL);
		}
	}

	/*
	 * Initialize the data information for the compression code
	 */
	db->totlen = sizeof(struct bsd_db) + (sizeof(struct bsd_dict) * hsize);
	db->hsize = hsize;
	db->hshift = hshift;
	db->maxmaxcode = maxmaxcode;
	db->maxbits = bits;

	return (void *)db;
}

/*
 * Initialize the database.
 */
static int bsd_init(void *state, struct isdn_ppp_comp_data *data, int unit, int debug)
{
	struct bsd_db *db = state;
	int indx;
	int decomp;

	if (!state || !data) {
		printk(KERN_ERR "isdn_bsd_init: [%d] ERR, state %lx data %lx\n", unit, (long)state, (long)data);
		return 0;
	}

	decomp = db->xmit ? 0 : 1;

	if (data->optlen != 1 || data->num != CI_BSD_COMPRESS
	    || (BSD_VERSION(data->options[0]) != BSD_CURRENT_VERSION)
	    || (BSD_NBITS(data->options[0]) != db->maxbits)
	    || (decomp && db->lens == NULL)) {
		printk(KERN_ERR "isdn_bsd: %d %d %d %d %lx\n", data->optlen, data->num, data->options[0], decomp, (unsigned long)db->lens);
		return 0;
	}

	if (decomp)
		for (indx = LAST; indx >= 0; indx--)
			db->lens[indx] = 1;

	indx = db->hsize;
	while (indx-- != 0) {
		db->dict[indx].codem1 = BADCODEM1;
		db->dict[indx].cptr   = 0;
	}

	db->unit = unit;
	db->mru  = 0;

	db->debug = 1;

	bsd_reset(db, 0, 0, NULL, 0, NULL);

	return 1;
}

/*
 * Obtain pointers to the various structures in the compression tables
 */

#define dict_ptrx(p, idx) &(p->dict[idx])
#define lens_ptrx(p, idx) &(p->lens[idx])

#ifdef DEBUG
static unsigned short *lens_ptr(struct bsd_db *db, int idx)
{
	if ((unsigned int) idx > (unsigned int) db->maxmaxcode) {
		printk(KERN_DEBUG "<9>ppp: lens_ptr(%d) > max\n", idx);
		idx = 0;
	}
	return lens_ptrx(db, idx);
}

static struct bsd_dict *dict_ptr(struct bsd_db *db, int idx)
{
	if ((unsigned int) idx >= (unsigned int) db->hsize) {
		printk(KERN_DEBUG "<9>ppp: dict_ptr(%d) > max\n", idx);
		idx = 0;
	}
	return dict_ptrx(db, idx);
}

#else
#define lens_ptr(db, idx) lens_ptrx(db, idx)
#define dict_ptr(db, idx) dict_ptrx(db, idx)
#endif

/*
 * compress a packet
 */
static int bsd_compress(void *state, struct sk_buff *skb_in, struct sk_buff *skb_out, int proto)
{
	struct bsd_db *db;
	int hshift;
	unsigned int max_ent;
	unsigned int n_bits;
	unsigned int bitno;
	unsigned long accm;
	int ent;
	unsigned long fcode;
	struct bsd_dict *dictp;
	unsigned char c;
	int hval, disp, ilen, mxcode;
	unsigned char *rptr = skb_in->data;
	int isize = skb_in->len;

#define OUTPUT(ent)							\
	{								\
		bitno -= n_bits;					\
		accm |= ((ent) << bitno);				\
		do	{						\
			if (skb_out && skb_tailroom(skb_out) > 0)	\
				skb_put_u8(skb_out, (u8)(accm >> 24));	\
			accm <<= 8;					\
			bitno += 8;					\
		} while (bitno <= 24);					\
	}

	/*
	 * If the protocol is not in the range we're interested in,
	 * just return without compressing the packet.  If it is,
	 * the protocol becomes the first byte to compress.
	 */
	printk(KERN_DEBUG "bsd_compress called with %x\n", proto);

	ent = proto;
	if (proto < 0x21 || proto > 0xf9 || !(proto & 0x1))
		return 0;

	db      = (struct bsd_db *) state;
	hshift  = db->hshift;
	max_ent = db->max_ent;
	n_bits  = db->n_bits;
	bitno   = 32;
	accm    = 0;
	mxcode  = MAXCODE(n_bits);

	/* This is the PPP header information */
	if (skb_out && skb_tailroom(skb_out) >= 2) {
		char *v = skb_put(skb_out, 2);
		/* we only push our own data on the header,
		   AC,PC and protos is pushed by caller  */
		v[0] = db->seqno >> 8;
		v[1] = db->seqno;
	}

	ilen = ++isize; /* This is off by one, but that is what is in draft! */

	while (--ilen > 0) {
		c = *rptr++;
		fcode = BSD_KEY(ent, c);
		hval = BSD_HASH(ent, c, hshift);
		dictp = dict_ptr(db, hval);

		/* Validate and then check the entry. */
		if (dictp->codem1 >= max_ent)
			goto nomatch;

		if (dictp->fcode == fcode) {
			ent = dictp->codem1 + 1;
			continue;	/* found (prefix,suffix) */
		}

		/* continue probing until a match or invalid entry */
		disp = (hval == 0) ? 1 : hval;

		do {
			hval += disp;
			if (hval >= db->hsize)
				hval -= db->hsize;
			dictp = dict_ptr(db, hval);
			if (dictp->codem1 >= max_ent)
				goto nomatch;
		} while (dictp->fcode != fcode);

		ent = dictp->codem1 + 1;	/* finally found (prefix,suffix) */
		continue;

	nomatch:
		OUTPUT(ent);		/* output the prefix */

		/* code -> hashtable */
		if (max_ent < db->maxmaxcode) {
			struct bsd_dict *dictp2;
			struct bsd_dict *dictp3;
			int indx;

			/* expand code size if needed */
			if (max_ent >= mxcode) {
				db->n_bits = ++n_bits;
				mxcode = MAXCODE(n_bits);
			}

			/*
			 * Invalidate old hash table entry using
			 * this code, and then take it over.
			 */
			dictp2 = dict_ptr(db, max_ent + 1);
			indx   = dictp2->cptr;
			dictp3 = dict_ptr(db, indx);

			if (dictp3->codem1 == max_ent)
				dictp3->codem1 = BADCODEM1;

			dictp2->cptr   = hval;
			dictp->codem1  = max_ent;
			dictp->fcode = fcode;
			db->max_ent    = ++max_ent;

			if (db->lens) {
				unsigned short *len1 = lens_ptr(db, max_ent);
				unsigned short *len2 = lens_ptr(db, ent);
				*len1 = *len2 + 1;
			}
		}
		ent = c;
	}

	OUTPUT(ent);		/* output the last code */

	if (skb_out)
		db->bytes_out    += skb_out->len; /* Do not count bytes from here */
	db->uncomp_bytes += isize;
	db->in_count     += isize;
	++db->uncomp_count;
	++db->seqno;

	if (bitno < 32)
		++db->bytes_out; /* must be set before calling bsd_check */

	/*
	 * Generate the clear command if needed
	 */

	if (bsd_check(db))
		OUTPUT(CLEAR);

	/*
	 * Pad dribble bits of last code with ones.
	 * Do not emit a completely useless byte of ones.
	 */
	if (bitno < 32 && skb_out && skb_tailroom(skb_out) > 0)
		skb_put_u8(skb_out,
			   (unsigned char)((accm | (0xff << (bitno - 8))) >> 24));

	/*
	 * Increase code size if we would have without the packet
	 * boundary because the decompressor will do so.
	 */
	if (max_ent >= mxcode && max_ent < db->maxmaxcode)
		db->n_bits++;

	/* If output length is too large then this is an incompressible frame. */
	if (!skb_out || skb_out->len >= skb_in->len) {
		++db->incomp_count;
		db->incomp_bytes += isize;
		return 0;
	}

	/* Count the number of compressed frames */
	++db->comp_count;
	db->comp_bytes += skb_out->len;
	return skb_out->len;

#undef OUTPUT
}

/*
 * Update the "BSD Compress" dictionary on the receiver for
 * incompressible data by pretending to compress the incoming data.
 */
static void bsd_incomp(void *state, struct sk_buff *skb_in, int proto)
{
	bsd_compress(state, skb_in, NULL, proto);
}

/*
 * Decompress "BSD Compress".
 */
static int bsd_decompress(void *state, struct sk_buff *skb_in, struct sk_buff *skb_out,
			  struct isdn_ppp_resetparams *rsparm)
{
	struct bsd_db *db;
	unsigned int max_ent;
	unsigned long accm;
	unsigned int bitno;		/* 1st valid bit in accm */
	unsigned int n_bits;
	unsigned int tgtbitno;	/* bitno when we have a code */
	struct bsd_dict *dictp;
	int seq;
	unsigned int incode;
	unsigned int oldcode;
	unsigned int finchar;
	unsigned char *p, *ibuf;
	int ilen;
	int codelen;
	int extra;

	db       = (struct bsd_db *) state;
	max_ent  = db->max_ent;
	accm     = 0;
	bitno    = 32;		/* 1st valid bit in accm */
	n_bits   = db->n_bits;
	tgtbitno = 32 - n_bits;	/* bitno when we have a code */

	printk(KERN_DEBUG "bsd_decompress called\n");

	if (!skb_in || !skb_out) {
		printk(KERN_ERR "bsd_decompress called with NULL parameter\n");
		return DECOMP_ERROR;
	}

	/*
	 * Get the sequence number.
	 */
	if ((p = skb_pull(skb_in, 2)) == NULL) {
		return DECOMP_ERROR;
	}
	p -= 2;
	seq = (p[0] << 8) + p[1];
	ilen = skb_in->len;
	ibuf = skb_in->data;

	/*
	 * Check the sequence number and give up if it differs from
	 * the value we're expecting.
	 */
	if (seq != db->seqno) {
		if (db->debug) {
			printk(KERN_DEBUG "bsd_decomp%d: bad sequence # %d, expected %d\n",
			       db->unit, seq, db->seqno - 1);
		}
		return DECOMP_ERROR;
	}

	++db->seqno;
	db->bytes_out += ilen;

	if (skb_tailroom(skb_out) > 0)
		skb_put_u8(skb_out, 0);
	else
		return DECOMP_ERR_NOMEM;

	oldcode = CLEAR;

	/*
	 * Keep the checkpoint correctly so that incompressible packets
	 * clear the dictionary at the proper times.
	 */

	for (;;) {
		if (ilen-- <= 0) {
			db->in_count += (skb_out->len - 1); /* don't count the header */
			break;
		}

		/*
		 * Accumulate bytes until we have a complete code.
		 * Then get the next code, relying on the 32-bit,
		 * unsigned accm to mask the result.
		 */

		bitno -= 8;
		accm  |= *ibuf++ << bitno;
		if (tgtbitno < bitno)
			continue;

		incode = accm >> tgtbitno;
		accm <<= n_bits;
		bitno += n_bits;

		/*
		 * The dictionary must only be cleared at the end of a packet.
		 */

		if (incode == CLEAR) {
			if (ilen > 0) {
				if (db->debug)
					printk(KERN_DEBUG "bsd_decomp%d: bad CLEAR\n", db->unit);
				return DECOMP_FATALERROR;	/* probably a bug */
			}
			bsd_clear(db);
			break;
		}

		if ((incode > max_ent + 2) || (incode > db->maxmaxcode)
		    || (incode > max_ent && oldcode == CLEAR)) {
			if (db->debug) {
				printk(KERN_DEBUG "bsd_decomp%d: bad code 0x%x oldcode=0x%x ",
				       db->unit, incode, oldcode);
				printk(KERN_DEBUG "max_ent=0x%x skb->Len=%d seqno=%d\n",
				       max_ent, skb_out->len, db->seqno);
			}
			return DECOMP_FATALERROR;	/* probably a bug */
		}

		/* Special case for KwKwK string. */
		if (incode > max_ent) {
			finchar = oldcode;
			extra   = 1;
		} else {
			finchar = incode;
			extra   = 0;
		}

		codelen = *(lens_ptr(db, finchar));
		if (skb_tailroom(skb_out) < codelen + extra) {
			if (db->debug) {
				printk(KERN_DEBUG "bsd_decomp%d: ran out of mru\n", db->unit);
#ifdef DEBUG
				printk(KERN_DEBUG "  len=%d, finchar=0x%x, codelen=%d,skblen=%d\n",
				       ilen, finchar, codelen, skb_out->len);
#endif
			}
			return DECOMP_FATALERROR;
		}

		/*
		 * Decode this code and install it in the decompressed buffer.
		 */

		p = skb_put(skb_out, codelen);
		p += codelen;
		while (finchar > LAST) {
			struct bsd_dict *dictp2 = dict_ptr(db, finchar);

			dictp = dict_ptr(db, dictp2->cptr);

#ifdef DEBUG
			if (--codelen <= 0 || dictp->codem1 != finchar - 1) {
				if (codelen <= 0) {
					printk(KERN_ERR "bsd_decomp%d: fell off end of chain ", db->unit);
					printk(KERN_ERR "0x%x at 0x%x by 0x%x, max_ent=0x%x\n", incode, finchar, dictp2->cptr, max_ent);
				} else {
					if (dictp->codem1 != finchar - 1) {
						printk(KERN_ERR "bsd_decomp%d: bad code chain 0x%x finchar=0x%x ", db->unit, incode, finchar);
						printk(KERN_ERR "oldcode=0x%x cptr=0x%x codem1=0x%x\n", oldcode, dictp2->cptr, dictp->codem1);
					}
				}
				return DECOMP_FATALERROR;
			}
#endif

			{
				u32 fcode = dictp->fcode;
				*--p    = (fcode >> 16) & 0xff;
				finchar = fcode & 0xffff;
			}
		}
		*--p = finchar;

#ifdef DEBUG
		if (--codelen != 0)
			printk(KERN_ERR "bsd_decomp%d: short by %d after code 0x%x, max_ent=0x%x\n", db->unit, codelen, incode, max_ent);
#endif

		if (extra)		/* the KwKwK case again */
			skb_put_u8(skb_out, finchar);

		/*
		 * If not first code in a packet, and
		 * if not out of code space, then allocate a new code.
		 *
		 * Keep the hash table correct so it can be used
		 * with uncompressed packets.
		 */
		if (oldcode != CLEAR && max_ent < db->maxmaxcode) {
			struct bsd_dict *dictp2, *dictp3;
			u16 *lens1, *lens2;
			unsigned long fcode;
			int hval, disp, indx;

			fcode = BSD_KEY(oldcode, finchar);
			hval  = BSD_HASH(oldcode, finchar, db->hshift);
			dictp = dict_ptr(db, hval);

			/* look for a free hash table entry */
			if (dictp->codem1 < max_ent) {
				disp = (hval == 0) ? 1 : hval;
				do {
					hval += disp;
					if (hval >= db->hsize)
						hval -= db->hsize;
					dictp = dict_ptr(db, hval);
				} while (dictp->codem1 < max_ent);
			}

			/*
			 * Invalidate previous hash table entry
			 * assigned this code, and then take it over
			 */

			dictp2 = dict_ptr(db, max_ent + 1);
			indx   = dictp2->cptr;
			dictp3 = dict_ptr(db, indx);

			if (dictp3->codem1 == max_ent)
				dictp3->codem1 = BADCODEM1;

			dictp2->cptr   = hval;
			dictp->codem1  = max_ent;
			dictp->fcode = fcode;
			db->max_ent    = ++max_ent;

			/* Update the length of this string. */
			lens1  = lens_ptr(db, max_ent);
			lens2  = lens_ptr(db, oldcode);
			*lens1 = *lens2 + 1;

			/* Expand code size if needed. */
			if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode) {
				db->n_bits = ++n_bits;
				tgtbitno   = 32-n_bits;
			}
		}
		oldcode = incode;
	}

	++db->comp_count;
	++db->uncomp_count;
	db->comp_bytes   += skb_in->len - BSD_OVHD;
	db->uncomp_bytes += skb_out->len;

	if (bsd_check(db)) {
		if (db->debug)
			printk(KERN_DEBUG "bsd_decomp%d: peer should have cleared dictionary on %d\n",
			       db->unit, db->seqno - 1);
	}
	return skb_out->len;
}

/*************************************************************
 * Table of addresses for the BSD compression module
 *************************************************************/

static struct isdn_ppp_compressor ippp_bsd_compress = {
	.owner          = THIS_MODULE,
	.num            = CI_BSD_COMPRESS,
	.alloc          = bsd_alloc,
	.free           = bsd_free,
	.init           = bsd_init,
	.reset          = bsd_reset,
	.compress       = bsd_compress,
	.decompress     = bsd_decompress,
	.incomp         = bsd_incomp,
	.stat           = bsd_stats,
};

/*************************************************************
 * Module support routines
 *************************************************************/

static int __init isdn_bsdcomp_init(void)
{
	int answer = isdn_ppp_register_compressor(&ippp_bsd_compress);
	if (answer == 0)
		printk(KERN_INFO "PPP BSD Compression module registered\n");
	return answer;
}

static void __exit isdn_bsdcomp_exit(void)
{
	isdn_ppp_unregister_compressor(&ippp_bsd_compress);
}

module_init(isdn_bsdcomp_init);
module_exit(isdn_bsdcomp_exit);
