/*
 * 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(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((maxmaxcode + 1) * sizeof(db->lens[0]));
		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);
