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.1.4 2003/10/14 08:09:53 sparq 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
)
411 if ((code
> 0) && (code
< 16) && (code_log_details
[code
][0] != '#')) {
412 LOGX_INFO("Received %s %s", PNAME(f
), code_log_details
[code
]);
417 if (f
->state
!= OPENED
)
419 /* send a reset-ack, which the transmitter will see and
420 reset its compression state. */
421 fsm_sdata(f
, CCP_RESETACK
, id
, NULL
, 0);
425 if (ccp_localstate
[f
->unit
] & RACK_PENDING
&& id
== f
->reqid
) {
426 ccp_localstate
[f
->unit
] &= ~(RACK_PENDING
| RREQ_REPEAT
);
427 UNTIMEOUT(ccp_rack_timeout
, f
);
439 * ccp_protrej - peer doesn't talk CCP.
445 ccp_flags_set(unit
, 0, 0);
446 fsm_lowerdown(&ccp_fsm
[unit
]);
450 * ccp_resetci - initialize at start of negotiation.
456 ccp_options
*go
= &ccp_gotoptions
[f
->unit
];
459 *go
= ccp_wantoptions
[f
->unit
];
460 all_rejected
[f
->unit
] = 0;
463 * Check whether the kernel knows about the various
464 * compression methods we might request.
466 if (go
->bsd_compress
) {
467 opt_buf
[0] = CI_BSD_COMPRESS
;
468 opt_buf
[1] = CILEN_BSD_COMPRESS
;
469 opt_buf
[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION
, BSD_MIN_BITS
);
470 if (ccp_test(f
->unit
, opt_buf
, CILEN_BSD_COMPRESS
, 0) <= 0)
471 go
->bsd_compress
= 0;
474 if (go
->deflate_correct
) {
475 opt_buf
[0] = CI_DEFLATE
;
476 opt_buf
[1] = CILEN_DEFLATE
;
477 opt_buf
[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS
);
478 opt_buf
[3] = DEFLATE_CHK_SEQUENCE
;
479 if (ccp_test(f
->unit
, opt_buf
, CILEN_DEFLATE
, 0) <= 0)
480 go
->deflate_correct
= 0;
482 if (go
->deflate_draft
) {
483 opt_buf
[0] = CI_DEFLATE_DRAFT
;
484 opt_buf
[1] = CILEN_DEFLATE
;
485 opt_buf
[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS
);
486 opt_buf
[3] = DEFLATE_CHK_SEQUENCE
;
487 if (ccp_test(f
->unit
, opt_buf
, CILEN_DEFLATE
, 0) <= 0)
488 go
->deflate_draft
= 0;
490 if (!go
->deflate_correct
&& !go
->deflate_draft
)
493 if (go
->predictor_1
) {
494 opt_buf
[0] = CI_PREDICTOR_1
;
495 opt_buf
[1] = CILEN_PREDICTOR_1
;
496 if (ccp_test(f
->unit
, opt_buf
, CILEN_PREDICTOR_1
, 0) <= 0)
499 if (go
->predictor_2
) {
500 opt_buf
[0] = CI_PREDICTOR_2
;
501 opt_buf
[1] = CILEN_PREDICTOR_2
;
502 if (ccp_test(f
->unit
, opt_buf
, CILEN_PREDICTOR_2
, 0) <= 0)
508 * ccp_cilen - Return total length of our configuration info.
514 ccp_options
*go
= &ccp_gotoptions
[f
->unit
];
516 return (go
->bsd_compress
? CILEN_BSD_COMPRESS
: 0)
517 + (go
->deflate
? CILEN_DEFLATE
: 0)
518 + (go
->predictor_1
? CILEN_PREDICTOR_1
: 0)
519 + (go
->predictor_2
? CILEN_PREDICTOR_2
: 0);
523 * ccp_addci - put our requests in a packet.
526 ccp_addci(f
, p
, lenp
)
532 ccp_options
*go
= &ccp_gotoptions
[f
->unit
];
536 * Add the compression types that we can receive, in decreasing
537 * preference order. Get the kernel to allocate the first one
538 * in case it gets Acked.
541 p
[0] = go
->deflate_correct
? CI_DEFLATE
: CI_DEFLATE_DRAFT
;
542 p
[1] = CILEN_DEFLATE
;
543 p
[2] = DEFLATE_MAKE_OPT(go
->deflate_size
);
544 p
[3] = DEFLATE_CHK_SEQUENCE
;
546 res
= ccp_test(f
->unit
, p
, CILEN_DEFLATE
, 0);
551 if (res
< 0 || go
->deflate_size
<= DEFLATE_MIN_WORKS
) {
556 p
[2] = DEFLATE_MAKE_OPT(go
->deflate_size
);
558 if (p
!= p0
&& go
->deflate_correct
&& go
->deflate_draft
) {
559 p
[0] = CI_DEFLATE_DRAFT
;
560 p
[1] = CILEN_DEFLATE
;
561 p
[2] = p
[2 - CILEN_DEFLATE
];
562 p
[3] = DEFLATE_CHK_SEQUENCE
;
566 if (go
->bsd_compress
) {
567 p
[0] = CI_BSD_COMPRESS
;
568 p
[1] = CILEN_BSD_COMPRESS
;
569 p
[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION
, go
->bsd_bits
);
571 p
+= CILEN_BSD_COMPRESS
; /* not the first option */
574 res
= ccp_test(f
->unit
, p
, CILEN_BSD_COMPRESS
, 0);
576 p
+= CILEN_BSD_COMPRESS
;
579 if (res
< 0 || go
->bsd_bits
<= BSD_MIN_BITS
) {
580 go
->bsd_compress
= 0;
584 p
[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION
, go
->bsd_bits
);
588 if (go
->predictor_1
) {
589 p
[0] = CI_PREDICTOR_1
;
590 p
[1] = CILEN_PREDICTOR_1
;
591 if (p
== p0
&& ccp_test(f
->unit
, p
, CILEN_PREDICTOR_1
, 0) <= 0) {
594 p
+= CILEN_PREDICTOR_1
;
597 if (go
->predictor_2
) {
598 p
[0] = CI_PREDICTOR_2
;
599 p
[1] = CILEN_PREDICTOR_2
;
600 if (p
== p0
&& ccp_test(f
->unit
, p
, CILEN_PREDICTOR_2
, 0) <= 0) {
603 p
+= CILEN_PREDICTOR_2
;
607 go
->method
= (p
> p0
)? p0
[0]: -1;
613 * ccp_ackci - process a received configure-ack, and return
614 * 1 iff the packet was OK.
622 ccp_options
*go
= &ccp_gotoptions
[f
->unit
];
626 if (len
< CILEN_DEFLATE
627 || p
[0] != (go
->deflate_correct
? CI_DEFLATE
: CI_DEFLATE_DRAFT
)
628 || p
[1] != CILEN_DEFLATE
629 || p
[2] != DEFLATE_MAKE_OPT(go
->deflate_size
)
630 || p
[3] != DEFLATE_CHK_SEQUENCE
)
633 len
-= CILEN_DEFLATE
;
636 if (go
->deflate_correct
&& go
->deflate_draft
) {
637 if (len
< CILEN_DEFLATE
638 || p
[0] != CI_DEFLATE_DRAFT
639 || p
[1] != CILEN_DEFLATE
640 || p
[2] != DEFLATE_MAKE_OPT(go
->deflate_size
)
641 || p
[3] != DEFLATE_CHK_SEQUENCE
)
644 len
-= CILEN_DEFLATE
;
647 if (go
->bsd_compress
) {
648 if (len
< CILEN_BSD_COMPRESS
649 || p
[0] != CI_BSD_COMPRESS
|| p
[1] != CILEN_BSD_COMPRESS
650 || p
[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION
, go
->bsd_bits
))
652 p
+= CILEN_BSD_COMPRESS
;
653 len
-= CILEN_BSD_COMPRESS
;
654 if (p
== p0
&& len
== 0)
657 if (go
->predictor_1
) {
658 if (len
< CILEN_PREDICTOR_1
659 || p
[0] != CI_PREDICTOR_1
|| p
[1] != CILEN_PREDICTOR_1
)
661 p
+= CILEN_PREDICTOR_1
;
662 len
-= CILEN_PREDICTOR_1
;
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 if (p
== p0
&& len
== 0)
682 * ccp_nakci - process received configure-nak.
683 * Returns 1 iff the nak was OK.
691 ccp_options
*go
= &ccp_gotoptions
[f
->unit
];
692 ccp_options no
; /* options we've seen already */
693 ccp_options
try; /* options to ask for next time */
695 memset(&no
, 0, sizeof(no
));
698 if (go
->deflate
&& len
>= CILEN_DEFLATE
699 && p
[0] == (go
->deflate_correct
? CI_DEFLATE
: CI_DEFLATE_DRAFT
)
700 && p
[1] == CILEN_DEFLATE
) {
703 * Peer wants us to use a different code size or something.
704 * Stop asking for Deflate if we don't understand his suggestion.
706 if (DEFLATE_METHOD(p
[2]) != DEFLATE_METHOD_VAL
707 || DEFLATE_SIZE(p
[2]) < DEFLATE_MIN_WORKS
708 || p
[3] != DEFLATE_CHK_SEQUENCE
)
710 else if (DEFLATE_SIZE(p
[2]) < go
->deflate_size
)
711 try.deflate_size
= DEFLATE_SIZE(p
[2]);
713 len
-= CILEN_DEFLATE
;
714 if (go
->deflate_correct
&& go
->deflate_draft
715 && len
>= CILEN_DEFLATE
&& p
[0] == CI_DEFLATE_DRAFT
716 && p
[1] == CILEN_DEFLATE
) {
718 len
-= CILEN_DEFLATE
;
722 if (go
->bsd_compress
&& len
>= CILEN_BSD_COMPRESS
723 && p
[0] == CI_BSD_COMPRESS
&& p
[1] == CILEN_BSD_COMPRESS
) {
726 * Peer wants us to use a different number of bits
727 * or a different version.
729 if (BSD_VERSION(p
[2]) != BSD_CURRENT_VERSION
)
730 try.bsd_compress
= 0;
731 else if (BSD_NBITS(p
[2]) < go
->bsd_bits
)
732 try.bsd_bits
= BSD_NBITS(p
[2]);
733 p
+= CILEN_BSD_COMPRESS
;
734 len
-= CILEN_BSD_COMPRESS
;
738 * Predictor-1 and 2 have no options, so they can't be Naked.
740 * There may be remaining options but we ignore them.
743 if (f
->state
!= OPENED
)
749 * ccp_rejci - reject some of our suggested compression methods.
757 ccp_options
*go
= &ccp_gotoptions
[f
->unit
];
758 ccp_options
try; /* options to request next time */
763 * Cope with empty configure-rejects by ceasing to send
764 * configure-requests.
766 if (len
== 0 && all_rejected
[f
->unit
])
769 if (go
->deflate
&& len
>= CILEN_DEFLATE
770 && p
[0] == (go
->deflate_correct
? CI_DEFLATE
: CI_DEFLATE_DRAFT
)
771 && p
[1] == CILEN_DEFLATE
) {
772 if (p
[2] != DEFLATE_MAKE_OPT(go
->deflate_size
)
773 || p
[3] != DEFLATE_CHK_SEQUENCE
)
774 return 0; /* Rej is bad */
775 if (go
->deflate_correct
)
776 try.deflate_correct
= 0;
778 try.deflate_draft
= 0;
780 len
-= CILEN_DEFLATE
;
781 if (go
->deflate_correct
&& go
->deflate_draft
782 && len
>= CILEN_DEFLATE
&& p
[0] == CI_DEFLATE_DRAFT
783 && p
[1] == CILEN_DEFLATE
) {
784 if (p
[2] != DEFLATE_MAKE_OPT(go
->deflate_size
)
785 || p
[3] != DEFLATE_CHK_SEQUENCE
)
786 return 0; /* Rej is bad */
787 try.deflate_draft
= 0;
789 len
-= CILEN_DEFLATE
;
791 if (!try.deflate_correct
&& !try.deflate_draft
)
794 if (go
->bsd_compress
&& len
>= CILEN_BSD_COMPRESS
795 && p
[0] == CI_BSD_COMPRESS
&& p
[1] == CILEN_BSD_COMPRESS
) {
796 if (p
[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION
, go
->bsd_bits
))
798 try.bsd_compress
= 0;
799 p
+= CILEN_BSD_COMPRESS
;
800 len
-= CILEN_BSD_COMPRESS
;
802 if (go
->predictor_1
&& len
>= CILEN_PREDICTOR_1
803 && p
[0] == CI_PREDICTOR_1
&& p
[1] == CILEN_PREDICTOR_1
) {
805 p
+= CILEN_PREDICTOR_1
;
806 len
-= CILEN_PREDICTOR_1
;
808 if (go
->predictor_2
&& len
>= CILEN_PREDICTOR_2
809 && p
[0] == CI_PREDICTOR_2
&& p
[1] == CILEN_PREDICTOR_2
) {
811 p
+= CILEN_PREDICTOR_2
;
812 len
-= CILEN_PREDICTOR_2
;
818 if (f
->state
!= OPENED
)
825 * ccp_reqci - processed a received configure-request.
826 * Returns CONFACK, CONFNAK or CONFREJ and the packet modified
830 ccp_reqci(f
, p
, lenp
, dont_nak
)
836 int ret
, newret
, res
;
838 int len
, clen
, type
, nb
;
839 ccp_options
*ho
= &ccp_hisoptions
[f
->unit
];
840 ccp_options
*ao
= &ccp_allowoptions
[f
->unit
];
846 memset(ho
, 0, sizeof(ccp_options
));
847 ho
->method
= (len
> 0)? p
[0]: -1;
851 if (len
< 2 || p
[1] < 2 || p
[1] > len
) {
862 case CI_DEFLATE_DRAFT
:
863 if (!ao
->deflate
|| clen
!= CILEN_DEFLATE
864 || (!ao
->deflate_correct
&& type
== CI_DEFLATE
)
865 || (!ao
->deflate_draft
&& type
== CI_DEFLATE_DRAFT
)) {
871 ho
->deflate_size
= nb
= DEFLATE_SIZE(p
[2]);
872 if (DEFLATE_METHOD(p
[2]) != DEFLATE_METHOD_VAL
873 || p
[3] != DEFLATE_CHK_SEQUENCE
874 || nb
> ao
->deflate_size
|| nb
< DEFLATE_MIN_WORKS
) {
877 p
[2] = DEFLATE_MAKE_OPT(ao
->deflate_size
);
878 p
[3] = DEFLATE_CHK_SEQUENCE
;
879 /* fall through to test this #bits below */
885 * Check whether we can do Deflate with the window
886 * size they want. If the window is too big, reduce
887 * it until the kernel can cope and nak with that.
888 * We only check this for the first option.
892 res
= ccp_test(f
->unit
, p
, CILEN_DEFLATE
, 1);
894 break; /* it's OK now */
895 if (res
< 0 || nb
== DEFLATE_MIN_WORKS
|| dont_nak
) {
897 p
[2] = DEFLATE_MAKE_OPT(ho
->deflate_size
);
902 p
[2] = DEFLATE_MAKE_OPT(nb
);
907 case CI_BSD_COMPRESS
:
908 if (!ao
->bsd_compress
|| clen
!= CILEN_BSD_COMPRESS
) {
913 ho
->bsd_compress
= 1;
914 ho
->bsd_bits
= nb
= BSD_NBITS(p
[2]);
915 if (BSD_VERSION(p
[2]) != BSD_CURRENT_VERSION
916 || nb
> ao
->bsd_bits
|| nb
< BSD_MIN_BITS
) {
919 p
[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION
, ao
->bsd_bits
);
920 /* fall through to test this #bits below */
926 * Check whether we can do BSD-Compress with the code
927 * size they want. If the code size is too big, reduce
928 * it until the kernel can cope and nak with that.
929 * We only check this for the first option.
933 res
= ccp_test(f
->unit
, p
, CILEN_BSD_COMPRESS
, 1);
936 if (res
< 0 || nb
== BSD_MIN_BITS
|| dont_nak
) {
938 p
[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION
,
944 p
[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION
, nb
);
950 if (!ao
->predictor_1
|| clen
!= CILEN_PREDICTOR_1
) {
957 && ccp_test(f
->unit
, p
, CILEN_PREDICTOR_1
, 1) <= 0) {
963 if (!ao
->predictor_2
|| clen
!= CILEN_PREDICTOR_2
) {
970 && ccp_test(f
->unit
, p
, CILEN_PREDICTOR_2
, 1) <= 0) {
980 if (newret
== CONFNAK
&& dont_nak
)
982 if (!(newret
== CONFACK
|| (newret
== CONFNAK
&& ret
== CONFREJ
))) {
983 /* we're returning this option */
984 if (newret
== CONFREJ
&& ret
== CONFNAK
)
988 BCOPY(p
, retp
, clen
);
996 if (ret
!= CONFACK
) {
997 if (ret
== CONFREJ
&& *lenp
== retp
- p0
)
998 all_rejected
[f
->unit
] = 1;
1006 * Make a string name for a compression method (or 2).
1009 method_name(opt
, opt2
)
1010 ccp_options
*opt
, *opt2
;
1012 static char result
[64];
1014 if (!ANY_COMPRESS(*opt
))
1016 switch (opt
->method
) {
1018 case CI_DEFLATE_DRAFT
:
1019 if (opt2
!= NULL
&& opt2
->deflate_size
!= opt
->deflate_size
)
1020 slprintf(result
, sizeof(result
), "Deflate%s (%d/%d)",
1021 (opt
->method
== CI_DEFLATE_DRAFT
? "(old#)": ""),
1022 opt
->deflate_size
, opt2
->deflate_size
);
1024 slprintf(result
, sizeof(result
), "Deflate%s (%d)",
1025 (opt
->method
== CI_DEFLATE_DRAFT
? "(old#)": ""),
1028 case CI_BSD_COMPRESS
:
1029 if (opt2
!= NULL
&& opt2
->bsd_bits
!= opt
->bsd_bits
)
1030 slprintf(result
, sizeof(result
), "BSD-Compress (%d/%d)",
1031 opt
->bsd_bits
, opt2
->bsd_bits
);
1033 slprintf(result
, sizeof(result
), "BSD-Compress (%d)",
1036 case CI_PREDICTOR_1
:
1037 return "Predictor 1";
1038 case CI_PREDICTOR_2
:
1039 return "Predictor 2";
1041 slprintf(result
, sizeof(result
), "Method %d", opt
->method
);
1047 * CCP has come up - inform the kernel driver and log a message.
1053 ccp_options
*go
= &ccp_gotoptions
[f
->unit
];
1054 ccp_options
*ho
= &ccp_hisoptions
[f
->unit
];
1057 ccp_flags_set(f
->unit
, 1, 1);
1058 if (ANY_COMPRESS(*go
)) {
1059 if (ANY_COMPRESS(*ho
)) {
1060 if (go
->method
== ho
->method
) {
1061 notice("%s compression enabled", method_name(go
, ho
));
1063 strlcpy(method1
, method_name(go
, NULL
), sizeof(method1
));
1064 notice("%s / %s compression enabled",
1065 method1
, method_name(ho
, NULL
));
1068 notice("%s receive compression enabled", method_name(go
, NULL
));
1069 } else if (ANY_COMPRESS(*ho
))
1070 notice("%s transmit compression enabled", method_name(ho
, NULL
));
1074 * CCP has gone down - inform the kernel driver.
1080 if (ccp_localstate
[f
->unit
] & RACK_PENDING
)
1081 UNTIMEOUT(ccp_rack_timeout
, f
);
1082 ccp_localstate
[f
->unit
] = 0;
1083 ccp_flags_set(f
->unit
, 1, 0);
1087 * Print the contents of a CCP packet.
1089 static char *ccp_codenames
[] = {
1090 "ConfReq", "ConfAck", "ConfNak", "ConfRej",
1091 "TermReq", "TermAck", "CodeRej",
1092 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
1093 "ResetReq", "ResetAck",
1097 ccp_printpkt(p
, plen
, printer
, arg
)
1100 void (*printer
) __P((void *, char *, ...));
1103 u_char
*p0
, *optend
;
1108 if (plen
< HEADERLEN
)
1112 len
= (p
[2] << 8) + p
[3];
1113 if (len
< HEADERLEN
|| len
> plen
)
1116 if (code
>= 1 && code
<= sizeof(ccp_codenames
) / sizeof(char *)
1117 && ccp_codenames
[code
-1] != NULL
)
1118 printer(arg
, " %s", ccp_codenames
[code
-1]);
1120 printer(arg
, " code=0x%x", code
);
1121 printer(arg
, " id=0x%x", id
);
1130 /* print list of possible compression methods */
1134 if (optlen
< 2 || optlen
> len
)
1138 optend
= p
+ optlen
;
1141 case CI_DEFLATE_DRAFT
:
1142 if (optlen
>= CILEN_DEFLATE
) {
1143 printer(arg
, "deflate%s %d",
1144 (code
== CI_DEFLATE_DRAFT
? "(old#)": ""),
1145 DEFLATE_SIZE(p
[2]));
1146 if (DEFLATE_METHOD(p
[2]) != DEFLATE_METHOD_VAL
)
1147 printer(arg
, " method %d", DEFLATE_METHOD(p
[2]));
1148 if (p
[3] != DEFLATE_CHK_SEQUENCE
)
1149 printer(arg
, " check %d", p
[3]);
1153 case CI_BSD_COMPRESS
:
1154 if (optlen
>= CILEN_BSD_COMPRESS
) {
1155 printer(arg
, "bsd v%d %d", BSD_VERSION(p
[2]),
1157 p
+= CILEN_BSD_COMPRESS
;
1160 case CI_PREDICTOR_1
:
1161 if (optlen
>= CILEN_PREDICTOR_1
) {
1162 printer(arg
, "predictor 1");
1163 p
+= CILEN_PREDICTOR_1
;
1166 case CI_PREDICTOR_2
:
1167 if (optlen
>= CILEN_PREDICTOR_2
) {
1168 printer(arg
, "predictor 2");
1169 p
+= CILEN_PREDICTOR_2
;
1174 printer(arg
, " %.2x", *p
++);
1181 if (len
> 0 && *p
>= ' ' && *p
< 0x7f) {
1182 print_string((char *)p
, len
, printer
, arg
);
1189 /* dump out the rest of the packet in hex */
1191 printer(arg
, " %.2x", *p
++);
1197 * We have received a packet that the decompressor failed to
1198 * decompress. Here we would expect to issue a reset-request, but
1199 * Motorola has a patent on resetting the compressor as a result of
1200 * detecting an error in the decompressed data after decompression.
1201 * (See US patent 5,130,993; international patent publication number
1202 * WO 91/10289; Australian patent 73296/91.)
1204 * So we ask the kernel whether the error was detected after
1205 * decompression; if it was, we take CCP down, thus disabling
1206 * compression :-(, otherwise we issue the reset-request.
1209 ccp_datainput(unit
, pkt
, len
)
1216 LOGX_INFO("Received a CCP Error-Code packet.");
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
;