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,
28 #define RCSID "$Id: ccp.c,v 1.1 2003/07/10 07:43:04 honor Exp $"
36 #include <net/ppp-comp.h>
38 static const char rcsid
[] = RCSID
;
41 * Unfortunately there is a bug in zlib which means that using a
42 * size of 8 (window size = 256) for Deflate compression will cause
43 * buffer overruns and kernel crashes in the deflate module.
44 * Until this is fixed we only accept sizes in the range 9 .. 15.
45 * Thanks to James Carlson for pointing this out.
47 #define DEFLATE_MIN_WORKS 9
50 * Command-line options.
52 static int setbsdcomp
__P((char **));
53 static int setdeflate
__P((char **));
54 static char bsd_value
[8];
55 static char deflate_value
[8];
57 static option_t ccp_option_list
[] = {
58 { "noccp", o_bool
, &ccp_protent
.enabled_flag
,
59 "Disable CCP negotiation" },
60 { "-ccp", o_bool
, &ccp_protent
.enabled_flag
,
61 "Disable CCP negotiation", OPT_ALIAS
},
63 { "bsdcomp", o_special
, (void *)setbsdcomp
,
64 "Request BSD-Compress packet compression",
65 OPT_PRIO
| OPT_A2STRVAL
| OPT_STATIC
, bsd_value
},
66 { "nobsdcomp", o_bool
, &ccp_wantoptions
[0].bsd_compress
,
67 "don't allow BSD-Compress", OPT_PRIOSUB
| OPT_A2CLR
,
68 &ccp_allowoptions
[0].bsd_compress
},
69 { "-bsdcomp", o_bool
, &ccp_wantoptions
[0].bsd_compress
,
70 "don't allow BSD-Compress", OPT_ALIAS
| OPT_PRIOSUB
| OPT_A2CLR
,
71 &ccp_allowoptions
[0].bsd_compress
},
73 { "deflate", o_special
, (void *)setdeflate
,
74 "request Deflate compression",
75 OPT_PRIO
| OPT_A2STRVAL
| OPT_STATIC
, deflate_value
},
76 { "nodeflate", o_bool
, &ccp_wantoptions
[0].deflate
,
77 "don't allow Deflate compression", OPT_PRIOSUB
| OPT_A2CLR
,
78 &ccp_allowoptions
[0].deflate
},
79 { "-deflate", o_bool
, &ccp_wantoptions
[0].deflate
,
80 "don't allow Deflate compression", OPT_ALIAS
| OPT_PRIOSUB
| OPT_A2CLR
,
81 &ccp_allowoptions
[0].deflate
},
83 { "nodeflatedraft", o_bool
, &ccp_wantoptions
[0].deflate_draft
,
84 "don't use draft deflate #", OPT_A2COPY
,
85 &ccp_allowoptions
[0].deflate_draft
},
87 { "predictor1", o_bool
, &ccp_wantoptions
[0].predictor_1
,
88 "request Predictor-1", 1, &ccp_allowoptions
[0].predictor_1
, OPT_PRIO
},
89 { "nopredictor1", o_bool
, &ccp_wantoptions
[0].predictor_1
,
90 "don't allow Predictor-1", OPT_PRIOSUB
| OPT_A2CLR
,
91 &ccp_allowoptions
[0].predictor_1
},
92 { "-predictor1", o_bool
, &ccp_wantoptions
[0].predictor_1
,
93 "don't allow Predictor-1", OPT_ALIAS
| OPT_PRIOSUB
| OPT_A2CLR
,
94 &ccp_allowoptions
[0].predictor_1
},
100 * Protocol entry points from main code.
102 static void ccp_init
__P((int unit
));
103 static void ccp_open
__P((int unit
));
104 static void ccp_close
__P((int unit
, char *));
105 static void ccp_lowerup
__P((int unit
));
106 static void ccp_lowerdown
__P((int));
107 static void ccp_input
__P((int unit
, u_char
*pkt
, int len
));
108 static void ccp_protrej
__P((int unit
));
109 static int ccp_printpkt
__P((u_char
*pkt
, int len
,
110 void (*printer
) __P((void *, char *, ...)),
112 static void ccp_datainput
__P((int unit
, u_char
*pkt
, int len
));
114 struct protent ccp_protent
= {
134 fsm ccp_fsm
[NUM_PPP
];
135 ccp_options ccp_wantoptions
[NUM_PPP
]; /* what to request the peer to use */
136 ccp_options ccp_gotoptions
[NUM_PPP
]; /* what the peer agreed to do */
137 ccp_options ccp_allowoptions
[NUM_PPP
]; /* what we'll agree to do */
138 ccp_options ccp_hisoptions
[NUM_PPP
]; /* what we agreed to do */
141 * Callbacks for fsm code.
143 static void ccp_resetci
__P((fsm
*));
144 static int ccp_cilen
__P((fsm
*));
145 static void ccp_addci
__P((fsm
*, u_char
*, int *));
146 static int ccp_ackci
__P((fsm
*, u_char
*, int));
147 static int ccp_nakci
__P((fsm
*, u_char
*, int));
148 static int ccp_rejci
__P((fsm
*, u_char
*, int));
149 static int ccp_reqci
__P((fsm
*, u_char
*, int *, int));
150 static void ccp_up
__P((fsm
*));
151 static void ccp_down
__P((fsm
*));
152 static int ccp_extcode
__P((fsm
*, int, int, u_char
*, int));
153 static void ccp_rack_timeout
__P((void *));
154 static char *method_name
__P((ccp_options
*, ccp_options
*));
156 static fsm_callbacks ccp_callbacks
= {
175 * Do we want / did we get any compression?
177 #define ANY_COMPRESS(opt) ((opt).deflate || (opt).bsd_compress \
178 || (opt).predictor_1 || (opt).predictor_2)
181 * Local state (mainly for handling reset-reqs and reset-acks).
183 static int ccp_localstate
[NUM_PPP
];
184 #define RACK_PENDING 1 /* waiting for reset-ack */
185 #define RREQ_REPEAT 2 /* send another reset-req if no reset-ack */
187 #define RACKTIMEOUT 1 /* second */
189 static int all_rejected
[NUM_PPP
]; /* we rejected all peer's options */
202 abits
= rbits
= strtol(str
, &endp
, 0);
203 if (endp
!= str
&& *endp
== ',') {
205 abits
= strtol(str
, &endp
, 0);
207 if (*endp
!= 0 || endp
== str
) {
208 option_error("invalid parameter '%s' for bsdcomp option", *argv
);
211 if ((rbits
!= 0 && (rbits
< BSD_MIN_BITS
|| rbits
> BSD_MAX_BITS
))
212 || (abits
!= 0 && (abits
< BSD_MIN_BITS
|| abits
> BSD_MAX_BITS
))) {
213 option_error("bsdcomp option values must be 0 or %d .. %d",
214 BSD_MIN_BITS
, BSD_MAX_BITS
);
218 ccp_wantoptions
[0].bsd_compress
= 1;
219 ccp_wantoptions
[0].bsd_bits
= rbits
;
221 ccp_wantoptions
[0].bsd_compress
= 0;
223 ccp_allowoptions
[0].bsd_compress
= 1;
224 ccp_allowoptions
[0].bsd_bits
= abits
;
226 ccp_allowoptions
[0].bsd_compress
= 0;
227 slprintf(bsd_value
, sizeof(bsd_value
),
228 rbits
== abits
? "%d": "%d,%d", rbits
, abits
);
241 abits
= rbits
= strtol(str
, &endp
, 0);
242 if (endp
!= str
&& *endp
== ',') {
244 abits
= strtol(str
, &endp
, 0);
246 if (*endp
!= 0 || endp
== str
) {
247 option_error("invalid parameter '%s' for deflate option", *argv
);
250 if ((rbits
!= 0 && (rbits
< DEFLATE_MIN_SIZE
|| rbits
> DEFLATE_MAX_SIZE
))
251 || (abits
!= 0 && (abits
< DEFLATE_MIN_SIZE
252 || abits
> DEFLATE_MAX_SIZE
))) {
253 option_error("deflate option values must be 0 or %d .. %d",
254 DEFLATE_MIN_SIZE
, DEFLATE_MAX_SIZE
);
257 if (rbits
== DEFLATE_MIN_SIZE
|| abits
== DEFLATE_MIN_SIZE
) {
258 if (rbits
== DEFLATE_MIN_SIZE
)
259 rbits
= DEFLATE_MIN_WORKS
;
260 if (abits
== DEFLATE_MIN_SIZE
)
261 abits
= DEFLATE_MIN_WORKS
;
262 warn("deflate option value of %d changed to %d to avoid zlib bug",
263 DEFLATE_MIN_SIZE
, DEFLATE_MIN_WORKS
);
266 ccp_wantoptions
[0].deflate
= 1;
267 ccp_wantoptions
[0].deflate_size
= rbits
;
269 ccp_wantoptions
[0].deflate
= 0;
271 ccp_allowoptions
[0].deflate
= 1;
272 ccp_allowoptions
[0].deflate_size
= abits
;
274 ccp_allowoptions
[0].deflate
= 0;
275 slprintf(deflate_value
, sizeof(deflate_value
),
276 rbits
== abits
? "%d": "%d,%d", rbits
, abits
);
282 * ccp_init - initialize CCP.
288 fsm
*f
= &ccp_fsm
[unit
];
291 f
->protocol
= PPP_CCP
;
292 f
->callbacks
= &ccp_callbacks
;
295 memset(&ccp_wantoptions
[unit
], 0, sizeof(ccp_options
));
296 memset(&ccp_gotoptions
[unit
], 0, sizeof(ccp_options
));
297 memset(&ccp_allowoptions
[unit
], 0, sizeof(ccp_options
));
298 memset(&ccp_hisoptions
[unit
], 0, sizeof(ccp_options
));
300 ccp_wantoptions
[0].deflate
= 1;
301 ccp_wantoptions
[0].deflate_size
= DEFLATE_MAX_SIZE
;
302 ccp_wantoptions
[0].deflate_correct
= 1;
303 ccp_wantoptions
[0].deflate_draft
= 1;
304 ccp_allowoptions
[0].deflate
= 1;
305 ccp_allowoptions
[0].deflate_size
= DEFLATE_MAX_SIZE
;
306 ccp_allowoptions
[0].deflate_correct
= 1;
307 ccp_allowoptions
[0].deflate_draft
= 1;
309 ccp_wantoptions
[0].bsd_compress
= 1;
310 ccp_wantoptions
[0].bsd_bits
= BSD_MAX_BITS
;
311 ccp_allowoptions
[0].bsd_compress
= 1;
312 ccp_allowoptions
[0].bsd_bits
= BSD_MAX_BITS
;
314 ccp_allowoptions
[0].predictor_1
= 1;
318 * ccp_open - CCP is allowed to come up.
324 fsm
*f
= &ccp_fsm
[unit
];
326 if (f
->state
!= OPENED
)
327 ccp_flags_set(unit
, 1, 0);
330 * Find out which compressors the kernel supports before
331 * deciding whether to open in silent mode.
334 if (!ANY_COMPRESS(ccp_gotoptions
[unit
]))
335 f
->flags
|= OPT_SILENT
;
341 * ccp_close - Terminate CCP.
344 ccp_close(unit
, reason
)
348 ccp_flags_set(unit
, 0, 0);
349 fsm_close(&ccp_fsm
[unit
], reason
);
353 * ccp_lowerup - we may now transmit CCP packets.
359 fsm_lowerup(&ccp_fsm
[unit
]);
363 * ccp_lowerdown - we may not transmit CCP packets.
369 fsm_lowerdown(&ccp_fsm
[unit
]);
373 * ccp_input - process a received CCP packet.
376 ccp_input(unit
, p
, len
)
381 fsm
*f
= &ccp_fsm
[unit
];
385 * Check for a terminate-request so we can print a message.
388 fsm_input(f
, p
, len
);
389 if (oldstate
== OPENED
&& p
[0] == TERMREQ
&& f
->state
!= OPENED
)
390 notice("Compression disabled by peer.");
393 * If we get a terminate-ack and we're not asking for compression,
396 if (oldstate
== REQSENT
&& p
[0] == TERMACK
397 && !ANY_COMPRESS(ccp_gotoptions
[unit
]))
398 ccp_close(unit
, "No compression negotiated");
402 * Handle a CCP-specific code.
405 ccp_extcode(f
, code
, id
, p
, len
)
413 if (f
->state
!= OPENED
)
415 /* send a reset-ack, which the transmitter will see and
416 reset its compression state. */
417 fsm_sdata(f
, CCP_RESETACK
, id
, NULL
, 0);
421 if (ccp_localstate
[f
->unit
] & RACK_PENDING
&& id
== f
->reqid
) {
422 ccp_localstate
[f
->unit
] &= ~(RACK_PENDING
| RREQ_REPEAT
);
423 UNTIMEOUT(ccp_rack_timeout
, f
);
435 * ccp_protrej - peer doesn't talk CCP.
441 ccp_flags_set(unit
, 0, 0);
442 fsm_lowerdown(&ccp_fsm
[unit
]);
446 * ccp_resetci - initialize at start of negotiation.
452 ccp_options
*go
= &ccp_gotoptions
[f
->unit
];
455 *go
= ccp_wantoptions
[f
->unit
];
456 all_rejected
[f
->unit
] = 0;
459 * Check whether the kernel knows about the various
460 * compression methods we might request.
462 if (go
->bsd_compress
) {
463 opt_buf
[0] = CI_BSD_COMPRESS
;
464 opt_buf
[1] = CILEN_BSD_COMPRESS
;
465 opt_buf
[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION
, BSD_MIN_BITS
);
466 if (ccp_test(f
->unit
, opt_buf
, CILEN_BSD_COMPRESS
, 0) <= 0)
467 go
->bsd_compress
= 0;
470 if (go
->deflate_correct
) {
471 opt_buf
[0] = CI_DEFLATE
;
472 opt_buf
[1] = CILEN_DEFLATE
;
473 opt_buf
[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS
);
474 opt_buf
[3] = DEFLATE_CHK_SEQUENCE
;
475 if (ccp_test(f
->unit
, opt_buf
, CILEN_DEFLATE
, 0) <= 0)
476 go
->deflate_correct
= 0;
478 if (go
->deflate_draft
) {
479 opt_buf
[0] = CI_DEFLATE_DRAFT
;
480 opt_buf
[1] = CILEN_DEFLATE
;
481 opt_buf
[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS
);
482 opt_buf
[3] = DEFLATE_CHK_SEQUENCE
;
483 if (ccp_test(f
->unit
, opt_buf
, CILEN_DEFLATE
, 0) <= 0)
484 go
->deflate_draft
= 0;
486 if (!go
->deflate_correct
&& !go
->deflate_draft
)
489 if (go
->predictor_1
) {
490 opt_buf
[0] = CI_PREDICTOR_1
;
491 opt_buf
[1] = CILEN_PREDICTOR_1
;
492 if (ccp_test(f
->unit
, opt_buf
, CILEN_PREDICTOR_1
, 0) <= 0)
495 if (go
->predictor_2
) {
496 opt_buf
[0] = CI_PREDICTOR_2
;
497 opt_buf
[1] = CILEN_PREDICTOR_2
;
498 if (ccp_test(f
->unit
, opt_buf
, CILEN_PREDICTOR_2
, 0) <= 0)
504 * ccp_cilen - Return total length of our configuration info.
510 ccp_options
*go
= &ccp_gotoptions
[f
->unit
];
512 return (go
->bsd_compress
? CILEN_BSD_COMPRESS
: 0)
513 + (go
->deflate
? CILEN_DEFLATE
: 0)
514 + (go
->predictor_1
? CILEN_PREDICTOR_1
: 0)
515 + (go
->predictor_2
? CILEN_PREDICTOR_2
: 0);
519 * ccp_addci - put our requests in a packet.
522 ccp_addci(f
, p
, lenp
)
528 ccp_options
*go
= &ccp_gotoptions
[f
->unit
];
532 * Add the compression types that we can receive, in decreasing
533 * preference order. Get the kernel to allocate the first one
534 * in case it gets Acked.
537 p
[0] = go
->deflate_correct
? CI_DEFLATE
: CI_DEFLATE_DRAFT
;
538 p
[1] = CILEN_DEFLATE
;
539 p
[2] = DEFLATE_MAKE_OPT(go
->deflate_size
);
540 p
[3] = DEFLATE_CHK_SEQUENCE
;
542 res
= ccp_test(f
->unit
, p
, CILEN_DEFLATE
, 0);
547 if (res
< 0 || go
->deflate_size
<= DEFLATE_MIN_WORKS
) {
552 p
[2] = DEFLATE_MAKE_OPT(go
->deflate_size
);
554 if (p
!= p0
&& go
->deflate_correct
&& go
->deflate_draft
) {
555 p
[0] = CI_DEFLATE_DRAFT
;
556 p
[1] = CILEN_DEFLATE
;
557 p
[2] = p
[2 - CILEN_DEFLATE
];
558 p
[3] = DEFLATE_CHK_SEQUENCE
;
562 if (go
->bsd_compress
) {
563 p
[0] = CI_BSD_COMPRESS
;
564 p
[1] = CILEN_BSD_COMPRESS
;
565 p
[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION
, go
->bsd_bits
);
567 p
+= CILEN_BSD_COMPRESS
; /* not the first option */
570 res
= ccp_test(f
->unit
, p
, CILEN_BSD_COMPRESS
, 0);
572 p
+= CILEN_BSD_COMPRESS
;
575 if (res
< 0 || go
->bsd_bits
<= BSD_MIN_BITS
) {
576 go
->bsd_compress
= 0;
580 p
[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION
, go
->bsd_bits
);
584 /* XXX Should Predictor 2 be preferable to Predictor 1? */
585 if (go
->predictor_1
) {
586 p
[0] = CI_PREDICTOR_1
;
587 p
[1] = CILEN_PREDICTOR_1
;
588 if (p
== p0
&& ccp_test(f
->unit
, p
, CILEN_PREDICTOR_1
, 0) <= 0) {
591 p
+= CILEN_PREDICTOR_1
;
594 if (go
->predictor_2
) {
595 p
[0] = CI_PREDICTOR_2
;
596 p
[1] = CILEN_PREDICTOR_2
;
597 if (p
== p0
&& ccp_test(f
->unit
, p
, CILEN_PREDICTOR_2
, 0) <= 0) {
600 p
+= CILEN_PREDICTOR_2
;
604 go
->method
= (p
> p0
)? p0
[0]: -1;
610 * ccp_ackci - process a received configure-ack, and return
611 * 1 iff the packet was OK.
619 ccp_options
*go
= &ccp_gotoptions
[f
->unit
];
623 if (len
< CILEN_DEFLATE
624 || p
[0] != (go
->deflate_correct
? CI_DEFLATE
: CI_DEFLATE_DRAFT
)
625 || p
[1] != CILEN_DEFLATE
626 || p
[2] != DEFLATE_MAKE_OPT(go
->deflate_size
)
627 || p
[3] != DEFLATE_CHK_SEQUENCE
)
630 len
-= CILEN_DEFLATE
;
631 /* XXX Cope with first/fast ack */
634 if (go
->deflate_correct
&& go
->deflate_draft
) {
635 if (len
< CILEN_DEFLATE
636 || p
[0] != CI_DEFLATE_DRAFT
637 || p
[1] != CILEN_DEFLATE
638 || p
[2] != DEFLATE_MAKE_OPT(go
->deflate_size
)
639 || p
[3] != DEFLATE_CHK_SEQUENCE
)
642 len
-= CILEN_DEFLATE
;
645 if (go
->bsd_compress
) {
646 if (len
< CILEN_BSD_COMPRESS
647 || p
[0] != CI_BSD_COMPRESS
|| p
[1] != CILEN_BSD_COMPRESS
648 || p
[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION
, go
->bsd_bits
))
650 p
+= CILEN_BSD_COMPRESS
;
651 len
-= CILEN_BSD_COMPRESS
;
652 /* XXX Cope with first/fast ack */
653 if (p
== p0
&& len
== 0)
656 if (go
->predictor_1
) {
657 if (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
;
662 /* XXX Cope with first/fast ack */
663 if (p
== p0
&& len
== 0)
666 if (go
->predictor_2
) {
667 if (len
< CILEN_PREDICTOR_2
668 || p
[0] != CI_PREDICTOR_2
|| p
[1] != CILEN_PREDICTOR_2
)
670 p
+= CILEN_PREDICTOR_2
;
671 len
-= CILEN_PREDICTOR_2
;
672 /* XXX Cope with first/fast ack */
673 if (p
== p0
&& len
== 0)
683 * ccp_nakci - process received configure-nak.
684 * Returns 1 iff the nak was OK.
692 ccp_options
*go
= &ccp_gotoptions
[f
->unit
];
693 ccp_options no
; /* options we've seen already */
694 ccp_options
try; /* options to ask for next time */
696 memset(&no
, 0, sizeof(no
));
699 if (go
->deflate
&& len
>= CILEN_DEFLATE
700 && p
[0] == (go
->deflate_correct
? CI_DEFLATE
: CI_DEFLATE_DRAFT
)
701 && p
[1] == CILEN_DEFLATE
) {
704 * Peer wants us to use a different code size or something.
705 * Stop asking for Deflate if we don't understand his suggestion.
707 if (DEFLATE_METHOD(p
[2]) != DEFLATE_METHOD_VAL
708 || DEFLATE_SIZE(p
[2]) < DEFLATE_MIN_WORKS
709 || p
[3] != DEFLATE_CHK_SEQUENCE
)
711 else if (DEFLATE_SIZE(p
[2]) < go
->deflate_size
)
712 try.deflate_size
= DEFLATE_SIZE(p
[2]);
714 len
-= CILEN_DEFLATE
;
715 if (go
->deflate_correct
&& go
->deflate_draft
716 && len
>= CILEN_DEFLATE
&& p
[0] == CI_DEFLATE_DRAFT
717 && p
[1] == CILEN_DEFLATE
) {
719 len
-= CILEN_DEFLATE
;
723 if (go
->bsd_compress
&& len
>= CILEN_BSD_COMPRESS
724 && p
[0] == CI_BSD_COMPRESS
&& p
[1] == CILEN_BSD_COMPRESS
) {
727 * Peer wants us to use a different number of bits
728 * or a different version.
730 if (BSD_VERSION(p
[2]) != BSD_CURRENT_VERSION
)
731 try.bsd_compress
= 0;
732 else if (BSD_NBITS(p
[2]) < go
->bsd_bits
)
733 try.bsd_bits
= BSD_NBITS(p
[2]);
734 p
+= CILEN_BSD_COMPRESS
;
735 len
-= CILEN_BSD_COMPRESS
;
739 * Predictor-1 and 2 have no options, so they can't be Naked.
741 * There may be remaining options but we ignore them.
744 if (f
->state
!= OPENED
)
750 * ccp_rejci - reject some of our suggested compression methods.
758 ccp_options
*go
= &ccp_gotoptions
[f
->unit
];
759 ccp_options
try; /* options to request next time */
764 * Cope with empty configure-rejects by ceasing to send
765 * configure-requests.
767 if (len
== 0 && all_rejected
[f
->unit
])
770 if (go
->deflate
&& len
>= CILEN_DEFLATE
771 && p
[0] == (go
->deflate_correct
? CI_DEFLATE
: CI_DEFLATE_DRAFT
)
772 && p
[1] == CILEN_DEFLATE
) {
773 if (p
[2] != DEFLATE_MAKE_OPT(go
->deflate_size
)
774 || p
[3] != DEFLATE_CHK_SEQUENCE
)
775 return 0; /* Rej is bad */
776 if (go
->deflate_correct
)
777 try.deflate_correct
= 0;
779 try.deflate_draft
= 0;
781 len
-= CILEN_DEFLATE
;
782 if (go
->deflate_correct
&& go
->deflate_draft
783 && len
>= CILEN_DEFLATE
&& p
[0] == CI_DEFLATE_DRAFT
784 && p
[1] == CILEN_DEFLATE
) {
785 if (p
[2] != DEFLATE_MAKE_OPT(go
->deflate_size
)
786 || p
[3] != DEFLATE_CHK_SEQUENCE
)
787 return 0; /* Rej is bad */
788 try.deflate_draft
= 0;
790 len
-= CILEN_DEFLATE
;
792 if (!try.deflate_correct
&& !try.deflate_draft
)
795 if (go
->bsd_compress
&& len
>= CILEN_BSD_COMPRESS
796 && p
[0] == CI_BSD_COMPRESS
&& p
[1] == CILEN_BSD_COMPRESS
) {
797 if (p
[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION
, go
->bsd_bits
))
799 try.bsd_compress
= 0;
800 p
+= CILEN_BSD_COMPRESS
;
801 len
-= CILEN_BSD_COMPRESS
;
803 if (go
->predictor_1
&& len
>= CILEN_PREDICTOR_1
804 && p
[0] == CI_PREDICTOR_1
&& p
[1] == CILEN_PREDICTOR_1
) {
806 p
+= CILEN_PREDICTOR_1
;
807 len
-= CILEN_PREDICTOR_1
;
809 if (go
->predictor_2
&& len
>= CILEN_PREDICTOR_2
810 && p
[0] == CI_PREDICTOR_2
&& p
[1] == CILEN_PREDICTOR_2
) {
812 p
+= CILEN_PREDICTOR_2
;
813 len
-= CILEN_PREDICTOR_2
;
819 if (f
->state
!= OPENED
)
826 * ccp_reqci - processed a received configure-request.
827 * Returns CONFACK, CONFNAK or CONFREJ and the packet modified
831 ccp_reqci(f
, p
, lenp
, dont_nak
)
837 int ret
, newret
, res
;
839 int len
, clen
, type
, nb
;
840 ccp_options
*ho
= &ccp_hisoptions
[f
->unit
];
841 ccp_options
*ao
= &ccp_allowoptions
[f
->unit
];
847 memset(ho
, 0, sizeof(ccp_options
));
848 ho
->method
= (len
> 0)? p
[0]: -1;
852 if (len
< 2 || p
[1] < 2 || p
[1] > len
) {
863 case CI_DEFLATE_DRAFT
:
864 if (!ao
->deflate
|| clen
!= CILEN_DEFLATE
865 || (!ao
->deflate_correct
&& type
== CI_DEFLATE
)
866 || (!ao
->deflate_draft
&& type
== CI_DEFLATE_DRAFT
)) {
872 ho
->deflate_size
= nb
= DEFLATE_SIZE(p
[2]);
873 if (DEFLATE_METHOD(p
[2]) != DEFLATE_METHOD_VAL
874 || p
[3] != DEFLATE_CHK_SEQUENCE
875 || nb
> ao
->deflate_size
|| nb
< DEFLATE_MIN_WORKS
) {
878 p
[2] = DEFLATE_MAKE_OPT(ao
->deflate_size
);
879 p
[3] = DEFLATE_CHK_SEQUENCE
;
880 /* fall through to test this #bits below */
886 * Check whether we can do Deflate with the window
887 * size they want. If the window is too big, reduce
888 * it until the kernel can cope and nak with that.
889 * We only check this for the first option.
893 res
= ccp_test(f
->unit
, p
, CILEN_DEFLATE
, 1);
895 break; /* it's OK now */
896 if (res
< 0 || nb
== DEFLATE_MIN_WORKS
|| dont_nak
) {
898 p
[2] = DEFLATE_MAKE_OPT(ho
->deflate_size
);
903 p
[2] = DEFLATE_MAKE_OPT(nb
);
908 case CI_BSD_COMPRESS
:
909 if (!ao
->bsd_compress
|| clen
!= CILEN_BSD_COMPRESS
) {
914 ho
->bsd_compress
= 1;
915 ho
->bsd_bits
= nb
= BSD_NBITS(p
[2]);
916 if (BSD_VERSION(p
[2]) != BSD_CURRENT_VERSION
917 || nb
> ao
->bsd_bits
|| nb
< BSD_MIN_BITS
) {
920 p
[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION
, ao
->bsd_bits
);
921 /* fall through to test this #bits below */
927 * Check whether we can do BSD-Compress with the code
928 * size they want. If the code size is too big, reduce
929 * it until the kernel can cope and nak with that.
930 * We only check this for the first option.
934 res
= ccp_test(f
->unit
, p
, CILEN_BSD_COMPRESS
, 1);
937 if (res
< 0 || nb
== BSD_MIN_BITS
|| dont_nak
) {
939 p
[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION
,
945 p
[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION
, nb
);
951 if (!ao
->predictor_1
|| clen
!= CILEN_PREDICTOR_1
) {
958 && ccp_test(f
->unit
, p
, CILEN_PREDICTOR_1
, 1) <= 0) {
964 if (!ao
->predictor_2
|| clen
!= CILEN_PREDICTOR_2
) {
971 && ccp_test(f
->unit
, p
, CILEN_PREDICTOR_2
, 1) <= 0) {
981 if (newret
== CONFNAK
&& dont_nak
)
983 if (!(newret
== CONFACK
|| (newret
== CONFNAK
&& ret
== CONFREJ
))) {
984 /* we're returning this option */
985 if (newret
== CONFREJ
&& ret
== CONFNAK
)
989 BCOPY(p
, retp
, clen
);
997 if (ret
!= CONFACK
) {
998 if (ret
== CONFREJ
&& *lenp
== retp
- p0
)
999 all_rejected
[f
->unit
] = 1;
1007 * Make a string name for a compression method (or 2).
1010 method_name(opt
, opt2
)
1011 ccp_options
*opt
, *opt2
;
1013 static char result
[64];
1015 if (!ANY_COMPRESS(*opt
))
1017 switch (opt
->method
) {
1019 case CI_DEFLATE_DRAFT
:
1020 if (opt2
!= NULL
&& opt2
->deflate_size
!= opt
->deflate_size
)
1021 slprintf(result
, sizeof(result
), "Deflate%s (%d/%d)",
1022 (opt
->method
== CI_DEFLATE_DRAFT
? "(old#)": ""),
1023 opt
->deflate_size
, opt2
->deflate_size
);
1025 slprintf(result
, sizeof(result
), "Deflate%s (%d)",
1026 (opt
->method
== CI_DEFLATE_DRAFT
? "(old#)": ""),
1029 case CI_BSD_COMPRESS
:
1030 if (opt2
!= NULL
&& opt2
->bsd_bits
!= opt
->bsd_bits
)
1031 slprintf(result
, sizeof(result
), "BSD-Compress (%d/%d)",
1032 opt
->bsd_bits
, opt2
->bsd_bits
);
1034 slprintf(result
, sizeof(result
), "BSD-Compress (%d)",
1037 case CI_PREDICTOR_1
:
1038 return "Predictor 1";
1039 case CI_PREDICTOR_2
:
1040 return "Predictor 2";
1042 slprintf(result
, sizeof(result
), "Method %d", opt
->method
);
1048 * CCP has come up - inform the kernel driver and log a message.
1054 ccp_options
*go
= &ccp_gotoptions
[f
->unit
];
1055 ccp_options
*ho
= &ccp_hisoptions
[f
->unit
];
1058 ccp_flags_set(f
->unit
, 1, 1);
1059 if (ANY_COMPRESS(*go
)) {
1060 if (ANY_COMPRESS(*ho
)) {
1061 if (go
->method
== ho
->method
) {
1062 notice("%s compression enabled", method_name(go
, ho
));
1064 strlcpy(method1
, method_name(go
, NULL
), sizeof(method1
));
1065 notice("%s / %s compression enabled",
1066 method1
, method_name(ho
, NULL
));
1069 notice("%s receive compression enabled", method_name(go
, NULL
));
1070 } else if (ANY_COMPRESS(*ho
))
1071 notice("%s transmit compression enabled", method_name(ho
, NULL
));
1075 * CCP has gone down - inform the kernel driver.
1081 if (ccp_localstate
[f
->unit
] & RACK_PENDING
)
1082 UNTIMEOUT(ccp_rack_timeout
, f
);
1083 ccp_localstate
[f
->unit
] = 0;
1084 ccp_flags_set(f
->unit
, 1, 0);
1088 * Print the contents of a CCP packet.
1090 static char *ccp_codenames
[] = {
1091 "ConfReq", "ConfAck", "ConfNak", "ConfRej",
1092 "TermReq", "TermAck", "CodeRej",
1093 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
1094 "ResetReq", "ResetAck",
1098 ccp_printpkt(p
, plen
, printer
, arg
)
1101 void (*printer
) __P((void *, char *, ...));
1104 u_char
*p0
, *optend
;
1109 if (plen
< HEADERLEN
)
1113 len
= (p
[2] << 8) + p
[3];
1114 if (len
< HEADERLEN
|| len
> plen
)
1117 if (code
>= 1 && code
<= sizeof(ccp_codenames
) / sizeof(char *)
1118 && ccp_codenames
[code
-1] != NULL
)
1119 printer(arg
, " %s", ccp_codenames
[code
-1]);
1121 printer(arg
, " code=0x%x", code
);
1122 printer(arg
, " id=0x%x", id
);
1131 /* print list of possible compression methods */
1135 if (optlen
< 2 || optlen
> len
)
1139 optend
= p
+ optlen
;
1142 case CI_DEFLATE_DRAFT
:
1143 if (optlen
>= CILEN_DEFLATE
) {
1144 printer(arg
, "deflate%s %d",
1145 (code
== CI_DEFLATE_DRAFT
? "(old#)": ""),
1146 DEFLATE_SIZE(p
[2]));
1147 if (DEFLATE_METHOD(p
[2]) != DEFLATE_METHOD_VAL
)
1148 printer(arg
, " method %d", DEFLATE_METHOD(p
[2]));
1149 if (p
[3] != DEFLATE_CHK_SEQUENCE
)
1150 printer(arg
, " check %d", p
[3]);
1154 case CI_BSD_COMPRESS
:
1155 if (optlen
>= CILEN_BSD_COMPRESS
) {
1156 printer(arg
, "bsd v%d %d", BSD_VERSION(p
[2]),
1158 p
+= CILEN_BSD_COMPRESS
;
1161 case CI_PREDICTOR_1
:
1162 if (optlen
>= CILEN_PREDICTOR_1
) {
1163 printer(arg
, "predictor 1");
1164 p
+= CILEN_PREDICTOR_1
;
1167 case CI_PREDICTOR_2
:
1168 if (optlen
>= CILEN_PREDICTOR_2
) {
1169 printer(arg
, "predictor 2");
1170 p
+= CILEN_PREDICTOR_2
;
1175 printer(arg
, " %.2x", *p
++);
1182 if (len
> 0 && *p
>= ' ' && *p
< 0x7f) {
1183 print_string((char *)p
, len
, printer
, arg
);
1190 /* dump out the rest of the packet in hex */
1192 printer(arg
, " %.2x", *p
++);
1198 * We have received a packet that the decompressor failed to
1199 * decompress. Here we would expect to issue a reset-request, but
1200 * Motorola has a patent on resetting the compressor as a result of
1201 * detecting an error in the decompressed data after decompression.
1202 * (See US patent 5,130,993; international patent publication number
1203 * WO 91/10289; Australian patent 73296/91.)
1205 * So we ask the kernel whether the error was detected after
1206 * decompression; if it was, we take CCP down, thus disabling
1207 * compression :-(, otherwise we issue the reset-request.
1210 ccp_datainput(unit
, pkt
, len
)
1218 if (f
->state
== OPENED
) {
1219 if (ccp_fatal_error(unit
)) {
1221 * Disable compression by taking CCP down.
1223 error("Lost compression sync: disabling compression");
1224 ccp_close(unit
, "Lost compression sync");
1227 * Send a reset-request to reset the peer's compressor.
1228 * We don't do that if we are still waiting for an
1229 * acknowledgement to a previous reset-request.
1231 if (!(ccp_localstate
[f
->unit
] & RACK_PENDING
)) {
1232 fsm_sdata(f
, CCP_RESETREQ
, f
->reqid
= ++f
->id
, NULL
, 0);
1233 TIMEOUT(ccp_rack_timeout
, f
, RACKTIMEOUT
);
1234 ccp_localstate
[f
->unit
] |= RACK_PENDING
;
1236 ccp_localstate
[f
->unit
] |= RREQ_REPEAT
;
1242 * Timeout waiting for reset-ack.
1245 ccp_rack_timeout(arg
)
1250 if (f
->state
== OPENED
&& ccp_localstate
[f
->unit
] & RREQ_REPEAT
) {
1251 fsm_sdata(f
, CCP_RESETREQ
, f
->reqid
, NULL
, 0);
1252 TIMEOUT(ccp_rack_timeout
, f
, RACKTIMEOUT
);
1253 ccp_localstate
[f
->unit
] &= ~RREQ_REPEAT
;
1255 ccp_localstate
[f
->unit
] &= ~RACK_PENDING
;