summaryrefslogtreecommitdiffstats
path: root/usr.sbin/pppd/ccp.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1998-03-22 06:57:20 +0000
committerpeter <peter@FreeBSD.org>1998-03-22 06:57:20 +0000
commit108c1ee1936470b173b9dd06d836ef7d304f27aa (patch)
tree3d7d39fbdc546ae43c9cd50547f79657797d59dd /usr.sbin/pppd/ccp.c
parent47129697379a8b3b8a693c593abc3422a63ed9bf (diff)
downloadFreeBSD-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/ccp.c')
-rw-r--r--usr.sbin/pppd/ccp.c163
1 files changed, 162 insertions, 1 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]),
OpenPOWER on IntegriCloud