X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fccp.c;h=a0eb2ad0d2d3da113cb5cdc762b5aa3c59cbf5f8;hp=355ba1d9450709e20f80e018b42e30da810734d3;hb=d28aba504f3abd38ed0aae269431dd55cc41efed;hpb=2bd94c4a4277cb05b770bdb3aac3a76f4110d9b4 diff --git a/pppd/ccp.c b/pppd/ccp.c index 355ba1d..a0eb2ad 100644 --- a/pppd/ccp.c +++ b/pppd/ccp.c @@ -26,9 +26,10 @@ */ #ifndef lint -static char rcsid[] = "$Id: ccp.c,v 1.12 1995/10/27 03:42:52 paulus Exp $"; +static char rcsid[] = "$Id: ccp.c,v 1.16 1996/04/04 03:35:37 paulus Exp $"; #endif +#include #include #include #include @@ -37,6 +38,12 @@ static char rcsid[] = "$Id: ccp.c,v 1.12 1995/10/27 03:42:52 paulus Exp $"; #include "fsm.h" #include "ccp.h" +struct protent ccp_protent = { + PPP_CCP, ccp_init, ccp_input, ccp_protrej, + ccp_lowerup, ccp_lowerdown, ccp_open, ccp_close, + ccp_printpkt, ccp_datainput, 1, "CCP", NULL, NULL +}; + fsm ccp_fsm[NUM_PPP]; ccp_options ccp_wantoptions[NUM_PPP]; /* what to request the peer to use */ ccp_options ccp_gotoptions[NUM_PPP]; /* what the peer agreed to do */ @@ -112,11 +119,17 @@ ccp_init(unit) memset(&ccp_allowoptions[unit], 0, sizeof(ccp_options)); memset(&ccp_hisoptions[unit], 0, sizeof(ccp_options)); - ccp_wantoptions[0].bsd_compress = 1; - ccp_wantoptions[0].bsd_bits = 12; /* default value */ + ccp_wantoptions[0].deflate = 1; + ccp_wantoptions[0].deflate_size = DEFLATE_MAX_SIZE; + ccp_allowoptions[0].deflate = 1; + ccp_allowoptions[0].deflate_size = DEFLATE_MAX_SIZE; + ccp_wantoptions[0].bsd_compress = 1; + ccp_wantoptions[0].bsd_bits = BSD_MAX_BITS; ccp_allowoptions[0].bsd_compress = 1; ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS; + + ccp_allowoptions[0].predictor_1 = 1; } /* @@ -130,8 +143,15 @@ ccp_open(unit) if (f->state != OPENED) ccp_flags_set(unit, 1, 0); - if (!ANY_COMPRESS(ccp_wantoptions[unit])) + + /* + * Find out which compressors the kernel supports before + * deciding whether to open in silent mode. + */ + ccp_resetci(f); + if (!ANY_COMPRESS(ccp_gotoptions[unit])) f->flags |= OPT_SILENT; + fsm_open(f); } @@ -139,11 +159,12 @@ ccp_open(unit) * ccp_close - Terminate CCP. */ void -ccp_close(unit) +ccp_close(unit, reason) int unit; + char *reason; { ccp_flags_set(unit, 0, 0); - fsm_close(&ccp_fsm[unit]); + fsm_close(&ccp_fsm[unit], reason); } /* @@ -192,7 +213,7 @@ ccp_input(unit, p, len) */ if (oldstate == REQSENT && p[0] == TERMACK && !ANY_COMPRESS(ccp_gotoptions[unit])) - ccp_close(unit); + ccp_close(unit, "No compression negotiated"); } /* @@ -246,7 +267,6 @@ static void ccp_resetci(f) fsm *f; { - int ok; ccp_options *go = &ccp_gotoptions[f->unit]; u_char opt_buf[16]; @@ -423,6 +443,8 @@ ccp_ackci(f, p, len) if (len < CILEN_PREDICTOR_1 || p[0] != CI_PREDICTOR_1 || p[1] != CILEN_PREDICTOR_1) return 0; + p += CILEN_PREDICTOR_1; + len -= CILEN_PREDICTOR_1; /* XXX Cope with first/fast ack */ if (p == p0 && len == 0) return 1; @@ -431,6 +453,8 @@ ccp_ackci(f, p, len) if (len < CILEN_PREDICTOR_2 || p[0] != CI_PREDICTOR_2 || p[1] != CILEN_PREDICTOR_2) return 0; + p += CILEN_PREDICTOR_2; + len -= CILEN_PREDICTOR_2; /* XXX Cope with first/fast ack */ if (p == p0 && len == 0) return 1; @@ -610,38 +634,34 @@ 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 > ao->deflate_size || nb < DEFLATE_MIN_SIZE) { newret = CONFNAK; - nb = ao->deflate_size; - } else { - /* - * 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. - */ + if (!dont_nak) { + p[2] = DEFLATE_MAKE_OPT(ao->deflate_size); + p[3] = DEFLATE_CHK_SEQUENCE; + } + 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 (;;) { - if (nb < DEFLATE_MIN_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) { newret = CONFREJ; p[2] = DEFLATE_MAKE_OPT(ho->deflate_size); break; } - p[2] = DEFLATE_MAKE_OPT(nb); - res = ccp_test(f->unit, p, CILEN_DEFLATE, 1); - if (res != 0) { - if (res < 0) - newret = CONFREJ; - break; - } newret = CONFNAK; --nb; - } - } - if (newret == CONFNAK && !dont_nak) { - if (nb >= DEFLATE_MIN_SIZE) { p[2] = DEFLATE_MAKE_OPT(nb); - p[3] = DEFLATE_CHK_SEQUENCE; - } else { - newret = CONFREJ; } } break; @@ -655,38 +675,33 @@ ccp_reqci(f, p, lenp, dont_nak) ho->bsd_compress = 1; ho->bsd_bits = nb = BSD_NBITS(p[2]); if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION - || nb > ao->bsd_bits) { + || nb > ao->bsd_bits || nb < BSD_MIN_BITS) { newret = CONFNAK; - nb = ao->bsd_bits; - } else { - /* - * Check whether we can do BSD_Compress with the code - * size they want. If the code size is too big, reduce - * it until the kernel can cope and nak with that. - */ + if (!dont_nak) + p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, ao->bsd_bits); + break; + } + + /* + * Check whether we can do BSD-Compress with the code + * size they want. If the code size 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 (;;) { - if (nb < BSD_MIN_BITS) { + res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 1); + if (res > 0) + break; + if (res < 0 || nb == BSD_MIN_BITS || dont_nak) { newret = CONFREJ; p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, ho->bsd_bits); break; } - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, nb); - res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 1); - if (res != 0) { - if (res < 0) - newret = CONFREJ; - break; - } newret = CONFNAK; --nb; - } - } - if (newret == CONFNAK && !dont_nak) { - if (nb >= BSD_MIN_BITS) { p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, nb); - } else { - newret = CONFREJ; } } break; @@ -698,7 +713,8 @@ ccp_reqci(f, p, lenp, dont_nak) } ho->predictor_1 = 1; - if (ccp_test(f->unit, p, CILEN_PREDICTOR_1, 1) <= 0) { + if (p == p0 + && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 1) <= 0) { newret = CONFREJ; } break; @@ -710,7 +726,8 @@ ccp_reqci(f, p, lenp, dont_nak) } ho->predictor_2 = 1; - if (ccp_test(f->unit, p, CILEN_PREDICTOR_2, 1) <= 0) { + if (p == p0 + && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 1) <= 0) { newret = CONFREJ; } break; @@ -900,7 +917,7 @@ ccp_datainput(unit, pkt, len) * Disable compression by taking CCP down. */ syslog(LOG_ERR, "Lost compression sync: disabling compression"); - ccp_close(unit); + ccp_close(unit, "Lost compression sync"); } else { /* * Send a reset-request to reset the peer's compressor.