xref: /openbsd/usr.sbin/npppd/l2tp/l2tpd.c (revision 91f110e0)
1 /*	$OpenBSD: l2tpd.c,v 1.14 2014/03/22 04:32:39 yasuoka Exp $ */
2 
3 /*-
4  * Copyright (c) 2009 Internet Initiative Japan Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 /**@file L2TP(Layer Two Tunneling Protocol "L2TP") / RFC2661 */
29 /* $Id: l2tpd.c,v 1.14 2014/03/22 04:32:39 yasuoka Exp $ */
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <sys/time.h>
33 #include <netinet/in.h>
34 #include <netinet/udp.h>
35 #include <stdlib.h>
36 #include <arpa/inet.h>
37 #include <stdio.h>
38 #include <unistd.h>
39 #include <netdb.h>
40 #include <syslog.h>
41 #include <signal.h>
42 #include <string.h>
43 #include <fcntl.h>
44 #include <errno.h>
45 #include <stdarg.h>
46 #include <event.h>
47 
48 #ifdef USE_LIBSOCKUTIL
49 #include <seil/sockfromto.h>
50 #else
51 #include "recvfromto.h"
52 #endif
53 
54 #include "bytebuf.h"
55 #include "hash.h"
56 #include "slist.h"
57 #include "debugutil.h"
58 #include "l2tp.h"
59 #include "l2tp_subr.h"
60 #include "l2tp_local.h"
61 #include "addr_range.h"
62 #include "net_utils.h"
63 
64 #ifdef	L2TPD_DEBUG
65 #define	L2TPD_ASSERT(x)	ASSERT(x)
66 #define	L2TPD_DBG(x)	l2tpd_log x
67 #else
68 #define	L2TPD_ASSERT(x)
69 #endif
70 #define L2TPD_IPSEC_POLICY_IN	"in ipsec esp/transport//require"
71 #define L2TPD_IPSEC_POLICY_OUT	"out ipsec esp/transport//require"
72 
73 static void             l2tpd_io_event (int, short, void *);
74 static inline int       short_cmp (const void *, const void *);
75 static inline uint32_t  short_hash (const void *, int);
76 
77 /* sequence # of l2tpd ID */
78 static u_int l2tpd_id_seq = 0;
79 
80 /* L2TP daemon instance */
81 
82 /**
83  * initialize L2TP daemon instance
84  * <p>
85  * {@link _l2tpd#bind_sin} will return with .sin_family = AF_INET,
86  * .sin_port = 1701 and .sin_len = "appropriate value"
87  * </p>
88  */
89 int
90 l2tpd_init(l2tpd *_this)
91 {
92 	int i, off;
93 	u_int id;
94 
95 	L2TPD_ASSERT(_this != NULL);
96 	memset(_this, 0, sizeof(l2tpd));
97 
98 	slist_init(&_this->listener);
99 	slist_init(&_this->free_session_id_list);
100 
101 	_this->id = l2tpd_id_seq++;
102 
103 	if ((_this->ctrl_map = hash_create(short_cmp, short_hash,
104 	    L2TPD_TUNNEL_HASH_SIZ)) == NULL) {
105 		log_printf(LOG_ERR, "hash_create() failed in %s(): %m",
106 		    __func__);
107 		return 1;
108 	}
109 
110 	if (slist_add(&_this->free_session_id_list,
111 	    (void *)L2TP_SESSION_ID_SHUFFLE_MARK) == NULL) {
112 		l2tpd_log(_this, LOG_ERR, "slist_add() failed on %s(): %m",
113 		    __func__);
114 		return 1;
115 	}
116 	off = arc4random() % L2TP_SESSION_ID_MASK;
117 	for (i = 0; i < L2TP_NCALL; i++) {
118 		id = (i + off) % L2TP_SESSION_ID_MASK;
119 		if (id == 0)
120 			id = (off - 1) % L2TP_SESSION_ID_MASK;
121 		if (slist_add(&_this->free_session_id_list,
122 		    (void *)(uintptr_t)id) == NULL) {
123 			l2tpd_log(_this, LOG_ERR,
124 			    "slist_add() failed on %s(): %m", __func__);
125 			return 1;
126 		}
127 	}
128 	_this->purge_ipsec_sa = 1;
129 	_this->state = L2TPD_STATE_INIT;
130 
131 	return 0;
132 }
133 
134 /*
135  * Add a {@link :l2tpd_listener} to the {@link ::l2tpd L2TP daemon}
136  * @param	_this	{@link ::l2tpd L2TP daemon}
137  * @param	idx	index of the lisnter
138  * @param	tun_name	tunnel name (ex. "L2TP")
139  * @param	bindaddr	bind address
140  */
141 int
142 l2tpd_add_listener(l2tpd *_this, int idx, struct l2tp_conf *conf,
143     struct sockaddr *addr)
144 {
145 	l2tpd_listener *plistener, *plsnr;
146 
147 	plistener = NULL;
148 	if (idx == 0 && slist_length(&_this->listener) > 0) {
149 		slist_itr_first(&_this->listener);
150 		while (slist_itr_has_next(&_this->listener)) {
151 			slist_itr_next(&_this->listener);
152 			plsnr = slist_itr_remove(&_this->listener);
153 			L2TPD_ASSERT(plsnr != NULL);
154 			L2TPD_ASSERT(plsnr->sock == -1);
155 			free(plsnr);
156 		}
157 	}
158 	L2TPD_ASSERT(slist_length(&_this->listener) == idx);
159 	if (slist_length(&_this->listener) != idx) {
160 		l2tpd_log(_this, LOG_ERR,
161 		    "Invalid argument error on %s(): idx must be %d but %d",
162 		    __func__, slist_length(&_this->listener), idx);
163 		goto fail;
164 	}
165 	if ((plistener = malloc(sizeof(l2tpd_listener))) == NULL) {
166 		l2tpd_log(_this, LOG_ERR, "malloc() failed in %s: %m",
167 		    __func__);
168 		goto fail;
169 	}
170 	memset(plistener, 0, sizeof(l2tpd_listener));
171 	L2TPD_ASSERT(sizeof(plistener->bind) >= addr->sa_len);
172 	memcpy(&plistener->bind, addr, addr->sa_len);
173 
174 	if (plistener->bind.sin6.sin6_port == 0)
175 		plistener->bind.sin6.sin6_port = htons(L2TPD_DEFAULT_UDP_PORT);
176 
177 	plistener->sock = -1;
178 	plistener->self = _this;
179 	plistener->index = idx;
180 	plistener->conf = conf;
181 	strlcpy(plistener->tun_name, conf->name, sizeof(plistener->tun_name));
182 
183 	if (slist_add(&_this->listener, plistener) == NULL) {
184 		l2tpd_log(_this, LOG_ERR, "slist_add() failed in %s: %m",
185 		    __func__);
186 		goto fail;
187 	}
188 	return 0;
189 fail:
190 	if (plistener != NULL)
191 		free(plistener);
192 	return 1;
193 }
194 
195 /* finalize L2TP daemon instance */
196 void
197 l2tpd_uninit(l2tpd *_this)
198 {
199 	l2tpd_listener *plsnr;
200 
201 	L2TPD_ASSERT(_this != NULL);
202 
203 	slist_fini(&_this->free_session_id_list);
204 	if (_this->ctrl_map != NULL) {
205 		hash_free(_this->ctrl_map);
206 		_this->ctrl_map = NULL;
207 	}
208 
209 	slist_itr_first(&_this->listener);
210 	while (slist_itr_has_next(&_this->listener)) {
211 		plsnr = slist_itr_next(&_this->listener);
212 		L2TPD_ASSERT(plsnr != NULL);
213 		L2TPD_ASSERT(plsnr->sock == -1);
214 		free(plsnr);
215 	}
216 	slist_fini(&_this->listener);
217 
218 	event_del(&_this->ev_timeout);	/* just in case */
219 	_this->state = L2TPD_STATE_STOPPED;
220 }
221 
222 /** assign the call to the l2tpd */
223 int
224 l2tpd_assign_call(l2tpd *_this, l2tp_call *call)
225 {
226 	int    shuffle_cnt;
227 	u_int  session_id;
228 
229 	shuffle_cnt = 0;
230 	do {
231 		session_id = (uintptr_t)slist_remove_first(
232 		    &_this->free_session_id_list);
233 		if (session_id != L2TP_SESSION_ID_SHUFFLE_MARK)
234 			break;
235 		L2TPD_ASSERT(shuffle_cnt == 0);
236 		if (shuffle_cnt++ > 0) {
237 			l2tpd_log(_this, LOG_ERR,
238 			    "unexpected errror in %s(): free_session_id_list "
239 			    "full", __func__);
240 			slist_add(&_this->free_session_id_list,
241 			    (void *)L2TP_SESSION_ID_SHUFFLE_MARK);
242 			return 1;
243 		}
244 		slist_shuffle(&_this->free_session_id_list);
245 		slist_add(&_this->free_session_id_list,
246 		    (void *)L2TP_SESSION_ID_SHUFFLE_MARK);
247 	} while (1);
248 	call->id = session_id;
249 
250 	return 0;
251 }
252 
253 /* this function will be called when the call is released */
254 void
255 l2tpd_release_call(l2tpd *_this, l2tp_call *call)
256 {
257 	slist_add(&_this->free_session_id_list, (void *)(uintptr_t)call->id);
258 }
259 
260 /* start l2tpd listner */
261 static int
262 l2tpd_listener_start(l2tpd_listener *_this)
263 {
264 	l2tpd *_l2tpd;
265 	int    af, lvl, opt, sock, ival;
266 	char   hbuf[NI_MAXHOST + NI_MAXSERV + 16];
267 
268 	_l2tpd = _this->self;
269 	sock = -1;
270 	af = _this->bind.sin6.sin6_family;
271 	lvl = (af == AF_INET)? IPPROTO_IP : IPPROTO_IPV6;
272 
273 	if (_this->tun_name[0] == '\0')
274 		strlcpy(_this->tun_name, L2TPD_DEFAULT_LAYER2_LABEL,
275 		    sizeof(_this->tun_name));
276 	if ((sock = socket(_this->bind.sin6.sin6_family,
277 	    SOCK_DGRAM, IPPROTO_UDP)) < 0) {
278 		l2tpd_log(_l2tpd, LOG_ERR,
279 		    "socket() failed in %s(): %m", __func__);
280 		goto fail;
281 	}
282 #if defined(IP_STRICT_RCVIF) && defined(USE_STRICT_RCVIF)
283 	ival = 1;
284 	if (setsockopt(sock, IPPROTO_IP, IP_STRICT_RCVIF, &ival, sizeof(ival))
285 	    != 0)
286 		l2tpd_log(_l2tpd, LOG_WARNING,
287 		    "%s(): setsockopt(IP_STRICT_RCVIF) failed: %m", __func__);
288 #endif
289 	if ((ival = fcntl(sock, F_GETFL, 0)) < 0) {
290 		l2tpd_log(_l2tpd, LOG_ERR,
291 		    "fcntl(,F_GETFL) failed in %s(): %m", __func__);
292 		goto fail;
293 	} else if (fcntl(sock, F_SETFL, ival | O_NONBLOCK) < 0) {
294 		l2tpd_log(_l2tpd, LOG_ERR, "fcntl(,F_SETFL,O_NONBLOCK) failed "
295 		    "in %s(): %m", __func__);
296 		goto fail;
297 	}
298 	ival = 1;
299 	if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &ival, sizeof(ival))
300 	    != 0) {
301 		l2tpd_log(_l2tpd, LOG_ERR,
302 		    "setsockopt(,,SO_REUSEPORT) failed in %s(): %m", __func__);
303 		goto fail;
304 	}
305 	if (bind(sock, (struct sockaddr *)&_this->bind,
306 	    _this->bind.sin6.sin6_len) != 0) {
307 		l2tpd_log(_l2tpd, LOG_ERR, "Binding %s/udp: %m",
308 		    addrport_tostring((struct sockaddr *)&_this->bind,
309 		    _this->bind.sin6.sin6_len, hbuf, sizeof(hbuf)));
310 		goto fail;
311 	}
312 #ifdef USE_LIBSOCKUTIL
313 	if (setsockoptfromto(sock) != 0) {
314 		l2tpd_log(_l2tpd, LOG_ERR,
315 		    "setsockoptfromto() failed in %s(): %m", __func__);
316 		goto fail;
317 	}
318 #else
319 	opt = (af == AF_INET)? IP_RECVDSTADDR : IPV6_RECVPKTINFO;
320 	ival = 1;
321 	if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0) {
322 		l2tpd_log(_l2tpd, LOG_ERR,
323 		    "setsockopt(,,IP{,V6}_RECVDSTADDR) failed in %s(): %m",
324 		    __func__);
325 		goto fail;
326 	}
327 #endif
328 #ifdef USE_SA_COOKIE
329 	if (af == AF_INET) {
330 		ival = 1;
331 		if (setsockopt(sock, IPPROTO_IP, IP_IPSECFLOWINFO, &ival,
332 		    sizeof(ival)) != 0) {
333 			l2tpd_log(_l2tpd, LOG_ERR,
334 			    "setsockopt(,,IP_IPSECFLOWINFO) failed in %s(): %m",
335 			    __func__);
336 			goto fail;
337 		}
338 	}
339 #endif
340 #ifdef IP_PIPEX
341 	opt = (af == AF_INET)? IP_PIPEX : IPV6_PIPEX;
342 	ival = 1;
343 	if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0)
344 		l2tpd_log(_l2tpd, LOG_WARNING,
345 		    "%s(): setsockopt(IP{,V6}_PIPEX) failed: %m", __func__);
346 #endif
347 	if (_this->conf->require_ipsec) {
348 #ifdef IP_IPSEC_POLICY
349 		caddr_t  ipsec_policy_in, ipsec_policy_out;
350 
351 		opt = (af == AF_INET)? IP_IPSEC_POLICY : IPV6_IPSEC_POLICY;
352 		/*
353 		 * Note: ipsec_set_policy() will assign the buffer for
354 		 * yacc parser stack, however it never free.
355 		 * it cause memory leak (-2000byte).
356 		 */
357 		if ((ipsec_policy_in = ipsec_set_policy(L2TPD_IPSEC_POLICY_IN,
358 		    strlen(L2TPD_IPSEC_POLICY_IN))) == NULL) {
359 			l2tpd_log(_l2tpd, LOG_ERR,
360 			    "ipsec_set_policy(L2TPD_IPSEC_POLICY_IN) failed "
361 			    "at %s(): %s: %m", __func__, ipsec_strerror());
362 		} else if (setsockopt(sock, lvl, opt, ipsec_policy_in,
363 		    ipsec_get_policylen(ipsec_policy_in)) < 0) {
364 			l2tpd_log(_l2tpd, LOG_WARNING,
365 			    "setsockopt(,,IP_IPSEC_POLICY(in)) failed "
366 			    "in %s(): %m", __func__);
367 		}
368 		if ((ipsec_policy_out = ipsec_set_policy(L2TPD_IPSEC_POLICY_OUT,
369 		    strlen(L2TPD_IPSEC_POLICY_OUT))) == NULL) {
370 			l2tpd_log(_l2tpd, LOG_ERR,
371 			    "ipsec_set_policy(L2TPD_IPSEC_POLICY_OUT) failed "
372 			    "at %s(): %s: %m", __func__, ipsec_strerror());
373 		}
374 		if (ipsec_policy_out != NULL &&
375 		    setsockopt(sock, lvl, opt, ipsec_policy_out,
376 		    ipsec_get_policylen(ipsec_policy_out)) < 0) {
377 			l2tpd_log(_l2tpd, LOG_WARNING,
378 			    "setsockopt(,,IP_IPSEC_POLICY(out)) failed "
379 			    "in %s(): %m", __func__);
380 		}
381 		if (ipsec_policy_in != NULL)
382 			free(ipsec_policy_in);
383 		if (ipsec_policy_out != NULL)
384 			free(ipsec_policy_out);
385 #elif defined(IP_ESP_TRANS_LEVEL)
386 		opt = (af == AF_INET)
387 		    ? IP_ESP_TRANS_LEVEL : IPV6_ESP_TRANS_LEVEL;
388 		ival = IPSEC_LEVEL_REQUIRE;
389 		if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0) {
390 			l2tpd_log(_l2tpd, LOG_WARNING,
391 			    "setsockopt(,,IP{,V6}_ESP_TRANS_LEVEL(out)) failed "
392 			    "in %s(): %m", __func__);
393 		}
394 #else
395 #error IP_IPSEC_POLICY or IP_ESP_TRANS_LEVEL must be usable.
396 #endif
397 	}
398 
399 	_this->sock = sock;
400 
401 	event_set(&_this->ev_sock, _this->sock, EV_READ | EV_PERSIST,
402 	    l2tpd_io_event, _this);
403 	event_add(&_this->ev_sock, NULL);
404 
405 	l2tpd_log(_l2tpd, LOG_INFO, "Listening %s/udp (L2TP LNS) [%s]",
406 	    addrport_tostring((struct sockaddr *)&_this->bind,
407 	    _this->bind.sin6.sin6_len, hbuf, sizeof(hbuf)), _this->tun_name);
408 
409 	return 0;
410 fail:
411 	if (sock >= 0)
412 		close(sock);
413 
414 	return 1;
415 }
416 
417 /* start L2TP daemon */
418 int
419 l2tpd_start(l2tpd *_this)
420 {
421 	int rval;
422 	l2tpd_listener *plsnr;
423 
424 	rval = 0;
425 
426 	L2TPD_ASSERT(_this->state == L2TPD_STATE_INIT);
427 	if (_this->state != L2TPD_STATE_INIT) {
428 		l2tpd_log(_this, LOG_ERR, "Failed to start l2tpd: illegal "
429 		    "state.");
430 		return -1;
431 	}
432 
433 	slist_itr_first(&_this->listener);
434 	while (slist_itr_has_next(&_this->listener)) {
435 		plsnr = slist_itr_next(&_this->listener);
436 		rval |= l2tpd_listener_start(plsnr);
437 	}
438 
439 	if (rval == 0)
440 		_this->state = L2TPD_STATE_RUNNING;
441 
442 	return rval;
443 }
444 
445 /* stop l2tp lisnter */
446 static void
447 l2tpd_listener_stop(l2tpd_listener *_this)
448 {
449 	char hbuf[NI_MAXHOST + NI_MAXSERV + 16];
450 
451 	if (_this->sock >= 0) {
452 		event_del(&_this->ev_sock);
453 		close(_this->sock);
454 		l2tpd_log(_this->self, LOG_INFO,
455 		    "Shutdown %s/udp (L2TP LNS)",
456 		    addrport_tostring((struct sockaddr *)&_this->bind,
457 		    _this->bind.sin6.sin6_len, hbuf, sizeof(hbuf)));
458 		_this->sock = -1;
459 	}
460 }
461 
462 /* stop immediattly without disconnect operation */
463 void
464 l2tpd_stop_immediatly(l2tpd *_this)
465 {
466 	l2tpd_listener *plsnr;
467 
468 	slist_itr_first(&_this->listener);
469 	while (slist_itr_has_next(&_this->listener)) {
470 		plsnr = slist_itr_next(&_this->listener);
471 		l2tpd_listener_stop(plsnr);
472 	}
473 	event_del(&_this->ev_timeout);	/* XXX */
474 	_this->state = L2TPD_STATE_STOPPED;
475 }
476 
477 /*
478  * this function will be called when {@link ::_l2tp_ctrl control}
479  * is terminated.
480  */
481 void
482 l2tpd_ctrl_finished_notify(l2tpd *_this)
483 {
484 	if (_this->state != L2TPD_STATE_SHUTTING_DOWN)
485 		return;
486 
487 	if (hash_first(_this->ctrl_map) != NULL)
488 		return;
489 
490 	l2tpd_stop_immediatly(_this);
491 }
492 
493 static void
494 l2tpd_stop_timeout(int fd, short evtype, void *ctx)
495 {
496 	hash_link *hl;
497 	l2tp_ctrl *ctrl;
498 	l2tpd *_this;
499 
500 	_this = ctx;
501 	l2tpd_log(_this, LOG_INFO, "Shutdown timeout");
502 	for (hl = hash_first(_this->ctrl_map); hl != NULL;
503 	    hl = hash_next(_this->ctrl_map)) {
504 		ctrl = hl->item;
505 		l2tp_ctrl_stop(ctrl, 0);
506 	}
507 	l2tpd_stop_immediatly(_this);
508 }
509 
510 /* stop L2TP daemon */
511 void
512 l2tpd_stop(l2tpd *_this)
513 {
514 	int nctrls = 0;
515 	hash_link *hl;
516 	l2tp_ctrl *ctrl;
517 
518 	nctrls = 0;
519 	event_del(&_this->ev_timeout);
520 	if (l2tpd_is_stopped(_this))
521 		return;
522 	if (l2tpd_is_shutting_down(_this)) {
523 		/* terminate immediately, when 2nd call */
524 		l2tpd_stop_immediatly(_this);
525 		return;
526 	}
527 	for (hl = hash_first(_this->ctrl_map); hl != NULL;
528 	    hl = hash_next(_this->ctrl_map)) {
529 		ctrl = hl->item;
530 		l2tp_ctrl_stop(ctrl, L2TP_STOP_CCN_RCODE_SHUTTING_DOWN);
531 		nctrls++;
532 	}
533 	_this->state = L2TPD_STATE_SHUTTING_DOWN;
534 	if (nctrls > 0) {
535 		struct timeval tv0;
536 
537 		tv0.tv_usec = 0;
538 		tv0.tv_sec = L2TPD_SHUTDOWN_TIMEOUT;
539 
540 		evtimer_set(&_this->ev_timeout, l2tpd_stop_timeout, _this);
541 		evtimer_add(&_this->ev_timeout, &tv0);
542 
543 		return;
544 	}
545 	l2tpd_stop_immediatly(_this);
546 }
547 
548 /*
549  * Configuration
550  */
551 int
552 l2tpd_reload(l2tpd *_this, struct l2tp_confs *l2tp_conf)
553 {
554 	int			 i;
555 	struct l2tp_conf	*conf;
556 	l2tpd_listener		*listener;
557 	struct l2tp_listen_addr	*addr;
558 
559 	if (slist_length(&_this->listener) > 0) {
560 		/*
561 		 * TODO: add / remove / restart listener.
562 		 */
563 		slist_itr_first(&_this->listener);
564 		while (slist_itr_has_next(&_this->listener)) {
565 			listener = slist_itr_next(&_this->listener);
566 			TAILQ_FOREACH(conf, l2tp_conf, entry) {
567 				if (strcmp(listener->tun_name,
568 				    conf->name) == 0) {
569 					listener->conf = conf;
570 					break;
571 				}
572 			}
573 		}
574 
575 		return 0;
576 	}
577 
578 	i = 0;
579 	TAILQ_FOREACH(conf, l2tp_conf, entry) {
580 		TAILQ_FOREACH(addr, &conf->listen, entry)
581 			l2tpd_add_listener(_this, i++, conf,
582 			    (struct sockaddr *)&addr->addr);
583 	}
584 	if (l2tpd_start(_this) != 0)
585 		return -1;
586 
587 	return 0;
588 }
589 
590 /*
591  * I/O functions
592  */
593 /* logging when deny an access */
594 void
595 l2tpd_log_access_deny(l2tpd *_this, const char *reason, struct sockaddr *peer)
596 {
597 	char buf[BUFSIZ];
598 
599 	l2tpd_log(_this, LOG_ALERT, "Received packet from %s/udp: "
600 	    "%s", addrport_tostring(peer, peer->sa_len, buf, sizeof(buf)),
601 	    reason);
602 }
603 
604 /* I/O event handler */
605 static void
606 l2tpd_io_event(int fd, short evtype, void *ctx)
607 {
608 	int sz;
609 	l2tpd *_l2tpd;
610 	l2tpd_listener *_this;
611 	socklen_t peerlen, socklen;
612 	struct sockaddr_storage peer, sock;
613 	u_char buf[8192];
614 	void *nat_t;
615 
616 	_this = ctx;
617 	_l2tpd = _this->self;
618 	if ((evtype & EV_READ) != 0) {
619 		peerlen = sizeof(peer);
620 		socklen = sizeof(sock);
621 		while (!l2tpd_is_stopped(_l2tpd)) {
622 #if defined(USE_LIBSOCKUTIL) || defined(USE_SA_COOKIE)
623 			int sa_cookie_len;
624 			struct in_ipsec_sa_cookie sa_cookie;
625 
626 			sa_cookie_len = sizeof(sa_cookie);
627 			if ((sz = recvfromto_nat_t(_this->sock, buf,
628 			    sizeof(buf), 0,
629 			    (struct sockaddr *)&peer, &peerlen,
630 			    (struct sockaddr *)&sock, &socklen,
631 			    &sa_cookie, &sa_cookie_len)) <= 0) {
632 #else
633 			if ((sz = recvfromto(_this->sock, buf,
634 			    sizeof(buf), 0,
635 			    (struct sockaddr *)&peer, &peerlen,
636 			    (struct sockaddr *)&sock, &socklen)) <= 0) {
637 #endif
638 				if (errno == EAGAIN || errno == EINTR)
639 					break;
640 				l2tpd_log(_l2tpd, LOG_ERR,
641 				    "recvfrom() failed in %s(): %m",
642 				    __func__);
643 				l2tpd_stop(_l2tpd);
644 				return;
645 			}
646 			/* source address check (allows.in) */
647 			switch (peer.ss_family) {
648 			case AF_INET:
649 #if defined(USE_LIBSOCKUTIL) || defined(USE_SA_COOKIE)
650 				if (sa_cookie_len > 0)
651 					nat_t = &sa_cookie;
652 				else
653 					nat_t = NULL;
654 #else
655 				nat_t = NULL;
656 #endif
657 				l2tp_ctrl_input(_l2tpd, _this->index,
658 				    (struct sockaddr *)&peer,
659 				    (struct sockaddr *)&sock, nat_t,
660 				    buf, sz);
661 				break;
662 			case AF_INET6:
663 				l2tp_ctrl_input(_l2tpd, _this->index,
664 				    (struct sockaddr *)&peer,
665 				    (struct sockaddr *)&sock, NULL,
666 				    buf, sz);
667 				break;
668 			default:
669 				l2tpd_log(_l2tpd, LOG_ERR,
670 				    "received from unknown address family = %d",
671 				    peer.ss_family);
672 				break;
673 			}
674 		}
675 	}
676 }
677 
678 /*
679  * L2TP control
680  */
681 l2tp_ctrl *
682 l2tpd_get_ctrl(l2tpd *_this, unsigned tunid)
683 {
684 	hash_link *hl;
685 
686 	hl = hash_lookup(_this->ctrl_map, (void *)(uintptr_t)tunid);
687 	if (hl == NULL)
688 		return NULL;
689 
690 	return hl->item;
691 }
692 
693 void
694 l2tpd_add_ctrl(l2tpd *_this, l2tp_ctrl *ctrl)
695 {
696 	hash_insert(_this->ctrl_map, (void *)(uintptr_t)ctrl->tunnel_id, ctrl);
697 }
698 
699 void
700 l2tpd_remove_ctrl(l2tpd *_this, unsigned tunid)
701 {
702 	hash_delete(_this->ctrl_map, (void *)(uintptr_t)tunid, 0);
703 }
704 
705 
706 /*
707  * misc
708  */
709 
710 void
711 l2tpd_log(l2tpd *_this, int prio, const char *fmt, ...)
712 {
713 	char logbuf[BUFSIZ];
714 	va_list ap;
715 
716 	va_start(ap, fmt);
717 #ifdef	L2TPD_MULTIPLE
718 	snprintf(logbuf, sizeof(logbuf), "l2tpd id=%u %s", _this->id, fmt);
719 #else
720 	snprintf(logbuf, sizeof(logbuf), "l2tpd %s", fmt);
721 #endif
722 	vlog_printf(prio, logbuf, ap);
723 	va_end(ap);
724 }
725