Bug Summary

File:src/usr.sbin/pppd/fsm.c
Warning:line 809, column 2
Null pointer passed as 2nd argument to memory copy function

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 fsm.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/fsm.c
1/* $OpenBSD: fsm.c,v 1.8 2009/10/27 23:59:53 deraadt Exp $ */
2
3/*
4 * fsm.c - {Link, IP} Control Protocol Finite State Machine.
5 *
6 * Copyright (c) 1984-2000 Carnegie Mellon University. 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 "Carnegie Mellon University" must not be used to
21 * endorse or promote products derived from this software without
22 * prior written permission. For permission or any legal
23 * details, please contact
24 * Office of Technology Transfer
25 * Carnegie Mellon University
26 * 5000 Forbes Avenue
27 * Pittsburgh, PA 15213-3890
28 * (412) 268-4387, fax: (412) 268-7395
29 * tech-transfer@andrew.cmu.edu
30 *
31 * 4. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by Computing Services
34 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
35 *
36 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
37 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
38 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
39 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
40 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
41 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
42 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
43 */
44
45/*
46 * TODO:
47 * Randomize fsm id on link/init.
48 * Deal with variable outgoing MTU.
49 */
50
51#include <stdio.h>
52#include <string.h>
53#include <sys/types.h>
54#include <syslog.h>
55
56#include "pppd.h"
57#include "fsm.h"
58
59static void fsm_timeout(void *);
60static void fsm_rconfreq(fsm *, int, u_char *, int);
61static void fsm_rconfack(fsm *, int, u_char *, int);
62static void fsm_rconfnakrej(fsm *, int, int, u_char *, int);
63static void fsm_rtermreq(fsm *, int, u_char *, int);
64static void fsm_rtermack(fsm *);
65static void fsm_rcoderej(fsm *, u_char *, int);
66static void fsm_sconfreq(fsm *, int);
67
68#define PROTO_NAME(f)((f)->callbacks->proto_name) ((f)->callbacks->proto_name)
69
70int peer_mru[NUM_PPP1];
71
72
73/*
74 * fsm_init - Initialize fsm.
75 *
76 * Initialize fsm state.
77 */
78void
79fsm_init(f)
80 fsm *f;
81{
82 f->state = INITIAL0;
83 f->flags = 0;
84 f->id = 0; /* XXX Start with random id? */
85 f->timeouttime = DEFTIMEOUT3;
86 f->maxconfreqtransmits = DEFMAXCONFREQS10;
87 f->maxtermtransmits = DEFMAXTERMREQS2;
88 f->maxnakloops = DEFMAXNAKLOOPS5;
89 f->term_reason_len = 0;
90}
91
92
93/*
94 * fsm_lowerup - The lower layer is up.
95 */
96void
97fsm_lowerup(f)
98 fsm *f;
99{
100 switch( f->state ){
101 case INITIAL0:
102 f->state = CLOSED2;
103 break;
104
105 case STARTING1:
106 if( f->flags & OPT_SILENT4 )
107 f->state = STOPPED3;
108 else {
109 /* Send an initial configure-request */
110 fsm_sconfreq(f, 0);
111 f->state = REQSENT6;
112 }
113 break;
114
115 default:
116 FSMDEBUG((LOG_INFO, "%s: Up event in state %d!",
117 PROTO_NAME(f), f->state));
118 }
119}
120
121
122/*
123 * fsm_lowerdown - The lower layer is down.
124 *
125 * Cancel all timeouts and inform upper layers.
126 */
127void
128fsm_lowerdown(f)
129 fsm *f;
130{
131 switch( f->state ){
132 case CLOSED2:
133 f->state = INITIAL0;
134 break;
135
136 case STOPPED3:
137 f->state = STARTING1;
138 if( f->callbacks->starting )
139 (*f->callbacks->starting)(f);
140 break;
141
142 case CLOSING4:
143 f->state = INITIAL0;
144 UNTIMEOUT(fsm_timeout, f)untimeout((fsm_timeout), (f)); /* Cancel timeout */
145 break;
146
147 case STOPPING5:
148 case REQSENT6:
149 case ACKRCVD7:
150 case ACKSENT8:
151 f->state = STARTING1;
152 UNTIMEOUT(fsm_timeout, f)untimeout((fsm_timeout), (f)); /* Cancel timeout */
153 break;
154
155 case OPENED9:
156 if( f->callbacks->down )
157 (*f->callbacks->down)(f);
158 f->state = STARTING1;
159 break;
160
161 default:
162 FSMDEBUG((LOG_INFO, "%s: Down event in state %d!",
163 PROTO_NAME(f), f->state));
164 }
165}
166
167
168/*
169 * fsm_open - Link is allowed to come up.
170 */
171void
172fsm_open(f)
173 fsm *f;
174{
175 switch( f->state ){
176 case INITIAL0:
177 f->state = STARTING1;
178 if( f->callbacks->starting )
179 (*f->callbacks->starting)(f);
180 break;
181
182 case CLOSED2:
183 if( f->flags & OPT_SILENT4 )
184 f->state = STOPPED3;
185 else {
186 /* Send an initial configure-request */
187 fsm_sconfreq(f, 0);
188 f->state = REQSENT6;
189 }
190 break;
191
192 case CLOSING4:
193 f->state = STOPPING5;
194 /* fall through */
195 case STOPPED3:
196 case OPENED9:
197 if( f->flags & OPT_RESTART2 ){
198 fsm_lowerdown(f);
199 fsm_lowerup(f);
200 }
201 break;
202 }
203}
204
205
206/*
207 * fsm_close - Start closing connection.
208 *
209 * Cancel timeouts and either initiate close or possibly go directly to
210 * the CLOSED state.
211 */
212void
213fsm_close(f, reason)
214 fsm *f;
215 char *reason;
216{
217 f->term_reason = reason;
1
Value assigned to field 'term_reason'
218 f->term_reason_len = (reason == NULL((void *)0)? 0: strlen(reason));
2
Assuming 'reason' is equal to NULL
3
'?' condition is true
219 switch( f->state ){
4
Control jumps to 'case 9:' at line 233
220 case STARTING1:
221 f->state = INITIAL0;
222 break;
223 case STOPPED3:
224 f->state = CLOSED2;
225 break;
226 case STOPPING5:
227 f->state = CLOSING4;
228 break;
229
230 case REQSENT6:
231 case ACKRCVD7:
232 case ACKSENT8:
233 case OPENED9:
234 if( f->state
4.1
Field 'state' is equal to OPENED
!= OPENED9 )
5
Taking false branch
235 UNTIMEOUT(fsm_timeout, f)untimeout((fsm_timeout), (f)); /* Cancel timeout */
236 else if( f->callbacks->down )
6
Assuming field 'down' is null
7
Taking false branch
237 (*f->callbacks->down)(f); /* Inform upper layers we're down */
238
239 /* Init restart counter, send Terminate-Request */
240 f->retransmits = f->maxtermtransmits;
241 fsm_sdata(f, TERMREQ5, f->reqid = ++f->id,
9
Calling 'fsm_sdata'
242 (u_char *) f->term_reason, f->term_reason_len);
8
Passing null pointer value via 4th parameter 'data'
243 TIMEOUT(fsm_timeout, f, f->timeouttime)timeout((fsm_timeout), (f), (f->timeouttime));
244 --f->retransmits;
245
246 f->state = CLOSING4;
247 break;
248 }
249}
250
251
252/*
253 * fsm_timeout - Timeout expired.
254 */
255static void
256fsm_timeout(arg)
257 void *arg;
258{
259 fsm *f = (fsm *) arg;
260
261 switch (f->state) {
262 case CLOSING4:
263 case STOPPING5:
264 if( f->retransmits <= 0 ){
265 /*
266 * We've waited for an ack long enough. Peer probably heard us.
267 */
268 f->state = (f->state == CLOSING4)? CLOSED2: STOPPED3;
269 if( f->callbacks->finished )
270 (*f->callbacks->finished)(f);
271 } else {
272 /* Send Terminate-Request */
273 fsm_sdata(f, TERMREQ5, f->reqid = ++f->id,
274 (u_char *) f->term_reason, f->term_reason_len);
275 TIMEOUT(fsm_timeout, f, f->timeouttime)timeout((fsm_timeout), (f), (f->timeouttime));
276 --f->retransmits;
277 }
278 break;
279
280 case REQSENT6:
281 case ACKRCVD7:
282 case ACKSENT8:
283 if (f->retransmits <= 0) {
284 syslog(LOG_WARNING4, "%s: timeout sending Config-Requests",
285 PROTO_NAME(f)((f)->callbacks->proto_name));
286 f->state = STOPPED3;
287 if( (f->flags & OPT_PASSIVE1) == 0 && f->callbacks->finished )
288 (*f->callbacks->finished)(f);
289
290 } else {
291 /* Retransmit the configure-request */
292 if (f->callbacks->retransmit)
293 (*f->callbacks->retransmit)(f);
294 fsm_sconfreq(f, 1); /* Re-send Configure-Request */
295 if( f->state == ACKRCVD7 )
296 f->state = REQSENT6;
297 }
298 break;
299
300 default:
301 FSMDEBUG((LOG_INFO, "%s: Timeout event in state %d!",
302 PROTO_NAME(f), f->state));
303 }
304}
305
306
307/*
308 * fsm_input - Input packet.
309 */
310void
311fsm_input(f, inpacket, l)
312 fsm *f;
313 u_char *inpacket;
314 int l;
315{
316 u_char *inp;
317 u_char code, id;
318 int len;
319
320 /*
321 * Parse header (code, id and length).
322 * If packet too short, drop it.
323 */
324 inp = inpacket;
325 if (l < HEADERLEN(sizeof (u_char) + sizeof (u_char) + sizeof (u_short))) {
326 FSMDEBUG((LOG_WARNING, "fsm_input(%x): Rcvd short header.",
327 f->protocol));
328 return;
329 }
330 GETCHAR(code, inp){ (code) = *(inp)++; };
331 GETCHAR(id, inp){ (id) = *(inp)++; };
332 GETSHORT(len, inp){ (len) = *(inp)++ << 8; (len) |= *(inp)++; };
333 if (len < HEADERLEN(sizeof (u_char) + sizeof (u_char) + sizeof (u_short))) {
334 FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd illegal length.",
335 f->protocol));
336 return;
337 }
338 if (len > l) {
339 FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd short packet.",
340 f->protocol));
341 return;
342 }
343 len -= HEADERLEN(sizeof (u_char) + sizeof (u_char) + sizeof (u_short)); /* subtract header length */
344
345 if( f->state == INITIAL0 || f->state == STARTING1 ){
346 FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd packet in state %d.",
347 f->protocol, f->state));
348 return;
349 }
350
351 /*
352 * Action depends on code.
353 */
354 switch (code) {
355 case CONFREQ1:
356 fsm_rconfreq(f, id, inp, len);
357 break;
358
359 case CONFACK2:
360 fsm_rconfack(f, id, inp, len);
361 break;
362
363 case CONFNAK3:
364 case CONFREJ4:
365 fsm_rconfnakrej(f, code, id, inp, len);
366 break;
367
368 case TERMREQ5:
369 fsm_rtermreq(f, id, inp, len);
370 break;
371
372 case TERMACK6:
373 fsm_rtermack(f);
374 break;
375
376 case CODEREJ7:
377 fsm_rcoderej(f, inp, len);
378 break;
379
380 default:
381 if( !f->callbacks->extcode
382 || !(*f->callbacks->extcode)(f, code, id, inp, len) )
383 fsm_sdata(f, CODEREJ7, ++f->id, inpacket, len + HEADERLEN(sizeof (u_char) + sizeof (u_char) + sizeof (u_short)));
384 break;
385 }
386}
387
388
389/*
390 * fsm_rconfreq - Receive Configure-Request.
391 */
392static void
393fsm_rconfreq(f, id, inp, len)
394 fsm *f;
395 u_char id;
396 u_char *inp;
397 int len;
398{
399 int code, reject_if_disagree;
400
401 FSMDEBUG((LOG_INFO, "fsm_rconfreq(%s): Rcvd id %d.", PROTO_NAME(f), id));
402 switch( f->state ){
403 case CLOSED2:
404 /* Go away, we're closed */
405 fsm_sdata(f, TERMACK6, id, NULL((void *)0), 0);
406 return;
407 case CLOSING4:
408 case STOPPING5:
409 return;
410
411 case OPENED9:
412 /* Go down and restart negotiation */
413 if( f->callbacks->down )
414 (*f->callbacks->down)(f); /* Inform upper layers */
415 fsm_sconfreq(f, 0); /* Send initial Configure-Request */
416 break;
417
418 case STOPPED3:
419 /* Negotiation started by our peer */
420 fsm_sconfreq(f, 0); /* Send initial Configure-Request */
421 f->state = REQSENT6;
422 break;
423 }
424
425 /*
426 * Pass the requested configuration options
427 * to protocol-specific code for checking.
428 */
429 if (f->callbacks->reqci){ /* Check CI */
430 reject_if_disagree = (f->nakloops >= f->maxnakloops);
431 code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree);
432 } else if (len)
433 code = CONFREJ4; /* Reject all CI */
434 else
435 code = CONFACK2;
436
437 /* send the Ack, Nak or Rej to the peer */
438 fsm_sdata(f, code, id, inp, len);
439
440 if (code == CONFACK2) {
441 if (f->state == ACKRCVD7) {
442 UNTIMEOUT(fsm_timeout, f)untimeout((fsm_timeout), (f)); /* Cancel timeout */
443 f->state = OPENED9;
444 if (f->callbacks->up)
445 (*f->callbacks->up)(f); /* Inform upper layers */
446 } else
447 f->state = ACKSENT8;
448 f->nakloops = 0;
449
450 } else {
451 /* we sent CONFACK or CONFREJ */
452 if (f->state != ACKRCVD7)
453 f->state = REQSENT6;
454 if( code == CONFNAK3 )
455 ++f->nakloops;
456 }
457}
458
459
460/*
461 * fsm_rconfack - Receive Configure-Ack.
462 */
463static void
464fsm_rconfack(f, id, inp, len)
465 fsm *f;
466 int id;
467 u_char *inp;
468 int len;
469{
470 FSMDEBUG((LOG_INFO, "fsm_rconfack(%s): Rcvd id %d.",
471 PROTO_NAME(f), id));
472
473 if (id != f->reqid || f->seen_ack) /* Expected id? */
474 return; /* Nope, toss... */
475 if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len):
476 (len == 0)) ){
477 /* Ack is bad - ignore it */
478 log_packet(inp, len, "Received bad configure-ack: ", LOG_ERR3);
479 FSMDEBUG((LOG_INFO, "%s: received bad Ack (length %d)",
480 PROTO_NAME(f), len));
481 return;
482 }
483 f->seen_ack = 1;
484
485 switch (f->state) {
486 case CLOSED2:
487 case STOPPED3:
488 fsm_sdata(f, TERMACK6, id, NULL((void *)0), 0);
489 break;
490
491 case REQSENT6:
492 f->state = ACKRCVD7;
493 f->retransmits = f->maxconfreqtransmits;
494 break;
495
496 case ACKRCVD7:
497 /* Huh? an extra valid Ack? oh well... */
498 UNTIMEOUT(fsm_timeout, f)untimeout((fsm_timeout), (f)); /* Cancel timeout */
499 fsm_sconfreq(f, 0);
500 f->state = REQSENT6;
501 break;
502
503 case ACKSENT8:
504 UNTIMEOUT(fsm_timeout, f)untimeout((fsm_timeout), (f)); /* Cancel timeout */
505 f->state = OPENED9;
506 f->retransmits = f->maxconfreqtransmits;
507 if (f->callbacks->up)
508 (*f->callbacks->up)(f); /* Inform upper layers */
509 break;
510
511 case OPENED9:
512 /* Go down and restart negotiation */
513 if (f->callbacks->down)
514 (*f->callbacks->down)(f); /* Inform upper layers */
515 fsm_sconfreq(f, 0); /* Send initial Configure-Request */
516 f->state = REQSENT6;
517 break;
518 }
519}
520
521
522/*
523 * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
524 */
525static void
526fsm_rconfnakrej(f, code, id, inp, len)
527 fsm *f;
528 int code, id;
529 u_char *inp;
530 int len;
531{
532 int (*proc)(fsm *, u_char *, int);
533 int ret;
534
535 FSMDEBUG((LOG_INFO, "fsm_rconfnakrej(%s): Rcvd id %d.",
536 PROTO_NAME(f), id));
537
538 if (id != f->reqid || f->seen_ack) /* Expected id? */
539 return; /* Nope, toss... */
540 proc = (code == CONFNAK3)? f->callbacks->nakci: f->callbacks->rejci;
541 if (!proc || !(ret = proc(f, inp, len))) {
542 /* Nak/reject is bad - ignore it */
543 log_packet(inp, len, "Received bad configure-nak/rej: ", LOG_ERR3);
544 FSMDEBUG((LOG_INFO, "%s: received bad %s (length %d)",
545 PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));
546 return;
547 }
548 f->seen_ack = 1;
549
550 switch (f->state) {
551 case CLOSED2:
552 case STOPPED3:
553 fsm_sdata(f, TERMACK6, id, NULL((void *)0), 0);
554 break;
555
556 case REQSENT6:
557 case ACKSENT8:
558 /* They didn't agree to what we wanted - try another request */
559 UNTIMEOUT(fsm_timeout, f)untimeout((fsm_timeout), (f)); /* Cancel timeout */
560 if (ret < 0)
561 f->state = STOPPED3; /* kludge for stopping CCP */
562 else
563 fsm_sconfreq(f, 0); /* Send Configure-Request */
564 break;
565
566 case ACKRCVD7:
567 /* Got a Nak/reject when we had already had an Ack?? oh well... */
568 UNTIMEOUT(fsm_timeout, f)untimeout((fsm_timeout), (f)); /* Cancel timeout */
569 fsm_sconfreq(f, 0);
570 f->state = REQSENT6;
571 break;
572
573 case OPENED9:
574 /* Go down and restart negotiation */
575 if (f->callbacks->down)
576 (*f->callbacks->down)(f); /* Inform upper layers */
577 fsm_sconfreq(f, 0); /* Send initial Configure-Request */
578 f->state = REQSENT6;
579 break;
580 }
581}
582
583
584/*
585 * fsm_rtermreq - Receive Terminate-Req.
586 */
587static void
588fsm_rtermreq(f, id, p, len)
589 fsm *f;
590 int id;
591 u_char *p;
592 int len;
593{
594 char str[80];
595
596 FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d.",
597 PROTO_NAME(f), id));
598
599 switch (f->state) {
600 case ACKRCVD7:
601 case ACKSENT8:
602 f->state = REQSENT6; /* Start over but keep trying */
603 break;
604
605 case OPENED9:
606 if (len > 0) {
607 fmtmsg(str, sizeof(str), "%0.*v", len, p);
608 syslog(LOG_INFO6, "%s terminated by peer (%s)", PROTO_NAME(f)((f)->callbacks->proto_name), str);
609 } else
610 syslog(LOG_INFO6, "%s terminated by peer", PROTO_NAME(f)((f)->callbacks->proto_name));
611 if (f->callbacks->down)
612 (*f->callbacks->down)(f); /* Inform upper layers */
613 f->retransmits = 0;
614 f->state = STOPPING5;
615 TIMEOUT(fsm_timeout, f, f->timeouttime)timeout((fsm_timeout), (f), (f->timeouttime));
616 break;
617 }
618
619 fsm_sdata(f, TERMACK6, id, NULL((void *)0), 0);
620}
621
622
623/*
624 * fsm_rtermack - Receive Terminate-Ack.
625 */
626static void
627fsm_rtermack(f)
628 fsm *f;
629{
630 FSMDEBUG((LOG_INFO, "fsm_rtermack(%s).", PROTO_NAME(f)));
631
632 switch (f->state) {
633 case CLOSING4:
634 UNTIMEOUT(fsm_timeout, f)untimeout((fsm_timeout), (f));
635 f->state = CLOSED2;
636 if( f->callbacks->finished )
637 (*f->callbacks->finished)(f);
638 break;
639 case STOPPING5:
640 UNTIMEOUT(fsm_timeout, f)untimeout((fsm_timeout), (f));
641 f->state = STOPPED3;
642 if( f->callbacks->finished )
643 (*f->callbacks->finished)(f);
644 break;
645
646 case ACKRCVD7:
647 f->state = REQSENT6;
648 break;
649
650 case OPENED9:
651 if (f->callbacks->down)
652 (*f->callbacks->down)(f); /* Inform upper layers */
653 fsm_sconfreq(f, 0);
654 break;
655 }
656}
657
658
659/*
660 * fsm_rcoderej - Receive an Code-Reject.
661 */
662static void
663fsm_rcoderej(f, inp, len)
664 fsm *f;
665 u_char *inp;
666 int len;
667{
668 u_char code, id;
669
670 FSMDEBUG((LOG_INFO, "fsm_rcoderej(%s).", PROTO_NAME(f)));
671
672 if (len < HEADERLEN(sizeof (u_char) + sizeof (u_char) + sizeof (u_short))) {
673 FSMDEBUG((LOG_INFO, "fsm_rcoderej: Rcvd short Code-Reject packet!"));
674 return;
675 }
676 GETCHAR(code, inp){ (code) = *(inp)++; };
677 GETCHAR(id, inp){ (id) = *(inp)++; };
678 syslog(LOG_WARNING4, "%s: Rcvd Code-Reject for code %d, id %d",
679 PROTO_NAME(f)((f)->callbacks->proto_name), code, id);
680
681 if( f->state == ACKRCVD7 )
682 f->state = REQSENT6;
683}
684
685
686/*
687 * fsm_protreject - Peer doesn't speak this protocol.
688 *
689 * Treat this as a catastrophic error (RXJ-).
690 */
691void
692fsm_protreject(f)
693 fsm *f;
694{
695 switch( f->state ){
696 case CLOSING4:
697 UNTIMEOUT(fsm_timeout, f)untimeout((fsm_timeout), (f)); /* Cancel timeout */
698 /* fall through */
699 case CLOSED2:
700 f->state = CLOSED2;
701 if( f->callbacks->finished )
702 (*f->callbacks->finished)(f);
703 break;
704
705 case STOPPING5:
706 case REQSENT6:
707 case ACKRCVD7:
708 case ACKSENT8:
709 UNTIMEOUT(fsm_timeout, f)untimeout((fsm_timeout), (f)); /* Cancel timeout */
710 /* fall through */
711 case STOPPED3:
712 f->state = STOPPED3;
713 if( f->callbacks->finished )
714 (*f->callbacks->finished)(f);
715 break;
716
717 case OPENED9:
718 if( f->callbacks->down )
719 (*f->callbacks->down)(f);
720
721 /* Init restart counter, send Terminate-Request */
722 f->retransmits = f->maxtermtransmits;
723 fsm_sdata(f, TERMREQ5, f->reqid = ++f->id,
724 (u_char *) f->term_reason, f->term_reason_len);
725 TIMEOUT(fsm_timeout, f, f->timeouttime)timeout((fsm_timeout), (f), (f->timeouttime));
726 --f->retransmits;
727
728 f->state = STOPPING5;
729 break;
730
731 default:
732 FSMDEBUG((LOG_INFO, "%s: Protocol-reject event in state %d!",
733 PROTO_NAME(f), f->state));
734 }
735}
736
737
738/*
739 * fsm_sconfreq - Send a Configure-Request.
740 */
741static void
742fsm_sconfreq(f, retransmit)
743 fsm *f;
744 int retransmit;
745{
746 u_char *outp;
747 int cilen;
748
749 if( f->state != REQSENT6 && f->state != ACKRCVD7 && f->state != ACKSENT8 ){
750 /* Not currently negotiating - reset options */
751 if( f->callbacks->resetci )
752 (*f->callbacks->resetci)(f);
753 f->nakloops = 0;
754 }
755
756 if( !retransmit ){
757 /* New request - reset retransmission counter, use new ID */
758 f->retransmits = f->maxconfreqtransmits;
759 f->reqid = ++f->id;
760 }
761
762 f->seen_ack = 0;
763
764 /*
765 * Make up the request packet
766 */
767 outp = outpacket_buf + PPP_HDRLEN4 + HEADERLEN(sizeof (u_char) + sizeof (u_char) + sizeof (u_short));
768 if( f->callbacks->cilen && f->callbacks->addci ){
769 cilen = (*f->callbacks->cilen)(f);
770 if( cilen > peer_mru[f->unit] - HEADERLEN(sizeof (u_char) + sizeof (u_char) + sizeof (u_short)) )
771 cilen = peer_mru[f->unit] - HEADERLEN(sizeof (u_char) + sizeof (u_char) + sizeof (u_short));
772 if (f->callbacks->addci)
773 (*f->callbacks->addci)(f, outp, &cilen);
774 } else
775 cilen = 0;
776
777 /* send the request to our peer */
778 fsm_sdata(f, CONFREQ1, f->reqid, outp, cilen);
779
780 /* start the retransmit timer */
781 --f->retransmits;
782 TIMEOUT(fsm_timeout, f, f->timeouttime)timeout((fsm_timeout), (f), (f->timeouttime));
783
784 FSMDEBUG((LOG_INFO, "%s: sending Configure-Request, id %d",
785 PROTO_NAME(f), f->reqid));
786}
787
788
789/*
790 * fsm_sdata - Send some data.
791 *
792 * Used for all packets sent to our peer by this module.
793 */
794void
795fsm_sdata(f, code, id, data, datalen)
796 fsm *f;
797 u_char code, id;
798 u_char *data;
799 int datalen;
800{
801 u_char *outp;
802 int outlen;
803
804 /* Adjust length to be smaller than MTU */
805 outp = outpacket_buf;
806 if (datalen > peer_mru[f->unit] - HEADERLEN(sizeof (u_char) + sizeof (u_char) + sizeof (u_short)))
10
Assuming the condition is true
11
Taking true branch
807 datalen = peer_mru[f->unit] - HEADERLEN(sizeof (u_char) + sizeof (u_char) + sizeof (u_short));
808 if (datalen && data != outp + PPP_HDRLEN4 + HEADERLEN(sizeof (u_char) + sizeof (u_char) + sizeof (u_short)))
12
Assuming 'datalen' is not equal to 0
13
Taking true branch
809 BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen)memcpy(outp + 4 + (sizeof (u_char) + sizeof (u_char) + sizeof
(u_short)), data, datalen)
;
14
Null pointer passed as 2nd argument to memory copy function
810 outlen = datalen + HEADERLEN(sizeof (u_char) + sizeof (u_char) + sizeof (u_short));
811 MAKEHEADER(outp, f->protocol){ { *(outp)++ = (u_char) (0xff); }; { *(outp)++ = (u_char) (0x03
); }; { *(outp)++ = (u_char) ((f->protocol) >> 8); *
(outp)++ = (u_char) (f->protocol); }; }
;
812 PUTCHAR(code, outp){ *(outp)++ = (u_char) (code); };
813 PUTCHAR(id, outp){ *(outp)++ = (u_char) (id); };
814 PUTSHORT(outlen, outp){ *(outp)++ = (u_char) ((outlen) >> 8); *(outp)++ = (u_char
) (outlen); }
;
815 output(f->unit, outpacket_buf, outlen + PPP_HDRLEN4);
816
817 FSMDEBUG((LOG_INFO, "fsm_sdata(%s): Sent code %d, id %d.",
818 PROTO_NAME(f), code, id));
819}