* OR MODIFICATIONS.
*/
-#define RCSID "$Id: ccp.c,v 1.35 2002/05/21 17:26:49 dfs Exp $"
+#define RCSID "$Id: ccp.c,v 1.40 2002/10/27 11:46:24 fcusack Exp $"
#include <stdlib.h>
#include <string.h>
#ifdef MPPE
#include "chap_ms.h" /* mppe_xxxx_key */
-#include "lcp.h" /* lcp_close() */
+#include "lcp.h" /* lcp_close(), lcp_fsm */
#endif
static const char rcsid[] = RCSID;
notice("Compression disabled by peer.");
#ifdef MPPE
if (ccp_gotoptions[unit].mppe) {
- notice("MPPE disabled, closing LCP");
+ error("MPPE disabled, closing LCP");
lcp_close(unit, "MPPE disabled by peer");
}
#endif
fsm_lowerdown(&ccp_fsm[unit]);
#ifdef MPPE
- if (ccp_gotoptions[unit].mppe)
+ if (ccp_gotoptions[unit].mppe) {
+ error("MPPE required but peer negotiation failed");
lcp_close(unit, "MPPE required but peer negotiation failed");
+ }
#endif
}
/*
* Add the compression types that we can receive, in decreasing
- * preference order.
+ * preference order. Get the kernel to allocate the first one
+ * in case it gets Acked.
*/
#ifdef MPPE
if (go->mppe) {
p[0] = CI_BSD_COMPRESS;
p[1] = CILEN_BSD_COMPRESS;
p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits);
- for (;;) {
- if (go->bsd_bits < BSD_MIN_BITS) {
- go->bsd_compress = 0;
- break;
- }
- res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 0);
- if (res > 0) {
- p += CILEN_BSD_COMPRESS;
- break;
- } else if (res < 0) {
- go->bsd_compress = 0;
- break;
+ if (p != p0) {
+ p += CILEN_BSD_COMPRESS; /* not the first option */
+ } else {
+ for (;;) {
+ if (go->bsd_bits < BSD_MIN_BITS) {
+ go->bsd_compress = 0;
+ break;
+ }
+ res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 0);
+ if (res > 0) {
+ p += CILEN_BSD_COMPRESS;
+ break;
+ } else if (res < 0) {
+ go->bsd_compress = 0;
+ break;
+ }
+ --go->bsd_bits;
+ p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits);
}
- --go->bsd_bits;
- p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits);
}
}
/* XXX Should Predictor 2 be preferable to Predictor 1? */
/* Peer must have set options we didn't request (suggest) */
try.mppe = 0;
- if (!try.mppe)
+ if (!try.mppe) {
+ error("MPPE required but peer negotiation failed");
lcp_close(f->unit, "MPPE required but peer negotiation failed");
+ }
}
#endif /* MPPE */
if (go->deflate && len >= CILEN_DEFLATE
#ifdef MPPE
if (go->mppe && len >= CILEN_MPPE
&& p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
+ error("MPPE required but peer refused");
lcp_close(f->unit, "MPPE required but peer refused");
p += CILEN_MPPE;
len -= CILEN_MPPE;
*lenp = retp - p0;
}
#ifdef MPPE
- if (ret == CONFREJ && ao->mppe && !seen_ci_mppe)
+ if (ret == CONFREJ && ao->mppe && !seen_ci_mppe) {
+ error("MPPE required but peer negotiation failed");
lcp_close(f->unit, "MPPE required but peer negotiation failed");
+ }
#endif
return ret;
}
if (go->mppe) {
BZERO(mppe_recv_key, MPPE_MAX_KEY_LEN);
BZERO(mppe_send_key, MPPE_MAX_KEY_LEN);
- start_networks(f->unit); /* Bring up IP et al */
+ continue_networks(f->unit); /* Bring up IP et al */
}
#endif
}
ccp_localstate[f->unit] = 0;
ccp_flags_set(f->unit, 1, 0);
#ifdef MPPE
- if (ccp_gotoptions[f->unit].mppe)
- lcp_close(f->unit, "MPPE disabled");
+ if (ccp_gotoptions[f->unit].mppe) {
+ ccp_gotoptions[f->unit].mppe = 0;
+ if (lcp_fsm[f->unit].state == OPENED) {
+ /* If LCP is not already going down, make sure it does. */
+ error("MPPE disabled");
+ lcp_close(f->unit, "MPPE disabled");
+ }
+ }
#endif
}