Bug Summary

File:src/usr.sbin/pppd/ccp.c
Warning:line 671, column 2
Value stored to 'p' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ccp.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/pppd/obj -resource-dir /usr/local/lib/clang/13.0.0 -I . -I /usr/src/usr.sbin/pppd/../../lib/libpcap -D HAVE_PATHS_H -D PPP_FILTER -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/pppd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/pppd/ccp.c
1/* $OpenBSD: ccp.c,v 1.13 2009/10/27 23:59:53 deraadt Exp $ */
2
3/*
4 * ccp.c - PPP Compression Control Protocol.
5 *
6 * Copyright (c) 1989-2002 Paul Mackerras. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. The name(s) of the authors of this software must not be used to
21 * endorse or promote products derived from this software without
22 * prior written permission.
23 *
24 * 4. Redistributions of any form whatsoever must retain the following
25 * acknowledgment:
26 * "This product includes software developed by Paul Mackerras
27 * <paulus@samba.org>".
28 *
29 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
30 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
31 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
32 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
33 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
34 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
35 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
36 */
37
38#include <string.h>
39#include <syslog.h>
40#include <sys/ioctl.h>
41#include <sys/types.h>
42
43#include "pppd.h"
44#include "fsm.h"
45#include "ccp.h"
46#include <net/ppp-comp.h>
47
48/*
49 * Protocol entry points from main code.
50 */
51static void ccp_init(int unit);
52static void ccp_open(int unit);
53static void ccp_close(int unit, char *);
54static void ccp_lowerup(int unit);
55static void ccp_lowerdown(int);
56static void ccp_input(int unit, u_char *pkt, int len);
57static void ccp_protrej(int unit);
58static int ccp_printpkt(u_char *pkt, int len,
59 void (*printer)(void *, char *, ...), void *arg);
60static void ccp_datainput(int unit, u_char *pkt, int len);
61
62struct protent ccp_protent = {
63 PPP_CCP0x80fd,
64 ccp_init,
65 ccp_input,
66 ccp_protrej,
67 ccp_lowerup,
68 ccp_lowerdown,
69 ccp_open,
70 ccp_close,
71 ccp_printpkt,
72 ccp_datainput,
73 1,
74 "CCP",
75 NULL((void *)0),
76 NULL((void *)0),
77 NULL((void *)0)
78};
79
80fsm ccp_fsm[NUM_PPP1];
81ccp_options ccp_wantoptions[NUM_PPP1]; /* what to request the peer to use */
82ccp_options ccp_gotoptions[NUM_PPP1]; /* what the peer agreed to do */
83ccp_options ccp_allowoptions[NUM_PPP1]; /* what we'll agree to do */
84ccp_options ccp_hisoptions[NUM_PPP1]; /* what we agreed to do */
85
86/*
87 * Callbacks for fsm code.
88 */
89static void ccp_resetci(fsm *);
90static int ccp_cilen(fsm *);
91static void ccp_addci(fsm *, u_char *, int *);
92static int ccp_ackci(fsm *, u_char *, int);
93static int ccp_nakci(fsm *, u_char *, int);
94static int ccp_rejci(fsm *, u_char *, int);
95static int ccp_reqci(fsm *, u_char *, int *, int);
96static void ccp_up(fsm *);
97static void ccp_down(fsm *);
98static int ccp_extcode(fsm *, int, int, u_char *, int);
99static void ccp_rack_timeout(void *);
100static char *method_name(ccp_options *, ccp_options *);
101
102static fsm_callbacks ccp_callbacks = {
103 ccp_resetci,
104 ccp_cilen,
105 ccp_addci,
106 ccp_ackci,
107 ccp_nakci,
108 ccp_rejci,
109 ccp_reqci,
110 ccp_up,
111 ccp_down,
112 NULL((void *)0),
113 NULL((void *)0),
114 NULL((void *)0),
115 NULL((void *)0),
116 ccp_extcode,
117 "CCP"
118};
119
120/*
121 * Do we want / did we get any compression?
122 */
123#define ANY_COMPRESS(opt)((opt).deflate || (opt).bsd_compress || (opt).predictor_1 || (
opt).predictor_2)
((opt).deflate || (opt).bsd_compress \
124 || (opt).predictor_1 || (opt).predictor_2)
125
126/*
127 * Local state (mainly for handling reset-reqs and reset-acks).
128 */
129static int ccp_localstate[NUM_PPP1];
130#define RACK_PENDING1 1 /* waiting for reset-ack */
131#define RREQ_REPEAT2 2 /* send another reset-req if no reset-ack */
132
133#define RACKTIMEOUT1 1 /* second */
134
135static int all_rejected[NUM_PPP1]; /* we rejected all peer's options */
136
137/*
138 * ccp_init - initialize CCP.
139 */
140static void
141ccp_init(unit)
142 int unit;
143{
144 fsm *f = &ccp_fsm[unit];
145
146 f->unit = unit;
147 f->protocol = PPP_CCP0x80fd;
148 f->callbacks = &ccp_callbacks;
149 fsm_init(f);
150
151 memset(&ccp_wantoptions[unit], 0, sizeof(ccp_options));
152 memset(&ccp_gotoptions[unit], 0, sizeof(ccp_options));
153 memset(&ccp_allowoptions[unit], 0, sizeof(ccp_options));
154 memset(&ccp_hisoptions[unit], 0, sizeof(ccp_options));
155
156 ccp_wantoptions[0].deflate = 1;
157 ccp_wantoptions[0].deflate_size = DEFLATE_MAX_SIZE15;
158 ccp_wantoptions[0].deflate_correct = 1;
159 ccp_wantoptions[0].deflate_draft = 1;
160 ccp_allowoptions[0].deflate = 1;
161 ccp_allowoptions[0].deflate_size = DEFLATE_MAX_SIZE15;
162 ccp_allowoptions[0].deflate_correct = 1;
163 ccp_allowoptions[0].deflate_draft = 1;
164
165 ccp_wantoptions[0].bsd_compress = 1;
166 ccp_wantoptions[0].bsd_bits = BSD_MAX_BITS15;
167 ccp_allowoptions[0].bsd_compress = 1;
168 ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS15;
169
170 ccp_allowoptions[0].predictor_1 = 1;
171}
172
173/*
174 * ccp_open - CCP is allowed to come up.
175 */
176static void
177ccp_open(unit)
178 int unit;
179{
180 fsm *f = &ccp_fsm[unit];
181
182 if (f->state != OPENED9)
183 ccp_flags_set(unit, 1, 0);
184
185 /*
186 * Find out which compressors the kernel supports before
187 * deciding whether to open in silent mode.
188 */
189 ccp_resetci(f);
190 if (!ANY_COMPRESS(ccp_gotoptions[unit])((ccp_gotoptions[unit]).deflate || (ccp_gotoptions[unit]).bsd_compress
|| (ccp_gotoptions[unit]).predictor_1 || (ccp_gotoptions[unit
]).predictor_2)
)
191 f->flags |= OPT_SILENT4;
192
193 fsm_open(f);
194}
195
196/*
197 * ccp_close - Terminate CCP.
198 */
199static void
200ccp_close(unit, reason)
201 int unit;
202 char *reason;
203{
204 ccp_flags_set(unit, 0, 0);
205 fsm_close(&ccp_fsm[unit], reason);
206}
207
208/*
209 * ccp_lowerup - we may now transmit CCP packets.
210 */
211static void
212ccp_lowerup(unit)
213 int unit;
214{
215 fsm_lowerup(&ccp_fsm[unit]);
216}
217
218/*
219 * ccp_lowerdown - we may not transmit CCP packets.
220 */
221static void
222ccp_lowerdown(unit)
223 int unit;
224{
225 fsm_lowerdown(&ccp_fsm[unit]);
226}
227
228/*
229 * ccp_input - process a received CCP packet.
230 */
231static void
232ccp_input(unit, p, len)
233 int unit;
234 u_char *p;
235 int len;
236{
237 fsm *f = &ccp_fsm[unit];
238 int oldstate;
239
240 /*
241 * Check for a terminate-request so we can print a message.
242 */
243 oldstate = f->state;
244 fsm_input(f, p, len);
245 if (oldstate == OPENED9 && p[0] == TERMREQ5 && f->state != OPENED9)
246 syslog(LOG_NOTICE5, "Compression disabled by peer.");
247
248 /*
249 * If we get a terminate-ack and we're not asking for compression,
250 * close CCP.
251 */
252 if (oldstate == REQSENT6 && p[0] == TERMACK6
253 && !ANY_COMPRESS(ccp_gotoptions[unit])((ccp_gotoptions[unit]).deflate || (ccp_gotoptions[unit]).bsd_compress
|| (ccp_gotoptions[unit]).predictor_1 || (ccp_gotoptions[unit
]).predictor_2)
)
254 ccp_close(unit, "No compression negotiated");
255}
256
257/*
258 * Handle a CCP-specific code.
259 */
260static int
261ccp_extcode(f, code, id, p, len)
262 fsm *f;
263 int code, id;
264 u_char *p;
265 int len;
266{
267 switch (code) {
268 case CCP_RESETREQ14:
269 if (f->state != OPENED9)
270 break;
271 /* send a reset-ack, which the transmitter will see and
272 reset its compression state. */
273 fsm_sdata(f, CCP_RESETACK15, id, NULL((void *)0), 0);
274 break;
275
276 case CCP_RESETACK15:
277 if (ccp_localstate[f->unit] & RACK_PENDING1 && id == f->reqid) {
278 ccp_localstate[f->unit] &= ~(RACK_PENDING1 | RREQ_REPEAT2);
279 UNTIMEOUT(ccp_rack_timeout, f)untimeout((ccp_rack_timeout), (f));
280 }
281 break;
282
283 default:
284 return 0;
285 }
286
287 return 1;
288}
289
290/*
291 * ccp_protrej - peer doesn't talk CCP.
292 */
293static void
294ccp_protrej(unit)
295 int unit;
296{
297 ccp_flags_set(unit, 0, 0);
298 fsm_lowerdown(&ccp_fsm[unit]);
299}
300
301/*
302 * ccp_resetci - initialize at start of negotiation.
303 */
304static void
305ccp_resetci(f)
306 fsm *f;
307{
308 ccp_options *go = &ccp_gotoptions[f->unit];
309 u_char opt_buf[16];
310
311 *go = ccp_wantoptions[f->unit];
312 all_rejected[f->unit] = 0;
313
314 /*
315 * Check whether the kernel knows about the various
316 * compression methods we might request.
317 */
318 if (go->bsd_compress) {
319 opt_buf[0] = CI_BSD_COMPRESS21;
320 opt_buf[1] = CILEN_BSD_COMPRESS3;
321 opt_buf[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, BSD_MIN_BITS)(((1) << 5) | (9));
322 if (ccp_test(f->unit, opt_buf, CILEN_BSD_COMPRESS3, 0) <= 0)
323 go->bsd_compress = 0;
324 }
325 if (go->deflate) {
326 if (go->deflate_correct) {
327 opt_buf[0] = CI_DEFLATE26;
328 opt_buf[1] = CILEN_DEFLATE4;
329 opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE)((((8) - 8) << 4) + 8);
330 opt_buf[3] = DEFLATE_CHK_SEQUENCE0;
331 if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE4, 0) <= 0)
332 go->deflate_correct = 0;
333 }
334 if (go->deflate_draft) {
335 opt_buf[0] = CI_DEFLATE_DRAFT24;
336 opt_buf[1] = CILEN_DEFLATE4;
337 opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE)((((8) - 8) << 4) + 8);
338 opt_buf[3] = DEFLATE_CHK_SEQUENCE0;
339 if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE4, 0) <= 0)
340 go->deflate_draft = 0;
341 }
342 if (!go->deflate_correct && !go->deflate_draft)
343 go->deflate = 0;
344 }
345 if (go->predictor_1) {
346 opt_buf[0] = CI_PREDICTOR_11;
347 opt_buf[1] = CILEN_PREDICTOR_12;
348 if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_12, 0) <= 0)
349 go->predictor_1 = 0;
350 }
351 if (go->predictor_2) {
352 opt_buf[0] = CI_PREDICTOR_22;
353 opt_buf[1] = CILEN_PREDICTOR_22;
354 if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_22, 0) <= 0)
355 go->predictor_2 = 0;
356 }
357}
358
359/*
360 * ccp_cilen - Return total length of our configuration info.
361 */
362static int
363ccp_cilen(f)
364 fsm *f;
365{
366 ccp_options *go = &ccp_gotoptions[f->unit];
367
368 return (go->bsd_compress? CILEN_BSD_COMPRESS3: 0)
369 + (go->deflate? CILEN_DEFLATE4: 0)
370 + (go->predictor_1? CILEN_PREDICTOR_12: 0)
371 + (go->predictor_2? CILEN_PREDICTOR_22: 0);
372}
373
374/*
375 * ccp_addci - put our requests in a packet.
376 */
377static void
378ccp_addci(f, p, lenp)
379 fsm *f;
380 u_char *p;
381 int *lenp;
382{
383 int res;
384 ccp_options *go = &ccp_gotoptions[f->unit];
385 u_char *p0 = p;
386
387 /*
388 * Add the compression types that we can receive, in decreasing
389 * preference order. Get the kernel to allocate the first one
390 * in case it gets Acked.
391 */
392 if (go->deflate) {
393 p[0] = go->deflate_correct? CI_DEFLATE26: CI_DEFLATE_DRAFT24;
394 p[1] = CILEN_DEFLATE4;
395 p[2] = DEFLATE_MAKE_OPT(go->deflate_size)((((go->deflate_size) - 8) << 4) + 8);
396 p[3] = DEFLATE_CHK_SEQUENCE0;
397 for (;;) {
398 res = ccp_test(f->unit, p, CILEN_DEFLATE4, 0);
399 if (res > 0) {
400 p += CILEN_DEFLATE4;
401 break;
402 }
403 if (res < 0 || go->deflate_size <= DEFLATE_MIN_SIZE8) {
404 go->deflate = 0;
405 break;
406 }
407 --go->deflate_size;
408 p[2] = DEFLATE_MAKE_OPT(go->deflate_size)((((go->deflate_size) - 8) << 4) + 8);
409 }
410 if (p != p0 && go->deflate_correct && go->deflate_draft) {
411 p[0] = CI_DEFLATE_DRAFT24;
412 p[1] = CILEN_DEFLATE4;
413 p[2] = p[2 - CILEN_DEFLATE4];
414 p[3] = DEFLATE_CHK_SEQUENCE0;
415 p += CILEN_DEFLATE4;
416 }
417 }
418 if (go->bsd_compress) {
419 p[0] = CI_BSD_COMPRESS21;
420 p[1] = CILEN_BSD_COMPRESS3;
421 p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)(((1) << 5) | (go->bsd_bits));
422 if (p != p0) {
423 p += CILEN_BSD_COMPRESS3; /* not the first option */
424 } else {
425 for (;;) {
426 res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS3, 0);
427 if (res > 0) {
428 p += CILEN_BSD_COMPRESS3;
429 break;
430 }
431 if (res < 0 || go->bsd_bits <= BSD_MIN_BITS9) {
432 go->bsd_compress = 0;
433 break;
434 }
435 --go->bsd_bits;
436 p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)(((1) << 5) | (go->bsd_bits));
437 }
438 }
439 }
440 /* XXX Should Predictor 2 be preferable to Predictor 1? */
441 if (go->predictor_1) {
442 p[0] = CI_PREDICTOR_11;
443 p[1] = CILEN_PREDICTOR_12;
444 if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_12, 0) <= 0) {
445 go->predictor_1 = 0;
446 } else {
447 p += CILEN_PREDICTOR_12;
448 }
449 }
450 if (go->predictor_2) {
451 p[0] = CI_PREDICTOR_22;
452 p[1] = CILEN_PREDICTOR_22;
453 if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_22, 0) <= 0) {
454 go->predictor_2 = 0;
455 } else {
456 p += CILEN_PREDICTOR_22;
457 }
458 }
459
460 go->method = (p > p0)? p0[0]: -1;
461
462 *lenp = p - p0;
463}
464
465/*
466 * ccp_ackci - process a received configure-ack, and return
467 * 1 iff the packet was OK.
468 */
469static int
470ccp_ackci(f, p, len)
471 fsm *f;
472 u_char *p;
473 int len;
474{
475 ccp_options *go = &ccp_gotoptions[f->unit];
476 u_char *p0 = p;
477
478 if (go->deflate) {
479 if (len < CILEN_DEFLATE4
480 || p[0] != (go->deflate_correct? CI_DEFLATE26: CI_DEFLATE_DRAFT24)
481 || p[1] != CILEN_DEFLATE4
482 || p[2] != DEFLATE_MAKE_OPT(go->deflate_size)((((go->deflate_size) - 8) << 4) + 8)
483 || p[3] != DEFLATE_CHK_SEQUENCE0)
484 return 0;
485 p += CILEN_DEFLATE4;
486 len -= CILEN_DEFLATE4;
487 /* XXX Cope with first/fast ack */
488 if (len == 0)
489 return 1;
490 if (go->deflate_correct && go->deflate_draft) {
491 if (len < CILEN_DEFLATE4
492 || p[0] != CI_DEFLATE_DRAFT24
493 || p[1] != CILEN_DEFLATE4
494 || p[2] != DEFLATE_MAKE_OPT(go->deflate_size)((((go->deflate_size) - 8) << 4) + 8)
495 || p[3] != DEFLATE_CHK_SEQUENCE0)
496 return 0;
497 p += CILEN_DEFLATE4;
498 len -= CILEN_DEFLATE4;
499 }
500 }
501 if (go->bsd_compress) {
502 if (len < CILEN_BSD_COMPRESS3
503 || p[0] != CI_BSD_COMPRESS21 || p[1] != CILEN_BSD_COMPRESS3
504 || p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)(((1) << 5) | (go->bsd_bits)))
505 return 0;
506 p += CILEN_BSD_COMPRESS3;
507 len -= CILEN_BSD_COMPRESS3;
508 /* XXX Cope with first/fast ack */
509 if (p == p0 && len == 0)
510 return 1;
511 }
512 if (go->predictor_1) {
513 if (len < CILEN_PREDICTOR_12
514 || p[0] != CI_PREDICTOR_11 || p[1] != CILEN_PREDICTOR_12)
515 return 0;
516 p += CILEN_PREDICTOR_12;
517 len -= CILEN_PREDICTOR_12;
518 /* XXX Cope with first/fast ack */
519 if (p == p0 && len == 0)
520 return 1;
521 }
522 if (go->predictor_2) {
523 if (len < CILEN_PREDICTOR_22
524 || p[0] != CI_PREDICTOR_22 || p[1] != CILEN_PREDICTOR_22)
525 return 0;
526 p += CILEN_PREDICTOR_22;
527 len -= CILEN_PREDICTOR_22;
528 /* XXX Cope with first/fast ack */
529 if (p == p0 && len == 0)
530 return 1;
531 }
532
533 if (len != 0)
534 return 0;
535 return 1;
536}
537
538/*
539 * ccp_nakci - process received configure-nak.
540 * Returns 1 iff the nak was OK.
541 */
542static int
543ccp_nakci(f, p, len)
544 fsm *f;
545 u_char *p;
546 int len;
547{
548 ccp_options *go = &ccp_gotoptions[f->unit];
549 ccp_options no; /* options we've seen already */
550 ccp_options try; /* options to ask for next time */
551
552 memset(&no, 0, sizeof(no));
553 try = *go;
554
555 if (go->deflate && len >= CILEN_DEFLATE4
556 && p[0] == (go->deflate_correct? CI_DEFLATE26: CI_DEFLATE_DRAFT24)
557 && p[1] == CILEN_DEFLATE4) {
558 no.deflate = 1;
559 /*
560 * Peer wants us to use a different code size or something.
561 * Stop asking for Deflate if we don't understand his suggestion.
562 */
563 if (DEFLATE_METHOD(p[2])((p[2]) & 0x0F) != DEFLATE_METHOD_VAL8
564 || DEFLATE_SIZE(p[2])(((p[2]) >> 4) + 8) < DEFLATE_MIN_SIZE8
565 || p[3] != DEFLATE_CHK_SEQUENCE0)
566 try.deflate = 0;
567 else if (DEFLATE_SIZE(p[2])(((p[2]) >> 4) + 8) < go->deflate_size)
568 try.deflate_size = DEFLATE_SIZE(p[2])(((p[2]) >> 4) + 8);
569 p += CILEN_DEFLATE4;
570 len -= CILEN_DEFLATE4;
571 if (go->deflate_correct && go->deflate_draft
572 && len >= CILEN_DEFLATE4 && p[0] == CI_DEFLATE_DRAFT24
573 && p[1] == CILEN_DEFLATE4) {
574 p += CILEN_DEFLATE4;
575 len -= CILEN_DEFLATE4;
576 }
577 }
578
579 if (go->bsd_compress && len >= CILEN_BSD_COMPRESS3
580 && p[0] == CI_BSD_COMPRESS21 && p[1] == CILEN_BSD_COMPRESS3) {
581 no.bsd_compress = 1;
582 /*
583 * Peer wants us to use a different number of bits
584 * or a different version.
585 */
586 if (BSD_VERSION(p[2])((p[2]) >> 5) != BSD_CURRENT_VERSION1)
587 try.bsd_compress = 0;
588 else if (BSD_NBITS(p[2])((p[2]) & 0x1F) < go->bsd_bits)
589 try.bsd_bits = BSD_NBITS(p[2])((p[2]) & 0x1F);
590 p += CILEN_BSD_COMPRESS3;
591 len -= CILEN_BSD_COMPRESS3;
592 }
593
594 /*
595 * Predictor-1 and 2 have no options, so they can't be Naked.
596 *
597 * XXX What should we do with any remaining options?
598 */
599
600 if (len != 0)
601 return 0;
602
603 if (f->state != OPENED9)
604 *go = try;
605 return 1;
606}
607
608/*
609 * ccp_rejci - reject some of our suggested compression methods.
610 */
611static int
612ccp_rejci(f, p, len)
613 fsm *f;
614 u_char *p;
615 int len;
616{
617 ccp_options *go = &ccp_gotoptions[f->unit];
618 ccp_options try; /* options to request next time */
619
620 try = *go;
621
622 /*
623 * Cope with empty configure-rejects by ceasing to send
624 * configure-requests.
625 */
626 if (len == 0 && all_rejected[f->unit])
627 return -1;
628
629 if (go->deflate && len >= CILEN_DEFLATE4
630 && p[0] == (go->deflate_correct? CI_DEFLATE26: CI_DEFLATE_DRAFT24)
631 && p[1] == CILEN_DEFLATE4) {
632 if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)((((go->deflate_size) - 8) << 4) + 8)
633 || p[3] != DEFLATE_CHK_SEQUENCE0)
634 return 0; /* Rej is bad */
635 if (go->deflate_correct)
636 try.deflate_correct = 0;
637 else
638 try.deflate_draft = 0;
639 p += CILEN_DEFLATE4;
640 len -= CILEN_DEFLATE4;
641 if (go->deflate_correct && go->deflate_draft
642 && len >= CILEN_DEFLATE4 && p[0] == CI_DEFLATE_DRAFT24
643 && p[1] == CILEN_DEFLATE4) {
644 if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)((((go->deflate_size) - 8) << 4) + 8)
645 || p[3] != DEFLATE_CHK_SEQUENCE0)
646 return 0; /* Rej is bad */
647 try.deflate_draft = 0;
648 p += CILEN_DEFLATE4;
649 len -= CILEN_DEFLATE4;
650 }
651 if (!try.deflate_correct && !try.deflate_draft)
652 try.deflate = 0;
653 }
654 if (go->bsd_compress && len >= CILEN_BSD_COMPRESS3
655 && p[0] == CI_BSD_COMPRESS21 && p[1] == CILEN_BSD_COMPRESS3) {
656 if (p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)(((1) << 5) | (go->bsd_bits)))
657 return 0;
658 try.bsd_compress = 0;
659 p += CILEN_BSD_COMPRESS3;
660 len -= CILEN_BSD_COMPRESS3;
661 }
662 if (go->predictor_1 && len >= CILEN_PREDICTOR_12
663 && p[0] == CI_PREDICTOR_11 && p[1] == CILEN_PREDICTOR_12) {
664 try.predictor_1 = 0;
665 p += CILEN_PREDICTOR_12;
666 len -= CILEN_PREDICTOR_12;
667 }
668 if (go->predictor_2 && len >= CILEN_PREDICTOR_22
669 && p[0] == CI_PREDICTOR_22 && p[1] == CILEN_PREDICTOR_22) {
670 try.predictor_2 = 0;
671 p += CILEN_PREDICTOR_22;
Value stored to 'p' is never read
672 len -= CILEN_PREDICTOR_22;
673 }
674
675 if (len != 0)
676 return 0;
677
678 if (f->state != OPENED9)
679 *go = try;
680
681 return 1;
682}
683
684/*
685 * ccp_reqci - processed a received configure-request.
686 * Returns CONFACK, CONFNAK or CONFREJ and the packet modified
687 * appropriately.
688 */
689static int
690ccp_reqci(f, p, lenp, dont_nak)
691 fsm *f;
692 u_char *p;
693 int *lenp;
694 int dont_nak;
695{
696 int ret, newret, res;
697 u_char *p0, *retp;
698 int len, clen, type, nb;
699 ccp_options *ho = &ccp_hisoptions[f->unit];
700 ccp_options *ao = &ccp_allowoptions[f->unit];
701
702 ret = CONFACK2;
703 retp = p0 = p;
704 len = *lenp;
705
706 memset(ho, 0, sizeof(ccp_options));
707 ho->method = (len > 0)? p[0]: -1;
708
709 while (len > 0) {
710 newret = CONFACK2;
711 if (len < 2 || p[1] < 2 || p[1] > len) {
712 /* length is bad */
713 clen = len;
714 newret = CONFREJ4;
715
716 } else {
717 type = p[0];
718 clen = p[1];
719
720 switch (type) {
721 case CI_DEFLATE26:
722 case CI_DEFLATE_DRAFT24:
723 if (!ao->deflate || clen != CILEN_DEFLATE4
724 || (!ao->deflate_correct && type == CI_DEFLATE26)
725 || (!ao->deflate_draft && type == CI_DEFLATE_DRAFT24)) {
726 newret = CONFREJ4;
727 break;
728 }
729
730 ho->deflate = 1;
731 ho->deflate_size = nb = DEFLATE_SIZE(p[2])(((p[2]) >> 4) + 8);
732 if (DEFLATE_METHOD(p[2])((p[2]) & 0x0F) != DEFLATE_METHOD_VAL8
733 || p[3] != DEFLATE_CHK_SEQUENCE0
734 || nb > ao->deflate_size || nb < DEFLATE_MIN_SIZE8) {
735 newret = CONFNAK3;
736 if (!dont_nak) {
737 p[2] = DEFLATE_MAKE_OPT(ao->deflate_size)((((ao->deflate_size) - 8) << 4) + 8);
738 p[3] = DEFLATE_CHK_SEQUENCE0;
739 /* fall through to test this #bits below */
740 } else
741 break;
742 }
743
744 /*
745 * Check whether we can do Deflate with the window
746 * size they want. If the window is too big, reduce
747 * it until the kernel can cope and nak with that.
748 * We only check this for the first option.
749 */
750 if (p == p0) {
751 for (;;) {
752 res = ccp_test(f->unit, p, CILEN_DEFLATE4, 1);
753 if (res > 0)
754 break; /* it's OK now */
755 if (res < 0 || nb == DEFLATE_MIN_SIZE8 || dont_nak) {
756 newret = CONFREJ4;
757 p[2] = DEFLATE_MAKE_OPT(ho->deflate_size)((((ho->deflate_size) - 8) << 4) + 8);
758 break;
759 }
760 newret = CONFNAK3;
761 --nb;
762 p[2] = DEFLATE_MAKE_OPT(nb)((((nb) - 8) << 4) + 8);
763 }
764 }
765 break;
766
767 case CI_BSD_COMPRESS21:
768 if (!ao->bsd_compress || clen != CILEN_BSD_COMPRESS3) {
769 newret = CONFREJ4;
770 break;
771 }
772
773 ho->bsd_compress = 1;
774 ho->bsd_bits = nb = BSD_NBITS(p[2])((p[2]) & 0x1F);
775 if (BSD_VERSION(p[2])((p[2]) >> 5) != BSD_CURRENT_VERSION1
776 || nb > ao->bsd_bits || nb < BSD_MIN_BITS9) {
777 newret = CONFNAK3;
778 if (!dont_nak) {
779 p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, ao->bsd_bits)(((1) << 5) | (ao->bsd_bits));
780 /* fall through to test this #bits below */
781 } else
782 break;
783 }
784
785 /*
786 * Check whether we can do BSD-Compress with the code
787 * size they want. If the code size is too big, reduce
788 * it until the kernel can cope and nak with that.
789 * We only check this for the first option.
790 */
791 if (p == p0) {
792 for (;;) {
793 res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS3, 1);
794 if (res > 0)
795 break;
796 if (res < 0 || nb == BSD_MIN_BITS9 || dont_nak) {
797 newret = CONFREJ4;
798 p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION,(((1) << 5) | (ho->bsd_bits))
799 ho->bsd_bits)(((1) << 5) | (ho->bsd_bits));
800 break;
801 }
802 newret = CONFNAK3;
803 --nb;
804 p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, nb)(((1) << 5) | (nb));
805 }
806 }
807 break;
808
809 case CI_PREDICTOR_11:
810 if (!ao->predictor_1 || clen != CILEN_PREDICTOR_12) {
811 newret = CONFREJ4;
812 break;
813 }
814
815 ho->predictor_1 = 1;
816 if (p == p0
817 && ccp_test(f->unit, p, CILEN_PREDICTOR_12, 1) <= 0) {
818 newret = CONFREJ4;
819 }
820 break;
821
822 case CI_PREDICTOR_22:
823 if (!ao->predictor_2 || clen != CILEN_PREDICTOR_22) {
824 newret = CONFREJ4;
825 break;
826 }
827
828 ho->predictor_2 = 1;
829 if (p == p0
830 && ccp_test(f->unit, p, CILEN_PREDICTOR_22, 1) <= 0) {
831 newret = CONFREJ4;
832 }
833 break;
834
835 default:
836 newret = CONFREJ4;
837 }
838 }
839
840 if (newret == CONFNAK3 && dont_nak)
841 newret = CONFREJ4;
842 if (!(newret == CONFACK2 || (newret == CONFNAK3 && ret == CONFREJ4))) {
843 /* we're returning this option */
844 if (newret == CONFREJ4 && ret == CONFNAK3)
845 retp = p0;
846 ret = newret;
847 if (p != retp)
848 BCOPY(p, retp, clen)memcpy(retp, p, clen);
849 retp += clen;
850 }
851
852 p += clen;
853 len -= clen;
854 }
855
856 if (ret != CONFACK2) {
857 if (ret == CONFREJ4 && *lenp == retp - p0)
858 all_rejected[f->unit] = 1;
859 else
860 *lenp = retp - p0;
861 }
862 return ret;
863}
864
865/*
866 * Make a string name for a compression method (or 2).
867 */
868static char *
869method_name(opt, opt2)
870 ccp_options *opt, *opt2;
871{
872 static char result[64];
873
874 if (!ANY_COMPRESS(*opt)((*opt).deflate || (*opt).bsd_compress || (*opt).predictor_1 ||
(*opt).predictor_2)
)
875 return "(none)";
876 switch (opt->method) {
877 case CI_DEFLATE26:
878 case CI_DEFLATE_DRAFT24:
879 if (opt2 != NULL((void *)0) && opt2->deflate_size != opt->deflate_size)
880 snprintf(result, sizeof result, "Deflate%s (%d/%d)",
881 (opt->method == CI_DEFLATE_DRAFT24? "(old#)": ""),
882 opt->deflate_size, opt2->deflate_size);
883 else
884 snprintf(result, sizeof result, "Deflate%s (%d)",
885 (opt->method == CI_DEFLATE_DRAFT24? "(old#)": ""),
886 opt->deflate_size);
887 break;
888 case CI_BSD_COMPRESS21:
889 if (opt2 != NULL((void *)0) && opt2->bsd_bits != opt->bsd_bits)
890 snprintf(result, sizeof result,
891 "BSD-Compress (%d/%d)", opt->bsd_bits,
892 opt2->bsd_bits);
893 else
894 snprintf(result, sizeof result, "BSD-Compress (%d)", opt->bsd_bits);
895 break;
896 case CI_PREDICTOR_11:
897 return "Predictor 1";
898 case CI_PREDICTOR_22:
899 return "Predictor 2";
900 default:
901 snprintf(result, sizeof result, "Method %d", opt->method);
902 }
903 return result;
904}
905
906/*
907 * CCP has come up - inform the kernel driver and log a message.
908 */
909static void
910ccp_up(f)
911 fsm *f;
912{
913 ccp_options *go = &ccp_gotoptions[f->unit];
914 ccp_options *ho = &ccp_hisoptions[f->unit];
915 char method1[64];
916
917 ccp_flags_set(f->unit, 1, 1);
918 if (ANY_COMPRESS(*go)((*go).deflate || (*go).bsd_compress || (*go).predictor_1 || (
*go).predictor_2)
) {
919 if (ANY_COMPRESS(*ho)((*ho).deflate || (*ho).bsd_compress || (*ho).predictor_1 || (
*ho).predictor_2)
) {
920 if (go->method == ho->method) {
921 syslog(LOG_NOTICE5, "%s compression enabled",
922 method_name(go, ho));
923 } else {
924 strncpy(method1, method_name(go, NULL((void *)0)), sizeof method1);
925 syslog(LOG_NOTICE5, "%s / %s compression enabled",
926 method1, method_name(ho, NULL((void *)0)));
927 }
928 } else
929 syslog(LOG_NOTICE5, "%s receive compression enabled",
930 method_name(go, NULL((void *)0)));
931 } else if (ANY_COMPRESS(*ho)((*ho).deflate || (*ho).bsd_compress || (*ho).predictor_1 || (
*ho).predictor_2)
)
932 syslog(LOG_NOTICE5, "%s transmit compression enabled",
933 method_name(ho, NULL((void *)0)));
934}
935
936/*
937 * CCP has gone down - inform the kernel driver.
938 */
939static void
940ccp_down(f)
941 fsm *f;
942{
943 if (ccp_localstate[f->unit] & RACK_PENDING1)
944 UNTIMEOUT(ccp_rack_timeout, f)untimeout((ccp_rack_timeout), (f));
945 ccp_localstate[f->unit] = 0;
946 ccp_flags_set(f->unit, 1, 0);
947}
948
949/*
950 * Print the contents of a CCP packet.
951 */
952static char *ccp_codenames[] = {
953 "ConfReq", "ConfAck", "ConfNak", "ConfRej",
954 "TermReq", "TermAck", "CodeRej",
955 NULL((void *)0), NULL((void *)0), NULL((void *)0), NULL((void *)0), NULL((void *)0), NULL((void *)0),
956 "ResetReq", "ResetAck",
957};
958
959static int
960ccp_printpkt(p, plen, printer, arg)
961 u_char *p;
962 int plen;
963 void (*printer)(void *, char *, ...);
964 void *arg;
965{
966 u_char *p0, *optend;
967 int code, id, len;
968 int optlen;
969
970 p0 = p;
971 if (plen < HEADERLEN(sizeof (u_char) + sizeof (u_char) + sizeof (u_short)))
972 return 0;
973 code = p[0];
974 id = p[1];
975 len = (p[2] << 8) + p[3];
976 if (len < HEADERLEN(sizeof (u_char) + sizeof (u_char) + sizeof (u_short)) || len > plen)
977 return 0;
978
979 if (code >= 1 && code <= sizeof(ccp_codenames) / sizeof(char *)
980 && ccp_codenames[code-1] != NULL((void *)0))
981 printer(arg, " %s", ccp_codenames[code-1]);
982 else
983 printer(arg, " code=0x%x", code);
984 printer(arg, " id=0x%x", id);
985 len -= HEADERLEN(sizeof (u_char) + sizeof (u_char) + sizeof (u_short));
986 p += HEADERLEN(sizeof (u_char) + sizeof (u_char) + sizeof (u_short));
987
988 switch (code) {
989 case CONFREQ1:
990 case CONFACK2:
991 case CONFNAK3:
992 case CONFREJ4:
993 /* print list of possible compression methods */
994 while (len >= 2) {
995 code = p[0];
996 optlen = p[1];
997 if (optlen < 2 || optlen > len)
998 break;
999 printer(arg, " <");
1000 len -= optlen;
1001 optend = p + optlen;
1002 switch (code) {
1003 case CI_DEFLATE26:
1004 case CI_DEFLATE_DRAFT24:
1005 if (optlen >= CILEN_DEFLATE4) {
1006 printer(arg, "deflate%s %d",
1007 (code == CI_DEFLATE_DRAFT24? "(old#)": ""),
1008 DEFLATE_SIZE(p[2])(((p[2]) >> 4) + 8));
1009 if (DEFLATE_METHOD(p[2])((p[2]) & 0x0F) != DEFLATE_METHOD_VAL8)
1010 printer(arg, " method %d", DEFLATE_METHOD(p[2])((p[2]) & 0x0F));
1011 if (p[3] != DEFLATE_CHK_SEQUENCE0)
1012 printer(arg, " check %d", p[3]);
1013 p += CILEN_DEFLATE4;
1014 }
1015 break;
1016 case CI_BSD_COMPRESS21:
1017 if (optlen >= CILEN_BSD_COMPRESS3) {
1018 printer(arg, "bsd v%d %d", BSD_VERSION(p[2])((p[2]) >> 5),
1019 BSD_NBITS(p[2])((p[2]) & 0x1F));
1020 p += CILEN_BSD_COMPRESS3;
1021 }
1022 break;
1023 case CI_PREDICTOR_11:
1024 if (optlen >= CILEN_PREDICTOR_12) {
1025 printer(arg, "predictor 1");
1026 p += CILEN_PREDICTOR_12;
1027 }
1028 break;
1029 case CI_PREDICTOR_22:
1030 if (optlen >= CILEN_PREDICTOR_22) {
1031 printer(arg, "predictor 2");
1032 p += CILEN_PREDICTOR_22;
1033 }
1034 break;
1035 }
1036 while (p < optend)
1037 printer(arg, " %.2x", *p++);
1038 printer(arg, ">");
1039 }
1040 break;
1041
1042 case TERMACK6:
1043 case TERMREQ5:
1044 if (len > 0 && *p >= ' ' && *p < 0x7f) {
1045 print_string(p, len, printer, arg);
1046 p += len;
1047 len = 0;
1048 }
1049 break;
1050 }
1051
1052 /* dump out the rest of the packet in hex */
1053 while (--len >= 0)
1054 printer(arg, " %.2x", *p++);
1055
1056 return p - p0;
1057}
1058
1059/*
1060 * We have received a packet that the decompressor failed to
1061 * decompress. Here we would expect to issue a reset-request, but
1062 * Motorola has a patent on resetting the compressor as a result of
1063 * detecting an error in the decompressed data after decompression.
1064 * (See US patent 5,130,993; international patent publication number
1065 * WO 91/10289; Australian patent 73296/91.)
1066 *
1067 * So we ask the kernel whether the error was detected after
1068 * decompression; if it was, we take CCP down, thus disabling
1069 * compression :-(, otherwise we issue the reset-request.
1070 */
1071static void
1072ccp_datainput(unit, pkt, len)
1073 int unit;
1074 u_char *pkt;
1075 int len;
1076{
1077 fsm *f;
1078
1079 f = &ccp_fsm[unit];
1080 if (f->state == OPENED9) {
1081 if (ccp_fatal_error(unit)) {
1082 /*
1083 * Disable compression by taking CCP down.
1084 */
1085 syslog(LOG_ERR3, "Lost compression sync: disabling compression");
1086 ccp_close(unit, "Lost compression sync");
1087 } else {
1088 /*
1089 * Send a reset-request to reset the peer's compressor.
1090 * We don't do that if we are still waiting for an
1091 * acknowledgement to a previous reset-request.
1092 */
1093 if (!(ccp_localstate[f->unit] & RACK_PENDING1)) {
1094 fsm_sdata(f, CCP_RESETREQ14, f->reqid = ++f->id, NULL((void *)0), 0);
1095 TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT)timeout((ccp_rack_timeout), (f), (1));
1096 ccp_localstate[f->unit] |= RACK_PENDING1;
1097 } else
1098 ccp_localstate[f->unit] |= RREQ_REPEAT2;
1099 }
1100 }
1101}
1102
1103/*
1104 * Timeout waiting for reset-ack.
1105 */
1106static void
1107ccp_rack_timeout(arg)
1108 void *arg;
1109{
1110 fsm *f = arg;
1111
1112 if (f->state == OPENED9 && ccp_localstate[f->unit] & RREQ_REPEAT2) {
1113 fsm_sdata(f, CCP_RESETREQ14, f->reqid, NULL((void *)0), 0);
1114 TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT)timeout((ccp_rack_timeout), (f), (1));
1115 ccp_localstate[f->unit] &= ~RREQ_REPEAT2;
1116 } else
1117 ccp_localstate[f->unit] &= ~RACK_PENDING1;
1118}
1119