]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/ccp.c
Merge in 1.3 and post 1.3 fixes; some of them might be applicable to
[ppp.git] / pppd / ccp.c
index d4e3b3c4b093ae5b3faa7c7750fe02f9236969d7..6d328b762d3c985df5d8523cc3ee87dd00a47d07 100644 (file)
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: ccp.c,v 1.21 1997/05/22 06:45:59 paulus Exp $";
+static char rcsid[] = "$Id: ccp.c,v 1.22 1998/03/25 01:25:02 paulus Exp $";
 #endif
 
 #include <string.h>
 #include <syslog.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
-#include <net/ppp_defs.h>
-#include <net/ppp-comp.h>
 
 #include "pppd.h"
 #include "fsm.h"
 #include "ccp.h"
+#include <net/ppp-comp.h>
 
 /*
  * Protocol entry points from main code.
@@ -151,8 +150,12 @@ ccp_init(unit)
 
     ccp_wantoptions[0].deflate = 1;
     ccp_wantoptions[0].deflate_size = DEFLATE_MAX_SIZE;
+    ccp_wantoptions[0].deflate_correct = 1;
+    ccp_wantoptions[0].deflate_draft = 1;
     ccp_allowoptions[0].deflate = 1;
     ccp_allowoptions[0].deflate_size = DEFLATE_MAX_SIZE;
+    ccp_allowoptions[0].deflate_correct = 1;
+    ccp_allowoptions[0].deflate_draft = 1;
 
     ccp_wantoptions[0].bsd_compress = 1;
     ccp_wantoptions[0].bsd_bits = BSD_MAX_BITS;
@@ -315,11 +318,23 @@ ccp_resetci(f)
            go->bsd_compress = 0;
     }
     if (go->deflate) {
-       opt_buf[0] = CI_DEFLATE;
-       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)
+       if (go->deflate_correct) {
+           opt_buf[0] = CI_DEFLATE;
+           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->deflate_correct = 0;
+       }
+       if (go->deflate_draft) {
+           opt_buf[0] = CI_DEFLATE_DRAFT;
+           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->deflate_draft = 0;
+       }
+       if (!go->deflate_correct && !go->deflate_draft)
            go->deflate = 0;
     }
     if (go->predictor_1) {
@@ -370,7 +385,7 @@ ccp_addci(f, p, lenp)
      * in case it gets Acked.
      */
     if (go->deflate) {
-       p[0] = CI_DEFLATE;
+       p[0] = go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT;
        p[1] = CILEN_DEFLATE;
        p[2] = DEFLATE_MAKE_OPT(go->deflate_size);
        p[3] = DEFLATE_CHK_SEQUENCE;
@@ -387,6 +402,13 @@ ccp_addci(f, p, lenp)
            --go->deflate_size;
            p[2] = DEFLATE_MAKE_OPT(go->deflate_size);
        }
+       if (p != p0 && go->deflate_correct && go->deflate_draft) {
+           p[0] = CI_DEFLATE_DRAFT;
+           p[1] = CILEN_DEFLATE;
+           p[2] = p[2 - CILEN_DEFLATE];
+           p[3] = DEFLATE_CHK_SEQUENCE;
+           p += CILEN_DEFLATE;
+       }
     }
     if (go->bsd_compress) {
        p[0] = CI_BSD_COMPRESS;
@@ -450,7 +472,8 @@ ccp_ackci(f, p, len)
 
     if (go->deflate) {
        if (len < CILEN_DEFLATE
-           || p[0] != CI_DEFLATE || p[1] != CILEN_DEFLATE
+           || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
+           || p[1] != CILEN_DEFLATE
            || p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
            || p[3] != DEFLATE_CHK_SEQUENCE)
            return 0;
@@ -459,6 +482,16 @@ ccp_ackci(f, p, len)
        /* XXX Cope with first/fast ack */
        if (len == 0)
            return 1;
+       if (go->deflate_correct && go->deflate_draft) {
+           if (len < CILEN_DEFLATE
+               || p[0] != CI_DEFLATE_DRAFT
+               || p[1] != CILEN_DEFLATE
+               || p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
+               || p[3] != DEFLATE_CHK_SEQUENCE)
+               return 0;
+           p += CILEN_DEFLATE;
+           len -= CILEN_DEFLATE;
+       }
     }
     if (go->bsd_compress) {
        if (len < CILEN_BSD_COMPRESS
@@ -515,7 +548,8 @@ ccp_nakci(f, p, len)
     try = *go;
 
     if (go->deflate && len >= CILEN_DEFLATE
-       && p[0] == CI_DEFLATE && p[1] == CILEN_DEFLATE) {
+       && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
+       && p[1] == CILEN_DEFLATE) {
        no.deflate = 1;
        /*
         * Peer wants us to use a different code size or something.
@@ -529,6 +563,12 @@ ccp_nakci(f, p, len)
            try.deflate_size = DEFLATE_SIZE(p[2]);
        p += CILEN_DEFLATE;
        len -= CILEN_DEFLATE;
+       if (go->deflate_correct && go->deflate_draft
+           && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT
+           && p[1] == CILEN_DEFLATE) {
+           p += CILEN_DEFLATE;
+           len -= CILEN_DEFLATE;
+       }
     }
 
     if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
@@ -582,13 +622,29 @@ ccp_rejci(f, p, len)
        return -1;
 
     if (go->deflate && len >= CILEN_DEFLATE
-       && p[0] == CI_DEFLATE && p[1] == CILEN_DEFLATE) {
+       && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
+       && p[1] == CILEN_DEFLATE) {
        if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
            || p[3] != DEFLATE_CHK_SEQUENCE)
            return 0;           /* Rej is bad */
-       try.deflate = 0;
+       if (go->deflate_correct)
+           try.deflate_correct = 0;
+       else
+           try.deflate_draft = 0;
        p += CILEN_DEFLATE;
        len -= CILEN_DEFLATE;
+       if (go->deflate_correct && go->deflate_draft
+           && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT
+           && p[1] == CILEN_DEFLATE) {
+           if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
+               || p[3] != DEFLATE_CHK_SEQUENCE)
+               return 0;               /* Rej is bad */
+           try.deflate_draft = 0;
+           p += CILEN_DEFLATE;
+           len -= CILEN_DEFLATE;
+       }
+       if (!try.deflate_correct && !try.deflate_draft)
+           try.deflate = 0;
     }
     if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
        && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
@@ -658,7 +714,10 @@ ccp_reqci(f, p, lenp, dont_nak)
 
            switch (type) {
            case CI_DEFLATE:
-               if (!ao->deflate || clen != CILEN_DEFLATE) {
+           case CI_DEFLATE_DRAFT:
+               if (!ao->deflate || clen != CILEN_DEFLATE
+                   || (!ao->deflate_correct && type == CI_DEFLATE)
+                   || (!ao->deflate_draft && type == CI_DEFLATE_DRAFT)) {
                    newret = CONFREJ;
                    break;
                }
@@ -811,11 +870,15 @@ method_name(opt, opt2)
        return "(none)";
     switch (opt->method) {
     case CI_DEFLATE:
+    case CI_DEFLATE_DRAFT:
        if (opt2 != NULL && opt2->deflate_size != opt->deflate_size)
-           sprintf(result, "Deflate (%d/%d)", opt->deflate_size,
-                   opt2->deflate_size);
+           sprintf(result, "Deflate%s (%d/%d)",
+                   (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
+                   opt->deflate_size, opt2->deflate_size);
        else
-           sprintf(result, "Deflate (%d)", opt->deflate_size);
+           sprintf(result, "Deflate%s (%d)",
+                   (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
+                   opt->deflate_size);
        break;
     case CI_BSD_COMPRESS:
        if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits)
@@ -932,8 +995,11 @@ ccp_printpkt(p, plen, printer, arg)
            optend = p + optlen;
            switch (code) {
            case CI_DEFLATE:
+           case CI_DEFLATE_DRAFT:
                if (optlen >= CILEN_DEFLATE) {
-                   printer(arg, "deflate %d", DEFLATE_SIZE(p[2]));
+                   printer(arg, "deflate%s %d",
+                           (code == CI_DEFLATE_DRAFT? "(old#)": ""),
+                           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)