Bug Summary

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