Bug Summary

File:src/usr.sbin/npppd/npppd/../pppoe/pppoe_session.c
Warning:line 111, column 6
Access to field 'state' results in a dereference of a null pointer (loaded from variable '_this')

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 pppoe_session.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/../pppoe/pppoe_session.c
1/* $OpenBSD: pppoe_session.c,v 1.12 2021/03/29 03:54:40 yasuoka 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
29/**@file
30 * Session management of PPPoE protocol
31 * $Id: pppoe_session.c,v 1.12 2021/03/29 03:54:40 yasuoka Exp $
32 */
33
34#include <sys/types.h>
35#include <sys/socket.h>
36#include <sys/uio.h>
37#include <netinet/in.h>
38#include <net/if.h>
39#if defined(__NetBSD__)
40#include <net/if_ether.h>
41#else
42#include <netinet/if_ether.h>
43#endif
44#include <net/if_dl.h>
45#include <time.h>
46#include <string.h>
47#include <stdlib.h>
48#include <stdio.h>
49#include <event.h>
50#include <syslog.h>
51#include <stdarg.h>
52
53#include "hash.h"
54#include "slist.h"
55#include "debugutil.h"
56#include "bytebuf.h"
57#include "pppoe.h"
58#include "pppoe_local.h"
59
60#include "npppd.h"
61#include "ppp.h"
62
63#ifdef PPPOE_SESSION_DEBUG
64#define PPPOE_SESSION_ASSERT(x) ASSERT(x)((void)0);
65#define PPPOE_SESSION_DBG(x) pppoe_session_log x
66#else
67#define PPPOE_SESSION_ASSERT(x)
68#define PPPOE_SESSION_DBG(x)
69#endif
70
71#define pppoed_listener_this(sess)((pppoed_listener *)slist_get(&(sess)->pppoed->listener
, (sess)->listener_index))
\
72 ((pppoed_listener *)slist_get(&(sess)->pppoed->listener, \
73 (sess)->listener_index))
74
75static void pppoe_session_log (pppoe_session *, int, const char *, ...) __printflike(3,4)__attribute__((__format__ (__printf__, 3, 4)));
76static int pppoe_session_send_PADS (pppoe_session *, struct pppoe_tlv *,
77 struct pppoe_tlv *);
78static int pppoe_session_send_PADT (pppoe_session *);
79static int pppoe_session_ppp_output (npppd_ppp *, u_char *, int, int);
80static void pppoe_session_close_by_ppp(npppd_ppp *);
81static int pppoe_session_bind_ppp (pppoe_session *);
82static void pppoe_session_dispose_event(int, short, void *);
83
84/* Initialize PPPoE session context */
85int
86pppoe_session_init(pppoe_session *_this, pppoed *_pppoed, int idx,
87 int session_id, u_char *ether_addr)
88{
89 memset(_this, 0, sizeof(pppoe_session));
90
91 _this->pppoed = _pppoed;
92 _this->session_id = session_id;
93 _this->listener_index = idx;
94 memcpy(_this->ether_addr, ether_addr, ETHER_ADDR_LEN6);
95
96 memcpy(_this->ehdr.ether_dhost, ether_addr, ETHER_ADDR_LEN6);
97 memcpy(_this->ehdr.ether_shost, pppoe_session_sock_ether_addr(_this)((pppoed_listener *)slist_get(&(_this)->pppoed->listener
, (_this)->listener_index))->ether_addr
,
98 ETHER_ADDR_LEN6);
99
100 evtimer_set(&_this->ev_disposing, pppoe_session_dispose_event, _this)event_set(&_this->ev_disposing, -1, 0, pppoe_session_dispose_event
, _this)
;
101
102 return 0;
103}
104
105/* Disconnect PPPoE session */
106void
107pppoe_session_disconnect(pppoe_session *_this)
108{
109 struct timeval tv;
110
111 if (_this->state != PPPOE_SESSION_STATE_DISPOSING2) {
6
Access to field 'state' results in a dereference of a null pointer (loaded from variable '_this')
112 pppoe_session_send_PADT(_this);
113
114 /* free process should be par event */
115 timerclear(&tv)(&tv)->tv_sec = (&tv)->tv_usec = 0;
116 evtimer_add(&_this->ev_disposing, &tv)event_add(&_this->ev_disposing, &tv);
117 _this->state = PPPOE_SESSION_STATE_DISPOSING2;
118 }
119 if (_this->ppp != NULL((void *)0))
120 ppp_phy_downed(_this->ppp);
121}
122
123/* Stop PPPoE session */
124void
125pppoe_session_stop(pppoe_session *_this)
126{
127 if (_this->state != PPPOE_SESSION_STATE_DISPOSING2)
128 pppoe_session_disconnect(_this);
129
130}
131
132/* Finish PPPoE session */
133void
134pppoe_session_fini(pppoe_session *_this)
135{
136 evtimer_del(&_this->ev_disposing)event_del(&_this->ev_disposing);
137}
138
139/* call back function from event(3) */
140static void
141pppoe_session_dispose_event(int fd, short ev, void *ctx)
142{
143 pppoe_session *_this;
144
145 _this = ctx;
146 pppoed_pppoe_session_close_notify(_this->pppoed, _this);
147}
148
149/*
150 * I/O
151 */
152void
153pppoe_session_input(pppoe_session *_this, u_char *pkt, int lpkt)
154{
155 int rval;
156 npppd_ppp *ppp;
157
158 ppp = _this->ppp;
159 if (_this->ppp == NULL((void *)0))
160 return;
161
162 if (_this->state != PPPOE_SESSION_STATE_RUNNING1)
163 return;
164
165 rval = ppp->recv_packet(ppp, pkt, lpkt, 0);
166 if (_this->ppp == NULL((void *)0)) /* ppp is freed */
167 return;
168
169 if (rval == 2) {
170 /*
171 * Quit this function before statistics counter
172 * is processed when the packet will be processed by
173 * PIPEX. Because current NPPPD PPPOE implementation
174 * is receiving all packet from BPF even though the
175 * PIPEX will process it.
176 */
177 } else if (rval != 0) {
178 ppp->ierrors++;
179 } else {
180 ppp->ipackets++;
181 ppp->ibytes += lpkt;
182 }
183
184 return;
185}
186
187static int
188pppoe_session_output(pppoe_session *_this, int is_disc, u_char *pkt,
189 int lpkt)
190{
191 int sz, niov, tlen;
192 struct iovec iov[4];
193 struct pppoe_header pppoe0, *pppoe;
194 char pad[ETHERMIN(64 - ((6 * 2) + 2) - 4)];
195
196
197 niov = 0;
198 tlen = 0;
199 iov[niov].iov_base = &_this->ehdr;
200 iov[niov++].iov_len = sizeof(_this->ehdr);
201
202 if (is_disc) {
203 _this->ehdr.ether_type = htons(ETHERTYPE_PPPOEDISC)(__uint16_t)(__builtin_constant_p(0x8863) ? (__uint16_t)(((__uint16_t
)(0x8863) & 0xffU) << 8 | ((__uint16_t)(0x8863) &
0xff00U) >> 8) : __swap16md(0x8863))
;
204 iov[niov].iov_base = pkt;
205 iov[niov++].iov_len = lpkt;
206 pppoe = (struct pppoe_header *)pkt;
207 pppoe->length = htons(lpkt - sizeof(pppoe0))(__uint16_t)(__builtin_constant_p(lpkt - sizeof(pppoe0)) ? (__uint16_t
)(((__uint16_t)(lpkt - sizeof(pppoe0)) & 0xffU) << 8
| ((__uint16_t)(lpkt - sizeof(pppoe0)) & 0xff00U) >>
8) : __swap16md(lpkt - sizeof(pppoe0)))
;
208 tlen += lpkt;
209 } else {
210 _this->ehdr.ether_type = htons(ETHERTYPE_PPPOE)(__uint16_t)(__builtin_constant_p(0x8864) ? (__uint16_t)(((__uint16_t
)(0x8864) & 0xffU) << 8 | ((__uint16_t)(0x8864) &
0xff00U) >> 8) : __swap16md(0x8864))
;
211 pppoe0.ver = PPPOE_RFC2516_VER0x01;
212 pppoe0.type = PPPOE_RFC2516_TYPE0x01;
213 pppoe0.code = 0;
214 pppoe0.session_id = htons(_this->session_id)(__uint16_t)(__builtin_constant_p(_this->session_id) ? (__uint16_t
)(((__uint16_t)(_this->session_id) & 0xffU) << 8
| ((__uint16_t)(_this->session_id) & 0xff00U) >>
8) : __swap16md(_this->session_id))
;
215 pppoe0.length = htons(lpkt)(__uint16_t)(__builtin_constant_p(lpkt) ? (__uint16_t)(((__uint16_t
)(lpkt) & 0xffU) << 8 | ((__uint16_t)(lpkt) & 0xff00U
) >> 8) : __swap16md(lpkt))
;
216 iov[niov].iov_base = &pppoe0;
217 iov[niov++].iov_len = sizeof(pppoe0);
218 tlen += sizeof(pppoe0);
219 iov[niov].iov_base = pkt;
220 iov[niov++].iov_len = lpkt;
221 tlen += lpkt;
222 }
223 if (tlen < ETHERMIN(64 - ((6 * 2) + 2) - 4)) {
224 memset(pad, 0, ETHERMIN(64 - ((6 * 2) + 2) - 4) - tlen);
225 iov[niov].iov_base = pad;
226 iov[niov++].iov_len = ETHERMIN(64 - ((6 * 2) + 2) - 4) - tlen;
227 }
228
229 sz = writev(pppoe_session_sock_bpf(_this)((pppoed_listener *)slist_get(&(_this)->pppoed->listener
, (_this)->listener_index))->bpf
, iov, niov);
230
231 return (sz > 0)? 0 : -1;
232}
233
234static int
235pppoe_session_send_PADT(pppoe_session *_this)
236{
237 u_char bufspace[2048];
238 bytebuffer *buf;
239 struct pppoe_header pppoe;
240 int rval = 0;
241 struct pppoe_tlv tlv;
242
243 if ((buf = bytebuffer_wrap(bufspace, sizeof(bufspace))) == NULL((void *)0)) {
244 pppoe_session_log(_this, LOG_ERR3,
245 "bytebuffer_wrap() failed on %s(): %m", __func__);
246 return -1;
247 }
248 bytebuffer_clear(buf);
249
250 /*
251 * PPPoE Header
252 */
253 memset(&pppoe, 0, sizeof(pppoe));
254 pppoe.ver = PPPOE_RFC2516_VER0x01;
255 pppoe.type = PPPOE_RFC2516_TYPE0x01;
256 pppoe.code = PPPOE_CODE_PADT0xa7;
257 pppoe.session_id = htons(_this->session_id)(__uint16_t)(__builtin_constant_p(_this->session_id) ? (__uint16_t
)(((__uint16_t)(_this->session_id) & 0xffU) << 8
| ((__uint16_t)(_this->session_id) & 0xff00U) >>
8) : __swap16md(_this->session_id))
;
258 bytebuffer_put(buf, &pppoe, sizeof(pppoe));
259
260 /*
261 * Tag - End-of-List
262 */
263 tlv.type = htons(PPPOE_TAG_END_OF_LIST)(__uint16_t)(__builtin_constant_p(0x0000) ? (__uint16_t)(((__uint16_t
)(0x0000) & 0xffU) << 8 | ((__uint16_t)(0x0000) &
0xff00U) >> 8) : __swap16md(0x0000))
;
264 tlv.length = 0;
265 bytebuffer_put(buf, &tlv, sizeof(tlv));
266 tlv.type = htons(PPPOE_TAG_END_OF_LIST)(__uint16_t)(__builtin_constant_p(0x0000) ? (__uint16_t)(((__uint16_t
)(0x0000) & 0xffU) << 8 | ((__uint16_t)(0x0000) &
0xff00U) >> 8) : __swap16md(0x0000))
;
267 tlv.length = 0;
268 bytebuffer_put(buf, &tlv, sizeof(tlv));
269
270 bytebuffer_flip(buf);
271 if (pppoe_session_output(_this, 1, bytebuffer_pointer(buf),
272 bytebuffer_remaining(buf)) != 0) {
273 pppoe_session_log(_this, LOG_ERR3, "pppoed_output failed: %m");
274 rval = 1;
275 }
276 pppoe_session_log(_this, LOG_INFO6, "SendPADT");
277
278 bytebuffer_unwrap(buf);
279 bytebuffer_destroy(buf);
280
281 return rval;
282}
283
284/* send PADS */
285static int
286pppoe_session_send_PADS(pppoe_session *_this, struct pppoe_tlv *hostuniq,
287 struct pppoe_tlv *service_name)
288{
289 int rval, len;
290 u_char bufspace[2048], msgbuf[80];
291 bytebuffer *buf;
292 struct pppoe_header pppoe;
293 struct pppoe_tlv tlv;
294
295 if ((buf = bytebuffer_wrap(bufspace, sizeof(bufspace))) == NULL((void *)0)) {
296 pppoe_session_log(_this, LOG_ERR3,
297 "bytebuffer_wrap() failed on %s(): %m", __func__);
298 return -1;
299 }
300 bytebuffer_clear(buf);
301
302 /*
303 * PPPoE Header
304 */
305 memset(&pppoe, 0, sizeof(pppoe));
306 pppoe.ver = PPPOE_RFC2516_VER0x01;
307 pppoe.type = PPPOE_RFC2516_TYPE0x01;
308 pppoe.code = PPPOE_CODE_PADS0x65;
309 pppoe.session_id = htons(_this->session_id)(__uint16_t)(__builtin_constant_p(_this->session_id) ? (__uint16_t
)(((__uint16_t)(_this->session_id) & 0xffU) << 8
| ((__uint16_t)(_this->session_id) & 0xff00U) >>
8) : __swap16md(_this->session_id))
;
310 bytebuffer_put(buf, &pppoe, sizeof(pppoe));
311
312 /*
313 * Tag - Service-Name
314 */
315 msgbuf[0] = '\0';
316 if (service_name != NULL((void *)0)) {
317 tlv.type = htons(PPPOE_TAG_SERVICE_NAME)(__uint16_t)(__builtin_constant_p(0x0101) ? (__uint16_t)(((__uint16_t
)(0x0101) & 0xffU) << 8 | ((__uint16_t)(0x0101) &
0xff00U) >> 8) : __swap16md(0x0101))
;
318 tlv.length = htons(service_name->length)(__uint16_t)(__builtin_constant_p(service_name->length) ? (
__uint16_t)(((__uint16_t)(service_name->length) & 0xffU
) << 8 | ((__uint16_t)(service_name->length) & 0xff00U
) >> 8) : __swap16md(service_name->length))
;
319 bytebuffer_put(buf, &tlv, sizeof(tlv));
320
321 len = service_name->length;
322 if (len > 0) {
323 bytebuffer_put(buf, service_name->value, len);
324 strlcpy(msgbuf, service_name->value,
325 MINIMUM(len + 1, sizeof(msgbuf))(((len + 1) < (sizeof(msgbuf))) ? (len + 1) : (sizeof(msgbuf
)))
);
326 }
327 }
328
329 /*
330 * Tag - Host-Uniq
331 */
332 if (hostuniq != NULL((void *)0)) {
333 tlv.type = htons(PPPOE_TAG_HOST_UNIQ)(__uint16_t)(__builtin_constant_p(0x0103) ? (__uint16_t)(((__uint16_t
)(0x0103) & 0xffU) << 8 | ((__uint16_t)(0x0103) &
0xff00U) >> 8) : __swap16md(0x0103))
;
334 tlv.length = htons(hostuniq->length)(__uint16_t)(__builtin_constant_p(hostuniq->length) ? (__uint16_t
)(((__uint16_t)(hostuniq->length) & 0xffU) << 8 |
((__uint16_t)(hostuniq->length) & 0xff00U) >> 8
) : __swap16md(hostuniq->length))
;
335 bytebuffer_put(buf, &tlv, sizeof(tlv));
336 bytebuffer_put(buf, hostuniq->value, hostuniq->length);
337 }
338 tlv.type = htons(PPPOE_TAG_END_OF_LIST)(__uint16_t)(__builtin_constant_p(0x0000) ? (__uint16_t)(((__uint16_t
)(0x0000) & 0xffU) << 8 | ((__uint16_t)(0x0000) &
0xff00U) >> 8) : __swap16md(0x0000))
;
339 tlv.length = 0;
340 bytebuffer_put(buf, &tlv, sizeof(tlv));
341
342 bytebuffer_flip(buf);
343 rval = 0;
344 if (pppoe_session_output(_this, 1, bytebuffer_pointer(buf),
345 bytebuffer_remaining(buf)) != 0) {
346 pppoe_session_log(_this, LOG_ERR3, "pppoed_output failed: %m");
347 rval = 1;
348 }
349 pppoe_session_log(_this, LOG_INFO6, "SendPADS serviceName=%s "
350 "hostUniq=%s", msgbuf,
351 hostuniq? pppoed_tlv_value_string(hostuniq) : "none");
352
353 bytebuffer_unwrap(buf);
354 bytebuffer_destroy(buf);
355
356 return rval;
357}
358
359/* process PADR from the peer */
360int
361pppoe_session_recv_PADR(pppoe_session *_this, slist *tag_list)
362{
363 pppoed *pppoed0 = _this->pppoed;
364 struct pppoe_tlv *tlv, *hostuniq, *service_name, *ac_cookie;
365
366 service_name = NULL((void *)0);
367 hostuniq = NULL((void *)0);
368 ac_cookie = NULL((void *)0);
369 for (slist_itr_first(tag_list); slist_itr_has_next(tag_list); ) {
370 tlv = slist_itr_next(tag_list);
371 if (tlv->type == PPPOE_TAG_HOST_UNIQ0x0103)
372 hostuniq = tlv;
373 if (tlv->type == PPPOE_TAG_SERVICE_NAME0x0101)
374 service_name = tlv;
375 if (tlv->type == PPPOE_TAG_AC_COOKIE0x0104)
376 ac_cookie = tlv;
377 }
378
379 if (ac_cookie) {
380 /* avoid a session which has already has cookie. */
381 if (hash_lookup(pppoed0->acookie_hash,
382 (void *)ac_cookie->value) != NULL((void *)0))
383 goto fail;
384
385 _this->acookie = *(uint32_t *)(ac_cookie->value);
386 hash_insert(pppoed0->acookie_hash,
387 (void *)(intptr_t)_this->acookie, _this);
388 }
389
390 if (pppoe_session_send_PADS(_this, hostuniq, service_name) != 0)
391 goto fail;
392
393 if (pppoe_session_bind_ppp(_this) != 0)
394 goto fail;
395
396 _this->state = PPPOE_SESSION_STATE_RUNNING1;
397 return 0;
398fail:
399 return -1;
400}
401
402/* process PADT from the peer */
403int
404pppoe_session_recv_PADT(pppoe_session *_this, slist *tag_list)
405{
406 pppoe_session_log(_this, LOG_INFO6, "RecvPADT");
407
408 pppoe_session_stop(_this);
409 _this->state = PPPOE_SESSION_STATE_DISPOSING2;
410
411 return 0;
412}
413
414/*
415 * Log
416 */
417static void
418pppoe_session_log(pppoe_session *_this, int prio, const char *fmt, ...)
419{
420 char logbuf[BUFSIZ1024];
421 va_list ap;
422
423 PPPOE_SESSION_ASSERT(_this != NULL);
424 va_start(ap, fmt)__builtin_va_start(ap, fmt);
425#ifdef PPPOED_MULTIPLE
426 snprintf(logbuf, sizeof(logbuf), "pppoed id=%u session=%d %s",
427 _this->pppoed->id, _this->session_id, fmt);
428#else
429 snprintf(logbuf, sizeof(logbuf), "pppoed if=%s session=%d %s",
430 pppoe_session_listen_ifname(_this)((pppoed_listener *)slist_get(&(_this)->pppoed->listener
, (_this)->listener_index))->listen_ifname
, _this->session_id, fmt);
431#endif
432 vlog_printf(prio, logbuf, ap);
433 va_end(ap)__builtin_va_end(ap);
434}
435
436/*
437 * PPP
438 */
439static int
440pppoe_session_ppp_output(npppd_ppp *ppp, u_char *pkt, int lpkt, int flag)
441{
442 int rval;
443 pppoe_session *_this;
444
445 _this = ppp->phy_context;
446
447 rval = pppoe_session_output(_this, 0, pkt, lpkt);
448
449 if (_this->ppp == NULL((void *)0)) /* ppp is freed */
450 return 0;
451
452 if (rval != 0) {
453 ppp->oerrors++;
454 } else {
455 ppp->opackets++;
456 ppp->obytes += lpkt;
457 }
458
459 return 0;
460}
461
462static void
463pppoe_session_close_by_ppp(npppd_ppp *ppp)
464{
465 pppoe_session *_this;
466
467 _this = ppp->phy_context;
1
Value assigned to '_this'
468 PPPOE_SESSION_ASSERT(_this != NULL);
469 if (_this != NULL((void *)0))
2
Assuming '_this' is equal to NULL
3
Taking false branch
470 /* do this before pptp_call_disconnect() */
471 _this->ppp = NULL((void *)0);
472
473 pppoe_session_disconnect(_this);
4
Passing null pointer value via 1st parameter '_this'
5
Calling 'pppoe_session_disconnect'
474}
475
476/* bind for PPP */
477static int
478pppoe_session_bind_ppp(pppoe_session *_this)
479{
480 int len;
481 npppd_ppp *ppp;
482 struct sockaddr_dl sdl;
483
484 ppp = NULL((void *)0);
485 if ((ppp = ppp_create()) == NULL((void *)0))
486 goto fail;
487
488 PPPOE_SESSION_ASSERT(_this->ppp == NULL);
489
490 if (_this->ppp != NULL((void *)0))
491 return -1;
492
493 _this->ppp = ppp;
494
495 ppp->tunnel_type = NPPPD_TUNNEL_PPPOE3;
496 ppp->tunnel_session_id = _this->session_id;
497 ppp->phy_context = _this;
498 ppp->send_packet = pppoe_session_ppp_output;
499 ppp->phy_close = pppoe_session_close_by_ppp;
500
501 strlcpy(ppp->phy_label, PPPOE_SESSION_LISTENER_TUN_NAME(_this)((pppoed_listener *)slist_get(&(_this)->pppoed->listener
, (_this)->listener_index))->tun_name
,
502 sizeof(ppp->phy_label));
503
504 memset(&sdl, 0, sizeof(sdl));
505 sdl.sdl_len = sizeof(sdl);
506 sdl.sdl_family = AF_LINK18;
507 sdl.sdl_index = if_nametoindex(pppoe_session_listen_ifname(_this)((pppoed_listener *)slist_get(&(_this)->pppoed->listener
, (_this)->listener_index))->listen_ifname
);
508 len = strlen(pppoe_session_listen_ifname(_this)((pppoed_listener *)slist_get(&(_this)->pppoed->listener
, (_this)->listener_index))->listen_ifname
);
509 memcpy(sdl.sdl_data, pppoe_session_listen_ifname(_this)((pppoed_listener *)slist_get(&(_this)->pppoed->listener
, (_this)->listener_index))->listen_ifname
, len);
510 sdl.sdl_nlen = len;
511 sdl.sdl_alen = ETHER_ADDR_LEN6;
512 memcpy(sdl.sdl_data + len, _this->ether_addr, ETHER_ADDR_LEN6);
513
514 memcpy(&ppp->phy_info.peer_dl, &sdl, sizeof(sdl));
515
516 if (ppp_init(npppd_get_npppd(), ppp) != 0)
517 goto fail;
518 ppp->has_acf = 0;
519
520
521 pppoe_session_log(_this, LOG_NOTICE5, "logtype=PPPBind ppp=%d", ppp->id);
522 ppp_start(ppp);
523
524 return 0;
525fail:
526 pppoe_session_log(_this, LOG_ERR3, "failed binding ppp");
527
528 if (ppp != NULL((void *)0))
529 ppp_destroy(ppp);
530 _this->ppp = NULL((void *)0);
531
532 return 1;
533}