X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fccp.c;h=6cbdafd12e7b0385ef5b1d5d2de245c7193e4412;hp=c93e963c4d2709e1c43e18b6a0cd6869113780f2;hb=d0f67b16e65edb6281d409af01de4597cc045ee6;hpb=1fae28ce79350b03f0cf8a69ad06dd68637cd6b1 diff --git a/pppd/ccp.c b/pppd/ccp.c index c93e963..6cbdafd 100644 --- a/pppd/ccp.c +++ b/pppd/ccp.c @@ -25,58 +25,72 @@ * OR MODIFICATIONS. */ -#ifndef lint -static char rcsid[] = "$Id: ccp.c,v 1.24 1999/03/12 06:07:14 paulus Exp $"; -#endif +#define RCSID "$Id: ccp.c,v 1.33 2002/03/06 15:00:30 dfs Exp $" #include #include -#include -#include -#include #include "pppd.h" #include "fsm.h" #include "ccp.h" #include +static const char rcsid[] = RCSID; + +/* + * Unfortunately there is a bug in zlib which means that using a + * size of 8 (window size = 256) for Deflate compression will cause + * buffer overruns and kernel crashes in the deflate module. + * Until this is fixed we only accept sizes in the range 9 .. 15. + * Thanks to James Carlson for pointing this out. + */ +#define DEFLATE_MIN_WORKS 9 + /* * Command-line options. */ static int setbsdcomp __P((char **)); static int setdeflate __P((char **)); +static char bsd_value[8]; +static char deflate_value[8]; static option_t ccp_option_list[] = { { "noccp", o_bool, &ccp_protent.enabled_flag, "Disable CCP negotiation" }, { "-ccp", o_bool, &ccp_protent.enabled_flag, - "Disable CCP negotiation" }, - { "bsdcomp", o_special, setbsdcomp, - "Request BSD-Compress packet compression" }, + "Disable CCP negotiation", OPT_ALIAS }, + + { "bsdcomp", o_special, (void *)setbsdcomp, + "Request BSD-Compress packet compression", + OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, bsd_value }, { "nobsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, - "don't allow BSD-Compress", OPT_A2COPY, + "don't allow BSD-Compress", OPT_PRIOSUB | OPT_A2CLR, &ccp_allowoptions[0].bsd_compress }, { "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, - "don't allow BSD-Compress", OPT_A2COPY, + "don't allow BSD-Compress", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &ccp_allowoptions[0].bsd_compress }, - { "deflate", 1, setdeflate, - "request Deflate compression" }, + + { "deflate", o_special, (void *)setdeflate, + "request Deflate compression", + OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, deflate_value }, { "nodeflate", o_bool, &ccp_wantoptions[0].deflate, - "don't allow Deflate compression", OPT_A2COPY, + "don't allow Deflate compression", OPT_PRIOSUB | OPT_A2CLR, &ccp_allowoptions[0].deflate }, { "-deflate", o_bool, &ccp_wantoptions[0].deflate, - "don't allow Deflate compression", OPT_A2COPY, + "don't allow Deflate compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &ccp_allowoptions[0].deflate }, + { "nodeflatedraft", o_bool, &ccp_wantoptions[0].deflate_draft, "don't use draft deflate #", OPT_A2COPY, &ccp_allowoptions[0].deflate_draft }, + { "predictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "request Predictor-1", 1, &ccp_allowoptions[0].predictor_1 }, + "request Predictor-1", OPT_PRIO | 1 }, { "nopredictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "don't allow Predictor-1", OPT_A2COPY, + "don't allow Predictor-1", OPT_PRIOSUB | OPT_A2CLR, &ccp_allowoptions[0].predictor_1 }, { "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "don't allow Predictor-1", OPT_A2COPY, + "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &ccp_allowoptions[0].predictor_1 }, { NULL } @@ -110,6 +124,7 @@ struct protent ccp_protent = { ccp_datainput, 1, "CCP", + "Compressed", ccp_option_list, NULL, NULL, @@ -209,6 +224,9 @@ setbsdcomp(argv) ccp_allowoptions[0].bsd_bits = abits; } else ccp_allowoptions[0].bsd_compress = 0; + slprintf(bsd_value, sizeof(bsd_value), + rbits == abits? "%d": "%d,%d", rbits, abits); + return 1; } @@ -236,6 +254,14 @@ setdeflate(argv) DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE); return 0; } + if (rbits == DEFLATE_MIN_SIZE || abits == DEFLATE_MIN_SIZE) { + if (rbits == DEFLATE_MIN_SIZE) + rbits = DEFLATE_MIN_WORKS; + if (abits == DEFLATE_MIN_SIZE) + abits = DEFLATE_MIN_WORKS; + warn("deflate option value of %d changed to %d to avoid zlib bug", + DEFLATE_MIN_SIZE, DEFLATE_MIN_WORKS); + } if (rbits > 0) { ccp_wantoptions[0].deflate = 1; ccp_wantoptions[0].deflate_size = rbits; @@ -246,10 +272,12 @@ setdeflate(argv) ccp_allowoptions[0].deflate_size = abits; } else ccp_allowoptions[0].deflate = 0; + slprintf(deflate_value, sizeof(deflate_value), + rbits == abits? "%d": "%d,%d", rbits, abits); + return 1; } - /* * ccp_init - initialize CCP. */ @@ -359,7 +387,7 @@ ccp_input(unit, p, len) oldstate = f->state; fsm_input(f, p, len); if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED) - syslog(LOG_NOTICE, "Compression disabled by peer."); + notice("Compression disabled by peer."); /* * If we get a terminate-ack and we're not asking for compression, @@ -442,7 +470,7 @@ ccp_resetci(f) if (go->deflate_correct) { opt_buf[0] = CI_DEFLATE; opt_buf[1] = CILEN_DEFLATE; - opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE); + opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS); opt_buf[3] = DEFLATE_CHK_SEQUENCE; if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0) go->deflate_correct = 0; @@ -450,7 +478,7 @@ ccp_resetci(f) if (go->deflate_draft) { opt_buf[0] = CI_DEFLATE_DRAFT; opt_buf[1] = CILEN_DEFLATE; - opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE); + opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS); opt_buf[3] = DEFLATE_CHK_SEQUENCE; if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0) go->deflate_draft = 0; @@ -516,7 +544,7 @@ ccp_addci(f, p, lenp) p += CILEN_DEFLATE; break; } - if (res < 0 || go->deflate_size <= DEFLATE_MIN_SIZE) { + if (res < 0 || go->deflate_size <= DEFLATE_MIN_WORKS) { go->deflate = 0; break; } @@ -677,7 +705,7 @@ ccp_nakci(f, p, len) * 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 + || DEFLATE_SIZE(p[2]) < DEFLATE_MIN_WORKS || p[3] != DEFLATE_CHK_SEQUENCE) try.deflate = 0; else if (DEFLATE_SIZE(p[2]) < go->deflate_size) @@ -710,12 +738,9 @@ ccp_nakci(f, p, len) /* * Predictor-1 and 2 have no options, so they can't be Naked. * - * XXX What should we do with any remaining options? + * There may be remaining options but we ignore them. */ - if (len != 0) - return 0; - if (f->state != OPENED) *go = try; return 1; @@ -847,7 +872,7 @@ ccp_reqci(f, p, lenp, dont_nak) ho->deflate_size = nb = DEFLATE_SIZE(p[2]); if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL || p[3] != DEFLATE_CHK_SEQUENCE - || nb > ao->deflate_size || nb < DEFLATE_MIN_SIZE) { + || nb > ao->deflate_size || nb < DEFLATE_MIN_WORKS) { newret = CONFNAK; if (!dont_nak) { p[2] = DEFLATE_MAKE_OPT(ao->deflate_size); @@ -868,7 +893,7 @@ ccp_reqci(f, p, lenp, dont_nak) 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) { + if (res < 0 || nb == DEFLATE_MIN_WORKS || dont_nak) { newret = CONFREJ; p[2] = DEFLATE_MAKE_OPT(ho->deflate_size); break; @@ -993,27 +1018,28 @@ method_name(opt, opt2) case CI_DEFLATE: case CI_DEFLATE_DRAFT: if (opt2 != NULL && opt2->deflate_size != opt->deflate_size) - sprintf(result, "Deflate%s (%d/%d)", - (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), - opt->deflate_size, opt2->deflate_size); + slprintf(result, sizeof(result), "Deflate%s (%d/%d)", + (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), + opt->deflate_size, opt2->deflate_size); else - sprintf(result, "Deflate%s (%d)", - (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), - opt->deflate_size); + slprintf(result, sizeof(result), "Deflate%s (%d)", + (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), + opt->deflate_size); break; case CI_BSD_COMPRESS: if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits) - sprintf(result, "BSD-Compress (%d/%d)", opt->bsd_bits, - opt2->bsd_bits); + slprintf(result, sizeof(result), "BSD-Compress (%d/%d)", + opt->bsd_bits, opt2->bsd_bits); else - sprintf(result, "BSD-Compress (%d)", opt->bsd_bits); + slprintf(result, sizeof(result), "BSD-Compress (%d)", + opt->bsd_bits); break; case CI_PREDICTOR_1: return "Predictor 1"; case CI_PREDICTOR_2: return "Predictor 2"; default: - sprintf(result, "Method %d", opt->method); + slprintf(result, sizeof(result), "Method %d", opt->method); } return result; } @@ -1033,19 +1059,16 @@ ccp_up(f) if (ANY_COMPRESS(*go)) { if (ANY_COMPRESS(*ho)) { if (go->method == ho->method) { - syslog(LOG_NOTICE, "%s compression enabled", - method_name(go, ho)); + notice("%s compression enabled", method_name(go, ho)); } else { - strlcpy(method1, sizeof(method1), method_name(go, NULL)); - syslog(LOG_NOTICE, "%s / %s compression enabled", + strlcpy(method1, method_name(go, NULL), sizeof(method1)); + notice("%s / %s compression enabled", method1, method_name(ho, NULL)); } } else - syslog(LOG_NOTICE, "%s receive compression enabled", - method_name(go, NULL)); + notice("%s receive compression enabled", method_name(go, NULL)); } else if (ANY_COMPRESS(*ho)) - syslog(LOG_NOTICE, "%s transmit compression enabled", - method_name(ho, NULL)); + notice("%s transmit compression enabled", method_name(ho, NULL)); } /* @@ -1157,7 +1180,7 @@ ccp_printpkt(p, plen, printer, arg) case TERMACK: case TERMREQ: if (len > 0 && *p >= ' ' && *p < 0x7f) { - print_string(p, len, printer, arg); + print_string((char *)p, len, printer, arg); p += len; len = 0; } @@ -1197,7 +1220,7 @@ ccp_datainput(unit, pkt, len) /* * Disable compression by taking CCP down. */ - syslog(LOG_ERR, "Lost compression sync: disabling compression"); + error("Lost compression sync: disabling compression"); ccp_close(unit, "Lost compression sync"); } else { /*