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