]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/ccp.c
Use paths.h if it is available.
[ppp.git] / pppd / ccp.c
index 5e90ce6ecf42dc25400d8021058a9fd163429b92..421542d47569cf946ccf676b0449f83738f37117 100644 (file)
@@ -1,9 +1,34 @@
 /*
  * 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>
@@ -109,6 +134,8 @@ ccp_open(unit)
 
     if (f->state != OPENED)
        ccp_flags_set(unit, 1, 0);
+    if (!ccp_wantoptions[unit].bsd_compress)
+       f->flags |= OPT_SILENT;
     fsm_open(f);
 }
 
@@ -206,7 +233,17 @@ static void
 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;
+    }
 }
 
 /*
@@ -358,7 +395,7 @@ ccp_reqci(f, p, lenp, dont_nak)
     ccp_options *ao = &ccp_allowoptions[f->unit];
 
     ret = CONFACK;
-    p0 = p;
+    retp = p0 = p;
     len = *lenp;
 
     memset(ho, 0, sizeof(ccp_options));
@@ -386,9 +423,15 @@ ccp_reqci(f, p, lenp, dont_nak)
                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;
@@ -400,10 +443,7 @@ ccp_reqci(f, p, lenp, dont_nak)
 
        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;
@@ -421,11 +461,20 @@ ccp_reqci(f, p, lenp, dont_nak)
 /*
  * 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)]);
 }
 
 /*
@@ -439,6 +488,7 @@ ccp_down(f)
        UNTIMEOUT(ccp_rack_timeout, (caddr_t) f);
     ccp_localstate[f->unit] = 0;
     ccp_flags_set(f->unit, 1, 0);
+    syslog(LOG_NOTICE, "Compression disabled.");
 }
 
 /*
@@ -517,8 +567,11 @@ ccp_printpkt(p, plen, printer, arg)
 }
 
 /*
- * 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)
@@ -530,12 +583,26 @@ 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;
     }
 }