X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=linux%2Fmppe%2Fppp_mppe_compress.c;h=051213273970fa4affb73b00d68c0c1bafe1945e;hb=8dab7e1cb378a55b57a7bca6bc66a7ecc091d41f;hp=0a757686de4ce1c83c23b9f78c8f8154b5ad4a3d;hpb=7bb8beb860037a6c18dd0b64b8d542a20aa2c8c0;p=ppp.git diff --git a/linux/mppe/ppp_mppe_compress.c b/linux/mppe/ppp_mppe_compress.c index 0a75768..0512132 100644 --- a/linux/mppe/ppp_mppe_compress.c +++ b/linux/mppe/ppp_mppe_compress.c @@ -1,11 +1,9 @@ /* - * ==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 . - * 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 @@ -13,10 +11,16 @@ * notice appears in all copies. This software is provided without any * warranty, express or implied. * + * Changelog: + * 2/15/04 - TS: added #include and testing for Kernel + * version before using + * MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are + * deprecated in 2.6 */ #include #include +#include #include #include #include @@ -170,7 +174,11 @@ mppe_alloc(unsigned char *options, int optlen) 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. */ @@ -194,7 +202,11 @@ mppe_free(void *arg) if (state) { kfree(state); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) + module_put(THIS_MODULE); +#else MOD_DEC_USE_COUNT; +#endif } } @@ -333,6 +345,9 @@ mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf, 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; @@ -412,12 +427,25 @@ mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf, 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)) { @@ -508,14 +536,32 @@ mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf, * 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++; @@ -539,7 +585,6 @@ mppe_incomp(void *arg, unsigned char *ibuf, int icnt) { 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! "