2 * ccp.c - PPP Compression Control Protocol.
4 * Copyright (c) 1994 The Australian National University.
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation is hereby granted, provided that the above copyright
9 * notice appears in all copies. This software is provided without any
10 * warranty, express or implied. The Australian National University
11 * makes no representations about the suitability of this software for
14 * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
15 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
16 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
17 * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
20 * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
21 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
23 * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
24 * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
29 static char rcsid[] = "$Id: ccp.c,v 1.8 1998/03/22 06:57:18 peter Exp $";
34 #include <sys/ioctl.h>
35 #include <sys/types.h>
40 #include <net/ppp_comp.h>
43 * Protocol entry points from main code.
45 static void ccp_init __P((int unit));
46 static void ccp_open __P((int unit));
47 static void ccp_close __P((int unit, char *));
48 static void ccp_lowerup __P((int unit));
49 static void ccp_lowerdown __P((int));
50 static void ccp_input __P((int unit, u_char *pkt, int len));
51 static void ccp_protrej __P((int unit));
52 static int ccp_printpkt __P((u_char *pkt, int len,
53 void (*printer) __P((void *, char *, ...)),
55 static void ccp_datainput __P((int unit, u_char *pkt, int len));
57 struct protent ccp_protent = {
76 ccp_options ccp_wantoptions[NUM_PPP]; /* what to request the peer to use */
77 ccp_options ccp_gotoptions[NUM_PPP]; /* what the peer agreed to do */
78 ccp_options ccp_allowoptions[NUM_PPP]; /* what we'll agree to do */
79 ccp_options ccp_hisoptions[NUM_PPP]; /* what we agreed to do */
82 * Callbacks for fsm code.
84 static void ccp_resetci __P((fsm *));
85 static int ccp_cilen __P((fsm *));
86 static void ccp_addci __P((fsm *, u_char *, int *));
87 static int ccp_ackci __P((fsm *, u_char *, int));
88 static int ccp_nakci __P((fsm *, u_char *, int));
89 static int ccp_rejci __P((fsm *, u_char *, int));
90 static int ccp_reqci __P((fsm *, u_char *, int *, int));
91 static void ccp_up __P((fsm *));
92 static void ccp_down __P((fsm *));
93 static int ccp_extcode __P((fsm *, int, int, u_char *, int));
94 static void ccp_rack_timeout __P((void *));
95 static char *method_name __P((ccp_options *, ccp_options *));
97 static fsm_callbacks ccp_callbacks = {
116 * Do we want / did we get any compression?
118 #define ANY_COMPRESS(opt) ((opt).deflate || (opt).bsd_compress \
119 || (opt).predictor_1 || (opt).predictor_2)
122 * Local state (mainly for handling reset-reqs and reset-acks).
124 static int ccp_localstate[NUM_PPP];
125 #define RACK_PENDING 1 /* waiting for reset-ack */
126 #define RREQ_REPEAT 2 /* send another reset-req if no reset-ack */
128 #define RACKTIMEOUT 1 /* second */
130 static int all_rejected[NUM_PPP]; /* we rejected all peer's options */
133 * ccp_init - initialize CCP.
139 fsm *f = &ccp_fsm[unit];
142 f->protocol = PPP_CCP;
143 f->callbacks = &ccp_callbacks;
146 memset(&ccp_wantoptions[unit], 0, sizeof(ccp_options));
147 memset(&ccp_gotoptions[unit], 0, sizeof(ccp_options));
148 memset(&ccp_allowoptions[unit], 0, sizeof(ccp_options));
149 memset(&ccp_hisoptions[unit], 0, sizeof(ccp_options));
151 ccp_wantoptions[0].deflate = 1;
152 ccp_wantoptions[0].deflate_size = DEFLATE_MAX_SIZE;
153 ccp_wantoptions[0].deflate_correct = 1;
154 ccp_wantoptions[0].deflate_draft = 1;
155 ccp_allowoptions[0].deflate = 1;
156 ccp_allowoptions[0].deflate_size = DEFLATE_MAX_SIZE;
157 ccp_allowoptions[0].deflate_correct = 1;
158 ccp_allowoptions[0].deflate_draft = 1;
160 ccp_wantoptions[0].bsd_compress = 1;
161 ccp_wantoptions[0].bsd_bits = BSD_MAX_BITS;
162 ccp_allowoptions[0].bsd_compress = 1;
163 ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS;
165 ccp_allowoptions[0].predictor_1 = 1;
169 * ccp_open - CCP is allowed to come up.
175 fsm *f = &ccp_fsm[unit];
177 if (f->state != OPENED)
178 ccp_flags_set(unit, 1, 0);
181 * Find out which compressors the kernel supports before
182 * deciding whether to open in silent mode.
185 if (!ANY_COMPRESS(ccp_gotoptions[unit]))
186 f->flags |= OPT_SILENT;
192 * ccp_close - Terminate CCP.
195 ccp_close(unit, reason)
199 ccp_flags_set(unit, 0, 0);
200 fsm_close(&ccp_fsm[unit], reason);
204 * ccp_lowerup - we may now transmit CCP packets.
210 fsm_lowerup(&ccp_fsm[unit]);
214 * ccp_lowerdown - we may not transmit CCP packets.
220 fsm_lowerdown(&ccp_fsm[unit]);
224 * ccp_input - process a received CCP packet.
227 ccp_input(unit, p, len)
232 fsm *f = &ccp_fsm[unit];
236 * Check for a terminate-request so we can print a message.
239 fsm_input(f, p, len);
240 if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED)
241 syslog(LOG_NOTICE, "Compression disabled by peer.");
244 * If we get a terminate-ack and we're not asking for compression,
247 if (oldstate == REQSENT && p[0] == TERMACK
248 && !ANY_COMPRESS(ccp_gotoptions[unit]))
249 ccp_close(unit, "No compression negotiated");
253 * Handle a CCP-specific code.
256 ccp_extcode(f, code, id, p, len)
264 if (f->state != OPENED)
266 /* send a reset-ack, which the transmitter will see and
267 reset its compression state. */
268 fsm_sdata(f, CCP_RESETACK, id, NULL, 0);
272 if (ccp_localstate[f->unit] & RACK_PENDING && id == f->reqid) {
273 ccp_localstate[f->unit] &= ~(RACK_PENDING | RREQ_REPEAT);
274 UNTIMEOUT(ccp_rack_timeout, f);
286 * ccp_protrej - peer doesn't talk CCP.
292 ccp_flags_set(unit, 0, 0);
293 fsm_lowerdown(&ccp_fsm[unit]);
297 * ccp_resetci - initialize at start of negotiation.
303 ccp_options *go = &ccp_gotoptions[f->unit];
306 *go = ccp_wantoptions[f->unit];
307 all_rejected[f->unit] = 0;
310 * Check whether the kernel knows about the various
311 * compression methods we might request.
313 if (go->bsd_compress) {
314 opt_buf[0] = CI_BSD_COMPRESS;
315 opt_buf[1] = CILEN_BSD_COMPRESS;
316 opt_buf[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, BSD_MIN_BITS);
317 if (ccp_test(f->unit, opt_buf, CILEN_BSD_COMPRESS, 0) <= 0)
318 go->bsd_compress = 0;
321 if (go->deflate_correct) {
322 opt_buf[0] = CI_DEFLATE;
323 opt_buf[1] = CILEN_DEFLATE;
324 opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE);
325 opt_buf[3] = DEFLATE_CHK_SEQUENCE;
326 if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0)
327 go->deflate_correct = 0;
329 if (go->deflate_draft) {
330 opt_buf[0] = CI_DEFLATE_DRAFT;
331 opt_buf[1] = CILEN_DEFLATE;
332 opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE);
333 opt_buf[3] = DEFLATE_CHK_SEQUENCE;
334 if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0)
335 go->deflate_draft = 0;
337 if (!go->deflate_correct && !go->deflate_draft)
340 if (go->predictor_1) {
341 opt_buf[0] = CI_PREDICTOR_1;
342 opt_buf[1] = CILEN_PREDICTOR_1;
343 if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_1, 0) <= 0)
346 if (go->predictor_2) {
347 opt_buf[0] = CI_PREDICTOR_2;
348 opt_buf[1] = CILEN_PREDICTOR_2;
349 if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_2, 0) <= 0)
355 * ccp_cilen - Return total length of our configuration info.
361 ccp_options *go = &ccp_gotoptions[f->unit];
363 return (go->bsd_compress? CILEN_BSD_COMPRESS: 0)
364 + (go->deflate? CILEN_DEFLATE: 0)
365 + (go->predictor_1? CILEN_PREDICTOR_1: 0)
366 + (go->predictor_2? CILEN_PREDICTOR_2: 0);
370 * ccp_addci - put our requests in a packet.
373 ccp_addci(f, p, lenp)
379 ccp_options *go = &ccp_gotoptions[f->unit];
383 * Add the compression types that we can receive, in decreasing
384 * preference order. Get the kernel to allocate the first one
385 * in case it gets Acked.
388 p[0] = go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT;
389 p[1] = CILEN_DEFLATE;
390 p[2] = DEFLATE_MAKE_OPT(go->deflate_size);
391 p[3] = DEFLATE_CHK_SEQUENCE;
393 res = ccp_test(f->unit, p, CILEN_DEFLATE, 0);
398 if (res < 0 || go->deflate_size <= DEFLATE_MIN_SIZE) {
403 p[2] = DEFLATE_MAKE_OPT(go->deflate_size);
405 if (p != p0 && go->deflate_correct && go->deflate_draft) {
406 p[0] = CI_DEFLATE_DRAFT;
407 p[1] = CILEN_DEFLATE;
408 p[2] = p[2 - CILEN_DEFLATE];
409 p[3] = DEFLATE_CHK_SEQUENCE;
413 if (go->bsd_compress) {
414 p[0] = CI_BSD_COMPRESS;
415 p[1] = CILEN_BSD_COMPRESS;
416 p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits);
418 p += CILEN_BSD_COMPRESS; /* not the first option */
421 res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 0);
423 p += CILEN_BSD_COMPRESS;
426 if (res < 0 || go->bsd_bits <= BSD_MIN_BITS) {
427 go->bsd_compress = 0;
431 p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits);
435 /* XXX Should Predictor 2 be preferable to Predictor 1? */
436 if (go->predictor_1) {
437 p[0] = CI_PREDICTOR_1;
438 p[1] = CILEN_PREDICTOR_1;
439 if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 0) <= 0) {
442 p += CILEN_PREDICTOR_1;
445 if (go->predictor_2) {
446 p[0] = CI_PREDICTOR_2;
447 p[1] = CILEN_PREDICTOR_2;
448 if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 0) <= 0) {
451 p += CILEN_PREDICTOR_2;
455 go->method = (p > p0)? p0[0]: -1;
461 * ccp_ackci - process a received configure-ack, and return
462 * 1 iff the packet was OK.
470 ccp_options *go = &ccp_gotoptions[f->unit];
474 if (len < CILEN_DEFLATE
475 || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
476 || p[1] != CILEN_DEFLATE
477 || p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
478 || p[3] != DEFLATE_CHK_SEQUENCE)
481 len -= CILEN_DEFLATE;
482 /* XXX Cope with first/fast ack */
485 if (go->deflate_correct && go->deflate_draft) {
486 if (len < CILEN_DEFLATE
487 || p[0] != CI_DEFLATE_DRAFT
488 || p[1] != CILEN_DEFLATE
489 || p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
490 || p[3] != DEFLATE_CHK_SEQUENCE)
493 len -= CILEN_DEFLATE;
496 if (go->bsd_compress) {
497 if (len < CILEN_BSD_COMPRESS
498 || p[0] != CI_BSD_COMPRESS || p[1] != CILEN_BSD_COMPRESS
499 || p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits))
501 p += CILEN_BSD_COMPRESS;
502 len -= CILEN_BSD_COMPRESS;
503 /* XXX Cope with first/fast ack */
504 if (p == p0 && len == 0)
507 if (go->predictor_1) {
508 if (len < CILEN_PREDICTOR_1
509 || p[0] != CI_PREDICTOR_1 || p[1] != CILEN_PREDICTOR_1)
511 p += CILEN_PREDICTOR_1;
512 len -= CILEN_PREDICTOR_1;
513 /* XXX Cope with first/fast ack */
514 if (p == p0 && len == 0)
517 if (go->predictor_2) {
518 if (len < CILEN_PREDICTOR_2
519 || p[0] != CI_PREDICTOR_2 || p[1] != CILEN_PREDICTOR_2)
521 p += CILEN_PREDICTOR_2;
522 len -= CILEN_PREDICTOR_2;
523 /* XXX Cope with first/fast ack */
524 if (p == p0 && len == 0)
534 * ccp_nakci - process received configure-nak.
535 * Returns 1 iff the nak was OK.
543 ccp_options *go = &ccp_gotoptions[f->unit];
544 ccp_options no; /* options we've seen already */
545 ccp_options try; /* options to ask for next time */
547 memset(&no, 0, sizeof(no));
550 if (go->deflate && len >= CILEN_DEFLATE
551 && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
552 && p[1] == CILEN_DEFLATE) {
555 * Peer wants us to use a different code size or something.
556 * Stop asking for Deflate if we don't understand his suggestion.
558 if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL
559 || DEFLATE_SIZE(p[2]) < DEFLATE_MIN_SIZE
560 || p[3] != DEFLATE_CHK_SEQUENCE)
562 else if (DEFLATE_SIZE(p[2]) < go->deflate_size)
563 try.deflate_size = DEFLATE_SIZE(p[2]);
565 len -= CILEN_DEFLATE;
566 if (go->deflate_correct && go->deflate_draft
567 && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT
568 && p[1] == CILEN_DEFLATE) {
570 len -= CILEN_DEFLATE;
574 if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
575 && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
578 * Peer wants us to use a different number of bits
579 * or a different version.
581 if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION)
582 try.bsd_compress = 0;
583 else if (BSD_NBITS(p[2]) < go->bsd_bits)
584 try.bsd_bits = BSD_NBITS(p[2]);
585 p += CILEN_BSD_COMPRESS;
586 len -= CILEN_BSD_COMPRESS;
590 * Predictor-1 and 2 have no options, so they can't be Naked.
592 * XXX What should we do with any remaining options?
598 if (f->state != OPENED)
604 * ccp_rejci - reject some of our suggested compression methods.
612 ccp_options *go = &ccp_gotoptions[f->unit];
613 ccp_options try; /* options to request next time */
618 * Cope with empty configure-rejects by ceasing to send
619 * configure-requests.
621 if (len == 0 && all_rejected[f->unit])
624 if (go->deflate && len >= CILEN_DEFLATE
625 && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
626 && p[1] == CILEN_DEFLATE) {
627 if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
628 || p[3] != DEFLATE_CHK_SEQUENCE)
629 return 0; /* Rej is bad */
630 if (go->deflate_correct)
631 try.deflate_correct = 0;
633 try.deflate_draft = 0;
635 len -= CILEN_DEFLATE;
636 if (go->deflate_correct && go->deflate_draft
637 && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT
638 && p[1] == CILEN_DEFLATE) {
639 if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
640 || p[3] != DEFLATE_CHK_SEQUENCE)
641 return 0; /* Rej is bad */
642 try.deflate_draft = 0;
644 len -= CILEN_DEFLATE;
646 if (!try.deflate_correct && !try.deflate_draft)
649 if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
650 && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
651 if (p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits))
653 try.bsd_compress = 0;
654 p += CILEN_BSD_COMPRESS;
655 len -= CILEN_BSD_COMPRESS;
657 if (go->predictor_1 && len >= CILEN_PREDICTOR_1
658 && p[0] == CI_PREDICTOR_1 && p[1] == CILEN_PREDICTOR_1) {
660 p += CILEN_PREDICTOR_1;
661 len -= CILEN_PREDICTOR_1;
663 if (go->predictor_2 && len >= CILEN_PREDICTOR_2
664 && p[0] == CI_PREDICTOR_2 && p[1] == CILEN_PREDICTOR_2) {
666 p += CILEN_PREDICTOR_2;
667 len -= CILEN_PREDICTOR_2;
673 if (f->state != OPENED)
680 * ccp_reqci - processed a received configure-request.
681 * Returns CONFACK, CONFNAK or CONFREJ and the packet modified
685 ccp_reqci(f, p, lenp, dont_nak)
691 int ret, newret, res;
693 int len, clen, type, nb;
694 ccp_options *ho = &ccp_hisoptions[f->unit];
695 ccp_options *ao = &ccp_allowoptions[f->unit];
701 memset(ho, 0, sizeof(ccp_options));
702 ho->method = (len > 0)? p[0]: -1;
706 if (len < 2 || p[1] < 2 || p[1] > len) {
717 case CI_DEFLATE_DRAFT:
718 if (!ao->deflate || clen != CILEN_DEFLATE
719 || (!ao->deflate_correct && type == CI_DEFLATE)
720 || (!ao->deflate_draft && type == CI_DEFLATE_DRAFT)) {
726 ho->deflate_size = nb = DEFLATE_SIZE(p[2]);
727 if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL
728 || p[3] != DEFLATE_CHK_SEQUENCE
729 || nb > ao->deflate_size || nb < DEFLATE_MIN_SIZE) {
732 p[2] = DEFLATE_MAKE_OPT(ao->deflate_size);
733 p[3] = DEFLATE_CHK_SEQUENCE;
734 /* fall through to test this #bits below */
740 * Check whether we can do Deflate with the window
741 * size they want. If the window is too big, reduce
742 * it until the kernel can cope and nak with that.
743 * We only check this for the first option.
747 res = ccp_test(f->unit, p, CILEN_DEFLATE, 1);
749 break; /* it's OK now */
750 if (res < 0 || nb == DEFLATE_MIN_SIZE || dont_nak) {
752 p[2] = DEFLATE_MAKE_OPT(ho->deflate_size);
757 p[2] = DEFLATE_MAKE_OPT(nb);
762 case CI_BSD_COMPRESS:
763 if (!ao->bsd_compress || clen != CILEN_BSD_COMPRESS) {
768 ho->bsd_compress = 1;
769 ho->bsd_bits = nb = BSD_NBITS(p[2]);
770 if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION
771 || nb > ao->bsd_bits || nb < BSD_MIN_BITS) {
774 p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, ao->bsd_bits);
775 /* fall through to test this #bits below */
781 * Check whether we can do BSD-Compress with the code
782 * size they want. If the code size is too big, reduce
783 * it until the kernel can cope and nak with that.
784 * We only check this for the first option.
788 res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 1);
791 if (res < 0 || nb == BSD_MIN_BITS || dont_nak) {
793 p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION,
799 p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, nb);
805 if (!ao->predictor_1 || clen != CILEN_PREDICTOR_1) {
812 && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 1) <= 0) {
818 if (!ao->predictor_2 || clen != CILEN_PREDICTOR_2) {
825 && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 1) <= 0) {
835 if (newret == CONFNAK && dont_nak)
837 if (!(newret == CONFACK || (newret == CONFNAK && ret == CONFREJ))) {
838 /* we're returning this option */
839 if (newret == CONFREJ && ret == CONFNAK)
843 BCOPY(p, retp, clen);
851 if (ret != CONFACK) {
852 if (ret == CONFREJ && *lenp == retp - p0)
853 all_rejected[f->unit] = 1;
861 * Make a string name for a compression method (or 2).
864 method_name(opt, opt2)
865 ccp_options *opt, *opt2;
867 static char result[64];
869 if (!ANY_COMPRESS(*opt))
871 switch (opt->method) {
873 case CI_DEFLATE_DRAFT:
874 if (opt2 != NULL && opt2->deflate_size != opt->deflate_size)
875 sprintf(result, "Deflate%s (%d/%d)",
876 (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
877 opt->deflate_size, opt2->deflate_size);
879 sprintf(result, "Deflate%s (%d)",
880 (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
883 case CI_BSD_COMPRESS:
884 if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits)
885 sprintf(result, "BSD-Compress (%d/%d)", opt->bsd_bits,
888 sprintf(result, "BSD-Compress (%d)", opt->bsd_bits);
891 return "Predictor 1";
893 return "Predictor 2";
895 sprintf(result, "Method %d", opt->method);
901 * CCP has come up - inform the kernel driver and log a message.
907 ccp_options *go = &ccp_gotoptions[f->unit];
908 ccp_options *ho = &ccp_hisoptions[f->unit];
911 ccp_flags_set(f->unit, 1, 1);
912 if (ANY_COMPRESS(*go)) {
913 if (ANY_COMPRESS(*ho)) {
914 if (go->method == ho->method) {
915 syslog(LOG_NOTICE, "%s compression enabled",
916 method_name(go, ho));
918 strcpy(method1, method_name(go, NULL));
919 syslog(LOG_NOTICE, "%s / %s compression enabled",
920 method1, method_name(ho, NULL));
923 syslog(LOG_NOTICE, "%s receive compression enabled",
924 method_name(go, NULL));
925 } else if (ANY_COMPRESS(*ho))
926 syslog(LOG_NOTICE, "%s transmit compression enabled",
927 method_name(ho, NULL));
931 * CCP has gone down - inform the kernel driver.
937 if (ccp_localstate[f->unit] & RACK_PENDING)
938 UNTIMEOUT(ccp_rack_timeout, f);
939 ccp_localstate[f->unit] = 0;
940 ccp_flags_set(f->unit, 1, 0);
944 * Print the contents of a CCP packet.
946 static char *ccp_codenames[] = {
947 "ConfReq", "ConfAck", "ConfNak", "ConfRej",
948 "TermReq", "TermAck", "CodeRej",
949 NULL, NULL, NULL, NULL, NULL, NULL,
950 "ResetReq", "ResetAck",
954 ccp_printpkt(p, plen, printer, arg)
957 void (*printer) __P((void *, char *, ...));
965 if (plen < HEADERLEN)
969 len = (p[2] << 8) + p[3];
970 if (len < HEADERLEN || len > plen)
973 if (code >= 1 && code <= sizeof(ccp_codenames) / sizeof(char *)
974 && ccp_codenames[code-1] != NULL)
975 printer(arg, " %s", ccp_codenames[code-1]);
977 printer(arg, " code=0x%x", code);
978 printer(arg, " id=0x%x", id);
987 /* print list of possible compression methods */
991 if (optlen < 2 || optlen > len)
998 case CI_DEFLATE_DRAFT:
999 if (optlen >= CILEN_DEFLATE) {
1000 printer(arg, "deflate%s %d",
1001 (code == CI_DEFLATE_DRAFT? "(old#)": ""),
1002 DEFLATE_SIZE(p[2]));
1003 if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL)
1004 printer(arg, " method %d", DEFLATE_METHOD(p[2]));
1005 if (p[3] != DEFLATE_CHK_SEQUENCE)
1006 printer(arg, " check %d", p[3]);
1010 case CI_BSD_COMPRESS:
1011 if (optlen >= CILEN_BSD_COMPRESS) {
1012 printer(arg, "bsd v%d %d", BSD_VERSION(p[2]),
1014 p += CILEN_BSD_COMPRESS;
1017 case CI_PREDICTOR_1:
1018 if (optlen >= CILEN_PREDICTOR_1) {
1019 printer(arg, "predictor 1");
1020 p += CILEN_PREDICTOR_1;
1023 case CI_PREDICTOR_2:
1024 if (optlen >= CILEN_PREDICTOR_2) {
1025 printer(arg, "predictor 2");
1026 p += CILEN_PREDICTOR_2;
1031 printer(arg, " %.2x", *p++);
1038 if (len > 0 && *p >= ' ' && *p < 0x7f) {
1039 print_string(p, len, printer, arg);
1046 /* dump out the rest of the packet in hex */
1048 printer(arg, " %.2x", *p++);
1054 * We have received a packet that the decompressor failed to
1055 * decompress. Here we would expect to issue a reset-request, but
1056 * Motorola has a patent on resetting the compressor as a result of
1057 * detecting an error in the decompressed data after decompression.
1058 * (See US patent 5,130,993; international patent publication number
1059 * WO 91/10289; Australian patent 73296/91.)
1061 * So we ask the kernel whether the error was detected after
1062 * decompression; if it was, we take CCP down, thus disabling
1063 * compression :-(, otherwise we issue the reset-request.
1066 ccp_datainput(unit, pkt, len)
1074 if (f->state == OPENED) {
1075 if (ccp_fatal_error(unit)) {
1077 * Disable compression by taking CCP down.
1079 syslog(LOG_ERR, "Lost compression sync: disabling compression");
1080 ccp_close(unit, "Lost compression sync");
1083 * Send a reset-request to reset the peer's compressor.
1084 * We don't do that if we are still waiting for an
1085 * acknowledgement to a previous reset-request.
1087 if (!(ccp_localstate[f->unit] & RACK_PENDING)) {
1088 fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0);
1089 TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT);
1090 ccp_localstate[f->unit] |= RACK_PENDING;
1092 ccp_localstate[f->unit] |= RREQ_REPEAT;
1098 * Timeout waiting for reset-ack.
1101 ccp_rack_timeout(arg)
1106 if (f->state == OPENED && ccp_localstate[f->unit] & RREQ_REPEAT) {
1107 fsm_sdata(f, CCP_RESETREQ, f->reqid, NULL, 0);
1108 TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT);
1109 ccp_localstate[f->unit] &= ~RREQ_REPEAT;
1111 ccp_localstate[f->unit] &= ~RACK_PENDING;