Bug Summary

File:src/usr.sbin/npppd/npppd/../l2tp/l2tp_call.c
Warning:line 639, column 2
Value stored to 'sessid' 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 l2tp_call.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/../l2tp/l2tp_call.c
1/* $OpenBSD: l2tp_call.c,v 1.20 2021/03/29 03:54:39 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/* $Id: l2tp_call.c,v 1.20 2021/03/29 03:54:39 yasuoka Exp $ */
29/**@file L2TP LNS call */
30#include <sys/types.h>
31#include <sys/socket.h>
32#include <sys/time.h>
33#include <stdlib.h>
34#include <stddef.h>
35#include <netinet/in.h>
36#include <stdio.h>
37#include <string.h>
38#include <syslog.h>
39#include <stdarg.h>
40#include <unistd.h>
41#include <event.h>
42#include <net/if_dl.h>
43
44#include "debugutil.h"
45#include "bytebuf.h"
46#include "hash.h"
47#include "slist.h"
48#include "l2tp.h"
49#include "l2tp_subr.h"
50
51#include "npppd.h"
52#include "l2tp_local.h"
53
54#ifdef L2TP_CALL_DEBUG
55#define L2TP_CALL_DBG(m) l2tp_call_log m
56#define L2TP_CALL_ASSERT(x) ASSERT(x)((void)0);
57#else
58#define L2TP_CALL_DBG(m)
59#define L2TP_CALL_ASSERT(x)
60#endif
61
62static void l2tp_call_log (l2tp_call *, int, const char *, ...) __printflike(3,4)__attribute__((__format__ (__printf__, 3, 4)));
63static void l2tp_call_disconnect (l2tp_call *, int, int, const char *, struct l2tp_avp *[], int);
64static int l2tp_call_recv_ICRQ (l2tp_call *, u_char *, int);
65static int l2tp_call_send_ICRP (l2tp_call *);
66static int l2tp_call_recv_ICCN (l2tp_call *, u_char *, int, dialin_proxy_info *);
67static int l2tp_recv_CDN (l2tp_call *, u_char *, int);
68static int l2tp_call_send_CDN (l2tp_call *, int, int, const char *, struct l2tp_avp *[], int);
69static int l2tp_call_send_ZLB (l2tp_call *);
70static inline const char *l2tp_call_state_string (l2tp_call *);
71static int l2tp_call_bind_ppp (l2tp_call *, dialin_proxy_info *);
72static void l2tp_call_notify_down (l2tp_call *);
73static int l2tp_call_send_data_packet (l2tp_call *, bytebuffer *);
74
75static int l2tp_call_ppp_output (npppd_ppp *, unsigned char *, int, int);
76static void l2tp_call_closed_by_ppp (npppd_ppp *);
77
78/* create {@link ::_l2tp_call L2TP call} instance */
79l2tp_call *
80l2tp_call_create(void)
81{
82 l2tp_call *_this;
83
84 if ((_this = malloc(sizeof(l2tp_call))) == NULL((void*)0))
85 return NULL((void*)0);
86
87 return _this;
88}
89
90/* initialize {@link ::_l2tp_call L2TP call} instance */
91int
92l2tp_call_init(l2tp_call *_this, l2tp_ctrl *ctrl)
93{
94 memset(_this, 0, sizeof(l2tp_call));
95
96 _this->ctrl = ctrl;
97 if (l2tpd_assign_call(ctrl->l2tpd, _this) != 0)
98 return -1;
99
100 _this->use_seq = ctrl->data_use_seq;
101
102 return 0;
103}
104
105/* free {@link ::_l2tp_call L2TP call} instance */
106void
107l2tp_call_destroy(l2tp_call *_this, int from_l2tp_ctrl)
108{
109 l2tpd_release_call(_this->ctrl->l2tpd, _this);
110 free(_this);
111}
112
113/*
114 * l2tp disconnect will occur when
115 * 1) disconnect request issued from nppdctl command
116 * 2) npppd is terminated
117 * in case 1) ppp_stop() is used to terminal. (PPP LCP TermReq)
118 * and in case 2) l2tp_call_disconnect() is used (L2TP CDN)
119 */
120/* administrative reason disconnection */
121void
122l2tp_call_admin_disconnect(l2tp_call *_this)
123{
124 l2tp_call_disconnect(_this, L2TP_CDN_RCODE_ADMINISTRATIVE_REASON3, 0,
125 NULL((void*)0), NULL((void*)0), 0);
126}
127
128void
129l2tp_call_drop(l2tp_call *_this)
130{
131 l2tp_call_disconnect(_this, 0, 0, NULL((void*)0), NULL((void*)0), 0);
132}
133
134/*
135 * disconnect l2tp connection
136 * @param result_code disconnect without CDN, specify zero
137 */
138static void
139l2tp_call_disconnect(l2tp_call *_this, int result_code, int error_code,
140 const char *errmes, struct l2tp_avp *addavp[], int naddavp)
141{
142 L2TP_CALL_ASSERT(_this != NULL);
143
144 if (_this->state == L2TP_CALL_STATE_CLEANUP_WAIT3) {
145 /* CDN received, or have been sent */
146 l2tp_call_notify_down(_this); /* just in case */
147 return;
148 }
149 if (result_code > 0) {
150 if (l2tp_call_send_CDN(_this, result_code, error_code, errmes,
151 addavp, naddavp)
152 != 0)
153 l2tp_call_log(_this, LOG_ERR3, "Error sending CDN: %m");
154 }
155 _this->state = L2TP_CALL_STATE_CLEANUP_WAIT3;
156 l2tp_call_notify_down(_this);
157}
158
159/*
160 * control packet
161 */
162
163/* call it when control packet is received */
164int
165l2tp_call_recv_packet(l2tp_ctrl *ctrl, l2tp_call *_this, int mestype,
166 u_char *pkt, int pktlen)
167{
168 int i, len, session_id, send_cdn;
169 l2tp_call *call;
170 dialin_proxy_info dpi;
171
172 /* when ICRQ, this will be NULL */
173 L2TP_CALL_ASSERT(_this != NULL ||
174 mestype == L2TP_AVP_MESSAGE_TYPE_ICRQ);
175
176 if (_this == NULL((void*)0)) {
177 if (mestype != L2TP_AVP_MESSAGE_TYPE_ICRQ10)
178 return 1;
179 if ((_this = l2tp_call_create()) == NULL((void*)0)) {
180 l2tp_ctrl_log(ctrl, LOG_ERR3,
181 "l2tp_call_create failed in %s(): %m", __func__);
182 return 1;
183 }
184 l2tp_call_init(_this, ctrl);
185
186 if (l2tp_call_recv_ICRQ(_this, pkt, pktlen) != 0)
187 return 1;
188
189 len = slist_length(&ctrl->call_list);
190 session_id = _this->id;
191 again:
192 /* assign a session ID */
193 session_id &= 0xffff;
194 if (session_id == 0)
195 session_id = 1;
196 for (i = 0; i < len; i++) {
197 call = slist_get(&ctrl->call_list, i);
198 if (call->session_id == session_id) {
199 session_id++;
200 goto again;
201 }
202 }
203 _this->session_id = session_id;
204
205 /* add the l2tp_call to call list */
206 slist_add(&_this->ctrl->call_list, _this);
207
208 if (l2tp_call_send_ICRP(_this) != 0)
209 return 1;
210 _this->state = L2TP_CALL_STATE_WAIT_CONN1;
211 return 0;
212 }
213
214 /* state machine */
215 send_cdn = 0;
216 switch (_this->state) {
217 default:
218 break;
219 case L2TP_CALL_STATE_WAIT_CONN1:
220 switch (mestype) {
221 case L2TP_AVP_MESSAGE_TYPE_ICCN12:
222 memset(&dpi, 0, sizeof(dpi));
223 if (l2tp_call_recv_ICCN(_this, pkt, pktlen, &dpi) != 0)
224 return 1;
225 l2tp_call_bind_ppp(_this, &dpi);
226 l2tp_call_send_ZLB(_this);
227 _this->state = L2TP_CALL_STATE_ESTABLISHED2;
228 _this->ctrl->ncalls++;
229 return 0;
230 case L2TP_AVP_MESSAGE_TYPE_ICRQ10:
231 case L2TP_AVP_MESSAGE_TYPE_ICRP11:
232 send_cdn = 1;
233 /* FALLTHROUGH */
234 default:
235 l2tp_call_log(_this, LOG_ERR3,
236 "Waiting ICCN. But received %s",
237 avp_mes_type_string(mestype));
238 if (send_cdn) {
239 l2tp_call_disconnect(_this,
240 L2TP_CDN_RCODE_ERROR_CODE2,
241 L2TP_ECODE_GENERIC_ERROR6, "Illegal state.",
242 NULL((void*)0), 0);
243 return 0;
244 }
245 }
246 break;
247 case L2TP_CALL_STATE_ESTABLISHED2:
248 switch (mestype) {
249 case L2TP_AVP_MESSAGE_TYPE_CDN14:
250 /* disconnect from peer. log it */
251 l2tp_recv_CDN(_this, pkt, pktlen);
252 _this->state = L2TP_CALL_STATE_CLEANUP_WAIT3;
253 l2tp_call_notify_down(_this);
254 l2tp_call_send_ZLB(_this);
255 return 0;
256 case L2TP_AVP_MESSAGE_TYPE_ICRQ10:
257 case L2TP_AVP_MESSAGE_TYPE_ICRP11:
258 case L2TP_AVP_MESSAGE_TYPE_ICCN12:
259 send_cdn = 1;
260 break;
261 default:
262 break;
263 }
264 l2tp_call_log(_this, LOG_ERR3,
265 "Call established. But received %s",
266 avp_mes_type_string(mestype));
267 if (send_cdn) {
268 l2tp_call_disconnect(_this,
269 L2TP_CDN_RCODE_ERROR_CODE2,
270 L2TP_ECODE_GENERIC_ERROR6, "Illegal state.",
271 NULL((void*)0), 0);
272 return 0;
273 }
274 l2tp_call_disconnect(_this, 0, 0, NULL((void*)0), NULL((void*)0), 0);
275 return 1;
276 }
277 l2tp_call_log(_this, LOG_INFO6, "Received %s in unexpected state=%s",
278 avp_mes_type_string(mestype), l2tp_call_state_string(_this));
279 l2tp_call_disconnect(_this, 0, 0, NULL((void*)0), NULL((void*)0), 0);
280 return 1;
281}
282/*
283 * receive ICRQ
284 * @return return 0 if the ICRQ is acceptable.
285 * other values means fail to receive, and
286 * CDN was sent and status was updated.
287 */
288static int
289l2tp_call_recv_ICRQ(l2tp_call *_this, u_char *pkt, int pktlen)
290{
291 int avpsz, slen;
292 struct l2tp_avp *avp;
293 char buf[L2TP_AVP_MAXSIZ1024], emes[256];
294
295 avp = (struct l2tp_avp *)buf;
296 while (pktlen >= 6 && (avpsz = avp_enum(avp, pkt, pktlen, 1)) > 0) {
297 pkt += avpsz;
298 pktlen -= avpsz;
299 if (avp->vendor_id != 0) {
300 L2TP_CALL_DBG((_this, LOG_DEBUG,
301 "Received a Vendor-specific AVP vendor-id=%d "
302 "type=%d", avp->vendor_id, avp->attr_type));
303 continue;
304 }
305 if (avp->is_hidden != 0) {
306 l2tp_call_log(_this, LOG_WARNING4,
307 "Received AVP (%s/%d) is hidden. But we don't "
308 "share secret.",
309 avp_attr_type_string(avp->attr_type),
310 avp->attr_type);
311 if (avp->is_mandatory != 0) {
312 l2tp_call_disconnect(_this,
313 L2TP_CDN_RCODE_ERROR_CODE2,
314 L2TP_ECODE_UNKNOWN_MANDATORY_AVP8, NULL((void*)0),
315 NULL((void*)0), 0);
316 return 1;
317 }
318 continue;
319 }
320 switch (avp->attr_type) {
321 case L2TP_AVP_TYPE_MESSAGE_TYPE0:
322 AVP_SIZE_CHECK(avp, ==, 8)do { if (!((avp)->length == (8))) { snprintf(emes, sizeof(
emes), "invalid packet size %s %d" "==" "%d)", avp_attr_type_string
((avp)->attr_type), (avp)->length, (8)); goto size_check_failed
; } } while ( 0)
;
323 continue;
324 case L2TP_AVP_TYPE_ASSIGNED_SESSION_ID14:
325 AVP_SIZE_CHECK(avp, ==, 8)do { if (!((avp)->length == (8))) { snprintf(emes, sizeof(
emes), "invalid packet size %s %d" "==" "%d)", avp_attr_type_string
((avp)->attr_type), (avp)->length, (8)); goto size_check_failed
; } } while ( 0)
;
326 _this->peer_session_id = avp_get_val16(avp);
327 continue;
328 case L2TP_AVP_TYPE_CALL_SERIAL_NUMBER15:
329 case L2TP_AVP_TYPE_BEARER_TYPE18:
330 case L2TP_AVP_TYPE_PHYSICAL_CHANNEL_ID25:
331 /*
332 * Memo:
333 * Microsoft "L2TP/IPsec VPN Client" for
334 * Windows 98/Me/NT asserts mandatory bit in
335 * Physical Channel Id
336 */
337 break;
338 case L2TP_AVP_TYPE_CALLING_NUMBER22:
339 slen = MINIMUM(sizeof(_this->calling_number) - 1,(((sizeof(_this->calling_number) - 1) < (((avp)->length
- 6))) ? (sizeof(_this->calling_number) - 1) : (((avp)->
length - 6)))
340 avp_attr_length(avp))(((sizeof(_this->calling_number) - 1) < (((avp)->length
- 6))) ? (sizeof(_this->calling_number) - 1) : (((avp)->
length - 6)))
;
341 memcpy(_this->calling_number, avp->attr_value, slen);
342 _this->calling_number[slen] = '\0';
343 break;
344 case L2TP_AVP_TYPE_CALLED_NUMBER21:
345 case L2TP_AVP_TYPE_SUB_ADDRESS23:
346 continue;
347 default:
348 if (avp->is_mandatory) {
349 l2tp_call_log(_this, LOG_WARNING4,
350 "AVP (%s/%d) is not supported, but it's "
351 "mandatory",
352 avp_attr_type_string(avp->attr_type),
353 avp->attr_type);
354 if (avp->is_mandatory != 0) {
355 l2tp_call_disconnect(_this,
356 L2TP_CDN_RCODE_ERROR_CODE2,
357 L2TP_ECODE_UNKNOWN_MANDATORY_AVP8,
358 NULL((void*)0), NULL((void*)0), 0);
359 return 1;
360 }
361#ifdef L2TP_CALL_DEBUG
362 } else {
363 L2TP_CALL_DBG((_this, LOG_DEBUG,
364 "AVP (%s/%d) is not handled",
365 avp_attr_type_string(avp->attr_type),
366 avp->attr_type));
367#endif
368 }
369 }
370 }
371 if (_this->peer_session_id == 0) {
372 l2tp_call_log(_this, LOG_ERR3,
373 "Received a bad ICRP: SessionId = 0");
374 l2tp_call_disconnect(_this, L2TP_CDN_RCODE_ERROR_CODE2,
375 L2TP_ECODE_INVALID_MESSAGE3, "Session Id must not be 0",
376 NULL((void*)0), 0);
377 return 1;
378 }
379 l2tp_call_log(_this, LOG_INFO6, "RecvICRQ session_id=%u",
380 _this->peer_session_id);
381
382 return 0;
383size_check_failed:
384 l2tp_call_log(_this, LOG_ERR3, "Received bad ICRQ: %s", emes);
385 l2tp_call_disconnect(_this, L2TP_CDN_RCODE_ERROR_CODE2,
386 L2TP_ECODE_WRONG_LENGTH2, NULL((void*)0), NULL((void*)0), 0);
387
388 return 1;
389}
390
391/* send ICRP */
392static int
393l2tp_call_send_ICRP(l2tp_call *_this)
394{
395 int rval;
396 struct l2tp_avp *avp;
397 char buf[L2TP_AVP_MAXSIZ1024];
398 bytebuffer *bytebuf;
399
400 bytebuf = l2tp_ctrl_prepare_snd_buffer(_this->ctrl, 1);
401 if (bytebuf == NULL((void*)0)) {
402 l2tp_call_log(_this, LOG_ERR3, "sending ICRP failed: no buffer");
403 return 1;
404 }
405 avp = (struct l2tp_avp *)buf;
406
407 /* Message Type = ICRP */
408 memset(avp, 0, sizeof(*avp));
409 avp->is_mandatory = 1;
410 avp->attr_type = L2TP_AVP_TYPE_MESSAGE_TYPE0;
411 avp_set_val16(avp, L2TP_AVP_MESSAGE_TYPE_ICRP11);
412 bytebuf_add_avp(bytebuf, avp, 2);
413
414 memset(avp, 0, sizeof(*avp));
415 avp->is_mandatory = 1;
416 avp->attr_type = L2TP_AVP_TYPE_ASSIGNED_SESSION_ID14;
417 avp_set_val16(avp, _this->session_id);
418 bytebuf_add_avp(bytebuf, avp, 2);
419
420 if ((rval = l2tp_ctrl_send_packet(_this->ctrl, _this->peer_session_id,
421 bytebuf)) != 0) {
422 l2tp_call_log(_this, LOG_ERR3, "failed to SendICRP: %m");
423 return 1;
424 }
425 l2tp_call_log(_this, LOG_INFO6, "SendICRP session_id=%u",
426 _this->session_id);
427 return 0;
428}
429
430/* send L2TP data message */
431static int
432l2tp_call_send_data_packet(l2tp_call *_this, bytebuffer *buffer)
433{
434 int rval;
435 struct l2tp_header *hdr;
436
437 bytebuffer_flip(buffer);
438 hdr = (struct l2tp_header *)bytebuffer_pointer(buffer);
439 memset(hdr, 0, sizeof(*hdr) - 4); /* Nr, NS are option */
440
441 hdr->t = 0;
442 hdr->ver = L2TP_HEADER_VERSION_RFC26610x02;
443 hdr->l = 1;
444 hdr->length = htons(bytebuffer_remaining(buffer))(__uint16_t)(__builtin_constant_p(bytebuffer_remaining(buffer
)) ? (__uint16_t)(((__uint16_t)(bytebuffer_remaining(buffer))
& 0xffU) << 8 | ((__uint16_t)(bytebuffer_remaining
(buffer)) & 0xff00U) >> 8) : __swap16md(bytebuffer_remaining
(buffer)))
;
445 hdr->tunnel_id = htons(_this->ctrl->peer_tunnel_id)(__uint16_t)(__builtin_constant_p(_this->ctrl->peer_tunnel_id
) ? (__uint16_t)(((__uint16_t)(_this->ctrl->peer_tunnel_id
) & 0xffU) << 8 | ((__uint16_t)(_this->ctrl->
peer_tunnel_id) & 0xff00U) >> 8) : __swap16md(_this
->ctrl->peer_tunnel_id))
;
446 hdr->session_id = htons(_this->peer_session_id)(__uint16_t)(__builtin_constant_p(_this->peer_session_id) ?
(__uint16_t)(((__uint16_t)(_this->peer_session_id) & 0xffU
) << 8 | ((__uint16_t)(_this->peer_session_id) &
0xff00U) >> 8) : __swap16md(_this->peer_session_id)
)
;
447 if (_this->use_seq) {
448 hdr->s = 1;
449 hdr->ns = htons(_this->snd_nxt++)(__uint16_t)(__builtin_constant_p(_this->snd_nxt++) ? (__uint16_t
)(((__uint16_t)(_this->snd_nxt++) & 0xffU) << 8 |
((__uint16_t)(_this->snd_nxt++) & 0xff00U) >> 8
) : __swap16md(_this->snd_nxt++))
;
450 hdr->nr = htons(_this->rcv_nxt)(__uint16_t)(__builtin_constant_p(_this->rcv_nxt) ? (__uint16_t
)(((__uint16_t)(_this->rcv_nxt) & 0xffU) << 8 | (
(__uint16_t)(_this->rcv_nxt) & 0xff00U) >> 8) : __swap16md
(_this->rcv_nxt))
;
451 }
452
453 if (L2TP_CTRL_CONF(_this->ctrl)((l2tpd_listener *)slist_get(&(_this->ctrl)->l2tpd->
listener, (_this->ctrl)->listener_index))->conf
->data_out_pktdump != 0) {
454 l2tpd_log(_this->ctrl->l2tpd, LOG_DEBUG7,
455 "ctrl=%u call=%u L2TP Data output packet dump",
456 _this->ctrl->id, _this->id);
457 show_hd(debug_get_debugfp(), bytebuffer_pointer(buffer),
458 bytebuffer_remaining(buffer));
459 }
460 if ((rval = l2tp_ctrl_send(_this->ctrl, bytebuffer_pointer(buffer),
461 bytebuffer_remaining(buffer))) < 0) {
462 L2TP_CALL_DBG((_this, LOG_DEBUG, "sendto() failed: %m"));
463 }
464
465 return (rval == bytebuffer_remaining(buffer))? 0 : 1;
466}
467
468/*
469 * receive ICCN
470 * @return return 0 if the ICCN is acceptable.
471 * other value means fail to receive, and
472 * CDN was sent and status was updated.
473 */
474static int
475l2tp_call_recv_ICCN(l2tp_call *_this, u_char *pkt, int pktlen,
476 dialin_proxy_info *dpi)
477{
478 int avpsz, tx_conn_speed;
479 uint32_t framing_type = 0;
480 struct l2tp_avp *avp;
481 char buf[L2TP_AVP_MAXSIZ1024], emes[256];
482
483 tx_conn_speed = 0;
484 avp = (struct l2tp_avp *)buf;
485 while (pktlen >= 6 && (avpsz = avp_enum(avp, pkt, pktlen, 1)) > 0) {
486 pkt += avpsz;
487 pktlen -= avpsz;
488 if (avp->vendor_id != 0) {
489 L2TP_CALL_DBG((_this, LOG_DEBUG,
490 "Received a Vendor-specific AVP vendor-id=%d "
491 "type=%d", avp->vendor_id, avp->attr_type));
492 continue;
493 }
494 if (avp->is_hidden != 0) {
495 l2tp_call_log(_this, LOG_WARNING4,
496 "Received AVP (%s/%d) is hidden. But we don't "
497 "share secret.",
498 avp_attr_type_string(avp->attr_type),
499 avp->attr_type);
500 if (avp->is_mandatory != 0) {
501 l2tp_call_disconnect(_this,
502 L2TP_CDN_RCODE_ERROR_CODE2,
503 L2TP_ECODE_UNKNOWN_MANDATORY_AVP8, NULL((void*)0),
504 NULL((void*)0), 0);
505 return 1;
506 }
507 continue;
508 }
509 switch (avp->attr_type) {
510 case L2TP_AVP_TYPE_MESSAGE_TYPE0:
511 AVP_SIZE_CHECK(avp, ==, 8)do { if (!((avp)->length == (8))) { snprintf(emes, sizeof(
emes), "invalid packet size %s %d" "==" "%d)", avp_attr_type_string
((avp)->attr_type), (avp)->length, (8)); goto size_check_failed
; } } while ( 0)
;
512 continue;
513 case L2TP_AVP_TYPE_RX_CONNECT_SPEED38:
514 /*
515 * As RFC 2661 this AVP is not mandatory. But `xl2tpd'
516 * sends this as a mandatory AVP. Handle this to
517 * ignore the xl2tpd' bug.
518 */
519 AVP_SIZE_CHECK(avp, ==, 10)do { if (!((avp)->length == (10))) { snprintf(emes, sizeof
(emes), "invalid packet size %s %d" "==" "%d)", avp_attr_type_string
((avp)->attr_type), (avp)->length, (10)); goto size_check_failed
; } } while ( 0)
;
520 continue;
521 case L2TP_AVP_TYPE_TX_CONNECT_SPEED24:
522 AVP_SIZE_CHECK(avp, ==, 10)do { if (!((avp)->length == (10))) { snprintf(emes, sizeof
(emes), "invalid packet size %s %d" "==" "%d)", avp_attr_type_string
((avp)->attr_type), (avp)->length, (10)); goto size_check_failed
; } } while ( 0)
;
523 tx_conn_speed = avp_get_val32(avp);
524 continue;
525 case L2TP_AVP_TYPE_FRAMING_TYPE19:
526 AVP_SIZE_CHECK(avp, ==, 10)do { if (!((avp)->length == (10))) { snprintf(emes, sizeof
(emes), "invalid packet size %s %d" "==" "%d)", avp_attr_type_string
((avp)->attr_type), (avp)->length, (10)); goto size_check_failed
; } } while ( 0)
;
527 framing_type = avp_get_val32(avp);
528 continue;
529 case L2TP_AVP_TYPE_SEQUENCING_REQUIRED39:
530 _this->seq_required = 1;
531 _this->use_seq = 1;
532 continue;
533 /*
534 * AVP's for Proxy-LCP and Proxy-Authen
535 */
536 case L2TP_AVP_TYPE_LAST_SENT_LCP_CONFREQ27:
537 AVP_MAXLEN_CHECK(avp, sizeof(dpi->last_sent_lcp.data))do { if ((avp)->length > (sizeof(dpi->last_sent_lcp.
data)) + 6) { snprintf(emes, sizeof(emes), "Attribute value is too long %s %d > %d"
, avp_attr_type_string((avp)->attr_type), (avp)->length
- 6, (int)(sizeof(dpi->last_sent_lcp.data))); goto size_check_failed
; } } while ( 0)
;
538 memcpy(dpi->last_sent_lcp.data, avp->attr_value,
539 avp_attr_length(avp)((avp)->length - 6));
540 dpi->last_sent_lcp.ldata = avp_attr_length(avp)((avp)->length - 6);
541 break;
542 case L2TP_AVP_TYPE_LAST_RECV_LCP_CONFREQ28:
543 AVP_MAXLEN_CHECK(avp, sizeof(dpi->last_recv_lcp.data))do { if ((avp)->length > (sizeof(dpi->last_recv_lcp.
data)) + 6) { snprintf(emes, sizeof(emes), "Attribute value is too long %s %d > %d"
, avp_attr_type_string((avp)->attr_type), (avp)->length
- 6, (int)(sizeof(dpi->last_recv_lcp.data))); goto size_check_failed
; } } while ( 0)
;
544 memcpy(dpi->last_recv_lcp.data, avp->attr_value,
545 avp_attr_length(avp)((avp)->length - 6));
546 dpi->last_recv_lcp.ldata = avp_attr_length(avp)((avp)->length - 6);
547 break;
548 case L2TP_AVP_TYPE_PROXY_AUTHEN_CHALLENGE31:
549 AVP_MAXLEN_CHECK(avp, sizeof(dpi->auth_chall))do { if ((avp)->length > (sizeof(dpi->auth_chall)) +
6) { snprintf(emes, sizeof(emes), "Attribute value is too long %s %d > %d"
, avp_attr_type_string((avp)->attr_type), (avp)->length
- 6, (int)(sizeof(dpi->auth_chall))); goto size_check_failed
; } } while ( 0)
;
550 memcpy(dpi->auth_chall, avp->attr_value,
551 avp_attr_length(avp)((avp)->length - 6));
552 dpi->lauth_chall = avp_attr_length(avp)((avp)->length - 6);
553 break;
554 case L2TP_AVP_TYPE_PROXY_AUTHEN_ID32:
555 AVP_SIZE_CHECK(avp, ==, 8)do { if (!((avp)->length == (8))) { snprintf(emes, sizeof(
emes), "invalid packet size %s %d" "==" "%d)", avp_attr_type_string
((avp)->attr_type), (avp)->length, (8)); goto size_check_failed
; } } while ( 0)
;
556 dpi->auth_id = avp_get_val16(avp);
557 break;
558 case L2TP_AVP_TYPE_PROXY_AUTHEN_NAME30:
559 AVP_MAXLEN_CHECK(avp, sizeof(dpi->username) - 1)do { if ((avp)->length > (sizeof(dpi->username) - 1)
+ 6) { snprintf(emes, sizeof(emes), "Attribute value is too long %s %d > %d"
, avp_attr_type_string((avp)->attr_type), (avp)->length
- 6, (int)(sizeof(dpi->username) - 1)); goto size_check_failed
; } } while ( 0)
;
560 memcpy(dpi->username, avp->attr_value,
561 avp_attr_length(avp)((avp)->length - 6));
562 break;
563 case L2TP_AVP_TYPE_PROXY_AUTHEN_RESPONSE33:
564 AVP_MAXLEN_CHECK(avp, sizeof(dpi->auth_resp))do { if ((avp)->length > (sizeof(dpi->auth_resp)) + 6
) { snprintf(emes, sizeof(emes), "Attribute value is too long %s %d > %d"
, avp_attr_type_string((avp)->attr_type), (avp)->length
- 6, (int)(sizeof(dpi->auth_resp))); goto size_check_failed
; } } while ( 0)
;
565 memcpy(dpi->auth_resp, avp->attr_value,
566 avp_attr_length(avp)((avp)->length - 6));
567 dpi->lauth_resp = avp_attr_length(avp)((avp)->length - 6);
568 break;
569 case L2TP_AVP_TYPE_PROXY_AUTHEN_TYPE29:
570 AVP_SIZE_CHECK(avp, ==, 8)do { if (!((avp)->length == (8))) { snprintf(emes, sizeof(
emes), "invalid packet size %s %d" "==" "%d)", avp_attr_type_string
((avp)->attr_type), (avp)->length, (8)); goto size_check_failed
; } } while ( 0)
;
571 switch (avp_get_val16(avp)) {
572 default:
573 l2tp_call_log(_this, LOG_WARNING4,
574 "RecvICCN Unknown proxy-authen-type=%d",
575 avp_get_val16(avp));
576 /* FALLTHROUGH */
577 case L2TP_AUTH_TYPE_NO_AUTH4:
578 dpi->auth_type = 0;
579 break;
580 case L2TP_AUTH_TYPE_PPP_CHAP2:
581 dpi->auth_type = PPP_AUTH_CHAP_MD50x05;
582 break;
583 case L2TP_AUTH_TYPE_PPP_PAP3:
584 dpi->auth_type = PPP_AUTH_PAP0xc023;
585 break;
586 case L2TP_AUTH_TYPE_MS_CHAP_V15:
587 dpi->auth_type = PPP_AUTH_CHAP_MS0x80;
588 break;
589 }
590 break;
591 default:
592 if (avp->is_mandatory != 0) {
593 l2tp_call_log(_this, LOG_WARNING4,
594 "AVP (%s/%d) is not supported, but it's "
595 "mandatory",
596 avp_attr_type_string(avp->attr_type),
597 avp->attr_type);
598 l2tp_call_disconnect(_this,
599 L2TP_CDN_RCODE_ERROR_CODE2,
600 L2TP_ECODE_UNKNOWN_MANDATORY_AVP8, NULL((void*)0),
601 NULL((void*)0), 0);
602 return 1;
603#ifdef L2TP_CALL_DEBUG
604 } else {
605 L2TP_CALL_DBG((_this, LOG_DEBUG,
606 "AVP (%s/%d) is not handled",
607 avp_attr_type_string(avp->attr_type),
608 avp->attr_type));
609#endif
610 }
611 }
612 }
613 l2tp_call_log(_this, LOG_INFO6, "RecvICCN "
614 "session_id=%u calling_number=%s tx_conn_speed=%u framing=%s",
615 _this->peer_session_id, _this->calling_number, tx_conn_speed,
616 ((framing_type & L2TP_FRAMING_CAP_FLAGS_ASYNC0x00000002) != 0)? "async" :
617 ((framing_type & L2TP_FRAMING_CAP_FLAGS_SYNC0x00000001) != 0)? "sync" :
618 "unknown");
619
620 return 0;
621size_check_failed:
622 l2tp_call_log(_this, LOG_ERR3, "Received bad ICCN: %s", emes);
623 l2tp_call_disconnect(_this, L2TP_CDN_RCODE_ERROR_CODE2,
624 L2TP_ECODE_WRONG_LENGTH2, NULL((void*)0), NULL((void*)0), 0);
625 return 1;
626}
627
628/* receive CDN */
629static int
630l2tp_recv_CDN(l2tp_call *_this, u_char *pkt, int pktlen)
631{
632 int result, error, avpsz, len, sessid;
633 struct l2tp_avp *avp;
634 char buf[L2TP_AVP_MAXSIZ1024], emes[256], pmes[256];
635
636 /* initialize */
637 result = 0;
638 error = 0;
639 sessid = 0;
Value stored to 'sessid' is never read
640 strlcpy(pmes, "(none)", sizeof(pmes));
641
642 avp = (struct l2tp_avp *)buf;
643 while (pktlen >= 6 && (avpsz = avp_enum(avp, pkt, pktlen, 1)) > 0) {
644 pkt += avpsz;
645 pktlen -= avpsz;
646 if (avp->vendor_id != 0) {
647 L2TP_CALL_DBG((_this, LOG_DEBUG,
648 "Received a Vendor-specific AVP vendor-id=%d "
649 "type=%d", avp->vendor_id, avp->attr_type));
650 continue;
651 }
652 if (avp->is_hidden != 0) {
653 l2tp_call_log(_this, LOG_WARNING4,
654 "Received AVP (%s/%d) is hidden. But we don't "
655 "share secret.",
656 avp_attr_type_string(avp->attr_type),
657 avp->attr_type);
658 if (avp->is_mandatory != 0) {
659 l2tp_call_disconnect(_this,
660 L2TP_CDN_RCODE_ERROR_CODE2,
661 L2TP_ECODE_UNKNOWN_MANDATORY_AVP8, NULL((void*)0),
662 NULL((void*)0), 0);
663 return 1;
664 }
665 continue;
666 }
667 switch (avp->attr_type) {
668 case L2TP_AVP_TYPE_MESSAGE_TYPE0:
669 AVP_SIZE_CHECK(avp, ==, 8)do { if (!((avp)->length == (8))) { snprintf(emes, sizeof(
emes), "invalid packet size %s %d" "==" "%d)", avp_attr_type_string
((avp)->attr_type), (avp)->length, (8)); goto size_check_failed
; } } while ( 0)
;
670 continue;
671 case L2TP_AVP_TYPE_RESULT_CODE1:
672 AVP_SIZE_CHECK(avp, >=, 8)do { if (!((avp)->length >= (8))) { snprintf(emes, sizeof
(emes), "invalid packet size %s %d" ">=" "%d)", avp_attr_type_string
((avp)->attr_type), (avp)->length, (8)); goto size_check_failed
; } } while ( 0)
;
673 result = avp->attr_value[0] << 8 | avp->attr_value[1];
674 if (avp->length >= 10) {
675 error = avp->attr_value[2] << 8 |
676 avp->attr_value[3];
677 len = avp->length - 12;
678 if (len > 0) {
679 len = MINIMUM(len, sizeof(pmes) - 1)(((len) < (sizeof(pmes) - 1)) ? (len) : (sizeof(pmes) - 1)
)
;
680 memcpy(pmes, &avp->attr_value[4], len);
681 pmes[len] = '\0';
682 }
683 }
684 continue;
685 case L2TP_AVP_TYPE_ASSIGNED_SESSION_ID14:
686 AVP_SIZE_CHECK(avp, >=, 8)do { if (!((avp)->length >= (8))) { snprintf(emes, sizeof
(emes), "invalid packet size %s %d" ">=" "%d)", avp_attr_type_string
((avp)->attr_type), (avp)->length, (8)); goto size_check_failed
; } } while ( 0)
;
687 sessid = avp_get_val16(avp);
688 continue;
689 default:
690 if (avp->is_mandatory) {
691 l2tp_call_log(_this, LOG_WARNING4,
692 "AVP (%s/%d) is not supported, but it's "
693 "mandatory",
694 avp_attr_type_string(avp->attr_type),
695 avp->attr_type);
696 if (avp->is_mandatory != 0) {
697 l2tp_call_disconnect(_this,
698 L2TP_CDN_RCODE_ERROR_CODE2,
699 L2TP_ECODE_UNKNOWN_MANDATORY_AVP8,
700 NULL((void*)0), NULL((void*)0), 0);
701 return 1;
702 }
703#ifdef L2TP_CALL_DEBUG
704 } else {
705 L2TP_CALL_DBG((_this, LOG_DEBUG,
706 "AVP (%s/%d) is not handled",
707 avp_attr_type_string(avp->attr_type),
708 avp->attr_type));
709#endif
710 }
711 }
712 }
713 if (error == 0) {
714 l2tp_call_log(_this, LOG_INFO6,
715 "RecvCDN result=%s/%d", l2tp_cdn_rcode_string(result),
716 result);
717 } else {
718 l2tp_call_log(_this, LOG_INFO6,
719 "RecvCDN result=%s/%d error=%s/%d message=%s",
720 l2tp_cdn_rcode_string(result), result,
721 l2tp_ecode_string(error), error, pmes);
722 }
723
724 return 0;
725
726size_check_failed:
727 /* continue to process even if the CDN message was broken */
728 l2tp_call_log(_this, LOG_ERR3, "Received bad CDN: %s", emes);
729
730 return 0;
731}
732
733/* send CDN */
734static int
735l2tp_call_send_CDN(l2tp_call *_this, int result_code, int error_code, const
736 char *errmes, struct l2tp_avp *addavp[], int naddavp)
737{
738 uint32_t val32;
739 int i, avplen, len;
740 struct l2tp_avp *avp;
741 char buf[L2TP_AVP_MAXSIZ1024];
742 bytebuffer *bytebuf;
743
744 L2TP_CALL_ASSERT(_this != NULL);
745 bytebuf = l2tp_ctrl_prepare_snd_buffer(_this->ctrl, 1);
746 if (bytebuf == NULL((void*)0)) {
747 l2tp_call_log(_this, LOG_ERR3, "sending CDN failed: no buffer");
748 return 1;
749 }
750 avp = (struct l2tp_avp *)buf;
751
752 /* Message Type = CDN */
753 memset(avp, 0, sizeof(*avp));
754 avp->is_mandatory = 1;
755 avp->attr_type = L2TP_AVP_TYPE_MESSAGE_TYPE0;
756 avp_set_val16(avp, L2TP_AVP_MESSAGE_TYPE_CDN14);
757 bytebuf_add_avp(bytebuf, avp, 2);
758
759 /* Result Code */
760 memset(avp, 0, sizeof(*avp));
761 avp->is_mandatory = 1;
762 avp->attr_type = L2TP_AVP_TYPE_RESULT_CODE1;
763#if 0
764/*
765 * Windows 2000 work around:
766 * Windows 2000 will return "2 - Length is wrong" in StopCCN,
767 * when it received "length = 8 and no error code AVP".
768 * Avoid the error, use AVP length = 10.
769 */
770 if (error_code > 0) {
771 val32 = (result_code << 16) | (error_code & 0xffff);
772 avplen = 4;
773 avp_set_val32(avp, val32);
774 } else {
775 avplen = 2;
776 avp_set_val16(avp, result_code);
777 }
778#else
779 val32 = (result_code << 16) | (error_code & 0xffff);
780 avplen = 4;
781 avp_set_val32(avp, val32);
782#endif
783
784 if (errmes != NULL((void*)0)) {
785 len = MINIMUM(strlen(errmes), L2TP_AVP_MAXSIZ - 128)(((strlen(errmes)) < (1024 - 128)) ? (strlen(errmes)) : (1024
- 128))
;
786 memcpy(&avp->attr_value[avplen], errmes, len);
787 avplen += len;
788 }
789 bytebuf_add_avp(bytebuf, avp, avplen);
790
791 /* Assigned Session Id */
792 memset(avp, 0, sizeof(*avp));
793 avp->is_mandatory = 1;
794 avp->attr_type = L2TP_AVP_TYPE_ASSIGNED_SESSION_ID14;
795 if (_this != NULL((void*)0) && _this->session_id != 0)
796 avp_set_val16(avp, _this->session_id);
797 else
798 avp_set_val16(avp, 0);
799 bytebuf_add_avp(bytebuf, avp, 2);
800
801 for (i = 0; i < naddavp; i++)
802 bytebuf_add_avp(bytebuf, addavp[i], addavp[i]->length - 6);
803
804 if (l2tp_ctrl_send_packet(_this->ctrl, _this->peer_session_id,
805 bytebuf) != 0) {
806 l2tp_call_log(_this, LOG_ERR3, "Error sending CDN: %m");
807 return 1;
808 }
809
810 if (error_code > 0) {
811 l2tp_call_log(_this, LOG_INFO6,
812 "SendCDN result=%s/%d error=%s/%d message=%s",
813 l2tp_cdn_rcode_string(result_code), result_code,
814 l2tp_ecode_string(error_code), error_code,
815 (errmes == NULL((void*)0))? "none" : errmes);
816 } else {
817 l2tp_call_log(_this, LOG_INFO6, "SendCDN result=%s/%d",
818 l2tp_cdn_rcode_string(result_code), result_code);
819 }
820
821 return 0;
822}
823
824/* send ZLB */
825static int
826l2tp_call_send_ZLB(l2tp_call *_this)
827{
828 bytebuffer *bytebuf;
829
830 l2tp_call_log(_this, LOG_INFO6, "SendZLB");
831 bytebuf = l2tp_ctrl_prepare_snd_buffer(_this->ctrl, 1);
832 if (bytebuf == NULL((void*)0)) {
833 l2tp_call_log(_this, LOG_ERR3, "sending ZLB failed: no buffer");
834 return 1;
835 }
836 return l2tp_ctrl_send_packet(_this->ctrl, _this->peer_session_id,
837 bytebuf);
838}
839
840/*
841 * misc
842 */
843/* logging with the label of the instance */
844static void
845l2tp_call_log(l2tp_call *_this, int prio, const char *fmt, ...)
846{
847 char logbuf[BUFSIZ1024];
848 va_list ap;
849
850 va_start(ap, fmt)__builtin_va_start(ap, fmt);
851#ifdef L2TPD_MULTIPLE
852 snprintf(logbuf, sizeof(logbuf), "l2tpd id=%u ctrl=%u call=%u %s",
853 _this->ctrl->l2tpd->id, _this->ctrl->id, _this->id, fmt);
854#else
855 snprintf(logbuf, sizeof(logbuf), "l2tpd ctrl=%u call=%u %s",
856 _this->ctrl->id, _this->id, fmt);
857#endif
858 vlog_printf(prio, logbuf, ap);
859 va_end(ap)__builtin_va_end(ap);
860}
861
862/* convert current status to strings */
863static inline const char *
864l2tp_call_state_string(l2tp_call *_this)
865{
866 switch (_this->state) {
867 case L2TP_CALL_STATE_IDLE0: return "idle";
868 case L2TP_CALL_STATE_WAIT_CONN1: return "wait-conn";
869 case L2TP_CALL_STATE_ESTABLISHED2: return "established";
870 case L2TP_CALL_STATE_CLEANUP_WAIT3: return "cleanup-wait";
871 }
872 return "unknown";
873}
874
875/*
876 * npppd physical layer
877 */
878
879/* input packet to ppp */
880void
881l2tp_call_ppp_input(l2tp_call *_this, u_char *pkt, int pktlen, int delayed)
882{
883 int rval;
884 npppd_ppp *ppp;
885
886 ppp = _this->ppp;
887 rval = ppp->recv_packet(ppp, pkt, pktlen,
888 delayed ? PPP_IO_FLAGS_DELAYED0x0002 : 0);
889
890 if (_this->ppp == NULL((void*)0)) /* ppp is freed */
891 return;
892
893 if (rval != 0)
894 ppp->ierrors++;
895 else {
896 ppp->ipackets++;
897 ppp->ibytes += pktlen;
898 }
899}
900
901/* called ppp output a packet */
902static int
903l2tp_call_ppp_output(npppd_ppp *ppp, unsigned char *bytes, int nbytes,
904 int flags)
905{
906 l2tp_call *_this;
907 bytebuffer *bytebuf;
908
909 _this = ppp->phy_context;
910
911 bytebuf = l2tp_ctrl_prepare_snd_buffer(_this->ctrl, _this->use_seq);
912
913 if (bytebuf != NULL((void*)0)) {
914 bytebuffer_put(bytebuf, bytes, nbytes);
915 if (l2tp_call_send_data_packet(_this, bytebuf) != 0)
916 ppp->oerrors++;
917 else {
918 ppp->opackets++;
919 ppp->obytes += nbytes;
920 }
921 } else
922 ppp->oerrors++;
923
924 return 0;
925}
926
927/* it will be called when the connection was closed at ppp */
928static void
929l2tp_call_closed_by_ppp(npppd_ppp *ppp)
930{
931 l2tp_call *_this;
932
933 L2TP_CALL_ASSERT(ppp != NULL);
934 L2TP_CALL_ASSERT(ppp->phy_context != NULL);
935
936 _this = ppp->phy_context;
937
938 /* do before l2tp_call_disconnect() */
939 _this->ppp = NULL((void*)0);
940
941 if (_this->state == L2TP_CALL_STATE_CLEANUP_WAIT3) {
942 /* no need to call l2tp_call_disconnect */
943 } else if (ppp->disconnect_code == PPP_DISCON_NO_INFORMATION) {
944 l2tp_call_disconnect(_this,
945 L2TP_CDN_RCODE_ADMINISTRATIVE_REASON3, 0, NULL((void*)0), NULL((void*)0), 0);
946 } else {
947 /*
948 * RFC3145 L2TP Disconnect Cause Information
949 */
950 struct l2tp_avp *avp[1];
951 struct _ppp_cause {
952 struct l2tp_avp avp;
953 uint16_t code;
954 uint16_t proto;
955 uint8_t direction;
956 char message[128];
957 } __attribute__((__packed__)) ppp_cause;
958
959 ppp_cause.avp.is_mandatory = 0;
960 ppp_cause.avp.is_hidden = 0;
961 ppp_cause.avp.vendor_id = 0; /* ietf */
962 ppp_cause.avp.attr_type =
963 L2TP_AVP_TYPE_PPP_DISCONNECT_CAUSE_CODE46;
964 ppp_cause.code = htons(ppp->disconnect_code)(__uint16_t)(__builtin_constant_p(ppp->disconnect_code) ? (
__uint16_t)(((__uint16_t)(ppp->disconnect_code) & 0xffU
) << 8 | ((__uint16_t)(ppp->disconnect_code) & 0xff00U
) >> 8) : __swap16md(ppp->disconnect_code))
;
965 ppp_cause.proto = htons(ppp->disconnect_proto)(__uint16_t)(__builtin_constant_p(ppp->disconnect_proto) ?
(__uint16_t)(((__uint16_t)(ppp->disconnect_proto) & 0xffU
) << 8 | ((__uint16_t)(ppp->disconnect_proto) & 0xff00U
) >> 8) : __swap16md(ppp->disconnect_proto))
;
966 ppp_cause.direction = ppp->disconnect_direction;
967 ppp_cause.avp.length = offsetof(struct _ppp_cause, message[0])__builtin_offsetof(struct _ppp_cause, message[0]);
968
969 if (ppp->disconnect_message != NULL((void*)0)) {
970 strlcpy(ppp_cause.message, ppp->disconnect_message,
971 sizeof(ppp_cause.message));
972 ppp_cause.avp.length += strlen(ppp_cause.message);
973 }
974 avp[0] = &ppp_cause.avp;
975 l2tp_call_disconnect(_this,
976 L2TP_CDN_RCODE_ERROR_CODE2, L2TP_ECODE_GENERIC_ERROR6,
977 "Disconnected by local PPP", avp, 1);
978 }
979 l2tp_call_log(_this, LOG_NOTICE5, "logtype=PPPUnbind");
980}
981
982/* notify disconnection to ppp to terminate or free of ppp */
983static void
984l2tp_call_notify_down(l2tp_call *_this)
985{
986 if (_this->ppp != NULL((void*)0))
987 ppp_phy_downed(_this->ppp);
988}
989
990/* bind ppp */
991static int
992l2tp_call_bind_ppp(l2tp_call *_this, dialin_proxy_info *dpi)
993{
994 int code, errcode;
995 npppd_ppp *ppp;
996
997 code = L2TP_CDN_RCODE_BUSY8;
998 errcode = 0;
999 ppp = NULL((void*)0);
1000 if ((ppp = ppp_create()) == NULL((void*)0))
1001 goto fail;
1002
1003 ASSERT(_this->ppp == NULL)((void)0);;
1004
1005 if (_this->ppp != NULL((void*)0))
1006 return -1;
1007
1008 _this->ppp = ppp;
1009
1010 ppp->tunnel_type = NPPPD_TUNNEL_L2TP1;
1011 ppp->tunnel_session_id = _this->session_id;
1012 ppp->phy_context = _this;
1013 ppp->send_packet = l2tp_call_ppp_output;
1014 ppp->phy_close = l2tp_call_closed_by_ppp;
1015
1016 strlcpy(ppp->phy_label, L2TP_CTRL_LISTENER_TUN_NAME(_this->ctrl)((l2tpd_listener *)slist_get(&(_this->ctrl)->l2tpd->
listener, (_this->ctrl)->listener_index))->tun_name
,
1017 sizeof(ppp->phy_label));
1018 L2TP_CALL_ASSERT(sizeof(ppp->phy_info) >= _this->ctrl->peer.ss_len);
1019 memcpy(&ppp->phy_info, &_this->ctrl->peer,
1020 MINIMUM(sizeof(ppp->phy_info), _this->ctrl->peer.ss_len)(((sizeof(ppp->phy_info)) < (_this->ctrl->peer.ss_len
)) ? (sizeof(ppp->phy_info)) : (_this->ctrl->peer.ss_len
))
);
1021 strlcpy(ppp->calling_number, _this->calling_number,
1022 sizeof(ppp->calling_number));
1023 if (ppp_init(npppd_get_npppd(), ppp) != 0) {
1024 l2tp_call_log(_this, LOG_ERR3, "failed binding ppp");
1025 goto fail;
1026 }
1027
1028 l2tp_call_log(_this, LOG_NOTICE5, "logtype=PPPBind ppp=%d", ppp->id);
1029 if (DIALIN_PROXY_IS_REQUESTED(dpi)(((dpi)->last_sent_lcp.ldata > 0)? 1 : 0)) {
1030 if (!L2TP_CTRL_CONF(_this->ctrl)((l2tpd_listener *)slist_get(&(_this->ctrl)->l2tpd->
listener, (_this->ctrl)->listener_index))->conf
->accept_dialin) {
1031 l2tp_call_log(_this, LOG_ERR3,
1032 "'accept_dialin' is 'false' in the setting.");
1033 code = L2TP_CDN_RCODE_ERROR_CODE2;
1034 errcode = L2TP_ECODE_INVALID_MESSAGE3;
1035 goto fail;
1036 }
1037
1038 if (ppp_dialin_proxy_prepare(ppp, dpi) != 0) {
1039 code = L2TP_CDN_RCODE_TEMP_NOT_AVALIABLE4;
1040 goto fail;
1041 }
1042 }
1043 ppp_start(ppp);
1044
1045 return 0;
1046fail:
1047 if (ppp != NULL((void*)0))
1048 ppp_destroy(ppp);
1049 _this->ppp = NULL((void*)0);
1050
1051 l2tp_call_disconnect(_this, code, errcode, NULL((void*)0), NULL((void*)0), 0);
1052 return 1;
1053}