1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/*
24 * ppp_comp.h - Definitions for doing PPP packet compression.
25 *
26 * Copyright (c) 1994 The Australian National University.
27 * All rights reserved.
28 *
29 * Permission to use, copy, modify, and distribute this software and its
30 * documentation is hereby granted, provided that the above copyright
31 * notice appears in all copies.  This software is provided without any
32 * warranty, express or implied. The Australian National University
33 * makes no representations about the suitability of this software for
34 * any purpose.
35 *
36 * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
37 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
38 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
39 * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
40 * OF SUCH DAMAGE.
41 *
42 * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
43 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
44 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
45 * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
46 * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
47 * OR MODIFICATIONS.
48 *
49 */
50
51#ifndef _NET_PPP_COMP_H
52#define _NET_PPP_COMP_H
53
54/*
55 * The following symbols control whether we include code for
56 * various compression methods.
57 */
58#ifndef DO_BSD_COMPRESS
59#define DO_BSD_COMPRESS	1	/* by default, include BSD-Compress */
60#endif
61#ifndef DO_DEFLATE
62#define DO_DEFLATE	1	/* by default, include Deflate */
63#endif
64#define DO_PREDICTOR_1	0
65#define DO_PREDICTOR_2	0
66
67#ifdef KERNEL
68
69/* Reference to a ppp compressor object */
70typedef void * ppp_comp_ref;
71
72/*
73 * Structure giving methods for compression/decompression.
74 */
75struct ppp_comp_reg {
76	int	compress_proto;	/* CCP compression protocol number */
77
78	/* Allocate space for a compressor (transmit side) */
79	void	*(*comp_alloc) __P((u_char *options, int opt_len));
80	/* Free space used by a compressor */
81	void	(*comp_free) __P((void *state));
82	/* Initialize a compressor */
83	int	(*comp_init) __P((void *state, u_char *options, int opt_len,
84				  int unit, int hdrlen, int mtu, int debug));
85	/* Reset a compressor */
86	void	(*comp_reset) __P((void *state));
87	/* Compress a packet */
88	int	(*compress) __P((void *state, mbuf_t *m));
89	/* Return compression statistics */
90	void	(*comp_stat) __P((void *state, struct compstat *stats));
91
92	/* Allocate space for a decompressor (receive side) */
93	void	*(*decomp_alloc) __P((u_char *options, int opt_len));
94	/* Free space used by a decompressor */
95	void	(*decomp_free) __P((void *state));
96	/* Initialize a decompressor */
97	int	(*decomp_init) __P((void *state, u_char *options, int opt_len,
98				    int unit, int hdrlen, int mru, int debug));
99	/* Reset a decompressor */
100	void	(*decomp_reset) __P((void *state));
101	/* Decompress a packet. */
102	int	(*decompress) __P((void *state, mbuf_t *m));
103	/* Update state for an incompressible packet received */
104	void	(*incomp) __P((void *state, mbuf_t m));
105	/* Return decompression statistics */
106	void	(*decomp_stat) __P((void *state, struct compstat *stats));
107};
108
109/*
110 * Return values for decompress routine.
111 * We need to make these distinctions so that we can disable certain
112 * useful functionality, namely sending a CCP reset-request as a result
113 * of an error detected after decompression.  This is to avoid infringing
114 * a patent held by Motorola.
115 * Don't you just lurve software patents.
116 */
117#define DECOMP_OK		0	/* everything went OK */
118#define DECOMP_ERROR		1	/* error detected before decomp. */
119#define DECOMP_FATALERROR	2	/* error detected after decomp. */
120
121#define COMP_OK			0	/* everything went OK, packet is compressed */
122#define COMP_NOTDONE		1	/* packet has not been compressed */
123
124#endif /* KERNEL */
125
126/*
127 * CCP codes.
128 */
129#define CCP_CONFREQ	1
130#define CCP_CONFACK	2
131#define CCP_TERMREQ	5
132#define CCP_TERMACK	6
133#define CCP_RESETREQ	14
134#define CCP_RESETACK	15
135
136/*
137 * Max # bytes for a CCP option
138 */
139#define CCP_MAX_OPTION_LENGTH	64
140
141/*
142 * Parts of a CCP packet.
143 */
144#define CCP_CODE(dp)		((dp)[0])
145#define CCP_ID(dp)		((dp)[1])
146#define CCP_LENGTH(dp)		(((dp)[2] << 8) + (dp)[3])
147#define CCP_HDRLEN		4
148
149#define CCP_OPT_CODE(dp)	((dp)[0])
150#define CCP_OPT_LENGTH(dp)	((dp)[1])
151#define CCP_OPT_MINLEN		2
152
153/*
154 * Definitions for BSD-Compress.
155 */
156#define CI_BSD_COMPRESS		21	/* config. option for BSD-Compress */
157#define CILEN_BSD_COMPRESS	3	/* length of config. option */
158
159/* Macros for handling the 3rd byte of the BSD-Compress config option. */
160#define BSD_NBITS(x)		((x) & 0x1F)	/* number of bits requested */
161#define BSD_VERSION(x)		((x) >> 5)	/* version of option format */
162#define BSD_CURRENT_VERSION	1		/* current version number */
163#define BSD_MAKE_OPT(v, n)	(((v) << 5) | (n))
164
165#define BSD_MIN_BITS		9	/* smallest code size supported */
166#define BSD_MAX_BITS		15	/* largest code size supported */
167
168/*
169 * Definitions for Deflate.
170 */
171#define CI_DEFLATE		26	/* config option for Deflate */
172#define CI_DEFLATE_DRAFT	24	/* value used in original draft RFC */
173#define CILEN_DEFLATE		4	/* length of its config option */
174
175#define DEFLATE_MIN_SIZE	8
176#define DEFLATE_MAX_SIZE	15
177#define DEFLATE_METHOD_VAL	8
178#define DEFLATE_SIZE(x)		(((x) >> 4) + DEFLATE_MIN_SIZE)
179#define DEFLATE_METHOD(x)	((x) & 0x0F)
180#define DEFLATE_MAKE_OPT(w)	((((w) - DEFLATE_MIN_SIZE) << 4) \
181				 + DEFLATE_METHOD_VAL)
182#define DEFLATE_CHK_SEQUENCE	0
183
184/*
185 * Definitions for MPPE.
186 */
187
188#define CI_MPPE			18	/* config. option for MPPE */
189#define CILEN_MPPE		6	/* length of config. option */
190
191#define MPPE_PAD                4       /* MPPE growth per frame */
192#define MPPE_MAX_KEY_LEN        16      /* largest key length (128-bit) */
193
194/* option bits for ccp_options.mppe */
195#define MPPE_OPT_40             0x01    /* 40 bit */
196#define MPPE_OPT_128            0x02    /* 128 bit */
197#define MPPE_OPT_STATEFUL       0x04    /* stateful mode */
198/* unsupported opts */
199#define MPPE_OPT_56             0x08    /* 56 bit */
200#define MPPE_OPT_MPPC           0x10    /* MPPC compression */
201#define MPPE_OPT_D              0x20    /* Unknown */
202#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D)
203#define MPPE_OPT_UNKNOWN        0x40    /* Bits !defined in RFC 3078 were set */
204
205/*
206 * This is not nice ... the alternative is a bitfield struct though.
207 * And unfortunately, we cannot share the same bits for the option
208 * names above since C and H are the same bit.  We could do a u_int32
209 * but then we have to do a htonl() all the time and/or we still need
210 * to know which octet is which.
211 */
212#define MPPE_C_BIT              0x01    /* MPPC */
213#define MPPE_D_BIT              0x10    /* Obsolete, usage unknown */
214#define MPPE_L_BIT              0x20    /* 40-bit */
215#define MPPE_S_BIT              0x40    /* 128-bit */
216#define MPPE_M_BIT              0x80    /* 56-bit, not supported */
217#define MPPE_H_BIT              0x01    /* Stateless (in a different byte) */
218
219/* Does not include H bit; used for least significant octet only. */
220#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT)
221
222/* Build a CI from mppe opts (see RFC 3078) */
223#define MPPE_OPTS_TO_CI(opts, ci)               \
224    do {                                        \
225        u_char *ptr = ci; /* u_char[4] */       \
226                                                \
227        /* H bit */                             \
228        if (opts & MPPE_OPT_STATEFUL)           \
229            *ptr++ = 0x0;                       \
230        else                                    \
231            *ptr++ = MPPE_H_BIT;                \
232        *ptr++ = 0;                             \
233        *ptr++ = 0;                             \
234                                                \
235        /* S,L bits */                          \
236        *ptr = 0;                               \
237        if (opts & MPPE_OPT_128)                \
238            *ptr |= MPPE_S_BIT;                 \
239        if (opts & MPPE_OPT_40)                 \
240            *ptr |= MPPE_L_BIT;                 \
241        /* M,D,C bits not supported */          \
242    } while (/* CONSTCOND */ 0)
243
244/* The reverse of the above */
245#define MPPE_CI_TO_OPTS(ci, opts)               \
246    do {                                        \
247        u_char *ptr = ci; /* u_char[4] */       \
248                                                \
249        opts = 0;                               \
250                                                \
251        /* H bit */                             \
252        if (!(ptr[0] & MPPE_H_BIT))             \
253            opts |= MPPE_OPT_STATEFUL;          \
254                                                \
255        /* S,L bits */                          \
256        if (ptr[3] & MPPE_S_BIT)                \
257            opts |= MPPE_OPT_128;               \
258        if (ptr[3] & MPPE_L_BIT)                \
259            opts |= MPPE_OPT_40;                \
260                                                \
261        /* M,D,C bits */                        \
262        if (ptr[3] & MPPE_M_BIT)                \
263            opts |= MPPE_OPT_56;                \
264        if (ptr[3] & MPPE_D_BIT)                \
265            opts |= MPPE_OPT_D;                 \
266        if (ptr[3] & MPPE_C_BIT)                \
267            opts |= MPPE_OPT_MPPC;              \
268                                                \
269        /* Other bits */                        \
270        if (ptr[0] & ~MPPE_H_BIT)               \
271            opts |= MPPE_OPT_UNKNOWN;           \
272        if (ptr[1] || ptr[2])                   \
273            opts |= MPPE_OPT_UNKNOWN;           \
274        if (ptr[3] & ~MPPE_ALL_BITS)            \
275            opts |= MPPE_OPT_UNKNOWN;           \
276    } while (/* CONSTCOND */ 0)
277
278/*
279 * Definitions for other, as yet unsupported, compression methods.
280 */
281#define CI_PREDICTOR_1		1	/* config option for Predictor-1 */
282#define CILEN_PREDICTOR_1	2	/* length of its config option */
283#define CI_PREDICTOR_2		2	/* config option for Predictor-2 */
284#define CILEN_PREDICTOR_2	2	/* length of its config option */
285
286
287#ifdef KERNEL
288
289/*
290 * FUNCTION :
291 * Register the compressor to the ppp family
292 *
293 * PARAMETERS :
294 * compreg : 	Registration structure containing compressor information
295 *          	and callback functions for the compressor.
296 *
297 * RETURN CODE :
298 * 0 : 		No error
299 *     		*compref will be filled with a compressor reference,
300 * 		to use in subsequent call to the ppp family
301 * EINVAL : 	Invalid registration structure
302 * ENOMEM : 	Not enough memory available to register the compressor
303 * EEXIST : 	compressor already registered
304 */
305
306int ppp_comp_register(struct ppp_comp_reg *compreg, ppp_comp_ref *compref);
307
308/*
309 * FUNCTION :
310 * Deregister the compressor
311 *
312 * PARAMETERS :
313 * compref : 	Reference to the compressor previously registered
314 *
315 * RETURN CODE :
316 * 0 : 		No error,
317 * 		The ppp family no longer knows about the compressor
318 * EINVAL : 	Invalid reference
319 */
320int ppp_comp_deregister(ppp_comp_ref *compref);
321
322#endif /* KERNEL */
323
324#endif /* _NET_PPP_COMP_H */
325