GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/npppd/npppd/../l2tp/l2tpd.c Lines: 0 244 0.0 %
Date: 2017-11-13 Branches: 0 116 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: l2tpd.c,v 1.20 2017/10/06 07:46:44 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.20 2017/10/06 07:46:44 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 = calloc(1, sizeof(l2tpd_listener))) == NULL) {
166
		l2tpd_log(_this, LOG_ERR, "calloc() failed in %s: %m",
167
		    __func__);
168
		goto fail;
169
	}
170
	L2TPD_ASSERT(sizeof(plistener->bind) >= addr->sa_len);
171
	memcpy(&plistener->bind, addr, addr->sa_len);
172
173
	if (plistener->bind.sin6.sin6_port == 0)
174
		plistener->bind.sin6.sin6_port = htons(L2TPD_DEFAULT_UDP_PORT);
175
176
	plistener->sock = -1;
177
	plistener->self = _this;
178
	plistener->index = idx;
179
	plistener->conf = conf;
180
	strlcpy(plistener->tun_name, conf->name, sizeof(plistener->tun_name));
181
182
	if (slist_add(&_this->listener, plistener) == NULL) {
183
		l2tpd_log(_this, LOG_ERR, "slist_add() failed in %s: %m",
184
		    __func__);
185
		goto fail;
186
	}
187
	return 0;
188
fail:
189
	free(plistener);
190
	return 1;
191
}
192
193
/* finalize L2TP daemon instance */
194
void
195
l2tpd_uninit(l2tpd *_this)
196
{
197
	l2tpd_listener *plsnr;
198
199
	L2TPD_ASSERT(_this != NULL);
200
201
	slist_fini(&_this->free_session_id_list);
202
	if (_this->ctrl_map != NULL) {
203
		hash_free(_this->ctrl_map);
204
		_this->ctrl_map = NULL;
205
	}
206
207
	slist_itr_first(&_this->listener);
208
	while (slist_itr_has_next(&_this->listener)) {
209
		plsnr = slist_itr_next(&_this->listener);
210
		L2TPD_ASSERT(plsnr != NULL);
211
		L2TPD_ASSERT(plsnr->sock == -1);
212
		free(plsnr);
213
	}
214
	slist_fini(&_this->listener);
215
216
	event_del(&_this->ev_timeout);	/* just in case */
217
	_this->state = L2TPD_STATE_STOPPED;
218
}
219
220
/** assign the call to the l2tpd */
221
int
222
l2tpd_assign_call(l2tpd *_this, l2tp_call *call)
223
{
224
	int    shuffle_cnt;
225
	u_int  session_id;
226
227
	shuffle_cnt = 0;
228
	do {
229
		session_id = (uintptr_t)slist_remove_first(
230
		    &_this->free_session_id_list);
231
		if (session_id != L2TP_SESSION_ID_SHUFFLE_MARK)
232
			break;
233
		L2TPD_ASSERT(shuffle_cnt == 0);
234
		if (shuffle_cnt++ > 0) {
235
			l2tpd_log(_this, LOG_ERR,
236
			    "unexpected errror in %s(): free_session_id_list "
237
			    "full", __func__);
238
			slist_add(&_this->free_session_id_list,
239
			    (void *)L2TP_SESSION_ID_SHUFFLE_MARK);
240
			return 1;
241
		}
242
		slist_shuffle(&_this->free_session_id_list);
243
		slist_add(&_this->free_session_id_list,
244
		    (void *)L2TP_SESSION_ID_SHUFFLE_MARK);
245
	} while (1);
246
	call->id = session_id;
247
248
	return 0;
249
}
250
251
/* this function will be called when the call is released */
252
void
253
l2tpd_release_call(l2tpd *_this, l2tp_call *call)
254
{
255
	slist_add(&_this->free_session_id_list, (void *)(uintptr_t)call->id);
256
}
257
258
/* start l2tpd listner */
259
static int
260
l2tpd_listener_start(l2tpd_listener *_this)
261
{
262
	l2tpd *_l2tpd;
263
	int    af, lvl, opt, sock, ival;
264
	char   hbuf[NI_MAXHOST + NI_MAXSERV + 16];
265
266
	_l2tpd = _this->self;
267
	sock = -1;
268
	af = _this->bind.sin6.sin6_family;
269
	lvl = (af == AF_INET)? IPPROTO_IP : IPPROTO_IPV6;
270
271
	if (_this->tun_name[0] == '\0')
272
		strlcpy(_this->tun_name, L2TPD_DEFAULT_LAYER2_LABEL,
273
		    sizeof(_this->tun_name));
274
	if ((sock = socket(_this->bind.sin6.sin6_family,
275
	    SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP)) < 0) {
276
		l2tpd_log(_l2tpd, LOG_ERR,
277
		    "socket() failed in %s(): %m", __func__);
278
		goto fail;
279
	}
280
#if defined(IP_STRICT_RCVIF) && defined(USE_STRICT_RCVIF)
281
	ival = 1;
282
	if (setsockopt(sock, IPPROTO_IP, IP_STRICT_RCVIF, &ival, sizeof(ival))
283
	    != 0)
284
		l2tpd_log(_l2tpd, LOG_WARNING,
285
		    "%s(): setsockopt(IP_STRICT_RCVIF) failed: %m", __func__);
286
#endif
287
	ival = 1;
288
	if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &ival, sizeof(ival))
289
	    != 0) {
290
		l2tpd_log(_l2tpd, LOG_ERR,
291
		    "setsockopt(,,SO_REUSEPORT) failed in %s(): %m", __func__);
292
		goto fail;
293
	}
294
	if (bind(sock, (struct sockaddr *)&_this->bind,
295
	    _this->bind.sin6.sin6_len) != 0) {
296
		l2tpd_log(_l2tpd, LOG_ERR, "Binding %s/udp: %m",
297
		    addrport_tostring((struct sockaddr *)&_this->bind,
298
		    _this->bind.sin6.sin6_len, hbuf, sizeof(hbuf)));
299
		goto fail;
300
	}
301
#ifdef USE_LIBSOCKUTIL
302
	if (setsockoptfromto(sock) != 0) {
303
		l2tpd_log(_l2tpd, LOG_ERR,
304
		    "setsockoptfromto() failed in %s(): %m", __func__);
305
		goto fail;
306
	}
307
#else
308
	opt = (af == AF_INET)? IP_RECVDSTADDR : IPV6_RECVPKTINFO;
309
	ival = 1;
310
	if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0) {
311
		l2tpd_log(_l2tpd, LOG_ERR,
312
		    "setsockopt(,,IP{,V6}_RECVDSTADDR) failed in %s(): %m",
313
		    __func__);
314
		goto fail;
315
	}
316
#endif
317
#ifdef USE_SA_COOKIE
318
	if (af == AF_INET) {
319
		ival = 1;
320
		if (setsockopt(sock, IPPROTO_IP, IP_IPSECFLOWINFO, &ival,
321
		    sizeof(ival)) != 0) {
322
			l2tpd_log(_l2tpd, LOG_ERR,
323
			    "setsockopt(,,IP_IPSECFLOWINFO) failed in %s(): %m",
324
			    __func__);
325
			goto fail;
326
		}
327
	}
328
#endif
329
#ifdef IP_PIPEX
330
	opt = (af == AF_INET)? IP_PIPEX : IPV6_PIPEX;
331
	ival = 1;
332
	if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0)
333
		l2tpd_log(_l2tpd, LOG_WARNING,
334
		    "%s(): setsockopt(IP{,V6}_PIPEX) failed: %m", __func__);
335
#endif
336
	if (_this->conf->require_ipsec) {
337
#ifdef IP_IPSEC_POLICY
338
		caddr_t  ipsec_policy_in, ipsec_policy_out;
339
340
		opt = (af == AF_INET)? IP_IPSEC_POLICY : IPV6_IPSEC_POLICY;
341
		/*
342
		 * Note: ipsec_set_policy() will assign the buffer for
343
		 * yacc parser stack, however it never free.
344
		 * it cause memory leak (-2000byte).
345
		 */
346
		if ((ipsec_policy_in = ipsec_set_policy(L2TPD_IPSEC_POLICY_IN,
347
		    strlen(L2TPD_IPSEC_POLICY_IN))) == NULL) {
348
			l2tpd_log(_l2tpd, LOG_ERR,
349
			    "ipsec_set_policy(L2TPD_IPSEC_POLICY_IN) failed "
350
			    "at %s(): %s: %m", __func__, ipsec_strerror());
351
		} else if (setsockopt(sock, lvl, opt, ipsec_policy_in,
352
		    ipsec_get_policylen(ipsec_policy_in)) < 0) {
353
			l2tpd_log(_l2tpd, LOG_WARNING,
354
			    "setsockopt(,,IP_IPSEC_POLICY(in)) failed "
355
			    "in %s(): %m", __func__);
356
		}
357
		if ((ipsec_policy_out = ipsec_set_policy(L2TPD_IPSEC_POLICY_OUT,
358
		    strlen(L2TPD_IPSEC_POLICY_OUT))) == NULL) {
359
			l2tpd_log(_l2tpd, LOG_ERR,
360
			    "ipsec_set_policy(L2TPD_IPSEC_POLICY_OUT) failed "
361
			    "at %s(): %s: %m", __func__, ipsec_strerror());
362
		}
363
		if (ipsec_policy_out != NULL &&
364
		    setsockopt(sock, lvl, opt, ipsec_policy_out,
365
		    ipsec_get_policylen(ipsec_policy_out)) < 0) {
366
			l2tpd_log(_l2tpd, LOG_WARNING,
367
			    "setsockopt(,,IP_IPSEC_POLICY(out)) failed "
368
			    "in %s(): %m", __func__);
369
		}
370
		free(ipsec_policy_in);
371
		free(ipsec_policy_out);
372
#elif defined(IP_ESP_TRANS_LEVEL)
373
		opt = (af == AF_INET)
374
		    ? IP_ESP_TRANS_LEVEL : IPV6_ESP_TRANS_LEVEL;
375
		ival = IPSEC_LEVEL_REQUIRE;
376
		if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0) {
377
			l2tpd_log(_l2tpd, LOG_WARNING,
378
			    "setsockopt(,,IP{,V6}_ESP_TRANS_LEVEL(out)) failed "
379
			    "in %s(): %m", __func__);
380
		}
381
#else
382
#error IP_IPSEC_POLICY or IP_ESP_TRANS_LEVEL must be usable.
383
#endif
384
	}
385
386
	_this->sock = sock;
387
388
	event_set(&_this->ev_sock, _this->sock, EV_READ | EV_PERSIST,
389
	    l2tpd_io_event, _this);
390
	event_add(&_this->ev_sock, NULL);
391
392
	l2tpd_log(_l2tpd, LOG_INFO, "Listening %s/udp (L2TP LNS) [%s]",
393
	    addrport_tostring((struct sockaddr *)&_this->bind,
394
	    _this->bind.sin6.sin6_len, hbuf, sizeof(hbuf)), _this->tun_name);
395
396
	return 0;
397
fail:
398
	if (sock >= 0)
399
		close(sock);
400
401
	return 1;
402
}
403
404
/* start L2TP daemon */
405
int
406
l2tpd_start(l2tpd *_this)
407
{
408
	int rval;
409
	l2tpd_listener *plsnr;
410
411
	rval = 0;
412
413
	L2TPD_ASSERT(_this->state == L2TPD_STATE_INIT);
414
	if (_this->state != L2TPD_STATE_INIT) {
415
		l2tpd_log(_this, LOG_ERR, "Failed to start l2tpd: illegal "
416
		    "state.");
417
		return -1;
418
	}
419
420
	slist_itr_first(&_this->listener);
421
	while (slist_itr_has_next(&_this->listener)) {
422
		plsnr = slist_itr_next(&_this->listener);
423
		rval |= l2tpd_listener_start(plsnr);
424
	}
425
426
	if (rval == 0)
427
		_this->state = L2TPD_STATE_RUNNING;
428
429
	return rval;
430
}
431
432
/* stop l2tp lisnter */
433
static void
434
l2tpd_listener_stop(l2tpd_listener *_this)
435
{
436
	char hbuf[NI_MAXHOST + NI_MAXSERV + 16];
437
438
	if (_this->sock >= 0) {
439
		event_del(&_this->ev_sock);
440
		close(_this->sock);
441
		l2tpd_log(_this->self, LOG_INFO,
442
		    "Shutdown %s/udp (L2TP LNS)",
443
		    addrport_tostring((struct sockaddr *)&_this->bind,
444
		    _this->bind.sin6.sin6_len, hbuf, sizeof(hbuf)));
445
		_this->sock = -1;
446
	}
447
}
448
449
/* stop immediattly without disconnect operation */
450
void
451
l2tpd_stop_immediatly(l2tpd *_this)
452
{
453
	l2tpd_listener *plsnr;
454
455
	slist_itr_first(&_this->listener);
456
	while (slist_itr_has_next(&_this->listener)) {
457
		plsnr = slist_itr_next(&_this->listener);
458
		l2tpd_listener_stop(plsnr);
459
	}
460
	event_del(&_this->ev_timeout);	/* XXX */
461
	_this->state = L2TPD_STATE_STOPPED;
462
}
463
464
/*
465
 * this function will be called when {@link ::_l2tp_ctrl control}
466
 * is terminated.
467
 */
468
void
469
l2tpd_ctrl_finished_notify(l2tpd *_this)
470
{
471
	if (_this->state != L2TPD_STATE_SHUTTING_DOWN)
472
		return;
473
474
	if (hash_first(_this->ctrl_map) != NULL)
475
		return;
476
477
	l2tpd_stop_immediatly(_this);
478
}
479
480
static void
481
l2tpd_stop_timeout(int fd, short evtype, void *ctx)
482
{
483
	hash_link *hl;
484
	l2tp_ctrl *ctrl;
485
	l2tpd *_this;
486
487
	_this = ctx;
488
	l2tpd_log(_this, LOG_INFO, "Shutdown timeout");
489
	for (hl = hash_first(_this->ctrl_map); hl != NULL;
490
	    hl = hash_next(_this->ctrl_map)) {
491
		ctrl = hl->item;
492
		l2tp_ctrl_stop(ctrl, 0);
493
	}
494
	l2tpd_stop_immediatly(_this);
495
}
496
497
/* stop L2TP daemon */
498
void
499
l2tpd_stop(l2tpd *_this)
500
{
501
	int nctrls = 0;
502
	hash_link *hl;
503
	l2tp_ctrl *ctrl;
504
505
	nctrls = 0;
506
	event_del(&_this->ev_timeout);
507
	if (l2tpd_is_stopped(_this))
508
		return;
509
	if (l2tpd_is_shutting_down(_this)) {
510
		/* terminate immediately, when 2nd call */
511
		l2tpd_stop_immediatly(_this);
512
		return;
513
	}
514
	for (hl = hash_first(_this->ctrl_map); hl != NULL;
515
	    hl = hash_next(_this->ctrl_map)) {
516
		ctrl = hl->item;
517
		l2tp_ctrl_stop(ctrl, L2TP_STOP_CCN_RCODE_SHUTTING_DOWN);
518
		nctrls++;
519
	}
520
	_this->state = L2TPD_STATE_SHUTTING_DOWN;
521
	if (nctrls > 0) {
522
		struct timeval tv0;
523
524
		tv0.tv_usec = 0;
525
		tv0.tv_sec = L2TPD_SHUTDOWN_TIMEOUT;
526
527
		evtimer_set(&_this->ev_timeout, l2tpd_stop_timeout, _this);
528
		evtimer_add(&_this->ev_timeout, &tv0);
529
530
		return;
531
	}
532
	l2tpd_stop_immediatly(_this);
533
}
534
535
/*
536
 * Configuration
537
 */
538
int
539
l2tpd_reload(l2tpd *_this, struct l2tp_confs *l2tp_conf)
540
{
541
	int			 i;
542
	struct l2tp_conf	*conf;
543
	l2tpd_listener		*listener;
544
	struct l2tp_listen_addr	*addr;
545
546
	if (slist_length(&_this->listener) > 0) {
547
		/*
548
		 * TODO: add / remove / restart listener.
549
		 */
550
		slist_itr_first(&_this->listener);
551
		while (slist_itr_has_next(&_this->listener)) {
552
			listener = slist_itr_next(&_this->listener);
553
			TAILQ_FOREACH(conf, l2tp_conf, entry) {
554
				if (strcmp(listener->tun_name,
555
				    conf->name) == 0) {
556
					listener->conf = conf;
557
					break;
558
				}
559
			}
560
		}
561
562
		return 0;
563
	}
564
565
	i = 0;
566
	TAILQ_FOREACH(conf, l2tp_conf, entry) {
567
		TAILQ_FOREACH(addr, &conf->listen, entry)
568
			l2tpd_add_listener(_this, i++, conf,
569
			    (struct sockaddr *)&addr->addr);
570
	}
571
	if (l2tpd_start(_this) != 0)
572
		return -1;
573
574
	return 0;
575
}
576
577
/*
578
 * I/O functions
579
 */
580
/* logging when deny an access */
581
void
582
l2tpd_log_access_deny(l2tpd *_this, const char *reason, struct sockaddr *peer)
583
{
584
	char buf[BUFSIZ];
585
586
	l2tpd_log(_this, LOG_ALERT, "Received packet from %s/udp: "
587
	    "%s", addrport_tostring(peer, peer->sa_len, buf, sizeof(buf)),
588
	    reason);
589
}
590
591
/* I/O event handler */
592
static void
593
l2tpd_io_event(int fd, short evtype, void *ctx)
594
{
595
	int sz;
596
	l2tpd *_l2tpd;
597
	l2tpd_listener *_this;
598
	socklen_t peerlen, socklen;
599
	struct sockaddr_storage peer, sock;
600
	u_char buf[8192];
601
	void *nat_t;
602
603
	_this = ctx;
604
	_l2tpd = _this->self;
605
	if ((evtype & EV_READ) != 0) {
606
		peerlen = sizeof(peer);
607
		socklen = sizeof(sock);
608
		while (!l2tpd_is_stopped(_l2tpd)) {
609
#if defined(USE_LIBSOCKUTIL) || defined(USE_SA_COOKIE)
610
			int sa_cookie_len;
611
			struct in_ipsec_sa_cookie sa_cookie;
612
613
			sa_cookie_len = sizeof(sa_cookie);
614
			if ((sz = recvfromto_nat_t(_this->sock, buf,
615
			    sizeof(buf), 0,
616
			    (struct sockaddr *)&peer, &peerlen,
617
			    (struct sockaddr *)&sock, &socklen,
618
			    &sa_cookie, &sa_cookie_len)) == -1) {
619
#else
620
			if ((sz = recvfromto(_this->sock, buf,
621
			    sizeof(buf), 0,
622
			    (struct sockaddr *)&peer, &peerlen,
623
			    (struct sockaddr *)&sock, &socklen)) == -1) {
624
#endif
625
				if (errno == EAGAIN || errno == EINTR)
626
					break;
627
				l2tpd_log(_l2tpd, LOG_ERR,
628
				    "recvfrom() failed in %s(): %m",
629
				    __func__);
630
				l2tpd_stop(_l2tpd);
631
				return;
632
			}
633
			/* source address check (allows.in) */
634
			switch (peer.ss_family) {
635
			case AF_INET:
636
#if defined(USE_LIBSOCKUTIL) || defined(USE_SA_COOKIE)
637
				if (sa_cookie_len > 0)
638
					nat_t = &sa_cookie;
639
				else
640
					nat_t = NULL;
641
#else
642
				nat_t = NULL;
643
#endif
644
				l2tp_ctrl_input(_l2tpd, _this->index,
645
				    (struct sockaddr *)&peer,
646
				    (struct sockaddr *)&sock, nat_t,
647
				    buf, sz);
648
				break;
649
			case AF_INET6:
650
				l2tp_ctrl_input(_l2tpd, _this->index,
651
				    (struct sockaddr *)&peer,
652
				    (struct sockaddr *)&sock, NULL,
653
				    buf, sz);
654
				break;
655
			default:
656
				l2tpd_log(_l2tpd, LOG_ERR,
657
				    "received from unknown address family = %d",
658
				    peer.ss_family);
659
				break;
660
			}
661
		}
662
	}
663
}
664
665
/*
666
 * L2TP control
667
 */
668
l2tp_ctrl *
669
l2tpd_get_ctrl(l2tpd *_this, unsigned tunid)
670
{
671
	hash_link *hl;
672
673
	hl = hash_lookup(_this->ctrl_map, (void *)(uintptr_t)tunid);
674
	if (hl == NULL)
675
		return NULL;
676
677
	return hl->item;
678
}
679
680
void
681
l2tpd_add_ctrl(l2tpd *_this, l2tp_ctrl *ctrl)
682
{
683
	hash_insert(_this->ctrl_map, (void *)(uintptr_t)ctrl->tunnel_id, ctrl);
684
}
685
686
void
687
l2tpd_remove_ctrl(l2tpd *_this, unsigned tunid)
688
{
689
	hash_delete(_this->ctrl_map, (void *)(uintptr_t)tunid, 0);
690
}
691
692
693
/*
694
 * misc
695
 */
696
697
void
698
l2tpd_log(l2tpd *_this, int prio, const char *fmt, ...)
699
{
700
	char logbuf[BUFSIZ];
701
	va_list ap;
702
703
	va_start(ap, fmt);
704
#ifdef	L2TPD_MULTIPLE
705
	snprintf(logbuf, sizeof(logbuf), "l2tpd id=%u %s", _this->id, fmt);
706
#else
707
	snprintf(logbuf, sizeof(logbuf), "l2tpd %s", fmt);
708
#endif
709
	vlog_printf(prio, logbuf, ap);
710
	va_end(ap);
711
}