annotate packages/net/ppp/current/src/bsd_comp.c @ 1694:5629b7c30ed2

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