^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Update: The Berkeley copyright was changed, and the change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * is retroactive to all "true" BSD software (ie everything
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * from UCB as opposed to other peoples code that just carried
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * the same license). The new copyright doesn't clash with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * GPL, so the module-only restriction has been removed..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) /* Because this code is derived from the 4.3BSD compress source:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright (c) 1985, 1986 The Regents of the University of California.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * This code is derived from software contributed to Berkeley by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * James A. Woods, derived from original work by Spencer Thomas
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * and Joseph Orost.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * notice, this list of conditions and the following disclaimer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * documentation and/or other materials provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * 3. All advertising materials mentioning features or use of this software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * must display the following acknowledgement:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * This product includes software developed by the University of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * California, Berkeley and its contributors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * 4. Neither the name of the University nor the names of its contributors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * may be used to endorse or promote products derived from this software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * This version is for use with contiguous buffers on Linux-derived systems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * ==FILEVERSION 20000226==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * NOTE TO MAINTAINERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * If you modify this file at all, please set the number above to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * date of the modification as YYMMDD (year month day).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * bsd_comp.c is shipped with a PPP distribution as well as with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * the kernel; if everyone increases the FILEVERSION number above,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * then scripts can do the right thing when deciding whether to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * install a new bsd_comp.c file. Don't change the format of that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * line otherwise, so the installation script can recognize it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * From: bsd_comp.c,v 1.3 1994/12/08 01:59:58 paulus Exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #include <linux/ppp_defs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #undef PACKETPTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define PACKETPTR 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #include <linux/ppp-comp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #undef PACKETPTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * PPP "BSD compress" compression
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * The differences between this compression and the classic BSD LZW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * source are obvious from the requirement that the classic code worked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * with files while this handles arbitrarily long streams that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * are broken into packets. They are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * When the code size expands, a block of junk is not emitted by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * the compressor and not expected by the decompressor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * New codes are not necessarily assigned every time an old
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * code is output by the compressor. This is because a packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * end forces a code to be emitted, but does not imply that a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * new sequence has been seen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * The compression ratio is checked at the first end of a packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * after the appropriate gap. Besides simplifying and speeding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * things up, this makes it more likely that the transmitter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * and receiver will agree when the dictionary is cleared when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * compression is not going well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * Macros to extract protocol version and number of bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * from the third byte of the BSD Compress CCP configuration option.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define BSD_VERSION(x) ((x) >> 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define BSD_NBITS(x) ((x) & 0x1F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define BSD_CURRENT_VERSION 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * A dictionary for doing BSD compress.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct bsd_dict {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) union { /* hash value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) unsigned long fcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #if defined(__LITTLE_ENDIAN) /* Little endian order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) unsigned short prefix; /* preceding code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned char suffix; /* last character of new code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) unsigned char pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #elif defined(__BIG_ENDIAN) /* Big endian order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) unsigned char pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned char suffix; /* last character of new code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned short prefix; /* preceding code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #error Endianness not defined...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) } hs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) } f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) unsigned short codem1; /* output of hash table -1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) unsigned short cptr; /* map code to hash table entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct bsd_db {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int totlen; /* length of this structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) unsigned int hsize; /* size of the hash table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) unsigned char hshift; /* used in hash function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) unsigned char n_bits; /* current bits/code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) unsigned char maxbits; /* maximum bits/code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) unsigned char debug; /* non-zero if debug desired */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) unsigned char unit; /* ppp unit number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) unsigned short seqno; /* sequence # of next packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) unsigned int mru; /* size of receive (decompress) bufr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) unsigned int maxmaxcode; /* largest valid code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) unsigned int max_ent; /* largest code in use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) unsigned int in_count; /* uncompressed bytes, aged */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) unsigned int bytes_out; /* compressed bytes, aged */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) unsigned int ratio; /* recent compression ratio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) unsigned int checkpoint; /* when to next check the ratio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) unsigned int clear_count; /* times dictionary cleared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) unsigned int incomp_count; /* incompressible packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) unsigned int incomp_bytes; /* incompressible bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) unsigned int uncomp_count; /* uncompressed packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) unsigned int uncomp_bytes; /* uncompressed bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) unsigned int comp_count; /* compressed packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) unsigned int comp_bytes; /* compressed bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) unsigned short *lens; /* array of lengths of codes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct bsd_dict *dict; /* dictionary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define BSD_OVHD 2 /* BSD compress overhead/packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define MIN_BSD_BITS 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define BSD_INIT_BITS MIN_BSD_BITS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define MAX_BSD_BITS 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static void bsd_free (void *state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static void *bsd_alloc(unsigned char *options, int opt_len, int decomp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static void *bsd_comp_alloc (unsigned char *options, int opt_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static void *bsd_decomp_alloc (unsigned char *options, int opt_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static int bsd_init (void *db, unsigned char *options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) int opt_len, int unit, int debug, int decomp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static int bsd_comp_init (void *state, unsigned char *options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int opt_len, int unit, int opthdr, int debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static int bsd_decomp_init (void *state, unsigned char *options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int opt_len, int unit, int opthdr, int mru,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static void bsd_reset (void *state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static void bsd_comp_stats (void *state, struct compstat *stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static int bsd_compress (void *state, unsigned char *rptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) unsigned char *obuf, int isize, int osize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static void bsd_incomp (void *state, unsigned char *ibuf, int icnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static int bsd_decompress (void *state, unsigned char *ibuf, int isize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) unsigned char *obuf, int osize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /* These are in ppp_generic.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) extern int ppp_register_compressor (struct compressor *cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) extern void ppp_unregister_compressor (struct compressor *cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * the next two codes should not be changed lightly, as they must not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * lie within the contiguous general code space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #define CLEAR 256 /* table clear output code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) #define FIRST 257 /* first free entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) #define LAST 255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define MAXCODE(b) ((1 << (b)) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define BADCODEM1 MAXCODE(MAX_BSD_BITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define BSD_HASH(prefix,suffix,hshift) ((((unsigned long)(suffix))<<(hshift)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ^ (unsigned long)(prefix))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #define BSD_KEY(prefix,suffix) ((((unsigned long)(suffix)) << 16) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) + (unsigned long)(prefix))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #define CHECK_GAP 10000 /* Ratio check interval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) #define RATIO_SCALE_LOG 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #define RATIO_SCALE (1<<RATIO_SCALE_LOG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #define RATIO_MAX (0x7fffffff>>RATIO_SCALE_LOG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * clear the dictionary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) bsd_clear(struct bsd_db *db)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) db->clear_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) db->max_ent = FIRST-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) db->n_bits = BSD_INIT_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) db->bytes_out = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) db->in_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) db->ratio = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) db->checkpoint = CHECK_GAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * If the dictionary is full, then see if it is time to reset it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * Compute the compression ratio using fixed-point arithmetic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * with 8 fractional bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * Since we have an infinite stream instead of a single file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * watch only the local compression ratio.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * Since both peers must reset the dictionary at the same time even in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * the absence of CLEAR codes (while packets are incompressible), they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * must compute the same ratio.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static int bsd_check (struct bsd_db *db) /* 1=output CLEAR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) unsigned int new_ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (db->in_count >= db->checkpoint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* age the ratio by limiting the size of the counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (db->in_count >= RATIO_MAX || db->bytes_out >= RATIO_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) db->in_count -= (db->in_count >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) db->bytes_out -= (db->bytes_out >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) db->checkpoint = db->in_count + CHECK_GAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (db->max_ent >= db->maxmaxcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* Reset the dictionary only if the ratio is worse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * or if it looks as if it has been poisoned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * by incompressible data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * This does not overflow, because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * db->in_count <= RATIO_MAX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) new_ratio = db->in_count << RATIO_SCALE_LOG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (db->bytes_out != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) new_ratio /= db->bytes_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (new_ratio < db->ratio || new_ratio < 1 * RATIO_SCALE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) bsd_clear (db);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) db->ratio = new_ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * Return statistics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static void bsd_comp_stats (void *state, struct compstat *stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct bsd_db *db = (struct bsd_db *) state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) stats->unc_bytes = db->uncomp_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) stats->unc_packets = db->uncomp_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) stats->comp_bytes = db->comp_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) stats->comp_packets = db->comp_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) stats->inc_bytes = db->incomp_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) stats->inc_packets = db->incomp_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) stats->in_count = db->in_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) stats->bytes_out = db->bytes_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * Reset state, as on a CCP ResetReq.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static void bsd_reset (void *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) struct bsd_db *db = (struct bsd_db *) state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) bsd_clear(db);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) db->seqno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) db->clear_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * Release the compression structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static void bsd_free (void *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct bsd_db *db = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (!db)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * Release the dictionary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) vfree(db->dict);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) db->dict = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * Release the string buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) vfree(db->lens);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) db->lens = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * Finally release the structure itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) kfree(db);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * Allocate space for a (de) compressor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static void *bsd_alloc (unsigned char *options, int opt_len, int decomp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) unsigned int hsize, hshift, maxmaxcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct bsd_db *db;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (opt_len != 3 || options[0] != CI_BSD_COMPRESS || options[1] != 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) bits = BSD_NBITS(options[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) switch (bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) case 9: /* needs 82152 for both directions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) case 10: /* needs 84144 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) case 11: /* needs 88240 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) case 12: /* needs 96432 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) hsize = 5003;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) hshift = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) case 13: /* needs 176784 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) hsize = 9001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) hshift = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) case 14: /* needs 353744 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) hsize = 18013;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) hshift = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) case 15: /* needs 691440 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) hsize = 35023;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) hshift = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) case 16: /* needs 1366160--far too much, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* hsize = 69001; */ /* and 69001 is too big for cptr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /* hshift = 8; */ /* in struct bsd_db */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /* break; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * Allocate the main control structure for this instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) maxmaxcode = MAXCODE(bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) db = kzalloc(sizeof (struct bsd_db),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (!db)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * Allocate space for the dictionary. This may be more than one page in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) db->dict = vmalloc(array_size(hsize, sizeof(struct bsd_dict)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (!db->dict)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) bsd_free (db);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * If this is the compression buffer then there is no length data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (!decomp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) db->lens = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * For decompression, the length information is needed as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) db->lens = vmalloc(array_size(sizeof(db->lens[0]), (maxmaxcode + 1)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (!db->lens)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) bsd_free (db);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * Initialize the data information for the compression code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) db->totlen = sizeof (struct bsd_db) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) (sizeof (struct bsd_dict) * hsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) db->hsize = hsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) db->hshift = hshift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) db->maxmaxcode = maxmaxcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) db->maxbits = bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return (void *) db;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static void *bsd_comp_alloc (unsigned char *options, int opt_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return bsd_alloc (options, opt_len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static void *bsd_decomp_alloc (unsigned char *options, int opt_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return bsd_alloc (options, opt_len, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * Initialize the database.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static int bsd_init (void *state, unsigned char *options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) int opt_len, int unit, int debug, int decomp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct bsd_db *db = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) int indx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if ((opt_len != 3) || (options[0] != CI_BSD_COMPRESS) || (options[1] != 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) || (BSD_VERSION(options[2]) != BSD_CURRENT_VERSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) || (BSD_NBITS(options[2]) != db->maxbits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) || (decomp && db->lens == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (decomp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) indx = LAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) db->lens[indx] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) while (indx-- > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) indx = db->hsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) while (indx-- != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) db->dict[indx].codem1 = BADCODEM1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) db->dict[indx].cptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) db->unit = unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) db->mru = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) #ifndef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) db->debug = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) bsd_reset(db);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) static int bsd_comp_init (void *state, unsigned char *options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) int opt_len, int unit, int opthdr, int debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return bsd_init (state, options, opt_len, unit, debug, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static int bsd_decomp_init (void *state, unsigned char *options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) int opt_len, int unit, int opthdr, int mru,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) int debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return bsd_init (state, options, opt_len, unit, debug, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * Obtain pointers to the various structures in the compression tables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) #define dict_ptrx(p,idx) &(p->dict[idx])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) #define lens_ptrx(p,idx) &(p->lens[idx])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) static unsigned short *lens_ptr(struct bsd_db *db, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if ((unsigned int) idx > (unsigned int) db->maxmaxcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) printk ("<9>ppp: lens_ptr(%d) > max\n", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return lens_ptrx (db, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) static struct bsd_dict *dict_ptr(struct bsd_db *db, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if ((unsigned int) idx >= (unsigned int) db->hsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) printk ("<9>ppp: dict_ptr(%d) > max\n", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return dict_ptrx (db, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) #define lens_ptr(db,idx) lens_ptrx(db,idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) #define dict_ptr(db,idx) dict_ptrx(db,idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * compress a packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * The result of this function is the size of the compressed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * packet. A zero is returned if the packet was not compressed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * for some reason, such as the size being larger than uncompressed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * One change from the BSD compress command is that when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * code size expands, we do not output a bunch of padding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static int bsd_compress (void *state, unsigned char *rptr, unsigned char *obuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) int isize, int osize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct bsd_db *db;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) int hshift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) unsigned int max_ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) unsigned int n_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) unsigned int bitno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) unsigned long accm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) int ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) unsigned long fcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) struct bsd_dict *dictp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) unsigned char c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) int hval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) int disp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) int ilen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) int mxcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) unsigned char *wptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) int olen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) #define PUTBYTE(v) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) ++olen; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (wptr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) *wptr++ = (unsigned char) (v); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (olen >= osize) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) wptr = NULL; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) #define OUTPUT(ent) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) bitno -= n_bits; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) accm |= ((ent) << bitno); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) do \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) PUTBYTE(accm >> 24); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) accm <<= 8; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) bitno += 8; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) while (bitno <= 24); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * If the protocol is not in the range we're interested in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * just return without compressing the packet. If it is,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * the protocol becomes the first byte to compress.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) ent = PPP_PROTOCOL(rptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (ent < 0x21 || ent > 0xf9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) db = (struct bsd_db *) state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) hshift = db->hshift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) max_ent = db->max_ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) n_bits = db->n_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) bitno = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) accm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) mxcode = MAXCODE (n_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /* Initialize the output pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) wptr = obuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) olen = PPP_HDRLEN + BSD_OVHD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (osize > isize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) osize = isize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) /* This is the PPP header information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (wptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) *wptr++ = PPP_ADDRESS(rptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) *wptr++ = PPP_CONTROL(rptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) *wptr++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) *wptr++ = PPP_COMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) *wptr++ = db->seqno >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) *wptr++ = db->seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) /* Skip the input header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) rptr += PPP_HDRLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) isize -= PPP_HDRLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) ilen = ++isize; /* Low byte of protocol is counted as input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) while (--ilen > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) c = *rptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) fcode = BSD_KEY (ent, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) hval = BSD_HASH (ent, c, hshift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) dictp = dict_ptr (db, hval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /* Validate and then check the entry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (dictp->codem1 >= max_ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) goto nomatch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (dictp->f.fcode == fcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) ent = dictp->codem1 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) continue; /* found (prefix,suffix) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) /* continue probing until a match or invalid entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) disp = (hval == 0) ? 1 : hval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) hval += disp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (hval >= db->hsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) hval -= db->hsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) dictp = dict_ptr (db, hval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (dictp->codem1 >= max_ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) goto nomatch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) while (dictp->f.fcode != fcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) ent = dictp->codem1 + 1; /* finally found (prefix,suffix) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) nomatch:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) OUTPUT(ent); /* output the prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) /* code -> hashtable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (max_ent < db->maxmaxcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) struct bsd_dict *dictp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) struct bsd_dict *dictp3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) int indx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) /* expand code size if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (max_ent >= mxcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) db->n_bits = ++n_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) mxcode = MAXCODE (n_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) /* Invalidate old hash table entry using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) * this code, and then take it over.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) dictp2 = dict_ptr (db, max_ent + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) indx = dictp2->cptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) dictp3 = dict_ptr (db, indx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (dictp3->codem1 == max_ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) dictp3->codem1 = BADCODEM1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) dictp2->cptr = hval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) dictp->codem1 = max_ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) dictp->f.fcode = fcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) db->max_ent = ++max_ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (db->lens)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) unsigned short *len1 = lens_ptr (db, max_ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) unsigned short *len2 = lens_ptr (db, ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) *len1 = *len2 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) ent = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) OUTPUT(ent); /* output the last code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) db->bytes_out += olen - PPP_HDRLEN - BSD_OVHD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) db->uncomp_bytes += isize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) db->in_count += isize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) ++db->uncomp_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) ++db->seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (bitno < 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) ++db->bytes_out; /* must be set before calling bsd_check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) * Generate the clear command if needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (bsd_check(db))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) OUTPUT (CLEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) * Pad dribble bits of last code with ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * Do not emit a completely useless byte of ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (bitno != 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) PUTBYTE((accm | (0xff << (bitno-8))) >> 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) * Increase code size if we would have without the packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * boundary because the decompressor will do so.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (max_ent >= mxcode && max_ent < db->maxmaxcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) db->n_bits++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) /* If output length is too large then this is an incomplete frame. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (wptr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) ++db->incomp_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) db->incomp_bytes += isize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) olen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) else /* Count the number of compressed frames */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) ++db->comp_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) db->comp_bytes += olen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) /* Return the resulting output length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) return olen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) #undef OUTPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) #undef PUTBYTE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) * Update the "BSD Compress" dictionary on the receiver for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * incompressible data by pretending to compress the incoming data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) static void bsd_incomp (void *state, unsigned char *ibuf, int icnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) (void) bsd_compress (state, ibuf, (char *) 0, icnt, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) * Decompress "BSD Compress".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) * Because of patent problems, we return DECOMP_ERROR for errors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) * found by inspecting the input data and for system problems, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * DECOMP_FATALERROR for any errors which could possibly be said to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) * be being detected "after" decompression. For DECOMP_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) * infringing a patent of Motorola's if we do, so we take CCP down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) * Given that the frame has the correct sequence number and a good FCS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) * errors such as invalid codes in the input most likely indicate a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) * bug, so we return DECOMP_FATALERROR for them in order to turn off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) * compression, even though they are detected by inspecting the input.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) static int bsd_decompress (void *state, unsigned char *ibuf, int isize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) unsigned char *obuf, int osize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) struct bsd_db *db;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) unsigned int max_ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) unsigned long accm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) unsigned int bitno; /* 1st valid bit in accm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) unsigned int n_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) unsigned int tgtbitno; /* bitno when we have a code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) struct bsd_dict *dictp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) int explen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) int seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) unsigned int incode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) unsigned int oldcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) unsigned int finchar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) unsigned char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) unsigned char *wptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) int adrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) int ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) int ilen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) int codelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) int extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) db = (struct bsd_db *) state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) max_ent = db->max_ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) accm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) bitno = 32; /* 1st valid bit in accm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) n_bits = db->n_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) tgtbitno = 32 - n_bits; /* bitno when we have a code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) * Save the address/control from the PPP header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) * and then get the sequence number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) adrs = PPP_ADDRESS (ibuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) ctrl = PPP_CONTROL (ibuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) seq = (ibuf[4] << 8) + ibuf[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) ibuf += (PPP_HDRLEN + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) ilen = isize - (PPP_HDRLEN + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) * Check the sequence number and give up if it differs from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) * the value we're expecting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (seq != db->seqno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (db->debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) printk("bsd_decomp%d: bad sequence # %d, expected %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) db->unit, seq, db->seqno - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return DECOMP_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) ++db->seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) db->bytes_out += ilen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * Fill in the ppp header, but not the last byte of the protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) * (that comes from the decompressed data).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) wptr = obuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) *wptr++ = adrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) *wptr++ = ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) *wptr++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) oldcode = CLEAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) explen = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) * Keep the checkpoint correctly so that incompressible packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) * clear the dictionary at the proper times.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) for (;;)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (ilen-- <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) db->in_count += (explen - 3); /* don't count the header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * Accumulate bytes until we have a complete code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) * Then get the next code, relying on the 32-bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * unsigned accm to mask the result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) bitno -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) accm |= *ibuf++ << bitno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (tgtbitno < bitno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) incode = accm >> tgtbitno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) accm <<= n_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) bitno += n_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) * The dictionary must only be cleared at the end of a packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (incode == CLEAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (ilen > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (db->debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) printk("bsd_decomp%d: bad CLEAR\n", db->unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) return DECOMP_FATALERROR; /* probably a bug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) bsd_clear(db);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if ((incode > max_ent + 2) || (incode > db->maxmaxcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) || (incode > max_ent && oldcode == CLEAR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (db->debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) printk("bsd_decomp%d: bad code 0x%x oldcode=0x%x ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) db->unit, incode, oldcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) printk("max_ent=0x%x explen=%d seqno=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) max_ent, explen, db->seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return DECOMP_FATALERROR; /* probably a bug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) /* Special case for KwKwK string. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (incode > max_ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) finchar = oldcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) extra = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) finchar = incode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) extra = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) codelen = *(lens_ptr (db, finchar));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) explen += codelen + extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (explen > osize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (db->debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) printk("bsd_decomp%d: ran out of mru\n", db->unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) printk(" len=%d, finchar=0x%x, codelen=%d, explen=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) ilen, finchar, codelen, explen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) return DECOMP_FATALERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) * Decode this code and install it in the decompressed buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) wptr += codelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) p = wptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) while (finchar > LAST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) struct bsd_dict *dictp2 = dict_ptr (db, finchar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) dictp = dict_ptr (db, dictp2->cptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) if (--codelen <= 0 || dictp->codem1 != finchar-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (codelen <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) printk("bsd_decomp%d: fell off end of chain ", db->unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) printk("0x%x at 0x%x by 0x%x, max_ent=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) incode, finchar, dictp2->cptr, max_ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) if (dictp->codem1 != finchar-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) printk("bsd_decomp%d: bad code chain 0x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) "finchar=0x%x ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) db->unit, incode, finchar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) printk("oldcode=0x%x cptr=0x%x codem1=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) oldcode, dictp2->cptr, dictp->codem1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) return DECOMP_FATALERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) *--p = dictp->f.hs.suffix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) finchar = dictp->f.hs.prefix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) *--p = finchar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (--codelen != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) printk("bsd_decomp%d: short by %d after code 0x%x, max_ent=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) db->unit, codelen, incode, max_ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (extra) /* the KwKwK case again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) *wptr++ = finchar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) * If not first code in a packet, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) * if not out of code space, then allocate a new code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) * Keep the hash table correct so it can be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) * with uncompressed packets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) if (oldcode != CLEAR && max_ent < db->maxmaxcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) struct bsd_dict *dictp2, *dictp3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) unsigned short *lens1, *lens2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) unsigned long fcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) int hval, disp, indx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) fcode = BSD_KEY(oldcode,finchar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) hval = BSD_HASH(oldcode,finchar,db->hshift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) dictp = dict_ptr (db, hval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) /* look for a free hash table entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (dictp->codem1 < max_ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) disp = (hval == 0) ? 1 : hval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) hval += disp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (hval >= db->hsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) hval -= db->hsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) dictp = dict_ptr (db, hval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) while (dictp->codem1 < max_ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) * Invalidate previous hash table entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) * assigned this code, and then take it over
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) dictp2 = dict_ptr (db, max_ent + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) indx = dictp2->cptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) dictp3 = dict_ptr (db, indx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (dictp3->codem1 == max_ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) dictp3->codem1 = BADCODEM1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) dictp2->cptr = hval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) dictp->codem1 = max_ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) dictp->f.fcode = fcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) db->max_ent = ++max_ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) /* Update the length of this string. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) lens1 = lens_ptr (db, max_ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) lens2 = lens_ptr (db, oldcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) *lens1 = *lens2 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) /* Expand code size if needed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) db->n_bits = ++n_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) tgtbitno = 32-n_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) oldcode = incode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) ++db->comp_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) ++db->uncomp_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) db->comp_bytes += isize - BSD_OVHD - PPP_HDRLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) db->uncomp_bytes += explen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (bsd_check(db))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (db->debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) printk("bsd_decomp%d: peer should have cleared dictionary on %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) db->unit, db->seqno - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) return explen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) /*************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) * Table of addresses for the BSD compression module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) *************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) static struct compressor ppp_bsd_compress = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) .compress_proto = CI_BSD_COMPRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) .comp_alloc = bsd_comp_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) .comp_free = bsd_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) .comp_init = bsd_comp_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) .comp_reset = bsd_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) .compress = bsd_compress,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) .comp_stat = bsd_comp_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) .decomp_alloc = bsd_decomp_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) .decomp_free = bsd_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) .decomp_init = bsd_decomp_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) .decomp_reset = bsd_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) .decompress = bsd_decompress,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) .incomp = bsd_incomp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) .decomp_stat = bsd_comp_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) .owner = THIS_MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) /*************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) * Module support routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) *************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) static int __init bsdcomp_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) int answer = ppp_register_compressor(&ppp_bsd_compress);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (answer == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) printk(KERN_INFO "PPP BSD Compression module registered\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) return answer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) static void __exit bsdcomp_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) ppp_unregister_compressor(&ppp_bsd_compress);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) module_init(bsdcomp_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) module_exit(bsdcomp_cleanup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) MODULE_LICENSE("Dual BSD/GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) MODULE_ALIAS("ppp-compress-" __stringify(CI_BSD_COMPRESS));