* 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.32 2001/03/08 05:11:11 paulus Exp $"
#include <stdlib.h>
#include <string.h>
-#include <syslog.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
#include "pppd.h"
#include "fsm.h"
#include "ccp.h"
#include <net/ppp-comp.h>
+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", 1, &ccp_allowoptions[0].predictor_1, OPT_PRIO },
{ "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 }
ccp_datainput,
1,
"CCP",
+ "Compressed",
ccp_option_list,
NULL,
NULL,
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;
}
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;
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.
*/
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,
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;
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;
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;
}
* 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)
/*
* 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;
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);
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;
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;
}
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));
}
/*
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;
}
/*
* 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 {
/*