Bug Summary

File:src/usr.sbin/npppd/npppd/ccp.c
Warning:line 127, column 2
Value stored to 'lnak' 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/npppd/npppd/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/npppd/npppd/../common -I /usr/src/usr.sbin/npppd/npppd -I /usr/src/usr.sbin/npppd/npppd/../pptp -I /usr/src/usr.sbin/npppd/npppd/../l2tp -I /usr/src/usr.sbin/npppd/npppd/../pppoe -D USE_NPPPD_PPTP -D USE_NPPPD_L2TP -D USE_NPPPD_PPPOE -D __COPYRIGHT(x)= -D __RCSID(x)= -D NPPPD_MAX_IFACE=8 -D NPPPD_MAX_POOL=8 -D USE_NPPPD_MPPE -D USE_NPPPD_PIPEX -D USE_NPPPD_RADIUS -D USE_SA_COOKIE -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/npppd/npppd/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/npppd/npppd/ccp.c
1/* $OpenBSD: ccp.c,v 1.8 2019/02/27 04:52:19 denis Exp $ */
2
3/*-
4 * Copyright (c) 2009 Internet Initiative Japan Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28/**@file
29 * This file provides functions for CCP (Compression Control Protocol).
30 * MPPE is supported as a CCP option.
31 * $Id: ccp.c,v 1.8 2019/02/27 04:52:19 denis Exp $
32 */
33#include <sys/types.h>
34#include <sys/socket.h>
35#include <sys/time.h>
36#include <net/if_dl.h>
37#include <netinet/in.h>
38#include <stdlib.h>
39#include <stdio.h>
40#include <syslog.h>
41#include <string.h>
42#include <event.h>
43
44#include "npppd.h"
45#include "fsm.h"
46
47#ifdef CCP_DEBUG
48#define CCPDEBUG(x) fsm_log(x)
49#define CCP_ASSERT(x) ASSERT(x)
50#else
51#define CCPDEBUG(x)
52#define CCP_ASSERT(x)
53#endif
54
55static int ccp_reqci (fsm *, u_char *, int *, int);
56static void ccp_open (fsm *);
57static void ccp_close (fsm *);
58static void ccp_start (fsm *);
59static void ccp_stop (fsm *);
60static void ccp_resetci (fsm *);
61static int ccp_cilen (fsm *);
62static void ccp_addci (fsm *, u_char *, int *);
63static int ccp_ackci (fsm *, u_char *, int);
64static int ccp_rejci (fsm *, u_char *, int);
65static int ccp_nakci (fsm *, u_char *, int);
66static int ccp_nackackci (fsm *, u_char *, int, int, int);
67static int ccp_ext (fsm *, int, int, u_char *, int);
68
69static struct fsm_callbacks ccp_callbacks = {
70 .cilen = ccp_cilen,
71 .resetci = ccp_resetci,
72 .addci = ccp_addci,
73 .ackci = ccp_ackci,
74 .nakci = ccp_nakci,
75 .rejci = ccp_rejci,
76 .reqci = ccp_reqci,
77 .up = ccp_open,
78 .down = ccp_close,
79 .starting = ccp_start,
80 .finished = ccp_stop,
81 .extcode = ccp_ext,
82 .proto_name = "ccp",
83};
84
85/** Initialize the context for ccp */
86void
87ccp_init(ccp *_this, npppd_ppp *ppp)
88{
89 struct tunnconf *conf;
90
91 memset(_this, 0, sizeof(ccp));
92
93 _this->ppp = ppp;
94 _this->fsm.callbacks = &ccp_callbacks;
95 _this->fsm.protocol = PPP_PROTO_NCP0x8000 | NCP_CCP0xfd;
96 _this->fsm.ppp = ppp;
97
98 fsm_init(&_this->fsm);
99
100 conf = ppp_get_tunnconf(ppp);
101 PPP_FSM_CONFIG(&_this->fsm, timeouttime, conf->ccp_timeout)do { (&_this->fsm)->timeouttime = ((conf->ccp_timeout
) == 0) ? (&_this->fsm)->timeouttime : (conf->ccp_timeout
); } while (0 )
;
102 PPP_FSM_CONFIG(&_this->fsm, maxconfreqtransmits,do { (&_this->fsm)->maxconfreqtransmits = ((conf->
ccp_max_configure) == 0) ? (&_this->fsm)->maxconfreqtransmits
: (conf->ccp_max_configure); } while (0 )
103 conf->ccp_max_configure)do { (&_this->fsm)->maxconfreqtransmits = ((conf->
ccp_max_configure) == 0) ? (&_this->fsm)->maxconfreqtransmits
: (conf->ccp_max_configure); } while (0 )
;
104 PPP_FSM_CONFIG(&_this->fsm, maxtermtransmits,do { (&_this->fsm)->maxtermtransmits = ((conf->ccp_max_terminate
) == 0) ? (&_this->fsm)->maxtermtransmits : (conf->
ccp_max_terminate); } while (0 )
105 conf->ccp_max_terminate)do { (&_this->fsm)->maxtermtransmits = ((conf->ccp_max_terminate
) == 0) ? (&_this->fsm)->maxtermtransmits : (conf->
ccp_max_terminate); } while (0 )
;
106 PPP_FSM_CONFIG(&_this->fsm, maxnakloops,do { (&_this->fsm)->maxnakloops = ((conf->ccp_max_nak_loop
) == 0) ? (&_this->fsm)->maxnakloops : (conf->ccp_max_nak_loop
); } while (0 )
107 conf->ccp_max_nak_loop)do { (&_this->fsm)->maxnakloops = ((conf->ccp_max_nak_loop
) == 0) ? (&_this->fsm)->maxnakloops : (conf->ccp_max_nak_loop
); } while (0 )
;
108}
109
110/** Request Command Interpreter */
111static int
112ccp_reqci(fsm *f, u_char *pktp, int *lpktp, int reject_if_disagree)
113{
114 int type, len, rcode, lrej, lnak;
115 u_char *rejbuf, *nakbuf, *nakbuf0, *pktp0;
116#ifdef USE_NPPPD_MPPE1
117 uint32_t peer_bits, our_bits;
118#endif
119 npppd_ppp *ppp;
120
121 ppp = f->ppp;
122
123 rejbuf = NULL((void *)0);
124 rcode = CONFACK2;
125 pktp0 = pktp;
126 lrej = 0;
127 lnak = 0;
Value stored to 'lnak' is never read
128
129 if ((rejbuf = malloc(*lpktp)) == NULL((void *)0)) {
130 return rcode;
131 }
132 if ((nakbuf0 = malloc(*lpktp)) == NULL((void *)0)) {
133 free(rejbuf);
134 return rcode;
135 }
136 nakbuf = nakbuf0;
137#define remlen()(lpkt - (pktp - pktp0)) (*lpktp - (pktp - pktp0))
138
139 while (remlen()(lpkt - (pktp - pktp0)) >= 2) {
140 GETCHAR(type, pktp){ (type) = *(pktp)++; };
141 GETCHAR(len, pktp){ (len) = *(pktp)++; };
142 if (len <= 0 || remlen()(lpkt - (pktp - pktp0)) + 2 < len)
143 goto fail;
144
145 switch (type) {
146#ifdef USE_NPPPD_MPPE1
147 case CCP_MPPE0x12:
148 if (len < 6)
149 goto fail;
150
151 if (ppp->mppe.enabled == 0)
152 goto reject;
153 GETLONG(peer_bits, pktp){ (peer_bits) = *(pktp)++ << 8; (peer_bits) |= *(pktp)++
; (peer_bits) <<= 8; (peer_bits) |= *(pktp)++; (peer_bits
) <<= 8; (peer_bits) |= *(pktp)++; }
;
154 our_bits = mppe_create_our_bits(&ppp->mppe, peer_bits);
155 if (our_bits != peer_bits) {
156 if (reject_if_disagree) {
157 pktp -= 4;
158 goto reject;
159 }
160 if (lrej > 0) {
161 /* don't nak because we are doing rej */
162 } else {
163 PUTCHAR(type, nakbuf){ *(nakbuf)++ = (u_char) (type); };
164 PUTCHAR(6, nakbuf){ *(nakbuf)++ = (u_char) (6); };
165 PUTLONG(our_bits, nakbuf){ *(nakbuf)++ = (u_char) ((our_bits) >> 24); *(nakbuf)++
= (u_char) ((our_bits) >> 16); *(nakbuf)++ = (u_char) (
(our_bits) >> 8); *(nakbuf)++ = (u_char) (our_bits); }
;
166 rcode = CONFNAK3;
167 }
168 } else
169 ppp->ccp.mppe_p_bits = our_bits;
170 break;
171reject:
172#endif
173 default:
174 pktp -= 2;
175 memcpy(rejbuf + lrej, pktp, len);
176 lrej += len;
177 pktp += len;
178 rcode = CONFREJ4;
179 }
180 continue;
181 }
182fail:
183 switch (rcode) {
184 case CONFREJ4:
185 memcpy(pktp0, rejbuf, lrej);
186 *lpktp = lrej;
187 break;
188 case CONFNAK3:
189 len = nakbuf - nakbuf0;
190 memcpy(pktp0, nakbuf0, len);
191 *lpktp = len;
192 break;
193 }
194 free(rejbuf);
195 free(nakbuf0);
196
197 return rcode;
198#undef remlen
199}
200
201static void
202ccp_open(fsm *f)
203{
204 ppp_ccp_opened(f->ppp);
205}
206
207static void
208ccp_close(fsm *f)
209{
210}
211
212static void
213ccp_start(fsm *f)
214{
215}
216
217static void
218ccp_stop(fsm *f)
219{
220#ifdef USE_NPPPD_MPPE1
221 fsm_log(f, LOG_INFO6, "CCP is stopped");
222 ppp_ccp_stopped(f->ppp);
223#endif
224}
225
226static void
227ccp_resetci(fsm *f)
228{
229#ifdef USE_NPPPD_MPPE1
230 if (f->ppp->mppe_started == 0)
231 f->ppp->ccp.mppe_o_bits =
232 mppe_create_our_bits(&f->ppp->mppe, 0);
233 /* don't reset if the ccp is started. */
234#endif
235}
236
237static int
238ccp_cilen(fsm *f)
239{
240 return f->ppp->mru;
241}
242
243/** Create a Confugre-Request */
244static void
245ccp_addci(fsm *f, u_char *pktp, int *lpktp)
246{
247 u_char *pktp0;
248
249 pktp0 = pktp;
250
251 if (f->ppp->ccp.mppe_rej == 0) {
252 PUTCHAR(CCP_MPPE, pktp){ *(pktp)++ = (u_char) (0x12); };
253 PUTCHAR(6, pktp){ *(pktp)++ = (u_char) (6); };
254 PUTLONG(f->ppp->ccp.mppe_o_bits, pktp){ *(pktp)++ = (u_char) ((f->ppp->ccp.mppe_o_bits) >>
24); *(pktp)++ = (u_char) ((f->ppp->ccp.mppe_o_bits) >>
16); *(pktp)++ = (u_char) ((f->ppp->ccp.mppe_o_bits) >>
8); *(pktp)++ = (u_char) (f->ppp->ccp.mppe_o_bits); }
;
255
256 *lpktp = pktp - pktp0;
257 } else
258 *lpktp = 0;
259}
260
261static int
262ccp_ackci(fsm *f, u_char *pktp, int lpkt)
263{
264 return ccp_nackackci(f, pktp, lpkt, 0, 0);
265}
266
267
268static int
269ccp_nakci(fsm *f, u_char *pktp, int lpkt)
270{
271 return ccp_nackackci(f, pktp, lpkt, 1, 0);
272}
273
274static int
275ccp_rejci(fsm *f, u_char *pktp, int lpkt)
276{
277 return ccp_nackackci(f, pktp, lpkt, 0, 1);
278}
279
280static int
281ccp_nackackci(fsm *f, u_char *pktp, int lpkt, int is_nak, int is_rej)
282{
283 int type, len;
284 u_char *pktp0;
285#ifdef USE_NPPPD_MPPE1
286 uint32_t peer_bits, our_bits;
287#endif
288 npppd_ppp *ppp;
289
290 ppp = f->ppp;
291
292 pktp0 = pktp;
293
294#define remlen()(lpkt - (pktp - pktp0)) (lpkt - (pktp - pktp0))
295 while (remlen()(lpkt - (pktp - pktp0)) >= 2) {
296 GETCHAR(type, pktp){ (type) = *(pktp)++; };
297 GETCHAR(len, pktp){ (len) = *(pktp)++; };
298 if (len <= 0 || remlen()(lpkt - (pktp - pktp0)) + 2 < len)
299 goto fail;
300
301 switch (type) {
302#ifdef USE_NPPPD_MPPE1
303 case CCP_MPPE0x12:
304 if (len < 6)
305 goto fail;
306 if (is_rej) {
307 f->ppp->ccp.mppe_rej = 1;
308 return 1;
309 }
310 if (ppp->mppe_started != 0) {
311 /* resend silently */
312 return 1;
313 }
314 GETLONG(peer_bits, pktp){ (peer_bits) = *(pktp)++ << 8; (peer_bits) |= *(pktp)++
; (peer_bits) <<= 8; (peer_bits) |= *(pktp)++; (peer_bits
) <<= 8; (peer_bits) |= *(pktp)++; }
;
315 /*
316 * With Yamaha RTX-1000 that is configured as
317 * "ppp ccp mppe-any",
318 *
319 * npppd ConfReq (40,56,128) => RTX 1000
320 * npppd <= (40,128) ConfNAK RTX 1000
321 * npppd ConfReq (40,56,128) => RTX 1000
322 * npppd <= (40,128) ConfNAK RTX 1000
323 *
324 * both peers never decide the final bits. We insist
325 * the longest bit if our request is nacked.
326 */
327 our_bits = mppe_create_our_bits(&ppp->mppe, peer_bits);
328 if (peer_bits == our_bits || is_nak)
329 ppp->ccp.mppe_o_bits = our_bits;
330
331 break;
332#endif
333 default:
334 goto fail;
335 }
336 }
337 return 1;
338fail:
339 return 0;
340}
341
342#define RESET_REQ0x0e 0x0e
343#define RESET_ACK0x0f 0x0f
344
345static int
346ccp_ext(fsm *f, int code, int id, u_char *pktp, int lpktp)
347{
348 switch (code) {
349 case RESET_REQ0x0e:
350 fsm_log(f, LOG_DEBUG7, "Received ResetReq %d", id);
351#ifdef USE_NPPPD_MPPE1
352 mppe_recv_ccp_reset(&f->ppp->mppe);
353#endif
354 /*
355 * RFC 3078 says MPPE can be synchronized without Reset-Ack,
356 * but it doesn't tell about necessity of Reset-Ack. But
357 * in fact, windows peer will complain Reset-Ack with
358 * Code-Reject. So we don't send Reset-Ack.
359 */
360 return 1;
361 case RESET_ACK0x0f:
362 fsm_log(f, LOG_DEBUG7, "Received ResetAck %d", id);
363 return 1;
364 }
365 return 0;
366}