Bug Summary

File:src/usr.sbin/npppd/npppd/npppd.c
Warning:line 1735, column 6
Value stored to 'rval' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name npppd.c -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 -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -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/llvm16/lib/clang/16 -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/llvm16/lib/clang/16/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 -fcf-protection=branch -fno-jump-tables -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/scan/2024-01-11-140451-98009-1 -x c /usr/src/usr.sbin/npppd/npppd/npppd.c
1/* $OpenBSD: npppd.c,v 1.53 2022/07/01 09:57:24 mvs Exp $ */
2
3/*-
4 * Copyright (c) 2005-2008,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 * Next pppd(nppd). This file provides a npppd daemon process and operations
30 * for npppd instance.
31 * @author Yasuoka Masahiko
32 * $Id: npppd.c,v 1.53 2022/07/01 09:57:24 mvs Exp $
33 */
34#include "version.h"
35#include <sys/param.h> /* ALIGNED_POINTER */
36#include <sys/types.h>
37#include <sys/socket.h>
38#include <sys/sysctl.h>
39#include <sys/wait.h>
40#include <netinet/in.h>
41#include <netinet/ip.h>
42#include <net/route.h>
43#include <arpa/inet.h>
44#include <net/if_dl.h>
45#include <unistd.h>
46#include <time.h>
47#include <syslog.h>
48#include <string.h>
49#include <stdlib.h>
50#include <stdio.h>
51#include <signal.h>
52#include <netdb.h>
53#include <fcntl.h>
54#include <event.h>
55#include <errno(*__errno()).h>
56#include <err.h>
57#include <pwd.h>
58
59#include "pathnames.h"
60#include "debugutil.h"
61#include "addr_range.h"
62#include "npppd_subr.h"
63#include "npppd_local.h"
64#include "npppd_auth.h"
65#include "radish.h"
66#include "net_utils.h"
67#include "time_utils.h"
68
69#include "l2tp_local.h" /* XXX sa_cookie */
70
71#ifdef USE_NPPPD_ARP
72#include "npppd_arp.h"
73#endif
74
75#ifdef USE_NPPPD_PIPEX1
76#ifdef USE_NPPPD_PPPOE1
77#include "pppoe_local.h"
78#endif /* USE_NPPPD_PPPOE */
79#include "psm-opt.h"
80#include <sys/ioctl.h>
81#include <net/pipex.h>
82#endif /* USE_NPPPD_PIPEX */
83
84#include "accept.h"
85#include "log.h"
86
87static npppd s_npppd; /* singleton */
88
89static void npppd_reload0 (npppd *);
90static void npppd_update_pool_reference (npppd *);
91static int npppd_rd_walktree_delete(struct radish_head *);
92static __dead__attribute__((__noreturn__)) void usage (void);
93static void npppd_stop_really (npppd *);
94static uint32_t str_hash(const void *, int);
95static void npppd_on_sighup (int, short, void *);
96static void npppd_on_sigterm (int, short, void *);
97static void npppd_on_sigint (int, short, void *);
98static void npppd_on_sigchld (int, short, void *);
99static void npppd_reset_timer(npppd *);
100static void npppd_timer(int, short, void *);
101static void npppd_auth_finalizer_periodic(npppd *);
102static int rd2slist_walk (struct radish *, void *);
103static int rd2slist (struct radish_head *, slist *);
104static slist *npppd_get_ppp_by_user (npppd *, const char *);
105static int npppd_get_all_users (npppd *, slist *);
106static struct ipcpstat
107 *npppd_get_ipcp_stat(struct ipcpstat_head *, const char *);
108static void npppd_destroy_ipcp_stats(struct ipcpstat_head *);
109static void npppd_ipcp_stats_reload(npppd *);
110
111#ifndef NO_ROUTE_FOR_POOLED_ADDRESS
112static struct in_addr loop; /* initialize at npppd_init() */
113#endif
114static uint32_t str_hash(const void *, int);
115
116#ifdef USE_NPPPD_PIPEX1
117static void pipex_periodic(npppd *);
118#endif /* USE_NPPPD_PIPEX */
119
120#ifdef NPPPD_DEBUG
121#define NPPPD_DBG(x) log_printf x
122#define NPPPD_ASSERT(x) ASSERT(x)((void)0);
123#else
124#define NPPPD_DBG(x)
125#define NPPPD_ASSERT(x)
126#endif
127
128/***********************************************************************
129 * Daemon process
130 ***********************************************************************/
131int main (int, char *[]);
132int debugsyslog = 0; /* used by log.c */
133
134int
135main(int argc, char *argv[])
136{
137 int ch, stop_by_error, runasdaemon = 1, nflag = 0;
138 const char *npppd_conf0 = DEFAULT_NPPPD_CONF"/etc/npppd/npppd.conf";
139 struct passwd *pw;
140
141 while ((ch = getopt(argc, argv, "nf:d")) != -1) {
142 switch (ch) {
143 case 'n':
144 nflag = 1;
145 break;
146 case 'f':
147 npppd_conf0 = optarg;
148 break;
149 case 'd':
150 debuglevel++;
151 runasdaemon = 0;
152 break;
153 default:
154 usage();
155 }
156 }
157 argc -= optind;
158 argv += optind;
159 if (argc != 0)
160 usage();
161 if (nflag) {
162 debuglevel++;
163 runasdaemon = 0;
164 }
165
166 /* for log.c */
167 log_init(debuglevel);
168 if (debuglevel > 0) {
169 /* for ../common/debugutil.c */
170 debug_set_debugfp(stderr(&__sF[2]));
171 debug_use_syslog(0);
172 }
173 if (runasdaemon)
174 daemon(0, 0);
175
176 /* check for root privileges */
177 if (geteuid())
178 errx(1, "need root privileges");
179 /* check for npppd user */
180 if (getpwnam(NPPPD_USER"_ppp") == NULL((void *)0))
181 errx(1, "unknown user %s", NPPPD_USER"_ppp");
182
183 if (privsep_init() != 0)
184 err(1, "cannot drop privileges");
185
186 if (nflag) {
187 if (npppd_config_check(npppd_conf0) == 0) {
188 fprintf(stderr(&__sF[2]), "configuration OK\n");
189 exit(EXIT_SUCCESS0);
190 }
191 exit(EXIT_FAILURE1);
192 }
193 if (npppd_init(&s_npppd, npppd_conf0) != 0)
194 exit(EXIT_FAILURE1);
195
196 if ((pw = getpwnam(NPPPD_USER"_ppp")) == NULL((void *)0))
197 err(EXIT_FAILURE1, "gwpwnam");
198 if (chroot(pw->pw_dir) == -1)
199 err(EXIT_FAILURE1, "chroot");
200 if (chdir("/") == -1)
201 err(EXIT_FAILURE1, "chdir(\"/\")");
202 if (setgroups(1, &pw->pw_gid) ||
203 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
204 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
205 err(EXIT_FAILURE1, "cannot drop privileges");
206 /* privileges is dropped */
207
208 npppd_start(&s_npppd);
209 stop_by_error = s_npppd.stop_by_error;
210 npppd_fini(&s_npppd);
211 privsep_fini();
212 log_printf(LOG_NOTICE5, "Terminate npppd.");
213
214 exit((!stop_by_error)? EXIT_SUCCESS0 : EXIT_FAILURE1);
215}
216
217static __dead__attribute__((__noreturn__)) void
218usage(void)
219{
220 fprintf(stderr(&__sF[2]), "usage: npppd [-dn] [-f config_file]\n");
221 exit(1);
222}
223
224/** Returns the singleton npppd instance */
225npppd *
226npppd_get_npppd()
227{
228 return &s_npppd;
229}
230
231/***********************************************************************
232 * Operations to npppd itself (initialize/finalize/start/stop)
233 ***********************************************************************/
234 /** Initialize the npppd */
235int
236npppd_init(npppd *_this, const char *config_file)
237{
238 int i, status = -1, value;
239 const char *pidpath0;
240 FILE *pidfp = NULL((void *)0);
241 struct tunnconf *tunn;
242 struct ipcpconf *ipcpconf;
243 struct ipcpstat *ipcpstat;
244 int mib[] = { CTL_NET4, PF_PIPEX35, PIPEXCTL_ENABLE1 };
245 size_t size;
246
247 memset(_this, 0, sizeof(npppd));
248#ifndef NO_ROUTE_FOR_POOLED_ADDRESS
249 loop.s_addr = htonl(INADDR_LOOPBACK)(__uint32_t)(__builtin_constant_p(((u_int32_t)(0x7f000001))) ?
(__uint32_t)(((__uint32_t)(((u_int32_t)(0x7f000001))) & 0xff
) << 24 | ((__uint32_t)(((u_int32_t)(0x7f000001))) &
0xff00) << 8 | ((__uint32_t)(((u_int32_t)(0x7f000001))
) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t)(0x7f000001
))) & 0xff000000) >> 24) : __swap32md(((u_int32_t)(
0x7f000001))))
;
250#endif
251
252 NPPPD_ASSERT(config_file != NULL);
253
254 pidpath0 = NULL((void *)0);
255 _this->pid = getpid();
256 slist_init(&_this->realms);
257 npppd_conf_init(&_this->conf);
258
259 log_printf(LOG_NOTICE5, "Starting npppd pid=%u version=%s",
260 _this->pid, VERSION"5.0.0");
261#if defined(BUILD_DATE) && defined(BUILD_TIME)
262 log_printf(LOG_INFO6, "Build %s %s ", BUILD_DATE, BUILD_TIME);
263#endif
264 if (get_nanotime() == INT64_MIN(-0x7fffffffffffffffLL - 1)) {
265 log_printf(LOG_ERR3, "get_nanotime() failed: %m");
266 return 1;
267 }
268
269 if (realpath(config_file, _this->config_file) == NULL((void *)0)) {
270 log_printf(LOG_ERR3, "realpath(%s,) failed in %s(): %m",
271 config_file, __func__);
272 return 1;
273 }
274 /* we assume 4.4 compatible realpath(). See realpath(3) on BSD. */
275 NPPPD_ASSERT(_this->config_file[0] == '/');
276
277 _this->boot_id = arc4random();
278
279#ifdef USE_NPPPD_L2TP1
280 if (l2tpd_init(&_this->l2tpd) != 0)
281 return (-1);
282#endif
283#ifdef USE_NPPPD_PPTP1
284 if (pptpd_init(&_this->pptpd) != 0)
285 return (-1);
286#endif
287#ifdef USE_NPPPD_PPPOE1
288 if (pppoed_init(&_this->pppoed) != 0)
289 return (-1);
290#endif
291 LIST_INIT(&_this->ipcpstats)do { ((&_this->ipcpstats)->lh_first) = ((void *)0);
} while (0)
;
292
293 /* load configuration */
294 if ((status = npppd_reload_config(_this)) != 0)
295 return status;
296
297 TAILQ_FOREACH(tunn, &_this->conf.tunnconfs, entry)for((tunn) = ((&_this->conf.tunnconfs)->tqh_first);
(tunn) != ((void *)0); (tunn) = ((tunn)->entry.tqe_next))
{
298 if (tunn->pipex) {
299 size = sizeof(value);
300 if (!sysctl(mib, nitems(mib)(sizeof((mib)) / sizeof((mib)[0])), &value, &size, NULL((void *)0), 0)
301 && value == 0)
302 log_printf(LOG_WARNING4,
303 "pipex(4) is disabled by sysctl");
304 break;
305 }
306 }
307
308 if ((_this->map_user_ppp = hash_create(
309 (int (*) (const void *, const void *))strcmp, str_hash,
310 NPPPD_USER_HASH_SIZ1777)) == NULL((void *)0)) {
311 log_printf(LOG_ERR3, "hash_create() failed in %s(): %m",
312 __func__);
313 return -1;
314 }
315
316 if (npppd_ifaces_load_config(_this) != 0) {
317 return -1;
318 }
319
320 TAILQ_FOREACH(ipcpconf, &_this->conf.ipcpconfs, entry)for((ipcpconf) = ((&_this->conf.ipcpconfs)->tqh_first
); (ipcpconf) != ((void *)0); (ipcpconf) = ((ipcpconf)->entry
.tqe_next))
{
321 ipcpstat = malloc(sizeof(*ipcpstat));
322 if (ipcpstat == NULL((void *)0)) {
323 log_printf(LOG_ERR3, "initializing ipcp_stats failed : %m");
324 npppd_destroy_ipcp_stats(&_this->ipcpstats);
325 return -1;
326 }
327 memset(ipcpstat, 0, sizeof(*ipcpstat));
328 strlcpy(ipcpstat->name, ipcpconf->name, sizeof(ipcpstat->name));
329 LIST_INSERT_HEAD(&_this->ipcpstats, ipcpstat, entry)do { if (((ipcpstat)->entry.le_next = (&_this->ipcpstats
)->lh_first) != ((void *)0)) (&_this->ipcpstats)->
lh_first->entry.le_prev = &(ipcpstat)->entry.le_next
; (&_this->ipcpstats)->lh_first = (ipcpstat); (ipcpstat
)->entry.le_prev = &(&_this->ipcpstats)->lh_first
; } while (0)
;
330 }
331
332 pidpath0 = DEFAULT_NPPPD_PIDFILE"/var/run/npppd.pid";
333
334 /* initialize event(3) */
335 event_init();
336 _this->ctl_sock.cs_name = NPPPD_SOCKET"/var/run/npppd.sock";
337 _this->ctl_sock.cs_ctx = _this;
338 if (control_init(&_this->ctl_sock) == -1) {
339 log_printf(LOG_ERR3, "control_init() failed %s(): %m",
340 __func__);
341 return (-1);
342 }
343 if (control_listen(&_this->ctl_sock) == -1) {
344 log_printf(LOG_ERR3, "control_listen() failed %s(): %m",
345 __func__);
346 return (-1);
347 }
348 accept_init();
349
350 /* ignore signals */
351 signal(SIGPIPE13, SIG_IGN(void (*)(int))1);
352 signal(SIGURG16, SIG_IGN(void (*)(int))1);
353
354 /* set signal handlers */
355 signal_set(&_this->ev_sigterm, SIGTERM, npppd_on_sigterm, _this)event_set(&_this->ev_sigterm, 15, 0x08|0x10, npppd_on_sigterm
, _this)
;
356 signal_set(&_this->ev_sigint, SIGINT, npppd_on_sigint, _this)event_set(&_this->ev_sigint, 2, 0x08|0x10, npppd_on_sigint
, _this)
;
357 signal_set(&_this->ev_sighup, SIGHUP, npppd_on_sighup, _this)event_set(&_this->ev_sighup, 1, 0x08|0x10, npppd_on_sighup
, _this)
;
358 signal_set(&_this->ev_sigchld, SIGCHLD, npppd_on_sigchld, _this)event_set(&_this->ev_sigchld, 20, 0x08|0x10, npppd_on_sigchld
, _this)
;
359 signal_add(&_this->ev_sigterm, NULL)event_add(&_this->ev_sigterm, ((void *)0));
360 signal_add(&_this->ev_sigint, NULL)event_add(&_this->ev_sigint, ((void *)0));
361 signal_add(&_this->ev_sighup, NULL)event_add(&_this->ev_sighup, ((void *)0));
362 signal_add(&_this->ev_sigchld, NULL)event_add(&_this->ev_sigchld, ((void *)0));
363
364 evtimer_set(&_this->ev_timer, npppd_timer, _this)event_set(&_this->ev_timer, -1, 0, npppd_timer, _this);
365
366 /* start tun(4) or pppac(4) */
367 status = 0;
368 for (i = 0; i < countof(_this->iface)(sizeof(_this->iface) / sizeof((_this->iface)[0])); i++) {
369 if (_this->iface[i].initialized != 0)
370 status |= npppd_iface_start(&_this->iface[i]);
371 }
372 if (status != 0)
373 return -1;
374
375 /*
376 * If the npppd can start(open) interfaces successfully, it can
377 * act as only one npppd process on the system and overwrite the pid
378 * file.
379 */
380 if ((pidfp = fopen(pidpath0, "w+")) == NULL((void *)0)) {
381 log_printf(LOG_ERR3, "fopen(%s,w+) failed in %s(): %m",
382 pidpath0, __func__);
383 return -1;
384 }
385 strlcpy(_this->pidpath, pidpath0, sizeof(_this->pidpath));
386 fprintf(pidfp, "%u\n", _this->pid);
387 fclose(pidfp);
388 pidfp = NULL((void *)0);
389#ifdef USE_NPPPD_ARP
390 arp_set_strictintfnetwork(npppd_config_str_equali(_this, "arpd.strictintfnetwork", "true", ARPD_STRICTINTFNETWORK_DEFAULT));
391 if (npppd_config_str_equali(_this, "arpd.enabled", "true", ARPD_DEFAULT) == 1)
392 arp_sock_init();
393#endif
394 if ((status = npppd_modules_reload(_this)) != 0)
395 return status;
396
397 npppd_update_pool_reference(_this);
398
399 return 0;
400}
401
402/** start the npppd */
403void
404npppd_start(npppd *_this)
405{
406 int rval = 0;
407
408 npppd_reset_timer(_this);
409 while ((rval = event_loop(EVLOOP_ONCE0x01)) == 0) {
410 if (_this->finalized != 0)
411 break;
412 }
413 if (rval != 0) {
414 log_printf(LOG_CRIT2, "event_loop() failed: %m");
415 abort();
416 }
417}
418
419/** stop the npppd */
420void
421npppd_stop(npppd *_this)
422{
423 int i;
424#ifdef USE_NPPPD_L2TP1
425 l2tpd_stop(&_this->l2tpd);
426#endif
427#ifdef USE_NPPPD_PPTP1
428 pptpd_stop(&_this->pptpd);
429#endif
430#ifdef USE_NPPPD_PPPOE1
431 pppoed_stop(&_this->pppoed);
432#endif
433#ifdef USE_NPPPD_ARP
434 arp_sock_fini();
435#endif
436 close(_this->ctl_sock.cs_fd);
437 control_cleanup(&_this->ctl_sock);
438
439 for (i = countof(_this->iface)(sizeof(_this->iface) / sizeof((_this->iface)[0])) - 1; i >= 0; i--) {
440 if (_this->iface[i].initialized != 0)
441 npppd_iface_stop(&_this->iface[i]);
442 }
443 npppd_set_radish(_this, NULL((void *)0));
444
445 _this->finalizing = 1;
446 npppd_reset_timer(_this);
447}
448
449static void
450npppd_stop_really(npppd *_this)
451{
452 int i;
453#if defined(USE_NPPPD_L2TP1) || defined(USE_NPPPD_PPTP1)
454 int wait_again;
455
456 wait_again = 0;
457
458#ifdef USE_NPPPD_L2TP1
459 if (!l2tpd_is_stopped(&_this->l2tpd)(((&_this->l2tpd)->state != 2 && (&_this
->l2tpd)->state != 1)? 1 : 0)
)
460 wait_again |= 1;
461#endif
462#ifdef USE_NPPPD_PPTP1
463 if (!pptpd_is_stopped(&_this->pptpd)(((&_this->pptpd)->state != 2 && (&_this
->pptpd)->state != 1)? 1 : 0)
)
464 wait_again |= 1;
465#endif
466 if (wait_again != 0) {
467 npppd_reset_timer(_this);
468 return;
469 }
470#endif
471 for (i = countof(_this->iface)(sizeof(_this->iface) / sizeof((_this->iface)[0])) - 1; i >= 0; i--) {
472 npppd_iface_fini(&_this->iface[i]);
473 }
474 _this->finalized = 1;
475}
476
477/** finalize the npppd */
478void
479npppd_fini(npppd *_this)
480{
481 int i;
482 npppd_auth_base *auth_base;
483
484#ifdef USE_NPPPD_L2TP1
485 l2tpd_uninit(&_this->l2tpd);
486#endif
487#ifdef USE_NPPPD_PPTP1
488 pptpd_uninit(&_this->pptpd);
489#endif
490#ifdef USE_NPPPD_PPPOE1
491 pppoed_uninit(&_this->pppoed);
492#endif
493 for (slist_itr_first(&_this->realms);
494 slist_itr_has_next(&_this->realms);) {
495 auth_base = slist_itr_next(&_this->realms);
496 npppd_auth_destroy(auth_base);
497 }
498 for (i = countof(_this->iface)(sizeof(_this->iface) / sizeof((_this->iface)[0])) - 1; i >= 0; i--) {
499 if (_this->iface[i].initialized != 0)
500 npppd_iface_fini(&_this->iface[i]);
501 }
502
503 for (i = countof(_this->pool)(sizeof(_this->pool) / sizeof((_this->pool)[0])) - 1; i >= 0; i--) {
504 if (_this->pool[i].initialized != 0)
505 npppd_pool_uninit(&_this->pool[i]);
506 }
507
508 npppd_destroy_ipcp_stats(&_this->ipcpstats);
509
510 signal_del(&_this->ev_sigterm)event_del(&_this->ev_sigterm);
511 signal_del(&_this->ev_sigint)event_del(&_this->ev_sigint);
512 signal_del(&_this->ev_sighup)event_del(&_this->ev_sighup);
513 signal_del(&_this->ev_sigchld)event_del(&_this->ev_sigchld);
514
515 npppd_conf_fini(&_this->conf);
516
517 slist_fini(&_this->realms);
518
519 if (_this->map_user_ppp != NULL((void *)0))
520 hash_free(_this->map_user_ppp);
521}
522
523/***********************************************************************
524 * Timer related functions
525 ***********************************************************************/
526static void
527npppd_reset_timer(npppd *_this)
528{
529 struct timeval tv;
530
531 if (_this->finalizing != 0) {
532 /* we can use the timer exclusively on finalizing */
533 tv.tv_usec = 500000;
534 tv.tv_sec = 0;
535 evtimer_add(&_this->ev_timer, &tv)event_add(&_this->ev_timer, &tv);
536 } else {
537 tv.tv_usec = 0;
538 tv.tv_sec = NPPPD_TIMER_TICK_IVAL4;
539 evtimer_add(&_this->ev_timer, &tv)event_add(&_this->ev_timer, &tv);
540 }
541}
542
543static void
544npppd_timer(int fd, short evtype, void *ctx)
545{
546 npppd *_this;
547
548 _this = ctx;
549 if (_this->finalizing != 0) {
550 npppd_stop_really(_this); /* The timer has been reset */
551 return; /* we can use the timer exclusively on finalizing */
552 }
553 _this->secs += NPPPD_TIMER_TICK_IVAL4;
554 if (_this->reloading_count > 0) {
555 _this->reloading_count -= NPPPD_TIMER_TICK_IVAL4;
556 if (_this->reloading_count <= 0) {
557 npppd_reload0(_this);
558 _this->reloading_count = 0;
559 }
560 } else {
561 if ((_this->secs % TIMER_TICK_RUP(((((300) % 4) == 0) ? (300) : (300) + 4 - ((300) % 4))
562 NPPPD_AUTH_REALM_FINALIZER_INTERVAL)((((300) % 4) == 0) ? (300) : (300) + 4 - ((300) % 4))) == 0)
563 npppd_auth_finalizer_periodic(_this);
564 }
565
566#ifdef USE_NPPPD_PPPOE1
567 if (pppoed_need_polling(&_this->pppoed)(((&_this->pppoed)->listen_incomplete != 0)? 1 : 0))
568 pppoed_reload_listeners(&_this->pppoed);
569#endif
570#ifdef USE_NPPPD_PIPEX1
571 pipex_periodic(_this);
572#endif
573
574 npppd_reset_timer(_this);
575}
576
577int
578npppd_reset_routing_table(npppd *_this, int pool_only)
579{
580#ifndef NO_ROUTE_FOR_POOLED_ADDRESS
581 slist rtlist0;
582
583 if (_this->iface[0].using_pppx)
584 return 0;
585
586 slist_init(&rtlist0);
587 if (rd2slist(_this->rd, &rtlist0) != 0)
588 return 1;
589
590 for (slist_itr_first(&rtlist0); slist_itr_has_next(&rtlist0); ) {
591 struct radish *rd;
592 struct sockaddr_npppd *snp;
593 npppd_ppp *ppp;
594 int is_first;
595
596 rd = slist_itr_next(&rtlist0);
597 snp = rd->rd_rtent;
598
599 is_first = 1;
600 for (snp = rd->rd_rtent; snp != NULL((void *)0); snp = snp->snp_next) {
601 switch (snp->snp_type) {
602 case SNP_POOL1:
603 case SNP_DYN_POOL2:
604 if (is_first)
605 in_route_add(&snp->snp_addrsin4.sin_addr,
606 &snp->snp_masksin4mask.sin_addr, &loop,
607 LOOPBACK_IFNAME"lo0", RTF_BLACKHOLE0x1000, 0);
608 break;
609
610 case SNP_PPP3:
611 if (pool_only)
612 break;
613 ppp = snp->snp_data_ptr;
614 if (ppp->ppp_framed_ip_netmasksnp.sin4mask.sin_addr.s_addr
615 == 0xffffffffL) {
616 in_host_route_add(&ppp->
617 ppp_framed_ip_addresssnp.sin4.sin_addr,
618 &ppp_iface(ppp)(&(ppp)->pppd->iface[(ppp)->ifidx])->ip4addr,
619 ppp_iface(ppp)(&(ppp)->pppd->iface[(ppp)->ifidx])->ifname,
620 MRU_IPMTU(ppp->peer_mru)(ppp->peer_mru));
621 } else {
622 in_route_add(&ppp->
623 ppp_framed_ip_addresssnp.sin4.sin_addr,
624 &ppp->ppp_framed_ip_netmasksnp.sin4mask.sin_addr,
625 &ppp_iface(ppp)(&(ppp)->pppd->iface[(ppp)->ifidx])->ip4addr,
626 ppp_iface(ppp)(&(ppp)->pppd->iface[(ppp)->ifidx])->ifname, 0,
627 MRU_IPMTU(ppp->peer_mru)(ppp->peer_mru));
628 }
629 break;
630 }
631 is_first = 0;
632 }
633
634 }
635
636 slist_fini(&rtlist0);
637#endif
638 return 0;
639}
640
641/***********************************************************************
642 * Other npppd related functions.
643 ***********************************************************************/
644/**
645 * Get the user's password. Return 0 on success.
646 *
647 * @param username Username who acquires password
648 * @param password A pointer to a buffer space to store the password.
649 * Use NULL when you need to know only the length of
650 * the password.
651 * @param plpassword A pointer to the length of the password parameter.
652 * This function uses this parameter value and stores
653 * the required length value pointed to by this
654 * parameter. Use NULL when use don't need to know
655 * the password and its length.
656 * @return If the function succeeds, 0 is returned. The function returns
657 * 1 if the username is unknown, returns 2 if the password buffer
658 * length is not enough. It returns negative value for other
659 * errors.
660 */
661int
662npppd_get_user_password(npppd *_this, npppd_ppp *ppp,
663 const char *username, char *password, int *plpassword)
664{
665 char buf0[MAX_USERNAME_LENGTH256];
666
667 NPPPD_ASSERT(ppp->realm != NULL);
668 return npppd_auth_get_user_password(ppp->realm,
669 npppd_auth_username_for_auth(ppp->realm, username, buf0), password,
670 plpassword);
671}
672
673/** Get the Framed-IP-Address attribute of the user */
674struct in_addr *
675npppd_get_user_framed_ip_address(npppd *_this, npppd_ppp *ppp,
676 const char *username)
677{
678
679 if (ppp->peer_auth == 0) {
680 ppp->realm_framed_ip_address.s_addr = 0;
681 goto do_default;
682 }
683 NPPPD_ASSERT(ppp->realm != NULL);
684
685 if (ppp->realm_framed_ip_address.s_addr != 0)
686 return &ppp->realm_framed_ip_address;
687
688 /* assign by the authentication realm */
689 if (npppd_auth_get_framed_ip(ppp->realm, username,
690 &ppp->realm_framed_ip_address,
691 &ppp->realm_framed_ip_netmask) != 0)
692 ppp->realm_framed_ip_address.s_addr = 0;
693
694do_default:
695 /* Use USER_SELECT if the realm doesn't specify the ip address */
696 if (ppp->realm_framed_ip_address.s_addr == 0)
697 ppp->realm_framed_ip_address.s_addr = INADDR_USER_SELECT((__uint32_t)(__builtin_constant_p(0xFFFFFFFFL) ? (__uint32_t
)(((__uint32_t)(0xFFFFFFFFL) & 0xff) << 24 | ((__uint32_t
)(0xFFFFFFFFL) & 0xff00) << 8 | ((__uint32_t)(0xFFFFFFFFL
) & 0xff0000) >> 8 | ((__uint32_t)(0xFFFFFFFFL) &
0xff000000) >> 24) : __swap32md(0xFFFFFFFFL)))
;
698
699
700 if (ppp->realm_framed_ip_address.s_addr == INADDR_USER_SELECT((__uint32_t)(__builtin_constant_p(0xFFFFFFFFL) ? (__uint32_t
)(((__uint32_t)(0xFFFFFFFFL) & 0xff) << 24 | ((__uint32_t
)(0xFFFFFFFFL) & 0xff00) << 8 | ((__uint32_t)(0xFFFFFFFFL
) & 0xff0000) >> 8 | ((__uint32_t)(0xFFFFFFFFL) &
0xff000000) >> 24) : __swap32md(0xFFFFFFFFL)))
) {
701 /* Use NAS_SELECT if USER_SELECT is not allowed by the config */
702 if (!ppp_ipcp(ppp)((ppp)->pppd->iface[(ppp)->ifidx].ipcpconf)->allow_user_select)
703 ppp->realm_framed_ip_address.s_addr = INADDR_NAS_SELECT((__uint32_t)(__builtin_constant_p(0xFFFFFFFEL) ? (__uint32_t
)(((__uint32_t)(0xFFFFFFFEL) & 0xff) << 24 | ((__uint32_t
)(0xFFFFFFFEL) & 0xff00) << 8 | ((__uint32_t)(0xFFFFFFFEL
) & 0xff0000) >> 8 | ((__uint32_t)(0xFFFFFFFEL) &
0xff000000) >> 24) : __swap32md(0xFFFFFFFEL)))
;
704 }
705 NPPPD_DBG((LOG_DEBUG, "%s() = %s", __func__,
706 inet_ntoa(ppp->realm_framed_ip_address)));
707
708 return &ppp->realm_framed_ip_address;
709}
710
711/** XXX */
712int
713npppd_check_calling_number(npppd *_this, npppd_ppp *ppp)
714{
715 struct tunnconf *conf;
716 int lnumber, rval;
717 char number[NPPPD_PHONE_NUMBER_LEN32 + 1];
718
719 conf = ppp_get_tunnconf(ppp);
720 if (conf->callnum_check != 0) {
721 lnumber = sizeof(number);
722 if ((rval = npppd_auth_get_calling_number(ppp->realm,
723 ppp->username, number, &lnumber)) == 0)
724 return
725 (strcmp(number, ppp->calling_number) == 0)? 1 : 0;
726 if ((conf->callnum_check & NPPPD_CALLNUM_CHECK_STRICT1) != 0)
727 return 0;
728 }
729
730 return 1;
731}
732
733/**
734 * This function finds a {@link npppd_ppp} instance that is assigned the
735 * specified ip address and returns it
736 * @param ipaddr IP Address(Specify in network byte order)
737 */
738npppd_ppp *
739npppd_get_ppp_by_ip(npppd *_this, struct in_addr ipaddr)
740{
741 struct sockaddr_npppd *snp;
742 struct radish *rdp;
743 struct sockaddr_in npppd_get_ppp_by_ip_sin4;
744
745 npppd_get_ppp_by_ip_sin4.sin_family = AF_INET2;
746 npppd_get_ppp_by_ip_sin4.sin_len = sizeof(struct sockaddr_in);
747 npppd_get_ppp_by_ip_sin4.sin_addr = ipaddr;
748 if (_this->rd == NULL((void *)0))
749 return NULL((void *)0); /* no radix tree on startup */
750 if (rd_match((struct sockaddr *)&npppd_get_ppp_by_ip_sin4, _this->rd,
751 &rdp)) {
752 snp = rdp->rd_rtent;
753 if (snp->snp_type == SNP_PPP3)
754 return snp->snp_data_ptr;
755 }
756 return NULL((void *)0);
757}
758
759/**
760 * This function finds {@link npppd_ppp} instances that are authenticated
761 * as the specified username and returns them as a {@link slist} list.
762 * @param username PPP Username.
763 * @return {@link slist} that contains the {@link npppd_ppp} instances.
764 * NULL may be returned if no instance has been found.
765 */
766static slist *
767npppd_get_ppp_by_user(npppd *_this, const char *username)
768{
769 hash_link *hl;
770
771 if ((hl = hash_lookup(_this->map_user_ppp, username)) != NULL((void *)0))
772 return hl->item;
773
774 return NULL((void *)0);
775}
776
777/**
778 * This function finds a {@link npppd_ppp} instance that matches the specified
779 * ppp id and returns it.
780 * @param id {@link npppd_ppp#id ppp's id}
781 * @return This function returns the pointer if the instance which has
782 * specified ID is found, otherwise it returns NULL.
783 */
784npppd_ppp *
785npppd_get_ppp_by_id(npppd *_this, u_int ppp_id)
786{
787 slist users;
788 npppd_ppp *ppp0, *ppp;
789
790 NPPPD_ASSERT(_this != NULL);
791
792 ppp = NULL((void *)0);
793 slist_init(&users);
794 if (npppd_get_all_users(_this, &users) != 0) {
795 log_printf(LOG_WARNING4,
796 "npppd_get_all_users() failed in %s()", __func__);
797 } else {
798 /* FIXME: This linear search eats CPU. */
799 for (slist_itr_first(&users); slist_itr_has_next(&users); ) {
800 ppp0 = slist_itr_next(&users);
801 if (ppp0->id == ppp_id) {
802 ppp = ppp0;
803 break;
804 }
805 }
806 }
807 slist_fini(&users);
808
809 return ppp;
810}
811
812static struct ipcpstat *
813npppd_get_ipcp_stat(struct ipcpstat_head *head , const char *ipcp_name)
814{
815 struct ipcpstat *ipcpstat = NULL((void *)0);
816
817 LIST_FOREACH(ipcpstat, head, entry)for((ipcpstat) = ((head)->lh_first); (ipcpstat)!= ((void *
)0); (ipcpstat) = ((ipcpstat)->entry.le_next))
{
818 if (strncmp(ipcpstat->name, ipcp_name,
819 sizeof(ipcpstat->name)) == 0)
820 return ipcpstat;
821 }
822
823 return NULL((void *)0);
824}
825
826static void
827npppd_destroy_ipcp_stats(struct ipcpstat_head *head)
828{
829 struct ipcpstat *ipcpstat, *tipcpstat;
830 npppd_ppp *ppp, *tppp;
831
832 LIST_FOREACH_SAFE(ipcpstat, head, entry, tipcpstat)for ((ipcpstat) = ((head)->lh_first); (ipcpstat) &&
((tipcpstat) = ((ipcpstat)->entry.le_next), 1); (ipcpstat
) = (tipcpstat))
{
833 LIST_FOREACH_SAFE(ppp, &ipcpstat->ppp, ipcpstat_entry, tppp)for ((ppp) = ((&ipcpstat->ppp)->lh_first); (ppp) &&
((tppp) = ((ppp)->ipcpstat_entry.le_next), 1); (ppp) = (tppp
))
{
834 ppp->ipcpstat = NULL((void *)0);
835 LIST_REMOVE(ppp, ipcpstat_entry)do { if ((ppp)->ipcpstat_entry.le_next != ((void *)0)) (ppp
)->ipcpstat_entry.le_next->ipcpstat_entry.le_prev = (ppp
)->ipcpstat_entry.le_prev; *(ppp)->ipcpstat_entry.le_prev
= (ppp)->ipcpstat_entry.le_next; ; ; } while (0)
;
836 }
837 free(ipcpstat);
838 }
839}
840
841static void
842npppd_ipcp_stats_reload(npppd *_this)
843{
844 struct ipcpstat *ipcpstat, *tipcpstat;
845 struct ipcpconf *ipcpconf;
846 struct ipcpstat_head destroy_list;
847
848 LIST_INIT(&destroy_list)do { ((&destroy_list)->lh_first) = ((void *)0); } while
(0)
;
849 LIST_FOREACH_SAFE(ipcpstat, &_this->ipcpstats, entry, tipcpstat)for ((ipcpstat) = ((&_this->ipcpstats)->lh_first); (
ipcpstat) && ((tipcpstat) = ((ipcpstat)->entry.le_next
), 1); (ipcpstat) = (tipcpstat))
{
850 LIST_REMOVE(ipcpstat, entry)do { if ((ipcpstat)->entry.le_next != ((void *)0)) (ipcpstat
)->entry.le_next->entry.le_prev = (ipcpstat)->entry.
le_prev; *(ipcpstat)->entry.le_prev = (ipcpstat)->entry
.le_next; ; ; } while (0)
;
851 LIST_INSERT_HEAD(&destroy_list, ipcpstat, entry)do { if (((ipcpstat)->entry.le_next = (&destroy_list)->
lh_first) != ((void *)0)) (&destroy_list)->lh_first->
entry.le_prev = &(ipcpstat)->entry.le_next; (&destroy_list
)->lh_first = (ipcpstat); (ipcpstat)->entry.le_prev = &
(&destroy_list)->lh_first; } while (0)
;
852 }
853
854 TAILQ_FOREACH(ipcpconf, &_this->conf.ipcpconfs, entry)for((ipcpconf) = ((&_this->conf.ipcpconfs)->tqh_first
); (ipcpconf) != ((void *)0); (ipcpconf) = ((ipcpconf)->entry
.tqe_next))
{
855 ipcpstat = npppd_get_ipcp_stat(&destroy_list, ipcpconf->name);
856 if (ipcpstat != NULL((void *)0)) {
857 LIST_REMOVE(ipcpstat, entry)do { if ((ipcpstat)->entry.le_next != ((void *)0)) (ipcpstat
)->entry.le_next->entry.le_prev = (ipcpstat)->entry.
le_prev; *(ipcpstat)->entry.le_prev = (ipcpstat)->entry
.le_next; ; ; } while (0)
;
858 LIST_INSERT_HEAD(&_this->ipcpstats, ipcpstat, entry)do { if (((ipcpstat)->entry.le_next = (&_this->ipcpstats
)->lh_first) != ((void *)0)) (&_this->ipcpstats)->
lh_first->entry.le_prev = &(ipcpstat)->entry.le_next
; (&_this->ipcpstats)->lh_first = (ipcpstat); (ipcpstat
)->entry.le_prev = &(&_this->ipcpstats)->lh_first
; } while (0)
;
859 continue;
860 }
861
862 ipcpstat = malloc(sizeof(*ipcpstat));
863 if (ipcpstat == NULL((void *)0)) {
864 log_printf(LOG_ERR3, "initializing ipcp_stats failed : %m");
865 continue;
866 }
867 memset(ipcpstat, 0, sizeof(*ipcpstat));
868 strlcpy(ipcpstat->name, ipcpconf->name, sizeof(ipcpconf->name));
869 LIST_INSERT_HEAD(&_this->ipcpstats, ipcpstat, entry)do { if (((ipcpstat)->entry.le_next = (&_this->ipcpstats
)->lh_first) != ((void *)0)) (&_this->ipcpstats)->
lh_first->entry.le_prev = &(ipcpstat)->entry.le_next
; (&_this->ipcpstats)->lh_first = (ipcpstat); (ipcpstat
)->entry.le_prev = &(&_this->ipcpstats)->lh_first
; } while (0)
;
870 }
871 npppd_destroy_ipcp_stats(&destroy_list);
872}
873
874/**
875 * Checks whether the user reaches the maximum session limit
876 * (user_max_serssion).
877 * @return This function returns 1(true) if the user does not reach the
878 * limit, otherwise it returns 0(false).
879 */
880int
881npppd_check_user_max_session(npppd *_this, npppd_ppp *ppp)
882{
883 int global_count, realm_count;
884 npppd_ppp *ppp1;
885 slist *uppp;
886
887 /* user_max_session == 0 means unlimit */
888 if (_this->conf.user_max_session == 0 &&
889 npppd_auth_user_session_unlimited(ppp->realm))
890 return 1;
891
892 global_count = realm_count = 0;
893 if ((uppp = npppd_get_ppp_by_user(_this, ppp->username)) != NULL((void *)0)) {
894 for (slist_itr_first(uppp); slist_itr_has_next(uppp); ) {
895 ppp1 = slist_itr_next(uppp);
896 if (ppp->realm == ppp1->realm)
897 realm_count++;
898 global_count++;
899 }
900 }
901
902 if (npppd_check_auth_user_max_session(ppp->realm, realm_count)) {
903 ppp_log(ppp, LOG_WARNING4,
904 "user %s exceeds user-max-session limit per auth",
905 ppp->username);
906 return 0;
907 } else if (_this->conf.user_max_session != 0 &&
908 _this->conf.user_max_session <= global_count) {
909 ppp_log(ppp, LOG_WARNING4,
910 "user %s exceeds user-max-session limit", ppp->username);
911 return 0;
912 } else
913 return 1;
914}
915
916/***********************************************************************
917 * Network I/O ralated functions.
918 ***********************************************************************/
919/**
920 * Call this function to output packets to the network(tun). This function
921 * currently assumes the packet is a IPv4 datagram.
922 */
923void
924npppd_network_output(npppd *_this, npppd_ppp *ppp, int proto, u_char *pktp,
925 int lpktp)
926{
927 struct ip *pip;
928 int lbuf;
929 u_char buf[256]; /* enough size for TCP/IP header */
930
931 NPPPD_ASSERT(ppp != NULL);
932
933 if (!ppp_ip_assigned(ppp)(ppp->snp.sin4.sin_addr.s_addr != 0))
934 return;
935
936 if (lpktp < sizeof(struct ip)) {
937 ppp_log(ppp, LOG_DEBUG7, "Received IP packet is too small");
938 return;
939 }
940 lbuf = MINIMUM(lpktp, sizeof(buf))(((lpktp) < (sizeof(buf))) ? (lpktp) : (sizeof(buf)));
941 if (!ALIGNED_POINTER(pktp, struct ip)1) {
942 memcpy(buf, pktp, lbuf);
943 pip = (struct ip *)buf;
944 } else {
945 pip = (struct ip *)pktp;
946 }
947
948 if (ppp->ingress_filter != 0 &&
949 (pip->ip_src.s_addr & ppp->ppp_framed_ip_netmasksnp.sin4mask.sin_addr.s_addr)
950 != (ppp->ppp_framed_ip_addresssnp.sin4.sin_addr.s_addr &
951 ppp->ppp_framed_ip_netmasksnp.sin4mask.sin_addr.s_addr)) {
952 char logbuf[80];
953 strlcpy(logbuf, inet_ntoa(pip->ip_dst), sizeof(logbuf));
954 ppp_log(ppp, LOG_INFO6,
955 "Drop packet by ingress filter. %s => %s",
956 inet_ntoa(pip->ip_src), logbuf);
957
958 return;
959 }
960 if (ppp->timeout_sec > 0 && !ip_is_idle_packet(pip, lbuf))
961 ppp_reset_idle_timeout(ppp);
962
963#ifndef NO_ADJUST_MSS
964 if (ppp->adjust_mss) {
965 if (lpktp == lbuf) {
966 /*
967 * We can assume the packet length is less than
968 * sizeof(buf).
969 */
970 if (!ALIGNED_POINTER(pktp, struct ip)1)
971 pktp = buf;
972 adjust_tcp_mss(pktp, lpktp, MRU_IPMTU(ppp->peer_mru)(ppp->peer_mru));
973 }
974 }
975#endif
976 npppd_iface_write(ppp_iface(ppp)(&(ppp)->pppd->iface[(ppp)->ifidx]), ppp, proto, pktp, lpktp);
977}
978
979#ifdef USE_NPPPD_PIPEX1
980/***********************************************************************
981 * PIPEX related functions
982 ***********************************************************************/
983static void
984pipex_setup_common(npppd_ppp *ppp, struct pipex_session_req *req)
985{
986 memset(req, 0, sizeof(*req));
987 if (psm_opt_is_accepted(&ppp->lcp, acfc)(((&ppp->lcp)->opt.acfc & 0x02) != 0))
988 req->pr_ppp_flags |= PIPEX_PPP_ACFC_ENABLED0x0004;
989 if (psm_peer_opt_is_accepted(&ppp->lcp, acfc)(((&ppp->lcp)->opt.acfc & 0x20) != 0))
990 req->pr_ppp_flags |= PIPEX_PPP_ACFC_ACCEPTED0x0001;
991
992 if (psm_peer_opt_is_accepted(&ppp->lcp, pfc)(((&ppp->lcp)->opt.pfc & 0x20) != 0))
993 req->pr_ppp_flags |= PIPEX_PPP_PFC_ACCEPTED0x0002;
994 if (psm_opt_is_accepted(&ppp->lcp, pfc)(((&ppp->lcp)->opt.pfc & 0x02) != 0))
995 req->pr_ppp_flags |= PIPEX_PPP_PFC_ENABLED0x0008;
996
997 if (ppp->has_acf != 0)
998 req->pr_ppp_flags |= PIPEX_PPP_HAS_ACF0x0080;
999
1000 if (ppp->adjust_mss != 0)
1001 req->pr_ppp_flags |= PIPEX_PPP_ADJUST_TCPMSS0x0100;
1002 if (ppp->ingress_filter != 0)
1003 req->pr_ppp_flags |= PIPEX_PPP_INGRESS_FILTER0x0200;
1004
1005 req->pr_ip_srcaddr = ppp->pppd->iface[0].ip4addr;
1006 req->pr_ip_address = ppp->ppp_framed_ip_addresssnp.sin4.sin_addr;
1007 req->pr_ip_netmask = ppp->ppp_framed_ip_netmasksnp.sin4mask.sin_addr;
1008 req->pr_peer_mru = ppp->peer_mru;
1009 req->pr_ppp_id = ppp->id;
1010
1011 req->pr_timeout_sec = ppp->timeout_sec;
1012
1013#ifdef USE_NPPPD_MPPE1
1014 req->pr_ccp_id = ppp->ccp.fsm.id;
1015 if (ppp->mppe.send.keybits > 0) {
1016 memcpy(req->pr_mppe_send.master_key,
1017 ppp->mppe.send.master_key,
1018 sizeof(req->pr_mppe_send.master_key));
1019 req->pr_mppe_send.stateless = ppp->mppe.send.stateless;
1020 req->pr_mppe_send.keylenbits = ppp->mppe.send.keybits;
1021 req->pr_ppp_flags |= PIPEX_PPP_MPPE_ENABLED0x0020;
1022 }
1023 if (ppp->mppe.recv.keybits > 0) {
1024 memcpy(req->pr_mppe_recv.master_key,
1025 ppp->mppe.recv.master_key,
1026 sizeof(req->pr_mppe_recv.master_key));
1027 req->pr_mppe_recv.stateless = ppp->mppe.recv.stateless;
1028 req->pr_mppe_recv.keylenbits = ppp->mppe.recv.keybits;
1029 req->pr_ppp_flags |= PIPEX_PPP_MPPE_ACCEPTED0x0010;
1030 }
1031 if (ppp->mppe.required)
1032 req->pr_ppp_flags |= PIPEX_PPP_MPPE_REQUIRED0x0040;
1033#endif /* USE_NPPPD_MPPE */
1034}
1035
1036/** Enable PIPEX of the {@link npppd_ppp ppp} */
1037int
1038npppd_ppp_pipex_enable(npppd *_this, npppd_ppp *ppp)
1039{
1040 struct pipex_session_req req;
1041#ifdef USE_NPPPD_PPPOE1
1042 pppoe_session *pppoe;
1043#endif
1044#ifdef USE_NPPPD_PPTP1
1045 pptp_call *call;
1046#endif
1047#ifdef USE_NPPPD_L2TP1
1048 l2tp_call *l2tp;
1049 l2tp_ctrl *l2tpctrl;
1050#endif
1051 int error;
1052
1053 NPPPD_ASSERT(ppp != NULL);
1054 NPPPD_ASSERT(ppp->phy_context != NULL);
1055 NPPPD_ASSERT(ppp->use_pipex != 0);
1056
1057 pipex_setup_common(ppp, &req);
1058
1059 switch (ppp->tunnel_type) {
1060#ifdef USE_NPPPD_PPPOE1
1061 case NPPPD_TUNNEL_PPPOE3:
1062 {
1063 struct sockaddr *sa;
1064 struct ether_header *eh;
1065 pppoe = (pppoe_session *)ppp->phy_context;
1066
1067 /* PPPoE specific information */
1068 req.pr_protocol = PIPEX_PROTO_PPPOE3;
1069 req.pr_session_id = pppoe->session_id;
1070 req.pr_peer_session_id = 0;
1071 strlcpy(req.pr_proto.pppoe.over_ifname,
1072 pppoe_session_listen_ifname(pppoe)((pppoed_listener *)slist_get(&(pppoe)->pppoed->listener
, (pppoe)->listener_index))->listen_ifname
,
1073 sizeof(req.pr_proto.pppoe.over_ifname));
1074
1075 sa = (struct sockaddr *)&req.pr_peer_address;
1076 sa->sa_family = AF_UNSPEC0;
1077 sa->sa_len = sizeof(struct sockaddr);
1078
1079 eh = (struct ether_header *)sa->sa_data;
1080 eh->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))
;
1081 memcpy(eh->ether_dhost, pppoe->ether_addr, ETHER_ADDR_LEN6);
1082 memset(eh->ether_shost, 0, ETHER_ADDR_LEN6);
1083
1084 break;
1085 }
1086#endif
1087#ifdef USE_NPPPD_PPTP1
1088 case NPPPD_TUNNEL_PPTP2:
1089 call = (pptp_call *)ppp->phy_context;
1090
1091 /* PPTP specific information */
1092 req.pr_session_id = call->id;
1093 req.pr_protocol = PIPEX_PROTO_PPTP2;
1094
1095 req.pr_peer_session_id = call->peers_call_id;
1096 req.pr_proto.pptp.snd_nxt = call->snd_nxt;
1097 req.pr_proto.pptp.snd_una = call->snd_una;
1098 req.pr_proto.pptp.rcv_nxt = call->rcv_nxt;
1099 req.pr_proto.pptp.rcv_acked = call->rcv_acked;
1100 req.pr_proto.pptp.winsz = call->winsz;
1101 req.pr_proto.pptp.maxwinsz = call->maxwinsz;
1102 req.pr_proto.pptp.peer_maxwinsz = call->peers_maxwinsz;
1103
1104 NPPPD_ASSERT(call->ctrl->peer.ss_family == AF_INET);
1105 NPPPD_ASSERT(call->ctrl->our.ss_family == AF_INET);
1106
1107 memcpy(&req.pr_peer_address, &call->ctrl->peer,
1108 call->ctrl->peer.ss_len);
1109 memcpy(&req.pr_local_address, &call->ctrl->our,
1110 call->ctrl->our.ss_len);
1111 break;
1112#endif
1113#ifdef USE_NPPPD_L2TP1
1114 case NPPPD_TUNNEL_L2TP1:
1115 l2tp = (l2tp_call *)ppp->phy_context;
1116 l2tpctrl = l2tp->ctrl;
1117
1118 /* L2TPv2 specific context */
1119 /* Session KEYS */
1120 req.pr_protocol = PIPEX_PROTO_L2TP1;
1121 req.pr_proto.l2tp.tunnel_id = l2tpctrl->tunnel_id;
1122 req.pr_proto.l2tp.peer_tunnel_id = l2tpctrl->peer_tunnel_id;
1123 req.pr_session_id = l2tp->session_id;
1124 req.pr_peer_session_id = l2tp->peer_session_id;
1125
1126 if (l2tpctrl->data_use_seq)
1127 req.pr_proto.l2tp.option_flags |=
1128 PIPEX_L2TP_USE_SEQUENCING0x00000001;
1129
1130 /* transmission control contexts */
1131 req.pr_proto.l2tp.ns_nxt = l2tp->snd_nxt;
1132 req.pr_proto.l2tp.nr_nxt = l2tp->rcv_nxt;
1133
1134 memcpy(&req.pr_peer_address, &l2tpctrl->peer,
1135 l2tpctrl->peer.ss_len);
1136 memcpy(&req.pr_local_address, &l2tpctrl->sock,
1137 l2tpctrl->sock.ss_len);
1138#ifdef USE_SA_COOKIE1
1139 if (l2tpctrl->sa_cookie != NULL((void *)0)) {
1140 req.pr_proto.l2tp.ipsecflowinfo =
1141 ((struct in_ipsec_sa_cookie *)l2tpctrl->sa_cookie)
1142 ->ipsecflow;
1143 }
1144#endif
1145 break;
1146#endif
1147 default:
1148 return 1;
1149 }
1150
1151 if ((error = ioctl(_this->iface[ppp->ifidx].devf, PIPEXASESSION((unsigned long)0x80000000 | ((sizeof(struct pipex_session_req
) & 0x1fff) << 16) | ((('p')) << 8) | ((3)))
, &req))
1152 != 0) {
1153 if (errno(*__errno()) == ENXIO6) /* pipex is disabled on runtime */
1154 error = 0;
1155 ppp->pipex_enabled = 0;
1156 return error;
1157 }
1158
1159 if (_this->iface[ppp->ifidx].using_pppx) {
1160 struct pipex_session_descr_req descr_req;
1161
1162 descr_req.pdr_protocol = req.pr_protocol;
1163 descr_req.pdr_session_id = req.pr_session_id;
1164 memset(descr_req.pdr_descr, 0, sizeof(descr_req.pdr_descr));
1165 strlcpy(descr_req.pdr_descr, ppp->username, sizeof(descr_req.pdr_descr));
1166 error = ioctl(_this->iface[ppp->ifidx].devf, PIPEXSIFDESCR((unsigned long)0x80000000 | ((sizeof(struct pipex_session_descr_req
) & 0x1fff) << 16) | ((('p')) << 8) | ((8)))
, &descr_req);
1167 if (error != 0) {
1168 log_printf(LOG_WARNING4, "PIPEXSIFDESCR(%s) failed: %d\n", ppp->username, error);
1169 }
1170 }
1171
1172 ppp->pipex_enabled = 1;
1173 if (ppp->timeout_sec > 0) {
1174 /* Stop the npppd's idle-timer. We use pipex's idle-timer */
1175 ppp->timeout_sec = 0;
1176 ppp_reset_idle_timeout(ppp);
1177 }
1178
1179 return error;
1180}
1181
1182/** Disable PIPEX of the {@link npppd_ppp ppp} */
1183int
1184npppd_ppp_pipex_disable(npppd *_this, npppd_ppp *ppp)
1185{
1186 struct pipex_session_close_req req;
1187#ifdef USE_NPPPD_PPPOE1
1188 pppoe_session *pppoe;
1189#endif
1190#ifdef USE_NPPPD_PPTP1
1191 pptp_call *call;
1192#endif
1193#ifdef USE_NPPPD_L2TP1
1194 l2tp_call *l2tp;
1195#endif
1196 int error;
1197
1198 if (ppp->pipex_started == 0)
1199 return 0; /* not started */
1200
1201 bzero(&req, sizeof(req));
1202 switch(ppp->tunnel_type) {
1203#ifdef USE_NPPPD_PPPOE1
1204 case NPPPD_TUNNEL_PPPOE3:
1205 pppoe = (pppoe_session *)ppp->phy_context;
1206
1207 /* PPPoE specific information */
1208 req.pcr_protocolpsr_protocol = PIPEX_PROTO_PPPOE3;
1209 req.pcr_session_idpsr_session_id = pppoe->session_id;
1210 break;
1211#endif
1212#ifdef USE_NPPPD_PPTP1
1213 case NPPPD_TUNNEL_PPTP2:
1214 call = (pptp_call *)ppp->phy_context;
1215
1216 /* PPTP specific information */
1217 req.pcr_session_idpsr_session_id = call->id;
1218 req.pcr_protocolpsr_protocol = PIPEX_PROTO_PPTP2;
1219 break;
1220#endif
1221#ifdef USE_NPPPD_L2TP1
1222 case NPPPD_TUNNEL_L2TP1:
1223 l2tp = (l2tp_call *)ppp->phy_context;
1224
1225 /* L2TP specific context */
1226 req.pcr_session_idpsr_session_id = l2tp->session_id;
1227 req.pcr_protocolpsr_protocol = PIPEX_PROTO_L2TP1;
1228 break;
1229#endif
1230 default:
1231 return 1;
1232 }
1233
1234 error = ioctl(_this->iface[ppp->ifidx].devf, PIPEXDSESSION(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct pipex_session_close_req) & 0x1fff) << 16) |
((('p')) << 8) | ((4)))
, &req);
1235 if (error == 0) {
1236 ppp->ipackets += req.pcr_statpsr_stat.ipackets;
1237 ppp->opackets += req.pcr_statpsr_stat.opackets;
1238 ppp->ierrors += req.pcr_statpsr_stat.ierrors;
1239 ppp->oerrors += req.pcr_statpsr_stat.oerrors;
1240 ppp->ibytes += req.pcr_statpsr_stat.ibytes;
1241 ppp->obytes += req.pcr_statpsr_stat.obytes;
1242 ppp->pipex_enabled = 0;
1243 }
1244
1245 return error;
1246}
1247
1248static void
1249pipex_periodic(npppd *_this)
1250{
1251 struct pipex_session_list_req req;
1252 npppd_ppp *ppp;
1253 int i, devf, error;
1254 u_int ppp_id;
1255 slist dlist, users;
1256
1257 slist_init(&dlist);
1258 slist_init(&users);
1259
1260 devf = -1;
1261 for (i = 0; i < nitems(_this->iface)(sizeof((_this->iface)) / sizeof((_this->iface)[0])); i++) {
1262 if (_this->iface[i].initialized != 0) {
1263 devf = _this->iface[i].devf;
1264 break;
1265 }
1266 }
1267 if (devf >= 0) {
1268 do {
1269 error = ioctl(devf, PIPEXGCLOSED((unsigned long)0x40000000 | ((sizeof(struct pipex_session_list_req
) & 0x1fff) << 16) | ((('p')) << 8) | ((7)))
, &req);
1270 if (error) {
1271 if (errno(*__errno()) != ENXIO6)
1272 log_printf(LOG_WARNING4,
1273 "PIPEXGCLOSED failed: %m");
1274 break;
1275 }
1276 for (i = 0; i < req.plr_ppp_id_count; i++) {
1277 ppp_id = req.plr_ppp_id[i];
1278 slist_add(&dlist, (void *)(uintptr_t)ppp_id);
1279 }
1280 } while (req.plr_flags & PIPEX_LISTREQ_MORE0x01);
1281 }
1282
1283 if (slist_length(&dlist) <= 0)
1284 goto pipex_done;
1285 if (npppd_get_all_users(_this, &users) != 0) {
1286 log_printf(LOG_WARNING4,
1287 "npppd_get_all_users() failed in %s()", __func__);
1288 slist_fini(&users);
1289 goto pipex_done;
1290 }
1291
1292 /* Disconnect request */
1293 slist_itr_first(&dlist);
1294 while (slist_itr_has_next(&dlist)) {
1295 /* FIXME: Linear search by PPP Id eats CPU */
1296 ppp_id = (uintptr_t)slist_itr_next(&dlist);
1297 slist_itr_first(&users);
1298 ppp = NULL((void *)0);
1299 while (slist_itr_has_next(&users)) {
1300 ppp = slist_itr_next(&users);
1301 if (ppp_id == ppp->id) {
1302 /* found */
1303 slist_itr_remove(&users);
1304 break;
1305 }
1306 ppp = NULL((void *)0);
1307 }
1308 if (ppp == NULL((void *)0)) {
1309 log_printf(LOG_WARNING4,
1310 "kernel requested a ppp down, but it's not found. "
1311 "ppp=%d", ppp_id);
1312 continue;
1313 }
1314 ppp_log(ppp, LOG_INFO6, "Stop requested by the kernel");
1315 /* TODO: PIPEX doesn't return the disconnect reason */
1316#ifdef USE_NPPPD_RADIUS1
1317 ppp_set_radius_terminate_cause(ppp,
1318 RADIUS_TERMNATE_CAUSE_IDLE_TIMEOUT4);
1319#endif
1320 ppp_stop(ppp, NULL((void *)0));
1321 }
1322pipex_done:
1323 slist_fini(&users);
1324 slist_fini(&dlist);
1325}
1326#endif /* USE_NPPPD_PIPEX */
1327
1328/***********************************************************************
1329 * IP address assignment related functions
1330 ***********************************************************************/
1331/** Prepare to use IP */
1332int
1333npppd_prepare_ip(npppd *_this, npppd_ppp *ppp)
1334{
1335
1336 if (ppp_ipcp(ppp)((ppp)->pppd->iface[(ppp)->ifidx].ipcpconf) == NULL((void *)0))
1337 return 1;
1338
1339 npppd_get_user_framed_ip_address(_this, ppp, ppp->username);
1340
1341 if (npppd_iface_ip_is_ready(ppp_iface(ppp))(((&(ppp)->pppd->iface[(ppp)->ifidx]))->initialized
!= 0 && ((&(ppp)->pppd->iface[(ppp)->ifidx
]))->ip4addr.s_addr != ((u_int32_t)(0x00000000)))
)
1342 ppp->ipcp.ip4_our = ppp_iface(ppp)(&(ppp)->pppd->iface[(ppp)->ifidx])->ip4addr;
1343 else if (npppd_iface_ip_is_ready(&_this->iface[0])((&_this->iface[0])->initialized != 0 && (&
_this->iface[0])->ip4addr.s_addr != ((u_int32_t)(0x00000000
)))
)
1344 ppp->ipcp.ip4_our = _this->iface[0].ip4addr;
1345 else
1346 return -1;
1347 ppp->ipcp.dns_pri = ppp_ipcp(ppp)((ppp)->pppd->iface[(ppp)->ifidx].ipcpconf)->dns_servers[0];
1348 ppp->ipcp.dns_sec = ppp_ipcp(ppp)((ppp)->pppd->iface[(ppp)->ifidx].ipcpconf)->dns_servers[1];
1349 ppp->ipcp.nbns_pri = ppp_ipcp(ppp)((ppp)->pppd->iface[(ppp)->ifidx].ipcpconf)->nbns_servers[0];
1350 ppp->ipcp.nbns_sec = ppp_ipcp(ppp)((ppp)->pppd->iface[(ppp)->ifidx].ipcpconf)->nbns_servers[1];
1351
1352 return 0;
1353}
1354
1355/** Notify stop using IP to npppd and release the resources. */
1356void
1357npppd_release_ip(npppd *_this, npppd_ppp *ppp)
1358{
1359
1360 if (!ppp_ip_assigned(ppp)(ppp->snp.sin4.sin_addr.s_addr != 0))
1361 return;
1362
1363 npppd_set_ip_enabled(_this, ppp, 0);
1364 npppd_pool_release_ip(ppp->assigned_pool, ppp);
1365 ppp->assigned_pool = NULL((void *)0);
1366 ppp->ppp_framed_ip_addresssnp.sin4.sin_addr.s_addr = 0;
1367}
1368
1369/**
1370 * Change IP enableness. When the enableness is change, npppd will operate
1371 * the route entry.
1372 */
1373void
1374npppd_set_ip_enabled(npppd *_this, npppd_ppp *ppp, int enabled)
1375{
1376 int was_enabled, found;
1377 slist *u;
1378 hash_link *hl;
1379 npppd_ppp *ppp1;
1380
1381 NPPPD_ASSERT(ppp_ip_assigned(ppp));
1382 NPPPD_DBG((LOG_DEBUG,
1383 "npppd_set_ip_enabled(%s/%s, %s)", ppp->username,
1384 inet_ntoa(ppp->ppp_framed_ip_address),
1385 (enabled)?"true" : "false"));
1386
1387 /*
1388 * Don't do anything if the enableness is not change. Changing route
1389 * makes many programs will wake up and do heavy operations, it causes
1390 * system overload, so we refrain useless changing route.
1391 */
1392 enabled = (enabled)? 1 : 0;
1393 was_enabled = (ppp->assigned_ip4_enabled != 0)? 1 : 0;
1394 if (enabled == was_enabled)
1395 return;
1396
1397 ppp->assigned_ip4_enabled = enabled;
1398 if (enabled) {
1399 if (ppp->username[0] != '\0') {
1400 if ((u = npppd_get_ppp_by_user(_this, ppp->username))
1401 == NULL((void *)0)) {
1402 if ((u = malloc(sizeof(slist))) == NULL((void *)0)) {
1403 ppp_log(ppp, LOG_ERR3,
1404 "Out of memory on %s: %m",
1405 __func__);
1406 } else {
1407 slist_init(u);
1408 slist_set_size(u, 4);
1409 hash_insert(_this->map_user_ppp,
1410 ppp->username, u);
1411 NPPPD_DBG((LOG_DEBUG,
1412 "hash_insert(user->ppp, %s)",
1413 ppp->username));
1414 }
1415 }
1416 if (u != NULL((void *)0)) /* above malloc() may failed */
1417 slist_add(u, ppp);
1418 }
1419
1420#ifndef NO_ROUTE_FOR_POOLED_ADDRESS
1421 if (_this->iface[ppp->ifidx].using_pppx == 0) {
1422 if (ppp->snp.snp_next != NULL((void *)0))
1423 /*
1424 * There is a blackhole route that has same
1425 * address/mask.
1426 */
1427 in_route_delete(&ppp->ppp_framed_ip_addresssnp.sin4.sin_addr,
1428 &ppp->ppp_framed_ip_netmasksnp.sin4mask.sin_addr, &loop,
1429 RTF_BLACKHOLE0x1000);
1430 /* See the comment for MRU_IPMTU() on ppp.h */
1431 if (ppp->ppp_framed_ip_netmasksnp.sin4mask.sin_addr.s_addr == 0xffffffffL) {
1432 in_host_route_add(&ppp->ppp_framed_ip_addresssnp.sin4.sin_addr,
1433 &ppp_iface(ppp)(&(ppp)->pppd->iface[(ppp)->ifidx])->ip4addr,
1434 ppp_iface(ppp)(&(ppp)->pppd->iface[(ppp)->ifidx])->ifname,
1435 MRU_IPMTU(ppp->peer_mru)(ppp->peer_mru));
1436 } else {
1437 in_route_add(&ppp->ppp_framed_ip_addresssnp.sin4.sin_addr,
1438 &ppp->ppp_framed_ip_netmasksnp.sin4mask.sin_addr,
1439 &ppp_iface(ppp)(&(ppp)->pppd->iface[(ppp)->ifidx])->ip4addr,
1440 ppp_iface(ppp)(&(ppp)->pppd->iface[(ppp)->ifidx])->ifname, 0,
1441 MRU_IPMTU(ppp->peer_mru)(ppp->peer_mru));
1442 }
1443 }
1444#endif
1445 } else {
1446#ifndef NO_ROUTE_FOR_POOLED_ADDRESS
1447 if (_this->iface[ppp->ifidx].using_pppx == 0) {
1448 if (ppp->ppp_framed_ip_netmasksnp.sin4mask.sin_addr.s_addr == 0xffffffffL) {
1449 in_host_route_delete(&ppp->ppp_framed_ip_addresssnp.sin4.sin_addr,
1450 &ppp_iface(ppp)(&(ppp)->pppd->iface[(ppp)->ifidx])->ip4addr);
1451 } else {
1452 in_route_delete(&ppp->ppp_framed_ip_addresssnp.sin4.sin_addr,
1453 &ppp->ppp_framed_ip_netmasksnp.sin4mask.sin_addr,
1454 &ppp_iface(ppp)(&(ppp)->pppd->iface[(ppp)->ifidx])->ip4addr, 0);
1455 }
1456 if (ppp->snp.snp_next != NULL((void *)0))
1457 /*
1458 * There is a blackhole route that has same
1459 * address/mask.
1460 */
1461 in_route_add(&ppp->snp.snp_addrsin4.sin_addr,
1462 &ppp->snp.snp_masksin4mask.sin_addr, &loop, LOOPBACK_IFNAME"lo0",
1463 RTF_BLACKHOLE0x1000, 0);
1464 }
1465#endif
1466 if (ppp->username[0] != '\0') {
1467 hl = hash_lookup(_this->map_user_ppp, ppp->username);
1468 NPPPD_ASSERT(hl != NULL);
1469 if (hl == NULL((void *)0)) {
1470 ppp_log(ppp, LOG_ERR3,
1471 "Unexpected error: cannot find user(%s) "
1472 "from user database", ppp->username);
1473 return;
1474 }
1475 found = 0;
1476 u = hl->item;
1477 for (slist_itr_first(u); slist_itr_has_next(u);) {
1478 ppp1 = slist_itr_next(u);
1479 if (ppp1 == ppp) {
1480 slist_itr_remove(u);
1481 found++;
1482 break;
1483 }
1484 }
1485 if (found == 0) {
1486 ppp_log(ppp, LOG_ERR3,
1487 "Unexpected error: PPP instance is "
1488 "not found in the user's list.");
1489 }
1490 NPPPD_ASSERT(found != 0);
1491 if (slist_length(u) <= 0) {
1492 /* The last PPP */
1493 NPPPD_DBG((LOG_DEBUG,
1494 "hash_delete(user->ppp, %s)",
1495 ppp->username));
1496 if (hash_delete(_this->map_user_ppp,
1497 ppp->username, 0) != 0) {
1498 ppp_log(ppp, LOG_ERR3,
1499 "Unexpected error: cannot delete "
1500 "user(%s) from user database",
1501 ppp->username);
1502 }
1503 slist_fini(u);
1504 free(u);
1505 } else {
1506 /* Replace the reference. */
1507 ppp1 = slist_get(u, 0);
1508 hl->key = ppp1->username;
1509 }
1510 }
1511 }
1512}
1513
1514/**
1515 * Assign the IP address. Returning "struct in_addr" is stored IP address
1516 * in network byte order.
1517 * @param req_ip4 IP address request to assign. If the address is used
1518 * already, this function will return fail.
1519 */
1520int
1521npppd_assign_ip_addr(npppd *_this, npppd_ppp *ppp, uint32_t req_ip4)
1522{
1523 uint32_t ip4, ip4mask;
1524 int dyna, rval, fallback_dyna;
1525 const char *reason = "out of the pool";
1526 struct sockaddr_npppd *snp;
1527 npppd_pool *pool;
1528 npppd_auth_base *realm;
1529
1530 NPPPD_DBG((LOG_DEBUG, "%s() assigned=%s", __func__,
1531 (ppp_ip_assigned(ppp))? "true" : "false"));
1532 if (ppp_ip_assigned(ppp)(ppp->snp.sin4.sin_addr.s_addr != 0))
1533 return 0;
1534
1535 ip4 = INADDR_ANY((u_int32_t)(0x00000000));
1536 ip4mask = 0xffffffffL;
1537 realm = ppp->realm;
1538 dyna = 0;
1539 fallback_dyna = 0;
1540 pool = NULL((void *)0);
1541
1542 if (ppp->realm_framed_ip_address.s_addr == INADDR_USER_SELECT((__uint32_t)(__builtin_constant_p(0xFFFFFFFFL) ? (__uint32_t
)(((__uint32_t)(0xFFFFFFFFL) & 0xff) << 24 | ((__uint32_t
)(0xFFFFFFFFL) & 0xff00) << 8 | ((__uint32_t)(0xFFFFFFFFL
) & 0xff0000) >> 8 | ((__uint32_t)(0xFFFFFFFFL) &
0xff000000) >> 24) : __swap32md(0xFFFFFFFFL)))
) {
1543 if (req_ip4 == INADDR_ANY((u_int32_t)(0x00000000)))
1544 dyna = 1;
1545 } else if (ppp->realm_framed_ip_address.s_addr == INADDR_NAS_SELECT((__uint32_t)(__builtin_constant_p(0xFFFFFFFEL) ? (__uint32_t
)(((__uint32_t)(0xFFFFFFFEL) & 0xff) << 24 | ((__uint32_t
)(0xFFFFFFFEL) & 0xff00) << 8 | ((__uint32_t)(0xFFFFFFFEL
) & 0xff0000) >> 8 | ((__uint32_t)(0xFFFFFFFEL) &
0xff000000) >> 24) : __swap32md(0xFFFFFFFEL)))
) {
1546 dyna = 1;
1547 } else {
1548 NPPPD_ASSERT(realm != NULL);
1549 fallback_dyna = 1;
1550 req_ip4 = ntohl(ppp->realm_framed_ip_address.s_addr)(__uint32_t)(__builtin_constant_p(ppp->realm_framed_ip_address
.s_addr) ? (__uint32_t)(((__uint32_t)(ppp->realm_framed_ip_address
.s_addr) & 0xff) << 24 | ((__uint32_t)(ppp->realm_framed_ip_address
.s_addr) & 0xff00) << 8 | ((__uint32_t)(ppp->realm_framed_ip_address
.s_addr) & 0xff0000) >> 8 | ((__uint32_t)(ppp->realm_framed_ip_address
.s_addr) & 0xff000000) >> 24) : __swap32md(ppp->
realm_framed_ip_address.s_addr))
;
1551 ip4mask = ntohl(ppp->realm_framed_ip_netmask.s_addr)(__uint32_t)(__builtin_constant_p(ppp->realm_framed_ip_netmask
.s_addr) ? (__uint32_t)(((__uint32_t)(ppp->realm_framed_ip_netmask
.s_addr) & 0xff) << 24 | ((__uint32_t)(ppp->realm_framed_ip_netmask
.s_addr) & 0xff00) << 8 | ((__uint32_t)(ppp->realm_framed_ip_netmask
.s_addr) & 0xff0000) >> 8 | ((__uint32_t)(ppp->realm_framed_ip_netmask
.s_addr) & 0xff000000) >> 24) : __swap32md(ppp->
realm_framed_ip_netmask.s_addr))
;
1552 }
1553 if (!dyna) {
1554 /*
1555 * Realm requires the fixed IP address, but the address
1556 * doesn't belong any address pool. Fallback to dynamic
1557 * assignment.
1558 */
1559 pool = ppp_pool(ppp)((ppp)->pppd->iface_pool[(ppp)->ifidx]);
1560 rval = npppd_pool_get_assignability(pool, req_ip4, ip4mask,
1561 &snp);
1562 switch (rval) {
1563 case ADDRESS_OK0:
1564 if (snp->snp_type == SNP_POOL1) {
1565 /*
1566 * Fixed address pool can be used only if the
1567 * realm specified to use it.
1568 */
1569 if (ppp->realm_framed_ip_address
1570 .s_addr != INADDR_USER_SELECT((__uint32_t)(__builtin_constant_p(0xFFFFFFFFL) ? (__uint32_t
)(((__uint32_t)(0xFFFFFFFFL) & 0xff) << 24 | ((__uint32_t
)(0xFFFFFFFFL) & 0xff00) << 8 | ((__uint32_t)(0xFFFFFFFFL
) & 0xff0000) >> 8 | ((__uint32_t)(0xFFFFFFFFL) &
0xff000000) >> 24) : __swap32md(0xFFFFFFFFL)))
)
1571 ip4 = req_ip4;
1572 break;
1573 }
1574 ppp->assign_dynapool = 1;
1575 ip4 = req_ip4;
1576 break;
1577 case ADDRESS_RESERVED1:
1578 reason = "reserved";
1579 break;
1580 case ADDRESS_OUT_OF_POOL4:
1581 reason = "out of the pool";
1582 break;
1583 case ADDRESS_BUSY2:
1584 fallback_dyna = 0;
1585 reason = "busy";
1586 break;
1587 default:
1588 case ADDRESS_INVALID3:
1589 fallback_dyna = 0;
1590 reason = "invalid";
1591 break;
1592 }
1593#define IP_4OCT(v)((0xff000000 & (v)) >> 24), ((0x00ff0000 & (v))
>> 16), ((0x0000ff00 & (v)) >> 8), (0x000000ff
& (v))
((0xff000000 & (v)) >> 24), ((0x00ff0000 & (v)) >> 16),\
1594 ((0x0000ff00 & (v)) >> 8), (0x000000ff & (v))
1595 if (ip4 == 0) {
1596 ppp_log(ppp, LOG_NOTICE5,
1597 "Requested IP address (%d.%d.%d.%d)/%d "
1598 "is %s", IP_4OCT(req_ip4)((0xff000000 & (req_ip4)) >> 24), ((0x00ff0000 &
(req_ip4)) >> 16), ((0x0000ff00 & (req_ip4)) >>
8), (0x000000ff & (req_ip4))
,
1599 netmask2prefixlen(ip4mask), reason);
1600 if (fallback_dyna)
1601 goto dyna_assign;
1602 return 1;
1603 }
1604 ppp->assigned_pool = pool;
1605
1606 ppp->ppp_framed_ip_addresssnp.sin4.sin_addr.s_addr = htonl(ip4)(__uint32_t)(__builtin_constant_p(ip4) ? (__uint32_t)(((__uint32_t
)(ip4) & 0xff) << 24 | ((__uint32_t)(ip4) & 0xff00
) << 8 | ((__uint32_t)(ip4) & 0xff0000) >> 8 |
((__uint32_t)(ip4) & 0xff000000) >> 24) : __swap32md
(ip4))
;
1607 ppp->ppp_framed_ip_netmasksnp.sin4mask.sin_addr.s_addr = htonl(ip4mask)(__uint32_t)(__builtin_constant_p(ip4mask) ? (__uint32_t)(((__uint32_t
)(ip4mask) & 0xff) << 24 | ((__uint32_t)(ip4mask) &
0xff00) << 8 | ((__uint32_t)(ip4mask) & 0xff0000) >>
8 | ((__uint32_t)(ip4mask) & 0xff000000) >> 24) : __swap32md
(ip4mask))
;
1608 ppp->acct_framed_ip_address = ppp->ppp_framed_ip_addresssnp.sin4.sin_addr;
1609 } else {
1610dyna_assign:
1611 pool = ppp_pool(ppp)((ppp)->pppd->iface_pool[(ppp)->ifidx]);
1612 ip4 = npppd_pool_get_dynamic(pool, ppp);
1613 if (ip4 == 0) {
1614 ppp_log(ppp, LOG_NOTICE5,
1615 "No free address in the pool.");
1616 return 1;
1617 }
1618 ppp->assigned_pool = pool;
1619 ppp->assign_dynapool = 1;
1620 ppp->ppp_framed_ip_addresssnp.sin4.sin_addr.s_addr = htonl(ip4)(__uint32_t)(__builtin_constant_p(ip4) ? (__uint32_t)(((__uint32_t
)(ip4) & 0xff) << 24 | ((__uint32_t)(ip4) & 0xff00
) << 8 | ((__uint32_t)(ip4) & 0xff0000) >> 8 |
((__uint32_t)(ip4) & 0xff000000) >> 24) : __swap32md
(ip4))
;
1621 ppp->ppp_framed_ip_netmasksnp.sin4mask.sin_addr.s_addr = htonl(0xffffffffL)(__uint32_t)(__builtin_constant_p(0xffffffffL) ? (__uint32_t)
(((__uint32_t)(0xffffffffL) & 0xff) << 24 | ((__uint32_t
)(0xffffffffL) & 0xff00) << 8 | ((__uint32_t)(0xffffffffL
) & 0xff0000) >> 8 | ((__uint32_t)(0xffffffffL) &
0xff000000) >> 24) : __swap32md(0xffffffffL))
;
1622 ppp->acct_framed_ip_address = ppp->ppp_framed_ip_addresssnp.sin4.sin_addr;
1623 }
1624
1625 return npppd_pool_assign_ip(ppp->assigned_pool, ppp);
1626}
1627
1628static void *
1629rtlist_remove(slist *prtlist, struct radish *radish)
1630{
1631 struct radish *r;
1632
1633 slist_itr_first(prtlist);
1634 while (slist_itr_has_next(prtlist)) {
1635 r = slist_itr_next(prtlist);
1636 if (!sockaddr_npppd_match(radish->rd_route, r->rd_route) ||
1637 !sockaddr_npppd_match(radish->rd_mask, r->rd_mask))
1638 continue;
1639
1640 return slist_itr_remove(prtlist);
1641 }
1642
1643 return NULL((void *)0);
1644}
1645
1646/** Set {@link ::npppd#rd the only radish of npppd} */
1647int
1648npppd_set_radish(npppd *_this, void *radish_head)
1649{
1650 int rval, delppp0, count;
1651 struct sockaddr_npppd *snp;
1652 struct radish *radish, *r;
1653 slist rtlist0, rtlist1, delppp;
1654 npppd_ppp *ppp;
1655 void *dummy;
1656
1657 slist_init(&rtlist0);
1658 slist_init(&rtlist1);
1659 slist_init(&delppp);
1660
1661 if (radish_head != NULL((void *)0)) {
1662 if (rd2slist(radish_head, &rtlist1) != 0) {
1663 log_printf(LOG_WARNING4, "rd2slist failed: %m");
1664 goto fail;
1665 }
1666 }
1667 if (_this->rd != NULL((void *)0)) {
1668 if (rd2slist(_this->rd, &rtlist0) != 0) {
1669 log_printf(LOG_WARNING4, "rd2slist failed: %m");
1670 goto fail;
1671 }
1672 }
1673 if (_this->rd != NULL((void *)0) && radish_head != NULL((void *)0)) {
1674 for (slist_itr_first(&rtlist0); slist_itr_has_next(&rtlist0);) {
1675 radish = slist_itr_next(&rtlist0);
1676 snp = radish->rd_rtent;
1677 /*
1678 * replace the pool address
1679 */
1680 if (snp->snp_type == SNP_POOL1 ||
1681 snp->snp_type == SNP_DYN_POOL2) {
1682 if (rd_lookup(radish->rd_route, radish->rd_mask,
1683 radish_head) == NULL((void *)0))
1684 continue;
1685 /* don't add */
1686 rtlist_remove(&rtlist1, radish);
1687 /* don't delete */
1688 slist_itr_remove(&rtlist0);
1689 continue;
1690 }
1691 /*
1692 * handle the active PPP sessions.
1693 */
1694 NPPPD_ASSERT(snp->snp_type == SNP_PPP);
1695 ppp = snp->snp_data_ptr;
1696
1697 /* Don't delete the route of active PPP session */
1698 slist_itr_remove(&rtlist0);
1699
1700 /* clear information about old pool configuration */
1701 snp->snp_next = NULL((void *)0);
1702
1703 delppp0 = 0;
1704 if (!rd_match((struct sockaddr *)snp, radish_head, &r)){
1705 /*
1706 * If the address doesn't belong the new pools,
1707 * add the PPP session to the deletion list.
1708 */
1709 slist_add(&delppp, snp->snp_data_ptr);
1710 delppp0 = 1;
1711 } else {
1712 NPPPD_ASSERT(
1713 ((struct sockaddr_npppd *)r->rd_rtent)
1714 ->snp_type == SNP_POOL ||
1715 ((struct sockaddr_npppd *)r->rd_rtent)
1716 ->snp_type == SNP_DYN_POOL);
1717 /*
1718 * If there is a pool entry that has same
1719 * address/mask, then make the RADISH entry a
1720 * list. Set SNP_PPP as the first in the list,
1721 * set current entry in snp->snp_next and
1722 * delete it.
1723 */
1724 if (sockaddr_npppd_match(
1725 radish->rd_route, r->rd_route) &&
1726 sockaddr_npppd_match(
1727 radish->rd_mask, r->rd_mask)) {
1728 /*
1729 * Releasing it, so remove it from the
1730 * new routing list.
1731 */
1732 rtlist_remove(&rtlist1, radish);
1733 /* set as snp_snp_next */
1734 snp->snp_next = r->rd_rtent;
1735 rval = rd_delete(r->rd_route,
Value stored to 'rval' is never read
1736 r->rd_mask, radish_head, &dummy);
1737 NPPPD_ASSERT(rval == 0);
1738 }
1739 }
1740 /* Register to the new radish */
1741 rval = rd_insert(radish->rd_route, radish->rd_mask,
1742 radish_head, snp);
1743 if (rval != 0) {
1744 errno(*__errno()) = rval;
1745 ppp_log(((npppd_ppp *)snp->snp_data_ptr),
1746 LOG_ERR3,
1747 "Fatal error on %s, cannot continue "
1748 "this ppp session: %m", __func__);
1749 if (!delppp0)
1750 slist_add(&delppp, snp->snp_data_ptr);
1751 }
1752 }
1753 }
1754 count = 0;
1755#ifndef NO_ROUTE_FOR_POOLED_ADDRESS
1756 if (_this->iface[0].using_pppx == 0) {
1757 for (slist_itr_first(&rtlist0); slist_itr_has_next(&rtlist0);) {
1758 radish = slist_itr_next(&rtlist0);
1759 in_route_delete(&SIN(radish->rd_route)((struct sockaddr_in *)(radish->rd_route))->sin_addr,
1760 &SIN(radish->rd_mask)((struct sockaddr_in *)(radish->rd_mask))->sin_addr, &loop,
1761 RTF_BLACKHOLE0x1000);
1762 count++;
1763 }
1764 if (count > 0)
1765 log_printf(LOG_INFO6,
1766 "Deleted %d routes for old pool addresses", count);
1767
1768 count = 0;
1769 for (slist_itr_first(&rtlist1); slist_itr_has_next(&rtlist1);) {
1770 radish = slist_itr_next(&rtlist1);
1771 in_route_add(&(SIN(radish->rd_route)((struct sockaddr_in *)(radish->rd_route))->sin_addr),
1772 &SIN(radish->rd_mask)((struct sockaddr_in *)(radish->rd_mask))->sin_addr, &loop,
1773 LOOPBACK_IFNAME"lo0", RTF_BLACKHOLE0x1000, 0);
1774 count++;
1775 }
1776 if (count > 0)
1777 log_printf(LOG_INFO6,
1778 "Added %d routes for new pool addresses",
1779 count);
1780 }
1781#endif
1782 slist_fini(&rtlist0);
1783 slist_fini(&rtlist1);
1784
1785 if (_this->rd != NULL((void *)0)) {
1786 npppd_rd_walktree_delete(_this->rd);
1787 _this->rd = NULL((void *)0);
1788 }
1789 if (radish_head == NULL((void *)0))
1790 npppd_get_all_users(_this, &delppp);
1791 _this->rd = radish_head;
1792
1793 for (slist_itr_first(&delppp); slist_itr_has_next(&delppp);) {
1794 ppp = slist_itr_next(&delppp);
1795 ppp_log(ppp, LOG_NOTICE5,
1796 "stop. IP address of this ppp is out of the pool.: %s",
1797 inet_ntoa(ppp->ppp_framed_ip_addresssnp.sin4.sin_addr));
1798 ppp_stop(ppp, NULL((void *)0));
1799 }
1800 slist_fini(&delppp);
1801
1802 return 0;
1803fail:
1804 slist_fini(&rtlist0);
1805 slist_fini(&rtlist1);
1806 slist_fini(&delppp);
1807
1808 return 1;
1809}
1810
1811/**
1812 * This function stores all users to {@link slist} and returns them.
1813 * References to {@link ::npppd_ppp} will be stored in users.
1814 */
1815static int
1816npppd_get_all_users(npppd *_this, slist *users)
1817{
1818 int rval;
1819 struct radish *rd;
1820 struct sockaddr_npppd *snp;
1821 slist list;
1822
1823 NPPPD_ASSERT(_this != NULL);
1824
1825 slist_init(&list);
1826 if (_this->rd == NULL((void *)0))
1827 return 0;
1828 rval = rd2slist(_this->rd, &list);
1829 if (rval != 0)
1830 return rval;
1831
1832 for (slist_itr_first(&list); slist_itr_has_next(&list);) {
1833 rd = slist_itr_next(&list);
1834 snp = rd->rd_rtent;
1835 if (snp->snp_type == SNP_PPP3) {
1836 if (slist_add(users, snp->snp_data_ptr) == NULL((void *)0)) {
1837 log_printf(LOG_ERR3,
1838 "slist_add() failed in %s: %m", __func__);
1839 goto fail;
1840 }
1841 }
1842 }
1843 slist_fini(&list);
1844
1845 return 0;
1846fail:
1847 slist_fini(&list);
1848
1849 return 1;
1850}
1851
1852static int
1853rd2slist_walk(struct radish *rd, void *list0)
1854{
1855 slist *list = list0;
1856 void *r;
1857
1858 r = slist_add(list, rd);
1859 if (r == NULL((void *)0))
1860 return -1;
1861 return 0;
1862}
1863static int
1864rd2slist(struct radish_head *h, slist *list)
1865{
1866 return rd_walktree(h, rd2slist_walk, list);
1867}
1868
1869static void
1870npppd_reload0(npppd *_this)
1871{
1872 int i;
1873
1874 npppd_reload_config(_this);
1875#ifdef USE_NPPPD_ARP
1876 arp_set_strictintfnetwork(npppd_config_str_equali(_this, "arpd.strictintfnetwork", "true", ARPD_STRICTINTFNETWORK_DEFAULT));
1877 if (npppd_config_str_equali(_this, "arpd.enabled", "true", ARPD_DEFAULT) == 1)
1878 arp_sock_init();
1879 else
1880 arp_sock_fini();
1881#endif
1882 npppd_modules_reload(_this);
1883 npppd_ifaces_load_config(_this);
1884 npppd_update_pool_reference(_this);
1885 npppd_auth_finalizer_periodic(_this);
1886 npppd_ipcp_stats_reload(_this);
1887
1888 for (i = 0; i < countof(_this->iface)(sizeof(_this->iface) / sizeof((_this->iface)[0])); i++) {
1889 if (_this->iface[i].initialized != 0 &&
1890 _this->iface[i].started == 0)
1891 npppd_iface_start(&_this->iface[i]);
1892 }
1893}
1894
1895static void
1896npppd_update_pool_reference(npppd *_this)
1897{
1898 int i, j;
1899 /* update iface to pool reference */
1900 for (i = 0; i < countof(_this->iface_pool)(sizeof(_this->iface_pool) / sizeof((_this->iface_pool)
[0]))
; i++) {
1901 _this->iface_pool[i] = NULL((void *)0);
1902 if (_this->iface[i].initialized == 0)
1903 continue;
1904 if (_this->iface[i].ipcpconf == NULL((void *)0))
1905 continue; /* no IPCP for this interface */
1906
1907 for (j = 0; j < countof(_this->pool)(sizeof(_this->pool) / sizeof((_this->pool)[0])); j++) {
1908 if (_this->pool[j].initialized == 0)
1909 continue;
1910 if (strcmp(_this->iface[i].ipcpconf->name,
1911 _this->pool[j].ipcp_name) == 0) {
1912 /* found the ipcp that has the pool */
1913 _this->iface_pool[i] = &_this->pool[j];
1914 break;
1915 }
1916 }
1917 }
1918}
1919
1920/***********************************************************************
1921 * Signal handlers
1922 ***********************************************************************/
1923static void
1924npppd_on_sighup(int fd, short ev_type, void *ctx)
1925{
1926 npppd *_this;
1927
1928 _this = ctx;
1929#ifndef NO_DELAYED_RELOAD
1930 if (_this->delayed_reload > 0)
1931 _this->reloading_count = _this->delayed_reload;
1932 else
1933#endif
1934 npppd_reload0(_this);
1935}
1936
1937static void
1938npppd_on_sigterm(int fd, short ev_type, void *ctx)
1939{
1940 npppd *_this;
1941
1942 _this = ctx;
1943 npppd_stop(_this);
1944}
1945
1946static void
1947npppd_on_sigint(int fd, short ev_type, void *ctx)
1948{
1949 npppd *_this;
1950
1951 _this = ctx;
1952 npppd_stop(_this);
1953}
1954
1955static void
1956npppd_on_sigchld(int fd, short ev_type, void *ctx)
1957{
1958 int status;
1959 pid_t wpid;
1960 npppd *_this;
1961
1962 _this = ctx;
1963 wpid = privsep_priv_pid();
1964 if (wait4(wpid, &status, WNOHANG0x01, NULL((void *)0)) == wpid) {
1965 if (WIFSIGNALED(status)(((status) & 0177) != 0177 && ((status) & 0177
) != 0)
)
1966 log_printf(LOG_WARNING4,
1967 "privileged process exits abnormally. signal=%d",
1968 WTERMSIG(status)(((status) & 0177)));
1969 else
1970 log_printf(LOG_WARNING4,
1971 "privileged process exits abnormally. status=%d",
1972 WEXITSTATUS(status)(int)(((unsigned)(status) >> 8) & 0xff));
1973 _this->stop_by_error = 1;
1974 npppd_stop(_this);
1975 }
1976}
1977/***********************************************************************
1978 * Miscellaneous functions
1979 ***********************************************************************/
1980static uint32_t
1981str_hash(const void *ptr, int sz)
1982{
1983 uint32_t hash = 0;
1984 int i, len;
1985 const char *str;
1986
1987 str = ptr;
1988 len = strlen(str);
1989 for (i = 0; i < len; i++)
1990 hash = hash*0x1F + str[i];
1991 hash = (hash << 16) ^ (hash & 0xffff);
1992
1993 return hash % sz;
1994}
1995
1996/**
1997 * Select a authentication realm that is for given {@link ::npppd_ppp PPP}.
1998 * Return 0 on success.
1999 */
2000int
2001npppd_ppp_bind_realm(npppd *_this, npppd_ppp *ppp, const char *username, int
2002 eap_required)
2003{
2004 struct confbind *bind;
2005 npppd_auth_base *realm = NULL((void *)0), *realm0 = NULL((void *)0), *realm1 = NULL((void *)0);
2006 char buf1[MAX_USERNAME_LENGTH256];
2007 int lsuffix, lusername, lmax;
2008
2009 NPPPD_ASSERT(_this != NULL);
2010 NPPPD_ASSERT(ppp != NULL);
2011 NPPPD_ASSERT(username != NULL);
2012
2013 /*
2014 * If the PPP suffix is the longest, and the length of the suffix is
2015 * same, select the first one.
2016 */
2017 lusername = strlen(username);
2018 lmax = -1;
2019 realm = NULL((void *)0);
2020
2021 TAILQ_FOREACH(bind, &_this->conf.confbinds, entry)for((bind) = ((&_this->conf.confbinds)->tqh_first);
(bind) != ((void *)0); (bind) = ((bind)->entry.tqe_next))
{
2022 if (strcmp(bind->tunnconf->name, ppp->phy_label) != 0)
2023 continue;
2024
2025 realm0 = NULL((void *)0);
2026 slist_itr_first(&_this->realms);
2027 while (slist_itr_has_next(&_this->realms)) {
2028 realm1 = slist_itr_next(&_this->realms);
2029 if (!npppd_auth_is_usable(realm1))
2030 continue;
2031 if (eap_required && !npppd_auth_is_eap_capable(realm1))
2032 continue;
2033 if (strcmp(npppd_auth_get_name(realm1),
2034 bind->authconf->name) == 0) {
2035 realm0 = realm1;
2036 break;
2037 }
2038 }
2039 if (realm0 == NULL((void *)0))
2040 continue;
2041
2042 lsuffix = strlen(npppd_auth_get_suffix(realm0));
2043 if (lsuffix > lmax &&
2044 (lsuffix == 0 ||
2045 (lsuffix < lusername && strcmp(username + lusername
2046 - lsuffix, npppd_auth_get_suffix(realm0))
2047 == 0))) {
2048 lmax = lsuffix;
2049 realm = realm0;
2050 }
2051 }
2052
2053 if (realm == NULL((void *)0)) {
2054 log_printf(LOG_INFO6, "user='%s' could not bind any realms",
2055 username);
2056 return 1;
2057 }
2058 NPPPD_DBG((LOG_DEBUG, "bind realm %s", npppd_auth_get_name(realm)));
2059
2060 if (npppd_auth_get_type(realm) == NPPPD_AUTH_TYPE_LOCAL1)
2061 /* hook the auto reload */
2062 npppd_auth_get_user_password(realm,
2063 npppd_auth_username_for_auth(realm1, username, buf1), NULL((void *)0),
2064 NULL((void *)0));
2065 ppp->realm = realm;
2066
2067 return 0;
2068}
2069
2070/** Is assigned realm a LOCAL authentication? */
2071int
2072npppd_ppp_is_realm_local(npppd *_this, npppd_ppp *ppp)
2073{
2074 NPPPD_ASSERT(_this != NULL);
2075 NPPPD_ASSERT(ppp != NULL);
2076
2077 if (ppp->realm == NULL((void *)0))
2078 return 0;
2079
2080 return (npppd_auth_get_type(ppp->realm) == NPPPD_AUTH_TYPE_LOCAL1)
2081 ? 1 : 0;
2082}
2083
2084/** Is assigned realm a RADIUS authentication? */
2085int
2086npppd_ppp_is_realm_radius(npppd *_this, npppd_ppp *ppp)
2087{
2088 NPPPD_ASSERT(_this != NULL);
2089 NPPPD_ASSERT(ppp != NULL);
2090
2091 if (ppp->realm == NULL((void *)0))
2092 return 0;
2093
2094 return (npppd_auth_get_type(ppp->realm) == NPPPD_AUTH_TYPE_RADIUS2)
2095 ? 1 : 0;
2096}
2097
2098/** Is assigned realm usable? */
2099int
2100npppd_ppp_is_realm_ready(npppd *_this, npppd_ppp *ppp)
2101{
2102 if (ppp->realm == NULL((void *)0))
2103 return 0;
2104
2105 return npppd_auth_is_ready(ppp->realm);
2106}
2107
2108/** Return the name of assigned realm */
2109const char *
2110npppd_ppp_get_realm_name(npppd *_this, npppd_ppp *ppp)
2111{
2112 if (ppp->realm == NULL((void *)0))
2113 return "(none)";
2114 return npppd_auth_get_name(ppp->realm);
2115}
2116
2117/** Return the interface name that bound given {@link ::npppd_ppp PPP} */
2118const char *
2119npppd_ppp_get_iface_name(npppd *_this, npppd_ppp *ppp)
2120{
2121 if (ppp == NULL((void *)0) || ppp->ifidx < 0)
2122 return "(not binding)";
2123 return ppp_iface(ppp)(&(ppp)->pppd->iface[(ppp)->ifidx])->ifname;
2124}
2125
2126/** Is the interface usable? */
2127int
2128npppd_ppp_iface_is_ready(npppd *_this, npppd_ppp *ppp)
2129{
2130 return (npppd_iface_ip_is_ready(ppp_iface(ppp))(((&(ppp)->pppd->iface[(ppp)->ifidx]))->initialized
!= 0 && ((&(ppp)->pppd->iface[(ppp)->ifidx
]))->ip4addr.s_addr != ((u_int32_t)(0x00000000)))
&&
2131 ppp_ipcp(ppp)((ppp)->pppd->iface[(ppp)->ifidx].ipcpconf) != NULL((void *)0))? 1 : 0;
2132}
2133
2134/** Select a suitable interface for {@link :npppd_ppp PPP} and bind them */
2135int
2136npppd_ppp_bind_iface(npppd *_this, npppd_ppp *ppp)
2137{
2138 int i, ifidx;
2139 struct confbind *bind;
2140 struct ipcpstat *ipcpstat;
2141
2142 NPPPD_ASSERT(_this != NULL);
2143 NPPPD_ASSERT(ppp != NULL);
2144
2145 if (ppp->ifidx >= 0)
2146 return 0;
2147
2148 TAILQ_FOREACH(bind, &_this->conf.confbinds, entry)for((bind) = ((&_this->conf.confbinds)->tqh_first);
(bind) != ((void *)0); (bind) = ((bind)->entry.tqe_next))
{
2149 if (strcmp(bind->tunnconf->name, ppp->phy_label) != 0)
2150 continue;
2151 if (ppp->realm == NULL((void *)0)) {
2152 if (bind->authconf == NULL((void *)0))
2153 break;
2154 } else if (strcmp(bind->authconf->name,
2155 npppd_auth_get_name(ppp->realm)) == 0)
2156 break;
2157 }
2158 if (bind == NULL((void *)0))
2159 return 1;
2160
2161 /* Search a interface */
2162 ifidx = -1;
2163 for (i = 0; i < countof(_this->iface)(sizeof(_this->iface) / sizeof((_this->iface)[0])); i++) {
2164 if (_this->iface[i].initialized == 0)
2165 continue;
2166 if (strcmp(_this->iface[i].ifname, bind->iface->name) == 0)
2167 ifidx = i;
2168 }
2169 if (ifidx < 0)
2170 return 1;
2171
2172 ppp->ifidx = ifidx;
2173 NPPPD_ASSERT(ppp_ipcp(ppp) != NULL);
2174 ipcpstat = npppd_get_ipcp_stat(&_this->ipcpstats, ppp_ipcp(ppp)((ppp)->pppd->iface[(ppp)->ifidx].ipcpconf)->name);
2175 if (ipcpstat == NULL((void *)0)) {
2176 ppp_log(ppp, LOG_WARNING4, "Unknown IPCP %s",
2177 ppp_ipcp(ppp)((ppp)->pppd->iface[(ppp)->ifidx].ipcpconf)->name);
2178 ppp->ifidx = -1; /* unbind interface */
2179 return 1;
2180 }
2181 if (ppp_ipcp(ppp)((ppp)->pppd->iface[(ppp)->ifidx].ipcpconf)->max_session > 0 &&
2182 ipcpstat->nsession >= ppp_ipcp(ppp)((ppp)->pppd->iface[(ppp)->ifidx].ipcpconf)->max_session) {
2183 ppp_log(ppp, LOG_WARNING4,
2184 "Number of sessions per IPCP reaches out of the limit=%d",
2185 ppp_ipcp(ppp)((ppp)->pppd->iface[(ppp)->ifidx].ipcpconf)->max_session);
2186 ppp->ifidx = -1; /* unbind interface */
2187 return 1;
2188 }
2189
2190 if (_this->conf.max_session > 0 &&
2191 _this->nsession >= _this->conf.max_session) {
2192 ppp_log(ppp, LOG_WARNING4,
2193 "Number of sessions reaches out of the limit=%d",
2194 _this->conf.max_session);
2195 ppp->ifidx = -1; /* unbind interface */
2196 return 1;
2197 }
2198 _this->nsession++;
2199
2200 LIST_INSERT_HEAD(&ipcpstat->ppp, ppp, ipcpstat_entry)do { if (((ppp)->ipcpstat_entry.le_next = (&ipcpstat->
ppp)->lh_first) != ((void *)0)) (&ipcpstat->ppp)->
lh_first->ipcpstat_entry.le_prev = &(ppp)->ipcpstat_entry
.le_next; (&ipcpstat->ppp)->lh_first = (ppp); (ppp)
->ipcpstat_entry.le_prev = &(&ipcpstat->ppp)->
lh_first; } while (0)
;
2201 ppp->ipcpstat = ipcpstat;
2202 ipcpstat->nsession++;
2203
2204 return 0;
2205}
2206
2207/** Unbind the interface from the {@link ::npppd_ppp PPP} */
2208void
2209npppd_ppp_unbind_iface(npppd *_this, npppd_ppp *ppp)
2210{
2211 if (ppp->ifidx >= 0) {
2212 _this->nsession--;
2213 if (ppp->ipcpstat!= NULL((void *)0)) {
2214 ppp->ipcpstat->nsession--;
2215 LIST_REMOVE(ppp, ipcpstat_entry)do { if ((ppp)->ipcpstat_entry.le_next != ((void *)0)) (ppp
)->ipcpstat_entry.le_next->ipcpstat_entry.le_prev = (ppp
)->ipcpstat_entry.le_prev; *(ppp)->ipcpstat_entry.le_prev
= (ppp)->ipcpstat_entry.le_next; ; ; } while (0)
;
2216 }
2217 }
2218 ppp->ifidx = -1;
2219}
2220
2221static int
2222npppd_rd_walktree_delete(struct radish_head *rh)
2223{
2224 void *dummy;
2225 struct radish *rd;
2226 slist list;
2227
2228 slist_init(&list);
2229 if (rd2slist(rh, &list) != 0)
2230 return 1;
2231 for (slist_itr_first(&list); slist_itr_has_next(&list);) {
2232 rd = slist_itr_next(&list);
2233 rd_delete(rd->rd_route, rd->rd_mask, rh, &dummy);
2234 }
2235 slist_fini(&list);
2236
2237 free(rh);
2238
2239 return 0;
2240}
2241
2242#ifdef USE_NPPPD_RADIUS1
2243/**
2244 * Return radius_req_setting for the given {@link ::npppd_ppp PPP}.
2245 * @return return NULL if no usable RADIUS setting.
2246 */
2247void *
2248npppd_get_radius_auth_setting(npppd *_this, npppd_ppp *ppp)
2249{
2250 NPPPD_ASSERT(_this != NULL);
2251 NPPPD_ASSERT(ppp != NULL);
2252
2253 if (ppp->realm == NULL((void *)0))
2254 return NULL((void *)0);
2255 if (!npppd_ppp_is_realm_radius(_this, ppp))
2256 return NULL((void *)0);
2257
2258 return npppd_auth_radius_get_radius_auth_setting(ppp->realm);
2259}
2260#endif
2261
2262/** Finalize authentication realm */
2263static void
2264npppd_auth_finalizer_periodic(npppd *_this)
2265{
2266 int ndisposing = 0, refcnt;
2267 slist users;
2268 npppd_auth_base *auth_base;
2269 npppd_ppp *ppp;
2270
2271 /*
2272 * For the realms with disposing flag, if the realm has assigned PPPs,
2273 * disconnect them. If all PPPs are disconnected then free the realm.
2274 */
2275 NPPPD_DBG((DEBUG_LEVEL_2, "%s() called", __func__));
2276 slist_itr_first(&_this->realms);
2277 while (slist_itr_has_next(&_this->realms)) {
2278 auth_base = slist_itr_next(&_this->realms);
2279 if (!npppd_auth_is_disposing(auth_base))
2280 continue;
2281 refcnt = 0;
2282 if (ndisposing++ == 0) {
2283 slist_init(&users);
2284 if (npppd_get_all_users(_this, &users) != 0) {
2285 log_printf(LOG_WARNING4,
2286 "npppd_get_all_users() failed in %s(): %m",
2287 __func__);
2288 break;
2289 }
2290 }
2291 slist_itr_first(&users);
2292 while (slist_itr_has_next(&users)) {
2293 ppp = slist_itr_next(&users);
2294 if (ppp->realm == auth_base) {
2295 refcnt++;
2296 ppp_stop(ppp, NULL((void *)0));
2297 ppp_log(ppp, LOG_INFO6,
2298 "Stop request by npppd. Binding "
2299 "authentication realm is disposing. "
2300 "realm=%s", npppd_auth_get_name(auth_base));
2301 slist_itr_remove(&users);
2302 }
2303 }
2304 if (refcnt == 0) {
2305 npppd_auth_destroy(auth_base);
2306 slist_itr_remove(&_this->realms);
2307 }
2308 }
2309 if (ndisposing > 0)
2310 slist_fini(&users);
2311}
2312
2313/** compare sockaddr_npppd. return 0 if matches */
2314int
2315sockaddr_npppd_match(void *a0, void *b0)
2316{
2317 struct sockaddr_npppd *a, *b;
2318
2319 a = a0;
2320 b = b0;
2321
2322 return (a->snp_addrsin4.sin_addr.s_addr == b->snp_addrsin4.sin_addr.s_addr)? 1 : 0;
2323}
2324
2325/**
2326 * This function stores the username for authentication to the space specified
2327 * by username_buffer and returns it. username_buffer must have space more
2328 * than MAX_USERNAME_LENGTH.
2329 */
2330const char *
2331npppd_ppp_get_username_for_auth(npppd *_this, npppd_ppp *ppp,
2332 const char *username, char *username_buffer)
2333{
2334 NPPPD_ASSERT(_this != NULL);
2335 NPPPD_ASSERT(ppp != NULL);
2336 NPPPD_ASSERT(ppp->realm != NULL);
2337
2338 return npppd_auth_username_for_auth(ppp->realm, username,
2339 username_buffer);
2340}
2341
2342const char *
2343npppd_tunnel_protocol_name(int tunn_protocol)
2344{
2345 switch (tunn_protocol) {
2346 case NPPPD_TUNNEL_NONE0:
2347 return "None";
2348 case NPPPD_TUNNEL_L2TP1:
2349 return "L2TP";
2350 case NPPPD_TUNNEL_PPTP2:
2351 return "PPTP";
2352 case NPPPD_TUNNEL_PPPOE3:
2353 return "PPPoE";
2354 case NPPPD_TUNNEL_SSTP4:
2355 return "SSTP";
2356 }
2357
2358 return "Error";
2359}
2360
2361const char *
2362npppd_ppp_tunnel_protocol_name(npppd *_this, npppd_ppp *ppp)
2363{
2364 return npppd_tunnel_protocol_name(ppp->tunnel_type);
2365}
2366
2367struct tunnconf *
2368npppd_get_tunnconf(npppd *_this, const char *name)
2369{
2370 struct tunnconf *conf;
2371
2372 TAILQ_FOREACH(conf, &_this->conf.tunnconfs, entry)for((conf) = ((&_this->conf.tunnconfs)->tqh_first);
(conf) != ((void *)0); (conf) = ((conf)->entry.tqe_next))
{
2373 if (strcmp(conf->name, name) == 0)
2374 return conf;
2375 }
2376
2377 return NULL((void *)0);
2378}
2379
2380void
2381npppd_on_ppp_start(npppd *_this, npppd_ppp *ppp)
2382{
2383 struct ctl_conn *c;
2384
2385 TAILQ_FOREACH(c, &ctl_conns, entry)for((c) = ((&ctl_conns)->tqh_first); (c) != ((void *)0
); (c) = ((c)->entry.tqe_next))
{
2386 if (npppd_ctl_add_started_ppp_id(c->ctx, ppp->id) == 0) {
2387 npppd_ctl_imsg_compose(c->ctx, &c->iev.ibuf);
2388 imsg_event_add(&c->iev);
2389 }
2390 }
2391}
2392
2393void
2394npppd_on_ppp_stop(npppd *_this, npppd_ppp *ppp)
2395{
2396 struct ctl_conn *c;
2397
2398 TAILQ_FOREACH(c, &ctl_conns, entry)for((c) = ((&ctl_conns)->tqh_first); (c) != ((void *)0
); (c) = ((c)->entry.tqe_next))
{
2399 if (npppd_ctl_add_stopped_ppp(c->ctx, ppp) == 0) {
2400 npppd_ctl_imsg_compose(c->ctx, &c->iev.ibuf);
2401 imsg_event_add(&c->iev);
2402 }
2403 }
2404}
2405
2406void
2407imsg_event_add(struct imsgev *iev)
2408{
2409 iev->events = EV_READ0x02;
2410 if (iev->ibuf.w.queued)
2411 iev->events |= EV_WRITE0x04;
2412
2413 event_del(&iev->ev);
2414 event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev->data);
2415 event_add(&iev->ev, NULL((void *)0));
2416}