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