/*
* ccp.c - PPP Compression Control Protocol.
+ *
+ * Copyright (c) 1994 The Australian National University.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation is hereby granted, provided that the above copyright
+ * notice appears in all copies. This software is provided without any
+ * warranty, express or implied. The Australian National University
+ * makes no representations about the suitability of this software for
+ * any purpose.
+ *
+ * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
+ * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+ * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
+ * OR MODIFICATIONS.
+ *
+ * $Id: ccp.c,v 1.3 1994/09/01 00:16:20 paulus Exp $
*/
#ifndef lint
-static char rcsid[] = "$Id: ccp.c,v 1.1 1994/08/11 01:44:32 paulus Exp $";
+static char rcsid[] = "$Id: ccp.c,v 1.3 1994/09/01 00:16:20 paulus Exp $";
#endif
#include <syslog.h>
if (f->state != OPENED)
ccp_flags_set(unit, 1, 0);
+ if (!ccp_wantoptions[unit].bsd_compress)
+ f->flags |= OPT_SILENT;
fsm_open(f);
}
ccp_resetci(f)
fsm *f;
{
- ccp_gotoptions[f->unit] = ccp_wantoptions[f->unit];
+ ccp_options *go = &ccp_gotoptions[f->unit];
+ u_char opt_buf[16];
+
+ *go = ccp_wantoptions[f->unit];
+ if (go->bsd_compress) {
+ opt_buf[0] = CI_BSD_COMPRESS;
+ opt_buf[1] = CILEN_BSD;
+ opt_buf[2] = go->bsd_bits;
+ if (!ccp_test(f->unit, opt_buf, 3, 0))
+ go->bsd_compress = 0;
+ }
}
/*
ccp_options *ao = &ccp_allowoptions[f->unit];
ret = CONFACK;
- p0 = p;
+ retp = p0 = p;
len = *lenp;
memset(ho, 0, sizeof(ccp_options));
if (ho->bsd_bits < MIN_BSD_BITS
|| ho->bsd_bits > ao->bsd_bits) {
newret = CONFNAK;
- if (!dont_nak)
- p[2] = (ho->bsd_bits < MIN_BSD_BITS? MIN_BSD_BITS:
- ao->bsd_bits);
+ } else if (!ccp_test(f->unit, p, CILEN_BSD, 1)) {
+ if (ho->bsd_bits > MIN_BSD_BITS)
+ newret = CONFNAK;
+ else
+ newret = CONFREJ;
+ }
+ if (newret == CONFNAK && !dont_nak) {
+ p[2] = (ho->bsd_bits < ao->bsd_bits? MIN_BSD_BITS:
+ ao->bsd_bits);
}
break;
if (!(newret == CONFACK || newret == CONFNAK && ret == CONFREJ)) {
/* we're returning this option */
- if (newret != ret) {
- retp = p0;
- ret = newret;
- }
+ ret = newret;
if (p != retp)
BCOPY(p, retp, clen);
retp += clen;
/*
* CCP has come up - inform the kernel driver.
*/
+static char *up_strings[] = {
+ "no ", "receive ", "transmit ", ""
+};
+
static void
ccp_up(f)
fsm *f;
{
+ ccp_options *go = &ccp_gotoptions[f->unit];
+ ccp_options *ho = &ccp_hisoptions[f->unit];
+
ccp_flags_set(f->unit, 1, 1);
+ syslog(LOG_INFO, "%scompression enabled",
+ up_strings[(go->bsd_compress? 1: 0) + (ho->bsd_compress? 2: 0)]);
}
/*
UNTIMEOUT(ccp_rack_timeout, (caddr_t) f);
ccp_localstate[f->unit] = 0;
ccp_flags_set(f->unit, 1, 0);
+ syslog(LOG_NOTICE, "Compression disabled.");
}
/*
}
/*
- * We have received a packet that the decompressor failed to decompress.
- * Issue a reset-req (if we haven't issued one recently).
+ * We have received a packet that the decompressor failed to
+ * decompress. Here we would expect to issue a reset-request,
+ * but Motorola has a patent on that, so instead we log a message
+ * and take CCP down :-(. (See US patent 5,130,993; international
+ * patent publication number WO 91/10289; Australian patent 73296/91.)
*/
void
ccp_datainput(unit, pkt, len)
f = &ccp_fsm[unit];
if (f->state == OPENED) {
- if (!(ccp_localstate[unit] & RACK_PENDING)) {
+ syslog(LOG_ERR, "Lost compression sync: disabling compression");
+ ccp_close(unit);
+ }
+}
+
+/*
+ * ccp_req_reset - Request that the peer reset the compression
+ * dictionary.
+ */
+void
+ccp_req_reset(f)
+ fsm *f;
+{
+ if (f->state == OPENED) {
+ if (!(ccp_localstate[f->unit] & RACK_PENDING)) {
fsm_sdata(f, RESETREQ, f->reqid = ++f->id, NULL, 0);
TIMEOUT(ccp_rack_timeout, (caddr_t) f, RACKTIMEOUT);
- ccp_localstate[unit] |= RACK_PENDING;
+ ccp_localstate[f->unit] |= RACK_PENDING;
} else
- ccp_localstate[unit] |= RREQ_REPEAT;
+ ccp_localstate[f->unit] |= RREQ_REPEAT;
}
}