/*
- * ==FILEVERSION 20020521==
- *
* ppp_mppe_compress.c - interface MPPE to the PPP code.
- * This version is for use with Linux kernel 2.2.19+ and 2.4.x.
+ * This version is for use with Linux kernel 2.2.19+, 2.4.18+ and 2.6.2+.
*
* By Frank Cusack <frank@google.com>.
- * Copyright (c) 2002 Google, Inc.
+ * Copyright (c) 2002,2003,2004 Google, Inc.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* notice appears in all copies. This software is provided without any
* warranty, express or implied.
*
+ * Changelog:
+ * 2/15/04 - TS: added #include <version.h> and testing for Kernel
+ * version before using
+ * MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are
+ * deprecated in 2.6
*/
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/version.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/slab.h>
if (state == NULL)
return NULL;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+ try_module_get(THIS_MODULE);
+#else
MOD_INC_USE_COUNT;
+#endif
memset(state, 0, sizeof(*state));
/* Save keys. */
if (state) {
kfree(state);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+ module_put(THIS_MODULE);
+#else
MOD_DEC_USE_COUNT;
+#endif
}
}
obuf += PPP_HDRLEN;
state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
+ if (state->debug >= 7)
+ printk(KERN_DEBUG "mppe_compress[%d]: ccount %d\n", state->unit,
+ state->ccount);
obuf[0] = state->ccount >> 8;
obuf[1] = state->ccount & 0xff;
state->unit, isize);
return DECOMP_ERROR;
}
- /* Strange ... our output size is always LESS than the input size. */
- /* assert(osize >= isize - MPPE_OVHD - 2); */
- osize = isize - MPPE_OVHD - 2;
+ /*
+ * Make sure we have enough room to decrypt the packet.
+ * Note that for our test we only subtract 1 byte whereas in
+ * mppe_compress() we added 2 bytes (+MPPE_OVHD);
+ * this is to account for possible PFC.
+ */
+ if (osize < isize - MPPE_OVHD - 1) {
+ printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! "
+ "(have: %d need: %d)\n", state->unit,
+ osize, isize - MPPE_OVHD - 1);
+ return DECOMP_ERROR;
+ }
+ osize = isize - MPPE_OVHD - 2; /* assume no PFC */
ccount = MPPE_CCOUNT(ibuf);
+ if (state->debug >= 7)
+ printk(KERN_DEBUG "mppe_decompress[%d]: ccount %d\n", state->unit,
+ ccount);
/* sanity checks -- terminate with extreme prejudice */
if (!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
* comes from the decrypted data.
*/
obuf[0] = PPP_ADDRESS(ibuf); /* +1 */
- obuf[1] = PPP_CONTROL(ibuf); /* +2 */
+ obuf[1] = PPP_CONTROL(ibuf); /* +1 */
obuf += 2;
ibuf += PPP_HDRLEN + MPPE_OVHD;
isize -= PPP_HDRLEN + MPPE_OVHD; /* -6 */
- /* net: -4 */
+ /* net osize: isize-4 */
+
+ /*
+ * Decrypt the first byte in order to check if it is
+ * a compressed or uncompressed protocol field.
+ */
+ arcfour_decrypt(&state->arcfour_context, ibuf, 1, obuf);
+
+ /*
+ * Do PFC decompression.
+ * This would be nicer if we were given the actual sk_buff
+ * instead of a char *.
+ */
+ if ((obuf[0] & 0x01) != 0) {
+ obuf[1] = obuf[0];
+ obuf[0] = 0;
+ obuf++;
+ osize++;
+ }
- /* And finally, decrypt the packet. */
- arcfour_decrypt(&state->arcfour_context, ibuf, isize, obuf);
+ /* And finally, decrypt the rest of the packet. */
+ arcfour_decrypt(&state->arcfour_context, ibuf + 1, isize - 1, obuf + 1);
state->stats.unc_bytes += osize;
state->stats.unc_packets++;
{
ppp_mppe_state *state = (ppp_mppe_state *) arg;
-/* XXX */
if (state->debug &&
(PPP_PROTOCOL(ibuf) >= 0x0021 && PPP_PROTOCOL(ibuf) <= 0x00fa))
printk(KERN_DEBUG "mppe_incomp[%d]: incompressible (unencrypted) data! "