diff options
author | peter <peter@FreeBSD.org> | 1998-03-22 06:57:20 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1998-03-22 06:57:20 +0000 |
commit | 108c1ee1936470b173b9dd06d836ef7d304f27aa (patch) | |
tree | 3d7d39fbdc546ae43c9cd50547f79657797d59dd /usr.sbin/pppd | |
parent | 47129697379a8b3b8a693c593abc3422a63ed9bf (diff) | |
download | FreeBSD-src-108c1ee1936470b173b9dd06d836ef7d304f27aa.zip FreeBSD-src-108c1ee1936470b173b9dd06d836ef7d304f27aa.tar.gz |
ppp-2.3.x ships with a bad compression number for deflate. It uses number
24 (which is magnalink!) rather than the correct (according to the rfc) 26.
Initial attempt at a compatability kludge that will negotiate for either
but will prefer to use the correct deflate compression type.
Diffstat (limited to 'usr.sbin/pppd')
-rw-r--r-- | usr.sbin/pppd/ccp.c | 163 | ||||
-rw-r--r-- | usr.sbin/pppd/ccp.h | 6 | ||||
-rw-r--r-- | usr.sbin/pppd/options.c | 21 |
3 files changed, 186 insertions, 4 deletions
diff --git a/usr.sbin/pppd/ccp.c b/usr.sbin/pppd/ccp.c index 000d916..08e5ddf 100644 --- a/usr.sbin/pppd/ccp.c +++ b/usr.sbin/pppd/ccp.c @@ -26,7 +26,7 @@ */ #ifndef lint -static char rcsid[] = "$Id$"; +static char rcsid[] = "$Id: ccp.c,v 1.7 1997/08/19 17:52:33 peter Exp $"; #endif #include <string.h> @@ -116,8 +116,14 @@ static fsm_callbacks ccp_callbacks = { /* * Do we want / did we get any compression? */ +#ifdef CI_BADDEFLATE +#define ANY_COMPRESS(opt) ((opt).deflate || (opt).baddeflate \ + || (opt).bsd_compress \ + || (opt).predictor_1 || (opt).predictor_2) +#else #define ANY_COMPRESS(opt) ((opt).deflate || (opt).bsd_compress \ || (opt).predictor_1 || (opt).predictor_2) +#endif /* * Local state (mainly for handling reset-reqs and reset-acks). @@ -154,6 +160,13 @@ ccp_init(unit) ccp_allowoptions[0].deflate = 1; ccp_allowoptions[0].deflate_size = DEFLATE_MAX_SIZE; +#ifdef CI_BADDEFLATE + ccp_wantoptions[0].baddeflate = 1; + ccp_wantoptions[0].baddeflate_size = DEFLATE_MAX_SIZE; + ccp_allowoptions[0].baddeflate = 1; + ccp_allowoptions[0].baddeflate_size = DEFLATE_MAX_SIZE; +#endif + ccp_wantoptions[0].bsd_compress = 1; ccp_wantoptions[0].bsd_bits = BSD_MAX_BITS; ccp_allowoptions[0].bsd_compress = 1; @@ -322,6 +335,16 @@ ccp_resetci(f) if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0) go->deflate = 0; } +#ifdef CI_BADDEFLATE + if (go->baddeflate) { + opt_buf[0] = CI_BADDEFLATE; + opt_buf[1] = CILEN_DEFLATE; + opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE); + opt_buf[3] = DEFLATE_CHK_SEQUENCE; + if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0) + go->baddeflate = 0; + } +#endif if (go->predictor_1) { opt_buf[0] = CI_PREDICTOR_1; opt_buf[1] = CILEN_PREDICTOR_1; @@ -347,6 +370,9 @@ ccp_cilen(f) return (go->bsd_compress? CILEN_BSD_COMPRESS: 0) + (go->deflate? CILEN_DEFLATE: 0) +#ifdef CI_BADDEFLATE + + (go->baddeflate? CILEN_DEFLATE: 0) +#endif + (go->predictor_1? CILEN_PREDICTOR_1: 0) + (go->predictor_2? CILEN_PREDICTOR_2: 0); } @@ -388,6 +414,31 @@ ccp_addci(f, p, lenp) p[2] = DEFLATE_MAKE_OPT(go->deflate_size); } } +#ifdef CI_BADDEFLATE + if (go->baddeflate) { + p[0] = CI_BADDEFLATE; + p[1] = CILEN_DEFLATE; + p[2] = DEFLATE_MAKE_OPT(go->baddeflate_size); + p[3] = DEFLATE_CHK_SEQUENCE; + if (p != p0) { + p += CILEN_DEFLATE; /* not the first option */ + } else { + for (;;) { + res = ccp_test(f->unit, p, CILEN_DEFLATE, 0); + if (res > 0) { + p += CILEN_DEFLATE; + break; + } + if (res < 0 || go->baddeflate_size <= DEFLATE_MIN_SIZE) { + go->baddeflate = 0; + break; + } + --go->baddeflate_size; + p[2] = DEFLATE_MAKE_OPT(go->baddeflate_size); + } + } + } +#endif if (go->bsd_compress) { p[0] = CI_BSD_COMPRESS; p[1] = CILEN_BSD_COMPRESS; @@ -460,6 +511,20 @@ ccp_ackci(f, p, len) if (len == 0) return 1; } +#ifdef CI_BADDEFLATE + if (go->baddeflate) { + if (len < CILEN_DEFLATE + || p[0] != CI_BADDEFLATE || p[1] != CILEN_DEFLATE + || p[2] != DEFLATE_MAKE_OPT(go->baddeflate_size) + || p[3] != DEFLATE_CHK_SEQUENCE) + return 0; + p += CILEN_DEFLATE; + len -= CILEN_DEFLATE; + /* XXX Cope with first/fast ack */ + if (p == p0 && len == 0) + return 1; + } +#endif if (go->bsd_compress) { if (len < CILEN_BSD_COMPRESS || p[0] != CI_BSD_COMPRESS || p[1] != CILEN_BSD_COMPRESS @@ -531,6 +596,25 @@ ccp_nakci(f, p, len) len -= CILEN_DEFLATE; } +#ifdef CI_BADDEFLATE + if (go->baddeflate && len >= CILEN_DEFLATE + && p[0] == CI_BADDEFLATE && p[1] == CILEN_DEFLATE) { + no.baddeflate = 1; + /* + * Peer wants us to use a different code size or something. + * Stop asking for Deflate if we don't understand his suggestion. + */ + if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL + || DEFLATE_SIZE(p[2]) < DEFLATE_MIN_SIZE + || p[3] != DEFLATE_CHK_SEQUENCE) + try.baddeflate = 0; + else if (DEFLATE_SIZE(p[2]) < go->baddeflate_size) + try.baddeflate_size = DEFLATE_SIZE(p[2]); + p += CILEN_DEFLATE; + len -= CILEN_DEFLATE; + } +#endif + if (go->bsd_compress && len >= CILEN_BSD_COMPRESS && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) { no.bsd_compress = 1; @@ -590,6 +674,17 @@ ccp_rejci(f, p, len) p += CILEN_DEFLATE; len -= CILEN_DEFLATE; } +#ifdef CI_BADDEFLATE + if (go->baddeflate && len >= CILEN_DEFLATE + && p[0] == CI_BADDEFLATE && p[1] == CILEN_DEFLATE) { + if (p[2] != DEFLATE_MAKE_OPT(go->baddeflate_size) + || p[3] != DEFLATE_CHK_SEQUENCE) + return 0; /* Rej is bad */ + try.baddeflate = 0; + p += CILEN_DEFLATE; + len -= CILEN_DEFLATE; + } +#endif if (go->bsd_compress && len >= CILEN_BSD_COMPRESS && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) { if (p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)) @@ -700,6 +795,51 @@ ccp_reqci(f, p, lenp, dont_nak) } break; +#ifdef CI_BADDEFLATE + case CI_BADDEFLATE: + if (!ao->baddeflate || clen != CILEN_DEFLATE) { + newret = CONFREJ; + break; + } + + ho->baddeflate = 1; + ho->baddeflate_size = nb = DEFLATE_SIZE(p[2]); + if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL + || p[3] != DEFLATE_CHK_SEQUENCE + || nb > ao->baddeflate_size || nb < DEFLATE_MIN_SIZE) { + newret = CONFNAK; + if (!dont_nak) { + p[2] = DEFLATE_MAKE_OPT(ao->baddeflate_size); + p[3] = DEFLATE_CHK_SEQUENCE; + /* fall through to test this #bits below */ + } else + break; + } + + /* + * Check whether we can do Deflate with the window + * size they want. If the window is too big, reduce + * it until the kernel can cope and nak with that. + * We only check this for the first option. + */ + if (p == p0) { + for (;;) { + res = ccp_test(f->unit, p, CILEN_DEFLATE, 1); + if (res > 0) + break; /* it's OK now */ + if (res < 0 || nb == DEFLATE_MIN_SIZE || dont_nak) { + newret = CONFREJ; + p[2] = DEFLATE_MAKE_OPT(ho->baddeflate_size); + break; + } + newret = CONFNAK; + --nb; + p[2] = DEFLATE_MAKE_OPT(nb); + } + } + break; +#endif + case CI_BSD_COMPRESS: if (!ao->bsd_compress || clen != CILEN_BSD_COMPRESS) { newret = CONFREJ; @@ -817,6 +957,15 @@ method_name(opt, opt2) else sprintf(result, "Deflate (%d)", opt->deflate_size); break; +#ifdef CI_BADDEFLATE + case CI_BADDEFLATE: + if (opt2 != NULL && opt2->baddeflate_size != opt->baddeflate_size) + sprintf(result, "Bad-Deflate (%d/%d)", opt->baddeflate_size, + opt2->baddeflate_size); + else + sprintf(result, "Bad-Deflate (%d)", opt->baddeflate_size); + break; +#endif case CI_BSD_COMPRESS: if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits) sprintf(result, "BSD-Compress (%d/%d)", opt->bsd_bits, @@ -941,6 +1090,18 @@ ccp_printpkt(p, plen, printer, arg) p += CILEN_DEFLATE; } break; +#ifdef CI_BADDEFLATE + case CI_BADDEFLATE: + if (optlen >= CILEN_DEFLATE) { + printer(arg, "baddeflate %d", DEFLATE_SIZE(p[2])); + if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL) + printer(arg, " method %d", DEFLATE_METHOD(p[2])); + if (p[3] != DEFLATE_CHK_SEQUENCE) + printer(arg, " check %d", p[3]); + p += CILEN_DEFLATE; + } + break; +#endif case CI_BSD_COMPRESS: if (optlen >= CILEN_BSD_COMPRESS) { printer(arg, "bsd v%d %d", BSD_VERSION(p[2]), diff --git a/usr.sbin/pppd/ccp.h b/usr.sbin/pppd/ccp.h index 32f7b05..843bddd 100644 --- a/usr.sbin/pppd/ccp.h +++ b/usr.sbin/pppd/ccp.h @@ -24,16 +24,18 @@ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, * OR MODIFICATIONS. * - * $Id$ + * $Id: ccp.h,v 1.5 1997/08/19 17:52:33 peter Exp $ */ typedef struct ccp_options { u_int bsd_compress: 1; /* do BSD Compress? */ - u_int deflate: 1; /* do Deflate? */ + u_int deflate: 1; /* do Deflate? (RFC code) */ + u_int baddeflate: 1; /* do Deflate? (Magnalink!) */ u_int predictor_1: 1; /* do Predictor-1? */ u_int predictor_2: 1; /* do Predictor-2? */ u_short bsd_bits; /* # bits/code for BSD Compress */ u_short deflate_size; /* lg(window size) for Deflate */ + u_short baddeflate_size; /* lg(window size) for Deflate */ short method; /* code for chosen compression method */ } ccp_options; diff --git a/usr.sbin/pppd/options.c b/usr.sbin/pppd/options.c index 4c55a77..a148b81 100644 --- a/usr.sbin/pppd/options.c +++ b/usr.sbin/pppd/options.c @@ -18,7 +18,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: options.c,v 1.16 1997/10/10 09:28:37 peter Exp $"; +static char rcsid[] = "$Id: options.c,v 1.17 1998/03/22 05:33:03 peter Exp $"; #endif #include <ctype.h> @@ -216,6 +216,7 @@ static int setbsdcomp __P((char **)); static int setnobsdcomp __P((char **)); static int setdeflate __P((char **)); static int setnodeflate __P((char **)); +static int setnobaddeflate __P((char **)); static int setdemand __P((char **)); static int setpred1comp __P((char **)); static int setnopred1comp __P((char **)); @@ -370,6 +371,8 @@ static struct cmd { {"deflate", 1, setdeflate}, /* request Deflate compression */ {"nodeflate", 0, setnodeflate}, /* don't allow Deflate compression */ {"-deflate", 0, setnodeflate}, /* don't allow Deflate compression */ + {"nobaddeflate", 0, setnobaddeflate}, /* don't allow (wrong) Deflate */ + {"-baddeflate", 0, setnobaddeflate}, /* don't allow (wrong) Deflate */ {"predictor1", 0, setpred1comp}, /* request Predictor-1 */ {"nopredictor1", 0, setnopred1comp},/* don't allow Predictor-1 */ {"-predictor1", 0, setnopred1comp}, /* don't allow Predictor-1 */ @@ -2220,6 +2223,13 @@ setdeflate(argv) ccp_allowoptions[0].deflate_size = abits; } else ccp_allowoptions[0].deflate = 0; + + /* XXX copy over settings for switch compatability */ + ccp_wantoptions[0].baddeflate = ccp_wantoptions[0].deflate; + ccp_wantoptions[0].baddeflate_size = ccp_wantoptions[0].deflate_size; + ccp_allowoptions[0].baddeflate = ccp_allowoptions[0].deflate; + ccp_allowoptions[0].baddeflate_size = ccp_allowoptions[0].deflate_size; + return 1; } @@ -2233,6 +2243,15 @@ setnodeflate(argv) } static int +setnobaddeflate(argv) + char **argv; +{ + ccp_wantoptions[0].baddeflate = 0; + ccp_allowoptions[0].baddeflate = 0; + return 1; +} + +static int setpred1comp(argv) char **argv; { |