xref: /openbsd/usr.sbin/npppd/l2tp/l2tp_ctrl.c (revision b01648a9)
1*b01648a9Syasuoka /*	$OpenBSD: l2tp_ctrl.c,v 1.11 2012/05/08 13:28:06 yasuoka Exp $	*/
2e109dc18Syasuoka 
30fbf3537Syasuoka /*-
40fbf3537Syasuoka  * Copyright (c) 2009 Internet Initiative Japan Inc.
50fbf3537Syasuoka  * All rights reserved.
60fbf3537Syasuoka  *
70fbf3537Syasuoka  * Redistribution and use in source and binary forms, with or without
80fbf3537Syasuoka  * modification, are permitted provided that the following conditions
90fbf3537Syasuoka  * are met:
100fbf3537Syasuoka  * 1. Redistributions of source code must retain the above copyright
110fbf3537Syasuoka  *    notice, this list of conditions and the following disclaimer.
120fbf3537Syasuoka  * 2. Redistributions in binary form must reproduce the above copyright
130fbf3537Syasuoka  *    notice, this list of conditions and the following disclaimer in the
140fbf3537Syasuoka  *    documentation and/or other materials provided with the distribution.
150fbf3537Syasuoka  *
160fbf3537Syasuoka  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
170fbf3537Syasuoka  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
180fbf3537Syasuoka  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
190fbf3537Syasuoka  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
200fbf3537Syasuoka  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
210fbf3537Syasuoka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
220fbf3537Syasuoka  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
230fbf3537Syasuoka  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
240fbf3537Syasuoka  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
250fbf3537Syasuoka  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
260fbf3537Syasuoka  * SUCH DAMAGE.
270fbf3537Syasuoka  */
28f0a4e295Syasuoka /**@file Control connection processing functions for L2TP LNS */
29*b01648a9Syasuoka /* $Id: l2tp_ctrl.c,v 1.11 2012/05/08 13:28:06 yasuoka Exp $ */
300fbf3537Syasuoka #include <sys/types.h>
310fbf3537Syasuoka #include <sys/param.h>
320fbf3537Syasuoka #include <sys/time.h>
330fbf3537Syasuoka #include <sys/socket.h>
340fbf3537Syasuoka #include <sys/endian.h>
350fbf3537Syasuoka #include <netinet/in.h>
360fbf3537Syasuoka #include <net/if.h>
370fbf3537Syasuoka #include <arpa/inet.h>
389a200ddfSyasuoka #include <errno.h>
390fbf3537Syasuoka #include <event.h>
400fbf3537Syasuoka #include <ifaddrs.h>
419a200ddfSyasuoka #include <netdb.h>
429a200ddfSyasuoka #include <stdarg.h>
439a200ddfSyasuoka #include <stddef.h>
449a200ddfSyasuoka #include <stdio.h>
459a200ddfSyasuoka #include <stdlib.h>
469a200ddfSyasuoka #include <string.h>
479a200ddfSyasuoka #include <syslog.h>
489a200ddfSyasuoka #include <time.h>
490fbf3537Syasuoka 
500fbf3537Syasuoka #ifdef USE_LIBSOCKUTIL
510fbf3537Syasuoka #include <seil/sockfromto.h>
520fbf3537Syasuoka #endif
530fbf3537Syasuoka 
540fbf3537Syasuoka #include "time_utils.h"
550fbf3537Syasuoka #include "ipsec_util.h"
560fbf3537Syasuoka #include "bytebuf.h"
570fbf3537Syasuoka #include "hash.h"
580fbf3537Syasuoka #include "debugutil.h"
590fbf3537Syasuoka #include "slist.h"
600fbf3537Syasuoka #include "l2tp.h"
610fbf3537Syasuoka #include "l2tp_local.h"
620fbf3537Syasuoka #include "l2tp_subr.h"
630fbf3537Syasuoka #include "net_utils.h"
640fbf3537Syasuoka #include "config_helper.h"
650fbf3537Syasuoka #include "version.h"
660fbf3537Syasuoka 
670fbf3537Syasuoka static int                l2tp_ctrl_init (l2tp_ctrl *, l2tpd *, struct sockaddr *, struct sockaddr *, void *);
680fbf3537Syasuoka static void               l2tp_ctrl_reload (l2tp_ctrl *);
690fbf3537Syasuoka static int                l2tp_ctrl_send_disconnect_notify (l2tp_ctrl *);
700fbf3537Syasuoka #if 0
710fbf3537Syasuoka static void               l2tp_ctrl_purge_ipsec_sa (l2tp_ctrl *);
720fbf3537Syasuoka #endif
730fbf3537Syasuoka static void               l2tp_ctrl_timeout (int, short, void *);
740fbf3537Syasuoka static int                l2tp_ctrl_resend_una_packets (l2tp_ctrl *);
750fbf3537Syasuoka static void               l2tp_ctrl_destroy_all_calls (l2tp_ctrl *);
760fbf3537Syasuoka static int                l2tp_ctrl_disconnect_all_calls (l2tp_ctrl *);
770fbf3537Syasuoka static void               l2tp_ctrl_reset_timeout (l2tp_ctrl *);
780fbf3537Syasuoka static inline int         l2tp_ctrl_txwin_size (l2tp_ctrl *);
790fbf3537Syasuoka static inline int         l2tp_ctrl_txwin_is_full (l2tp_ctrl *);
800fbf3537Syasuoka static int                l2tp_ctrl_recv_SCCRQ (l2tp_ctrl *, u_char *, int, l2tpd *, struct sockaddr *);
810fbf3537Syasuoka static int                l2tp_ctrl_send_StopCCN (l2tp_ctrl *, int);
820fbf3537Syasuoka static int                l2tp_ctrl_recv_StopCCN (l2tp_ctrl *, u_char *, int);
830fbf3537Syasuoka static void               l2tp_ctrl_send_SCCRP (l2tp_ctrl *);
840fbf3537Syasuoka static int                l2tp_ctrl_send_HELLO (l2tp_ctrl *);
850fbf3537Syasuoka static int                l2tp_ctrl_send_ZLB (l2tp_ctrl *);
860fbf3537Syasuoka static inline const char  *l2tp_ctrl_state_string (l2tp_ctrl *);
870fbf3537Syasuoka 
880fbf3537Syasuoka #ifdef	L2TP_CTRL_DEBUG
890fbf3537Syasuoka #define	L2TP_CTRL_ASSERT(x)	ASSERT(x)
900fbf3537Syasuoka #define	L2TP_CTRL_DBG(x)	l2tp_ctrl_log x
910fbf3537Syasuoka #else
920fbf3537Syasuoka #define	L2TP_CTRL_ASSERT(x)
930fbf3537Syasuoka #define	L2TP_CTRL_DBG(x)
940fbf3537Syasuoka #endif
950fbf3537Syasuoka 
96f0a4e295Syasuoka /* Sequence # of l2tp_ctrl ID */
97c46ae403Syasuoka static u_int l2tp_ctrl_id_seq = 0;
980fbf3537Syasuoka 
990fbf3537Syasuoka #define SEQ_LT(a,b)	((int16_t)((a) - (b)) <  0)
1000fbf3537Syasuoka #define SEQ_GT(a,b)	((int16_t)((a) - (b)) >  0)
1010fbf3537Syasuoka 
1020fbf3537Syasuoka /**
103f0a4e295Syasuoka  * Build instance of {@link ::_l2tp_ctrl L2TP LNS control connection}
1040fbf3537Syasuoka  */
1050fbf3537Syasuoka l2tp_ctrl *
1060fbf3537Syasuoka l2tp_ctrl_create(void)
1070fbf3537Syasuoka {
1080fbf3537Syasuoka 	l2tp_ctrl *_this;
1090fbf3537Syasuoka 
1100fbf3537Syasuoka 	if ((_this = malloc(sizeof(l2tp_ctrl))) == NULL)
1110fbf3537Syasuoka 		return NULL;
1120fbf3537Syasuoka 
1130fbf3537Syasuoka 	memset(_this, 0, sizeof(l2tp_ctrl));
1140fbf3537Syasuoka 	return (l2tp_ctrl *)_this;
1150fbf3537Syasuoka }
1160fbf3537Syasuoka 
1170fbf3537Syasuoka /**
118f0a4e295Syasuoka  * initialize and startup of {@link ::_l2tp_ctrl L2TP LNS control connection}
119f0a4e295Syasuoka  * instance
1200fbf3537Syasuoka  */
1210fbf3537Syasuoka static int
1220fbf3537Syasuoka l2tp_ctrl_init(l2tp_ctrl *_this, l2tpd *_l2tpd, struct sockaddr *peer,
1230fbf3537Syasuoka     struct sockaddr *sock, void *nat_t_ctx)
1240fbf3537Syasuoka {
1250fbf3537Syasuoka 	int tunid, i;
1260fbf3537Syasuoka 	bytebuffer *bytebuf;
1270fbf3537Syasuoka 	time_t curr_time;
1280fbf3537Syasuoka 
1290fbf3537Syasuoka 	memset(_this, 0, sizeof(l2tp_ctrl));
1300fbf3537Syasuoka 
1310fbf3537Syasuoka 	curr_time = get_monosec();
1320fbf3537Syasuoka 	_this->l2tpd = _l2tpd;
1330fbf3537Syasuoka 	_this->state = L2TP_CTRL_STATE_IDLE;
1340fbf3537Syasuoka 	_this->last_snd_ctrl = curr_time;
1350fbf3537Syasuoka 
1360fbf3537Syasuoka 	slist_init(&_this->call_list);
137f0a4e295Syasuoka 
138f0a4e295Syasuoka 	/* seek a free tunnel ID */
1390fbf3537Syasuoka 	i = 0;
1400fbf3537Syasuoka 	_this->id = ++l2tp_ctrl_id_seq;
1410fbf3537Syasuoka 	for (i = 0, tunid = _this->id; ; i++, tunid++) {
1420fbf3537Syasuoka 		tunid &= 0xffff;
1430fbf3537Syasuoka 		_this->tunnel_id = l2tp_ctrl_id_seq & 0xffff;
1440fbf3537Syasuoka 		if (tunid == 0)
1450fbf3537Syasuoka 			continue;
1460fbf3537Syasuoka 		if (l2tpd_get_ctrl(_l2tpd, tunid) == NULL)
1470fbf3537Syasuoka 			break;
1480fbf3537Syasuoka 		if (i > 80000) {
149f0a4e295Syasuoka 			/* this must be happen, just log it. */
1500fbf3537Syasuoka 			l2tpd_log(_l2tpd, LOG_ERR, "Too many l2tp controls");
1510fbf3537Syasuoka 			return -1;
1520fbf3537Syasuoka 		}
1530fbf3537Syasuoka 	}
1540fbf3537Syasuoka 
1550fbf3537Syasuoka 	_this->tunnel_id = tunid;
1560fbf3537Syasuoka 
1570fbf3537Syasuoka 	L2TP_CTRL_ASSERT(peer != NULL);
1580fbf3537Syasuoka 	L2TP_CTRL_ASSERT(sock != NULL);
1590fbf3537Syasuoka 	memcpy(&_this->peer, peer, peer->sa_len);
1600fbf3537Syasuoka 	memcpy(&_this->sock, sock, sock->sa_len);
1610fbf3537Syasuoka 
162f0a4e295Syasuoka 	/* prepare send buffer */
1630fbf3537Syasuoka 	_this->winsz = L2TPD_DEFAULT_SEND_WINSZ;
1640fbf3537Syasuoka 	if ((_this->snd_buffers = calloc(_this->winsz, sizeof(bytebuffer *)))
1650fbf3537Syasuoka 	    == NULL) {
1660fbf3537Syasuoka 		l2tpd_log(_l2tpd, LOG_ERR,
1670fbf3537Syasuoka 		    "calloc() failed in %s(): %m", __func__);
168f0a4e295Syasuoka 		goto fail;
1690fbf3537Syasuoka 	}
1700fbf3537Syasuoka 	for (i = 0; i < _this->winsz; i++) {
1710fbf3537Syasuoka 		if ((bytebuf = bytebuffer_create(L2TPD_SND_BUFSIZ)) == NULL) {
1720fbf3537Syasuoka 			l2tpd_log(_l2tpd, LOG_ERR,
1730fbf3537Syasuoka 			    "bytebuffer_create() failed in %s(): %m", __func__);
174f0a4e295Syasuoka 			goto fail;
1750fbf3537Syasuoka 		}
1760fbf3537Syasuoka 		_this->snd_buffers[i] = bytebuf;
1770fbf3537Syasuoka 	}
1780fbf3537Syasuoka 	if ((_this->zlb_buffer = bytebuffer_create(sizeof(struct l2tp_header)
1790fbf3537Syasuoka 	    + 128)) == NULL) {
1800fbf3537Syasuoka 		l2tpd_log(_l2tpd, LOG_ERR,
1810fbf3537Syasuoka 		    "bytebuffer_create() failed in %s(): %m", __func__);
182f0a4e295Syasuoka 		goto fail;
1830fbf3537Syasuoka 	}
1840fbf3537Syasuoka #ifdef USE_LIBSOCKUTIL
1850fbf3537Syasuoka 	if (nat_t_ctx != NULL) {
1860fbf3537Syasuoka 		if ((_this->sa_cookie = malloc(
1870fbf3537Syasuoka 		    sizeof(struct in_ipsec_sa_cookie))) != NULL) {
1880fbf3537Syasuoka 			*(struct in_ipsec_sa_cookie *)_this->sa_cookie =
1890fbf3537Syasuoka 			    *(struct in_ipsec_sa_cookie *)nat_t_ctx;
1900fbf3537Syasuoka 		} else {
1910fbf3537Syasuoka 			l2tpd_log(_l2tpd, LOG_ERR,
1920fbf3537Syasuoka 			    "creating sa_cookie failed: %m");
193f0a4e295Syasuoka 			goto fail;
1940fbf3537Syasuoka 		}
1950fbf3537Syasuoka 	}
1960fbf3537Syasuoka #endif
1970fbf3537Syasuoka 	_this->hello_interval = L2TP_CTRL_DEFAULT_HELLO_INTERVAL;
1980fbf3537Syasuoka 	_this->hello_timeout = L2TP_CTRL_DEFAULT_HELLO_TIMEOUT;
1990fbf3537Syasuoka 	_this->hello_io_time = curr_time;
2000fbf3537Syasuoka 
201f0a4e295Syasuoka 	/* initialize timeout timer */
2020fbf3537Syasuoka 	l2tp_ctrl_reset_timeout(_this);
2030fbf3537Syasuoka 
204f0a4e295Syasuoka 	/* register l2tp context */
2050fbf3537Syasuoka 	l2tpd_add_ctrl(_l2tpd, _this);
2060fbf3537Syasuoka 	return 0;
207f0a4e295Syasuoka fail:
2080fbf3537Syasuoka 	l2tp_ctrl_stop(_this, 0);
2090fbf3537Syasuoka 	return -1;
2100fbf3537Syasuoka }
2110fbf3537Syasuoka 
212f0a4e295Syasuoka /*
213f0a4e295Syasuoka  * setup {@link ::_l2tp_ctrl L2TP LNS control connection} instance
2140fbf3537Syasuoka  */
2150fbf3537Syasuoka static void
2160fbf3537Syasuoka l2tp_ctrl_reload(l2tp_ctrl *_this)
2170fbf3537Syasuoka {
2180fbf3537Syasuoka 	int ival;
2190fbf3537Syasuoka 
2200fbf3537Syasuoka 	_this->data_use_seq = l2tp_ctrl_config_str_equal(_this,
2210fbf3537Syasuoka 	    "l2tp.data_use_seq", "true", 1);
2220fbf3537Syasuoka 
2230fbf3537Syasuoka 	if ((ival = l2tp_ctrl_config_int(_this, "l2tp.hello_interval", 0))!= 0)
2240fbf3537Syasuoka 		_this->hello_interval = ival;
2250fbf3537Syasuoka 	if ((ival = l2tp_ctrl_config_int(_this, "l2tp.hello_timeout", 0)) != 0)
2260fbf3537Syasuoka 		_this->hello_timeout = ival;
2270fbf3537Syasuoka 
2280fbf3537Syasuoka 	return;
2290fbf3537Syasuoka }
2300fbf3537Syasuoka 
231f0a4e295Syasuoka /*
232f0a4e295Syasuoka  * free {@link ::_l2tp_ctrl L2TP LNS control connection} instance
2330fbf3537Syasuoka  */
2340fbf3537Syasuoka void
2350fbf3537Syasuoka l2tp_ctrl_destroy(l2tp_ctrl *_this)
2360fbf3537Syasuoka {
2370fbf3537Syasuoka 	L2TP_CTRL_ASSERT(_this != NULL);
2380fbf3537Syasuoka #ifdef USE_LIBSOCKUTIL
2390fbf3537Syasuoka 	if (_this->sa_cookie != NULL)
2400fbf3537Syasuoka 		free(_this->sa_cookie);
2410fbf3537Syasuoka #endif
2420fbf3537Syasuoka 	free(_this);
2430fbf3537Syasuoka }
2440fbf3537Syasuoka 
245f0a4e295Syasuoka /*
246f0a4e295Syasuoka  * nortify disconnection to peer
2470fbf3537Syasuoka  *
248f0a4e295Syasuoka  * @return 	0: all CDN and StopCCN have been sent.
249f0a4e295Syasuoka  *		N: if the remaining calls which still not sent CDN exist,
250f0a4e295Syasuoka  *		   return # of the calls.
251f0a4e295Syasuoka  *		-1: when try to send of StopCCN failed.
2520fbf3537Syasuoka  */
2530fbf3537Syasuoka static int
2540fbf3537Syasuoka l2tp_ctrl_send_disconnect_notify(l2tp_ctrl *_this)
2550fbf3537Syasuoka {
2560fbf3537Syasuoka 	int ncalls;
2570fbf3537Syasuoka 
2580fbf3537Syasuoka 	L2TP_CTRL_ASSERT(_this != NULL)
2590fbf3537Syasuoka 	L2TP_CTRL_ASSERT(_this->state == L2TP_CTRL_STATE_ESTABLISHED ||
2600fbf3537Syasuoka 	    _this->state == L2TP_CTRL_STATE_CLEANUP_WAIT);
2610fbf3537Syasuoka 
2627a7bab9dSyasuoka 	/* this control is not actively closing or StopCCN have been sent */
2630fbf3537Syasuoka 	if (_this->active_closing == 0)
2640fbf3537Syasuoka 		return 0;
2650fbf3537Syasuoka 
2667a7bab9dSyasuoka 	/* Send CDN all Calls */
2670fbf3537Syasuoka 	ncalls = 0;
2680fbf3537Syasuoka 	if (slist_length(&_this->call_list) != 0) {
2690fbf3537Syasuoka 		ncalls = l2tp_ctrl_disconnect_all_calls(_this);
2700fbf3537Syasuoka 		if (ncalls > 0) {
2710fbf3537Syasuoka 			/*
2727a7bab9dSyasuoka 			 * Call the function again to check whether the
2737a7bab9dSyasuoka 			 * sending window is fulled.  In case ncalls == 0,
2747a7bab9dSyasuoka 			 * it means we've sent CDN for all calls.
2750fbf3537Syasuoka 			 */
2760fbf3537Syasuoka 			ncalls = l2tp_ctrl_disconnect_all_calls(_this);
2770fbf3537Syasuoka 		}
2780fbf3537Syasuoka 	}
2790fbf3537Syasuoka 	if (ncalls > 0)
2800fbf3537Syasuoka 		return ncalls;
2810fbf3537Syasuoka 
2820fbf3537Syasuoka 	if (l2tp_ctrl_send_StopCCN(_this, _this->active_closing) != 0)
2830fbf3537Syasuoka 		return -1;
2840fbf3537Syasuoka 	_this->active_closing = 0;
2850fbf3537Syasuoka 
2860fbf3537Syasuoka 	return 0;
2870fbf3537Syasuoka }
2880fbf3537Syasuoka 
289f0a4e295Syasuoka /*
290f0a4e295Syasuoka  * Terminate the control connection
2910fbf3537Syasuoka  *
2920fbf3537Syasuoka  * <p>
2937a7bab9dSyasuoka  * please specify an appropriate value to result( >0 ) for
294f0a4e295Syasuoka  * StopCCN ResultCode AVP, when to sent Active Close (which
295f0a4e295Syasuoka  * require StopCCN sent).</p>
2960fbf3537Syasuoka  * <p>
297f0a4e295Syasuoka  * When the return value of this function is zero, the _this
298f0a4e295Syasuoka  * is already released. The lt2p_ctrl process that was bound to it
299f0a4e295Syasuoka  * could not contine.
300f0a4e295Syasuoka  * When the return value of this function is one, the timer
301f0a4e295Syasuoka  * is reset.</p>
3020fbf3537Syasuoka  *
303f0a4e295Syasuoka  * @return	return 0 if terminate process was completed.
3040fbf3537Syasuoka  */
3050fbf3537Syasuoka int
3060fbf3537Syasuoka l2tp_ctrl_stop(l2tp_ctrl *_this, int result)
3070fbf3537Syasuoka {
3080fbf3537Syasuoka 	int i;
3090fbf3537Syasuoka 	l2tpd *_l2tpd;
3100fbf3537Syasuoka 
3110fbf3537Syasuoka 	L2TP_CTRL_ASSERT(_this != NULL);
3120fbf3537Syasuoka 
3130fbf3537Syasuoka 	switch (_this->state) {
3140fbf3537Syasuoka 	case L2TP_CTRL_STATE_ESTABLISHED:
3150fbf3537Syasuoka 		_this->state = L2TP_CTRL_STATE_CLEANUP_WAIT;
3160fbf3537Syasuoka 		if (result > 0) {
3170fbf3537Syasuoka 			_this->active_closing = result;
3180fbf3537Syasuoka 			l2tp_ctrl_send_disconnect_notify(_this);
3190fbf3537Syasuoka 			break;
3200fbf3537Syasuoka 		}
3210fbf3537Syasuoka 		goto cleanup;
3220fbf3537Syasuoka 	default:
3230fbf3537Syasuoka 		l2tp_ctrl_log(_this, LOG_DEBUG, "%s() unexpected state=%s",
3240fbf3537Syasuoka 		    __func__, l2tp_ctrl_state_string(_this));
325f0a4e295Syasuoka 		/* FALLTHROUGH */
3260fbf3537Syasuoka 	case L2TP_CTRL_STATE_WAIT_CTL_CONN:
327f0a4e295Syasuoka 		/* FALLTHROUGH */
3280fbf3537Syasuoka 	case L2TP_CTRL_STATE_CLEANUP_WAIT:
3290fbf3537Syasuoka cleanup:
3300fbf3537Syasuoka 		if (slist_length(&_this->call_list) != 0) {
3310fbf3537Syasuoka 			if (l2tp_ctrl_disconnect_all_calls(_this) > 0)
3320fbf3537Syasuoka 				break;
3330fbf3537Syasuoka 		}
3340fbf3537Syasuoka #if 0
3350fbf3537Syasuoka 		if (_this->l2tpd->purge_ipsec_sa != 0)
3360fbf3537Syasuoka 			l2tp_ctrl_purge_ipsec_sa(_this);
3370fbf3537Syasuoka #endif
3380fbf3537Syasuoka 
3390fbf3537Syasuoka 		l2tp_ctrl_log(_this, LOG_NOTICE, "logtype=Finished");
3400fbf3537Syasuoka 
3410fbf3537Syasuoka 		evtimer_del(&_this->ev_timeout);
3420fbf3537Syasuoka 
343f0a4e295Syasuoka 		/* free send buffer */
3440fbf3537Syasuoka 		if (_this->snd_buffers != NULL) {
3450fbf3537Syasuoka 			for (i = 0; i < _this->winsz; i++)
3460fbf3537Syasuoka 				bytebuffer_destroy(_this->snd_buffers[i]);
3470fbf3537Syasuoka 			free(_this->snd_buffers);
3480fbf3537Syasuoka 			_this->snd_buffers = NULL;
3490fbf3537Syasuoka 		}
3500fbf3537Syasuoka 		if (_this->zlb_buffer != NULL) {
3510fbf3537Syasuoka 			bytebuffer_destroy(_this->zlb_buffer);
3520fbf3537Syasuoka 			_this->zlb_buffer = NULL;
3530fbf3537Syasuoka 		}
354f0a4e295Syasuoka 
355f0a4e295Syasuoka 		/* free l2tp_call */
3560fbf3537Syasuoka 		l2tp_ctrl_destroy_all_calls(_this);
3570fbf3537Syasuoka 		slist_fini(&_this->call_list);
3580fbf3537Syasuoka 
3590fbf3537Syasuoka 		l2tpd_remove_ctrl(_this->l2tpd, _this->tunnel_id);
3600fbf3537Syasuoka 
3610fbf3537Syasuoka 		_l2tpd = _this->l2tpd;
3620fbf3537Syasuoka 		l2tp_ctrl_destroy(_this);
3630fbf3537Syasuoka 
3640fbf3537Syasuoka 		l2tpd_ctrl_finished_notify(_l2tpd);
365f0a4e295Syasuoka 		return 0;	/* stopped */
3660fbf3537Syasuoka 	}
3670fbf3537Syasuoka 	l2tp_ctrl_reset_timeout(_this);
3680fbf3537Syasuoka 
3690fbf3537Syasuoka 	return 1;
3700fbf3537Syasuoka }
3710fbf3537Syasuoka 
3720fbf3537Syasuoka #if 0
3730fbf3537Syasuoka /** Delete the IPsec SA for disconnection */
3740fbf3537Syasuoka static void
3750fbf3537Syasuoka l2tp_ctrl_purge_ipsec_sa(l2tp_ctrl *_this)
3760fbf3537Syasuoka {
3770fbf3537Syasuoka 	int is_natt, proto;
378886d2b78Syasuoka 	struct sockaddr_storage peer, sock;
3790fbf3537Syasuoka 	hash_link *hl;
3800fbf3537Syasuoka #ifdef USE_LIBSOCKUTIL
3810fbf3537Syasuoka 	struct in_ipsec_sa_cookie *ipsec_sa_cookie;
3820fbf3537Syasuoka #endif
3830fbf3537Syasuoka 	l2tp_ctrl *anot;
3840fbf3537Syasuoka 
3850fbf3537Syasuoka 	/*
3860fbf3537Syasuoka 	 * Search another tunnel that uses the same IPsec SA
3870fbf3537Syasuoka 	 * by lineer.
3880fbf3537Syasuoka 	 */
3890fbf3537Syasuoka 	for (hl = hash_first(_this->l2tpd->ctrl_map);
3900fbf3537Syasuoka 	    hl != NULL; hl = hash_next(_this->l2tpd->ctrl_map)) {
3910fbf3537Syasuoka 		anot = hl->item;
3920fbf3537Syasuoka 		if (anot == _this)
3930fbf3537Syasuoka 			continue;
3940fbf3537Syasuoka 
395886d2b78Syasuoka 		if (_this->peer.ss_family != anot->peer.ss_family)
396886d2b78Syasuoka 			continue;
397886d2b78Syasuoka 		if (_this->peer.ss_family == AF_INET) {
398886d2b78Syasuoka 			if (SIN(&_this->peer)->sin_addr.s_addr !=
399886d2b78Syasuoka 			    SIN(&anot->peer)->sin_addr.s_addr)
400886d2b78Syasuoka 				continue;
401886d2b78Syasuoka 		} else if (_this->peer.ss_family == AF_INET6) {
402886d2b78Syasuoka 			if (!IN6_ARE_ADDR_EQUAL(
403886d2b78Syasuoka 			    &(SIN6(&_this->peer)->sin6_addr),
404886d2b78Syasuoka 			    &(SIN6(&anot->peer)->sin6_addr)))
405886d2b78Syasuoka 				continue;
4060fbf3537Syasuoka 		}
4070fbf3537Syasuoka #ifdef USE_LIBSOCKUTIL
408886d2b78Syasuoka 		if (_this->sa_cookie != NULL && anot->sa_cookie != NULL) {
4090fbf3537Syasuoka 			/* Both tunnels belong the same NAT box.  */
4100fbf3537Syasuoka 
4110fbf3537Syasuoka 			if (memcmp(_this->sa_cookie, anot->sa_cookie,
4120fbf3537Syasuoka 			    sizeof(struct in_ipsec_sa_cookie)) != 0)
4130fbf3537Syasuoka 				/* Different hosts behind the NAT box.  */
4140fbf3537Syasuoka 				continue;
4150fbf3537Syasuoka 
4160fbf3537Syasuoka 			/* The SA is shared by another tunnels by one host. */
4170fbf3537Syasuoka 			return;	/* don't purge the sa */
4180fbf3537Syasuoka 
419886d2b78Syasuoka 		} else if (_this->sa_cookie != NULL || anot->sa_cookie != NULL)
4200fbf3537Syasuoka 			/* Only one is behind the NAT */
4210fbf3537Syasuoka 			continue;
4220fbf3537Syasuoka #endif
4230fbf3537Syasuoka 		return;	/* don't purge the sa */
4240fbf3537Syasuoka 	}
4250fbf3537Syasuoka 
4269a200ddfSyasuoka #if defined(USE_LIBSOCKUTIL)  && defined(IP_IPSEC_SA_COOKIE)
4270fbf3537Syasuoka 	is_natt = (_this->sa_cookie != NULL)? 1 : 0;
4280fbf3537Syasuoka #else
4290fbf3537Syasuoka 	is_natt = 0;
4300fbf3537Syasuoka #endif
4319a200ddfSyasuoka 	proto = 0;
432886d2b78Syasuoka 	memcpy(&peer, &_this->peer, _this->peer.ss_len);
433886d2b78Syasuoka 	memcpy(&sock, &_this->sock, _this->sock.ss_len);
4349a200ddfSyasuoka 	if (!is_natt)
435886d2b78Syasuoka 		SIN(&peer)->sin_port = SIN(&sock)->sin_port = 0;
4369a200ddfSyasuoka #if defined(USE_LIBSOCKUTIL)  && defined(IP_IPSEC_SA_COOKIE)
4370fbf3537Syasuoka 	else {
4380fbf3537Syasuoka 		ipsec_sa_cookie = _this->sa_cookie;
439886d2b78Syasuoka 		SIN(&peer)->sin_port = ipsec_sa_cookie->remote_port;
440886d2b78Syasuoka 		SIN(&sock)->sin_port = ipsec_sa_cookie->local_port;
4410fbf3537Syasuoka #if 1
4420fbf3537Syasuoka 		/*
4430fbf3537Syasuoka 		 * XXX: As RFC 2367, protocol sould be specified if the port
4440fbf3537Syasuoka 		 * XXX: number is non-zero.
4450fbf3537Syasuoka 		 */
4460fbf3537Syasuoka 		proto = 0;
4470fbf3537Syasuoka #else
4480fbf3537Syasuoka 		proto = IPPROTO_UDP;
4490fbf3537Syasuoka #endif
4500fbf3537Syasuoka 	}
4510fbf3537Syasuoka #endif
4520fbf3537Syasuoka 	if (ipsec_util_purge_transport_sa((struct sockaddr *)&peer,
453886d2b78Syasuoka 	    (struct sockaddr *)&sock, proto, IPSEC_UTIL_DIRECTION_BOTH) != 0)
4540fbf3537Syasuoka 		l2tp_ctrl_log(_this, LOG_NOTICE, "failed to purge IPSec SA");
4550fbf3537Syasuoka }
4560fbf3537Syasuoka #endif
4570fbf3537Syasuoka 
458f0a4e295Syasuoka /* timeout processing */
4590fbf3537Syasuoka static void
4600fbf3537Syasuoka l2tp_ctrl_timeout(int fd, short evtype, void *ctx)
4610fbf3537Syasuoka {
4620fbf3537Syasuoka 	int next_timeout, need_resend;
4630fbf3537Syasuoka 	time_t curr_time;
4640fbf3537Syasuoka 	l2tp_ctrl *_this;
4650fbf3537Syasuoka 	l2tp_call *call;
4660fbf3537Syasuoka 
4670fbf3537Syasuoka 	/*
468f0a4e295Syasuoka 	 * the timer must be reset, when leave this function.
469f0a4e295Syasuoka 	 * MEMO: l2tp_ctrl_stop() will reset the timer in it.
470f0a4e295Syasuoka 	 * and please remember that the l2tp_ctrl_stop() may free _this.
4710fbf3537Syasuoka 	 */
4720fbf3537Syasuoka 	_this = ctx;
4730fbf3537Syasuoka 	L2TP_CTRL_ASSERT(_this != NULL);
4740fbf3537Syasuoka 
4750fbf3537Syasuoka 	curr_time = get_monosec();
4760fbf3537Syasuoka 
4770fbf3537Syasuoka 	next_timeout = 2;
4780fbf3537Syasuoka 	need_resend = 0;
4790fbf3537Syasuoka 
4800fbf3537Syasuoka 	if (l2tp_ctrl_txwin_size(_this) > 0)  {
4810fbf3537Syasuoka 		if (_this->state == L2TP_CTRL_STATE_ESTABLISHED) {
4820fbf3537Syasuoka 			if (_this->hello_wait_ack != 0) {
483f0a4e295Syasuoka 				/* wait Hello reply */
4840fbf3537Syasuoka 				if (curr_time - _this->hello_io_time >=
4850fbf3537Syasuoka 				    _this->hello_timeout) {
4860fbf3537Syasuoka 					l2tp_ctrl_log(_this, LOG_NOTICE,
4870fbf3537Syasuoka 					    "timeout waiting ack for hello "
4880fbf3537Syasuoka 					    "packets.");
4890fbf3537Syasuoka 					l2tp_ctrl_stop(_this,
4900fbf3537Syasuoka 					    L2TP_STOP_CCN_RCODE_GENERAL);
4910fbf3537Syasuoka 					return;
4920fbf3537Syasuoka 				}
4930fbf3537Syasuoka 			}
4940fbf3537Syasuoka 		} else if (curr_time - _this->last_snd_ctrl >=
4950fbf3537Syasuoka 		    L2TP_CTRL_CTRL_PKT_TIMEOUT) {
4960fbf3537Syasuoka 			l2tp_ctrl_log(_this, LOG_NOTICE,
4970fbf3537Syasuoka 			    "timeout waiting ack for ctrl packets.");
4980fbf3537Syasuoka 			l2tp_ctrl_stop(_this,
4990fbf3537Syasuoka 			    L2TP_STOP_CCN_RCODE_GENERAL);
5000fbf3537Syasuoka 			return;
5010fbf3537Syasuoka 		}
5020fbf3537Syasuoka 		need_resend = 1;
5030fbf3537Syasuoka 	} else {
5040fbf3537Syasuoka 		for (slist_itr_first(&_this->call_list);
5050fbf3537Syasuoka 		    slist_itr_has_next(&_this->call_list);) {
5060fbf3537Syasuoka 			call = slist_itr_next(&_this->call_list);
5070fbf3537Syasuoka 			if (call->state == L2TP_CALL_STATE_CLEANUP_WAIT) {
5080fbf3537Syasuoka 				l2tp_call_destroy(call, 1);
5090fbf3537Syasuoka 				slist_itr_remove(&_this->call_list);
5100fbf3537Syasuoka 			}
5110fbf3537Syasuoka 		}
5120fbf3537Syasuoka 	}
5130fbf3537Syasuoka 
5140fbf3537Syasuoka 	switch (_this->state) {
5150fbf3537Syasuoka 	case L2TP_CTRL_STATE_IDLE:
5160fbf3537Syasuoka 		/*
517f0a4e295Syasuoka 		 * idle:
518f0a4e295Syasuoka 		 * XXX: never happen in current implementation
5190fbf3537Syasuoka 		 */
5200fbf3537Syasuoka 		l2tp_ctrl_log(_this, LOG_ERR,
5210fbf3537Syasuoka 		    "Internal error, timeout on illegal state=idle");
5220fbf3537Syasuoka 		l2tp_ctrl_stop(_this, L2TP_STOP_CCN_RCODE_GENERAL);
5230fbf3537Syasuoka 		break;
5240fbf3537Syasuoka 	case L2TP_CTRL_STATE_WAIT_CTL_CONN:
5250fbf3537Syasuoka 		/*
526f0a4e295Syasuoka 		 * wait-ctrl-conn:
527f0a4e295Syasuoka 		 * 	if there is no ack for SCCRP, the peer will
528f0a4e295Syasuoka 		 * 	resend SCCRQ. however this implementation can
529f0a4e295Syasuoka 		 *	not recognize that the SCCRQ was resent or not.
530f0a4e295Syasuoka 		 *	Therefore, never resent from this side.
5310fbf3537Syasuoka 		 */
5320fbf3537Syasuoka 		need_resend = 0;
5330fbf3537Syasuoka 		break;
5340fbf3537Syasuoka 	case L2TP_CTRL_STATE_ESTABLISHED:
5350fbf3537Syasuoka 		if (slist_length(&_this->call_list) == 0 &&
5360fbf3537Syasuoka 		    curr_time - _this->last_snd_ctrl >=
5370fbf3537Syasuoka 			    L2TP_CTRL_WAIT_CALL_TIMEOUT) {
5380fbf3537Syasuoka 			if (_this->ncalls == 0)
539421b67a1Sjasper 				/* fail to receive first call */
5400fbf3537Syasuoka 				l2tp_ctrl_log(_this, LOG_WARNING,
5410fbf3537Syasuoka 				    "timeout waiting call");
5420fbf3537Syasuoka 			l2tp_ctrl_stop(_this,
5430fbf3537Syasuoka 			    L2TP_STOP_CCN_RCODE_GENERAL);
5440fbf3537Syasuoka 			return;
5450fbf3537Syasuoka 		}
5460fbf3537Syasuoka 		if (_this->hello_wait_ack == 0 && _this->hello_interval > 0) {
547f0a4e295Syasuoka 			/* send Hello */
5480fbf3537Syasuoka 			if (curr_time - _this->hello_interval >=
5490fbf3537Syasuoka 			    _this->hello_io_time) {
5500fbf3537Syasuoka 				if (l2tp_ctrl_send_HELLO(_this) == 0)
551f0a4e295Syasuoka 					/* success */
5520fbf3537Syasuoka 					_this->hello_wait_ack = 1;
5530fbf3537Syasuoka 				_this->hello_io_time = curr_time;
5540fbf3537Syasuoka 				need_resend = 0;
5550fbf3537Syasuoka 			}
5560fbf3537Syasuoka 		}
5570fbf3537Syasuoka 		break;
5580fbf3537Syasuoka 	case L2TP_CTRL_STATE_CLEANUP_WAIT:
5590fbf3537Syasuoka 		if (curr_time - _this->last_snd_ctrl >=
5600fbf3537Syasuoka 		    L2TP_CTRL_CLEANUP_WAIT_TIME) {
5610fbf3537Syasuoka 			l2tp_ctrl_log(_this, LOG_NOTICE,
5620fbf3537Syasuoka 			    "Cleanup timeout state=%d", _this->state);
5630fbf3537Syasuoka 			l2tp_ctrl_stop(_this, 0);
5640fbf3537Syasuoka 			return;
5650fbf3537Syasuoka 		}
5660fbf3537Syasuoka 		if (_this->active_closing != 0)
5670fbf3537Syasuoka 			l2tp_ctrl_send_disconnect_notify(_this);
5680fbf3537Syasuoka 		break;
5690fbf3537Syasuoka 	default:
5700fbf3537Syasuoka 		l2tp_ctrl_log(_this, LOG_ERR,
5710fbf3537Syasuoka 		    "Internal error, timeout on illegal state=%d",
5720fbf3537Syasuoka 			_this->state);
5730fbf3537Syasuoka 		l2tp_ctrl_stop(_this, L2TP_STOP_CCN_RCODE_GENERAL);
5740fbf3537Syasuoka 		return;
5750fbf3537Syasuoka 	}
576f0a4e295Syasuoka 	/* resend if required */
5770fbf3537Syasuoka 	if (need_resend)
5780fbf3537Syasuoka 		l2tp_ctrl_resend_una_packets(_this);
5790fbf3537Syasuoka 	l2tp_ctrl_reset_timeout(_this);
5800fbf3537Syasuoka }
5810fbf3537Syasuoka 
5820fbf3537Syasuoka int
5830fbf3537Syasuoka l2tp_ctrl_send(l2tp_ctrl *_this, const void *msg, int len)
5840fbf3537Syasuoka {
5850fbf3537Syasuoka 	int rval;
5860fbf3537Syasuoka 
5870fbf3537Syasuoka #ifdef USE_LIBSOCKUTIL
5880fbf3537Syasuoka 	if (_this->sa_cookie != NULL)
5890fbf3537Syasuoka 		rval = sendfromto_nat_t(LISTENER_SOCK(_this), msg, len, 0,
5900fbf3537Syasuoka 		    (struct sockaddr *)&_this->sock,
5910fbf3537Syasuoka 		    (struct sockaddr *)&_this->peer, _this->sa_cookie);
5920fbf3537Syasuoka 	else
5930fbf3537Syasuoka 		rval = sendfromto(LISTENER_SOCK(_this), msg, len, 0,
5940fbf3537Syasuoka 		    (struct sockaddr *)&_this->sock,
5950fbf3537Syasuoka 		    (struct sockaddr *)&_this->peer);
5960fbf3537Syasuoka #else
5970fbf3537Syasuoka 	rval = sendto(LISTENER_SOCK(_this), msg, len, 0,
5980fbf3537Syasuoka 	    (struct sockaddr *)&_this->peer, _this->peer.ss_len);
5990fbf3537Syasuoka #endif
6000fbf3537Syasuoka 	return rval;
6010fbf3537Syasuoka }
6020fbf3537Syasuoka 
603f0a4e295Syasuoka /* resend una packets */
6040fbf3537Syasuoka static int
6050fbf3537Syasuoka l2tp_ctrl_resend_una_packets(l2tp_ctrl *_this)
6060fbf3537Syasuoka {
6070fbf3537Syasuoka 	uint16_t seq;
6080fbf3537Syasuoka 	bytebuffer *bytebuf;
6090fbf3537Syasuoka 	struct l2tp_header *header;
6100fbf3537Syasuoka 	int nsend;
6110fbf3537Syasuoka 
6120fbf3537Syasuoka 	nsend = 0;
6130fbf3537Syasuoka 	for (seq = _this->snd_una; SEQ_LT(seq, _this->snd_nxt); seq++) {
6140fbf3537Syasuoka 		bytebuf = _this->snd_buffers[seq % _this->winsz];
6150fbf3537Syasuoka 		header = bytebuffer_pointer(bytebuf);
6160fbf3537Syasuoka 		header->nr = htons(_this->rcv_nxt);
6170fbf3537Syasuoka #ifdef L2TP_CTRL_DEBUG
6180fbf3537Syasuoka 		if (debuglevel >= 3) {
6190fbf3537Syasuoka 			l2tp_ctrl_log(_this, DEBUG_LEVEL_3, "RESEND seq=%u",
6200fbf3537Syasuoka 			    ntohs(header->ns));
6210fbf3537Syasuoka 			show_hd(debug_get_debugfp(),
6220fbf3537Syasuoka 			    bytebuffer_pointer(bytebuf),
6230fbf3537Syasuoka 			    bytebuffer_remaining(bytebuf));
6240fbf3537Syasuoka 		}
6250fbf3537Syasuoka #endif
6260fbf3537Syasuoka 		if (l2tp_ctrl_send(_this, bytebuffer_pointer(bytebuf),
6270fbf3537Syasuoka 		    bytebuffer_remaining(bytebuf)) < 0) {
6280fbf3537Syasuoka 			l2tp_ctrl_log(_this, LOG_ERR,
6290fbf3537Syasuoka 			    "sendto() failed in %s: %m", __func__);
6300fbf3537Syasuoka 			return -1;
6310fbf3537Syasuoka 		}
6320fbf3537Syasuoka 		nsend++;
6330fbf3537Syasuoka 	}
6340fbf3537Syasuoka 	return nsend;
6350fbf3537Syasuoka }
6360fbf3537Syasuoka 
637f0a4e295Syasuoka /* free all calls */
6380fbf3537Syasuoka static void
6390fbf3537Syasuoka l2tp_ctrl_destroy_all_calls(l2tp_ctrl *_this)
6400fbf3537Syasuoka {
6410fbf3537Syasuoka 	l2tp_call *call;
6420fbf3537Syasuoka 
6430fbf3537Syasuoka 	L2TP_CTRL_ASSERT(_this != NULL);
6440fbf3537Syasuoka 
6450fbf3537Syasuoka 	while ((call = slist_remove_first(&_this->call_list)) != NULL)
6460fbf3537Syasuoka 		l2tp_call_destroy(call, 1);
6470fbf3537Syasuoka }
6480fbf3537Syasuoka 
649f0a4e295Syasuoka 
650f0a4e295Syasuoka /* disconnect all calls on the control context
651f0a4e295Syasuoka  * @return return # of calls that is not waiting cleanup.
6520fbf3537Syasuoka  */
6530fbf3537Syasuoka static int
6540fbf3537Syasuoka l2tp_ctrl_disconnect_all_calls(l2tp_ctrl *_this)
6550fbf3537Syasuoka {
6560fbf3537Syasuoka 	int i, len, ncalls;
6570fbf3537Syasuoka 	l2tp_call *call;
6580fbf3537Syasuoka 
6590fbf3537Syasuoka 	L2TP_CTRL_ASSERT(_this != NULL);
6600fbf3537Syasuoka 
6610fbf3537Syasuoka 	ncalls = 0;
6620fbf3537Syasuoka 	len = slist_length(&_this->call_list);
6630fbf3537Syasuoka 	for (i = 0; i < len; i++) {
6640fbf3537Syasuoka 		call = slist_get(&_this->call_list, i);
6650fbf3537Syasuoka 		if (call->state != L2TP_CALL_STATE_CLEANUP_WAIT) {
6660fbf3537Syasuoka 			ncalls++;
6670fbf3537Syasuoka 
6680fbf3537Syasuoka 			if (l2tp_ctrl_txwin_is_full(_this)) {
6690fbf3537Syasuoka 				L2TP_CTRL_DBG((_this, LOG_INFO,
6700fbf3537Syasuoka 				    "Too many calls.  Sending window is not "
6710fbf3537Syasuoka 				    "enough to send CDN to all clients."));
6720fbf3537Syasuoka 				/* nothing to do */
6730fbf3537Syasuoka 			} else
6740fbf3537Syasuoka 				l2tp_call_admin_disconnect(call);
6750fbf3537Syasuoka 		}
6760fbf3537Syasuoka 	}
6770fbf3537Syasuoka 	return ncalls;
6780fbf3537Syasuoka }
6790fbf3537Syasuoka 
680f0a4e295Syasuoka /* reset timeout */
6810fbf3537Syasuoka static void
6820fbf3537Syasuoka l2tp_ctrl_reset_timeout(l2tp_ctrl *_this)
6830fbf3537Syasuoka {
6840fbf3537Syasuoka 	int intvl;
6850fbf3537Syasuoka 	struct timeval tv0;
6860fbf3537Syasuoka 
6870fbf3537Syasuoka 	L2TP_CTRL_ASSERT(_this != NULL);
6880fbf3537Syasuoka 
6890fbf3537Syasuoka 	if (evtimer_initialized(&_this->ev_timeout))
6900fbf3537Syasuoka 		evtimer_del(&_this->ev_timeout);
6910fbf3537Syasuoka 
6920fbf3537Syasuoka 	switch (_this->state) {
6930fbf3537Syasuoka 	case L2TP_CTRL_STATE_CLEANUP_WAIT:
6940fbf3537Syasuoka 		intvl = 1;
6950fbf3537Syasuoka 		break;
6960fbf3537Syasuoka 	default:
6970fbf3537Syasuoka 		intvl = 2;
6980fbf3537Syasuoka 		break;
6990fbf3537Syasuoka 	}
7000fbf3537Syasuoka 	tv0.tv_usec = 0;
7010fbf3537Syasuoka 	tv0.tv_sec = intvl;
7020fbf3537Syasuoka 	if (!evtimer_initialized(&_this->ev_timeout))
7030fbf3537Syasuoka 		evtimer_set(&_this->ev_timeout, l2tp_ctrl_timeout, _this);
7040fbf3537Syasuoka 	evtimer_add(&_this->ev_timeout, &tv0);
7050fbf3537Syasuoka }
7060fbf3537Syasuoka 
707f0a4e295Syasuoka /*
708f0a4e295Syasuoka  * protocols / send and receive
7090fbf3537Syasuoka  */
710421b67a1Sjasper /* Receive packet */
7110fbf3537Syasuoka void
7120fbf3537Syasuoka l2tp_ctrl_input(l2tpd *_this, int listener_index, struct sockaddr *peer,
7130fbf3537Syasuoka     struct sockaddr *sock, void *nat_t_ctx, u_char *pkt, int pktlen)
7140fbf3537Syasuoka {
7150fbf3537Syasuoka 	int i, len, offsiz, reqlen, is_ctrl;
7160fbf3537Syasuoka 	uint16_t mestype;
7170fbf3537Syasuoka 	struct l2tp_avp *avp, *avp0;
7180fbf3537Syasuoka 	l2tp_ctrl *ctrl;
7190fbf3537Syasuoka 	l2tp_call *call;
7200fbf3537Syasuoka 	char buf[L2TP_AVP_MAXSIZ], errmsg[256];
7210fbf3537Syasuoka 	time_t curr_time;
7220fbf3537Syasuoka 	u_char *pkt0;
7230fbf3537Syasuoka 	char ifname[IF_NAMESIZE], phy_label[256];
7240fbf3537Syasuoka 	struct l2tp_header hdr;
725886d2b78Syasuoka 	char hbuf[NI_MAXHOST + NI_MAXSERV + 16];
7260fbf3537Syasuoka 
7270fbf3537Syasuoka 	ctrl = NULL;
7280fbf3537Syasuoka 	curr_time = get_monosec();
7290fbf3537Syasuoka 	pkt0 = pkt;
7300fbf3537Syasuoka 
731886d2b78Syasuoka 	L2TP_CTRL_ASSERT(peer->sa_family == sock->sa_family);
732886d2b78Syasuoka 	L2TP_CTRL_ASSERT(peer->sa_family == AF_INET ||
733886d2b78Syasuoka 	    peer->sa_family == AF_INET6)
7340fbf3537Syasuoka     /*
7350fbf3537Syasuoka      * Parse L2TP Header
7360fbf3537Syasuoka      */
7370fbf3537Syasuoka 	memset(&hdr, 0, sizeof(hdr));
7380fbf3537Syasuoka 	if (pktlen < 2) {
7390fbf3537Syasuoka 		snprintf(errmsg, sizeof(errmsg), "a short packet.  "
7400fbf3537Syasuoka 		    "length=%d", pktlen);
7410fbf3537Syasuoka 		goto bad_packet;
7420fbf3537Syasuoka 	}
7430fbf3537Syasuoka 	memcpy(&hdr, pkt, 2);
7440fbf3537Syasuoka 	pkt += 2;
7450fbf3537Syasuoka 	if (hdr.ver != L2TP_HEADER_VERSION_RFC2661) {
746f0a4e295Syasuoka 		/* XXX: only RFC2661 is supported */
7470fbf3537Syasuoka 		snprintf(errmsg, sizeof(errmsg),
7480fbf3537Syasuoka 		    "Unsupported version at header = %d", hdr.ver);
7490fbf3537Syasuoka 		goto bad_packet;
7500fbf3537Syasuoka 	}
7510fbf3537Syasuoka 	is_ctrl = (hdr.t != 0)? 1 : 0;
7520fbf3537Syasuoka 
7530fbf3537Syasuoka 	/* calc required length */
7540fbf3537Syasuoka 	reqlen = 6;		/* for Flags, Tunnel-Id, Session-Id field */
7550fbf3537Syasuoka 	if (hdr.l) reqlen += 2;	/* for Length field (opt) */
7560fbf3537Syasuoka 	if (hdr.s) reqlen += 4;	/* for Ns, Nr field (opt) */
7570fbf3537Syasuoka 	if (hdr.o) reqlen += 2;	/* for Offset Size field (opt) */
7580fbf3537Syasuoka 	if (reqlen > pktlen) {
7590fbf3537Syasuoka 		snprintf(errmsg, sizeof(errmsg),
7600fbf3537Syasuoka 		    "a short packet. length=%d", pktlen);
7610fbf3537Syasuoka 		goto bad_packet;
7620fbf3537Syasuoka 	}
7630fbf3537Syasuoka 
7640fbf3537Syasuoka 	if (hdr.l != 0) {
7650fbf3537Syasuoka 		GETSHORT(hdr.length, pkt);
7660fbf3537Syasuoka 		if (hdr.length > pktlen) {
7670fbf3537Syasuoka 			snprintf(errmsg, sizeof(errmsg),
7680fbf3537Syasuoka 			    "Actual packet size is smaller than the length "
7690fbf3537Syasuoka 			    "field %d < %d", pktlen, hdr.length);
7700fbf3537Syasuoka 			goto bad_packet;
7710fbf3537Syasuoka 		}
7720fbf3537Syasuoka 		pktlen = hdr.length;	/* remove trailing trash */
7730fbf3537Syasuoka 	}
7740fbf3537Syasuoka 	GETSHORT(hdr.tunnel_id, pkt);
7750fbf3537Syasuoka 	GETSHORT(hdr.session_id, pkt);
7760fbf3537Syasuoka 	if (hdr.s != 0) {
7770fbf3537Syasuoka 		GETSHORT(hdr.ns, pkt);
7780fbf3537Syasuoka 		GETSHORT(hdr.nr, pkt);
7790fbf3537Syasuoka 	}
7800fbf3537Syasuoka 	if (hdr.o != 0) {
7810fbf3537Syasuoka 		GETSHORT(offsiz, pkt);
7820fbf3537Syasuoka 		if (pktlen < offsiz) {
7830fbf3537Syasuoka 			snprintf(errmsg, sizeof(errmsg),
7840fbf3537Syasuoka 			    "offset field is bigger than remaining packet "
7850fbf3537Syasuoka 			    "length %d > %d", offsiz, pktlen);
7860fbf3537Syasuoka 			goto bad_packet;
7870fbf3537Syasuoka 		}
7880fbf3537Syasuoka 		pkt += offsiz;
7890fbf3537Syasuoka 	}
7900fbf3537Syasuoka 	L2TP_CTRL_ASSERT(pkt - pkt0 == reqlen);
7910fbf3537Syasuoka 	pktlen -= (pkt - pkt0);	/* cut down the length of header */
7920fbf3537Syasuoka 
7930fbf3537Syasuoka 	ctrl = NULL;
7940fbf3537Syasuoka 	memset(buf, 0, sizeof(buf));
7950fbf3537Syasuoka 	mestype = 0;
7960fbf3537Syasuoka 	avp = NULL;
7970fbf3537Syasuoka 
7980fbf3537Syasuoka 	if (is_ctrl) {
7990fbf3537Syasuoka 		avp0 = (struct l2tp_avp *)buf;
8000fbf3537Syasuoka 		avp = avp_find_message_type_avp(avp0, pkt, pktlen);
8010fbf3537Syasuoka 		if (avp != NULL)
8020fbf3537Syasuoka 			mestype = avp->attr_value[0] << 8 | avp->attr_value[1];
8030fbf3537Syasuoka 	}
8040fbf3537Syasuoka 	ctrl = l2tpd_get_ctrl(_this, hdr.tunnel_id);
8050fbf3537Syasuoka 
8060fbf3537Syasuoka 	if (ctrl == NULL) {
807f0a4e295Syasuoka 		/* new control */
8080fbf3537Syasuoka 		if (!is_ctrl) {
8090fbf3537Syasuoka 			snprintf(errmsg, sizeof(errmsg),
8100fbf3537Syasuoka 			    "bad data message: tunnelId=%d is not "
8110fbf3537Syasuoka 			    "found.", hdr.tunnel_id);
8120fbf3537Syasuoka 			goto bad_packet;
8130fbf3537Syasuoka 		}
8140fbf3537Syasuoka 		if (mestype != L2TP_AVP_MESSAGE_TYPE_SCCRQ) {
8150fbf3537Syasuoka 			snprintf(errmsg, sizeof(errmsg),
8160fbf3537Syasuoka 			    "bad control message: tunnelId=%d is not "
8170fbf3537Syasuoka 			    "found.  mestype=%s", hdr.tunnel_id,
8180fbf3537Syasuoka 			    avp_mes_type_string(mestype));
8190fbf3537Syasuoka 			goto bad_packet;
8200fbf3537Syasuoka 		}
8210fbf3537Syasuoka 
8220fbf3537Syasuoka 		strlcpy(phy_label,
8230fbf3537Syasuoka 		    ((l2tpd_listener *)slist_get(&_this->listener,
8240fbf3537Syasuoka 		    listener_index))->phy_label, sizeof(phy_label));
8250fbf3537Syasuoka 		if (_this->phy_label_with_ifname != 0) {
8260fbf3537Syasuoka 			if (get_ifname_by_sockaddr(sock, ifname) == NULL) {
8279a200ddfSyasuoka 				if (errno != ENOENT)
8289a200ddfSyasuoka 					l2tp_ctrl_log(ctrl, LOG_ERR,
8299a200ddfSyasuoka 					    "get_ifname_by_sockaddr() "
8309a200ddfSyasuoka 					    "failed: %m");
8319a200ddfSyasuoka 				else
8320fbf3537Syasuoka 					l2tpd_log_access_deny(_this,
8339a200ddfSyasuoka 					    "could not determine received "
8349a200ddfSyasuoka 					    "interface", peer);
835f0a4e295Syasuoka 				goto fail;
8360fbf3537Syasuoka 			}
8370fbf3537Syasuoka 			if (l2tpd_config_str_equal(_this,
8380fbf3537Syasuoka 			    config_key_prefix("l2tpd.interface", ifname),
8390fbf3537Syasuoka 			    "accept", 0)){
8400fbf3537Syasuoka 				strlcat(phy_label, "%", sizeof(phy_label));
8410fbf3537Syasuoka 				strlcat(phy_label, ifname, sizeof(phy_label));
8420fbf3537Syasuoka 			} else if (l2tpd_config_str_equal(_this,
8430fbf3537Syasuoka 			    config_key_prefix("l2tpd.interface", "any"),
8440fbf3537Syasuoka 			    "accept", 0)){
8450fbf3537Syasuoka 			} else {
846f0a4e295Syasuoka 				/* the interface is not permited */
8470fbf3537Syasuoka 				snprintf(errmsg, sizeof(errmsg),
8480fbf3537Syasuoka 				    "'%s' is not allowed by config.", ifname);
8490fbf3537Syasuoka 				l2tpd_log_access_deny(_this, errmsg, peer);
850f0a4e295Syasuoka 				goto fail;
8510fbf3537Syasuoka 			}
8520fbf3537Syasuoka 		}
8530fbf3537Syasuoka 
8540fbf3537Syasuoka 		if ((ctrl = l2tp_ctrl_create()) == NULL) {
8550fbf3537Syasuoka 			l2tp_ctrl_log(ctrl, LOG_ERR,
8560fbf3537Syasuoka 			    "l2tp_ctrl_create() failed: %m");
857f0a4e295Syasuoka 			goto fail;
8580fbf3537Syasuoka 		}
8590fbf3537Syasuoka 		if (l2tp_ctrl_init(ctrl, _this, peer, sock, nat_t_ctx) != 0) {
8600fbf3537Syasuoka 			l2tp_ctrl_log(ctrl, LOG_ERR,
8610fbf3537Syasuoka 			    "l2tp_ctrl_start() failed: %m");
862f0a4e295Syasuoka 			goto fail;
8630fbf3537Syasuoka 		}
8640fbf3537Syasuoka 
8650fbf3537Syasuoka 		ctrl->listener_index = listener_index;
8660fbf3537Syasuoka 		strlcpy(ctrl->phy_label, phy_label, sizeof(ctrl->phy_label));
8670fbf3537Syasuoka 		l2tp_ctrl_reload(ctrl);
8680fbf3537Syasuoka 	} else {
8690fbf3537Syasuoka 		/*
870f0a4e295Syasuoka 		 * treat as an error if src address and port is not
871f0a4e295Syasuoka 		 * match. (because it is potentially DoS attach)
8720fbf3537Syasuoka 		 */
873886d2b78Syasuoka 		int notmatch = 0;
8740fbf3537Syasuoka 
875886d2b78Syasuoka 		if (ctrl->peer.ss_family != peer->sa_family)
876886d2b78Syasuoka 			notmatch = 1;
877886d2b78Syasuoka 		else if (peer->sa_family == AF_INET) {
878886d2b78Syasuoka 			if (SIN(peer)->sin_addr.s_addr !=
879886d2b78Syasuoka 			    SIN(&ctrl->peer)->sin_addr.s_addr ||
880886d2b78Syasuoka 			    SIN(peer)->sin_port != SIN(&ctrl->peer)->sin_port)
881886d2b78Syasuoka 				notmatch = 1;
882886d2b78Syasuoka 		} else if (peer->sa_family == AF_INET6) {
883886d2b78Syasuoka 			if (!IN6_ARE_ADDR_EQUAL(&(SIN6(peer)->sin6_addr),
884886d2b78Syasuoka 				    &(SIN6(&ctrl->peer)->sin6_addr)) ||
885886d2b78Syasuoka 			    SIN6(peer)->sin6_port !=
886886d2b78Syasuoka 				    SIN6(&ctrl->peer)->sin6_port)
887886d2b78Syasuoka 				notmatch = 1;
888886d2b78Syasuoka  		}
889886d2b78Syasuoka 		if (notmatch) {
8900fbf3537Syasuoka 			snprintf(errmsg, sizeof(errmsg),
891886d2b78Syasuoka 			    "tunnelId=%u is already assigned for %s",
892886d2b78Syasuoka 			    hdr.tunnel_id, addrport_tostring(
893886d2b78Syasuoka 				(struct sockaddr *)&ctrl->peer,
894886d2b78Syasuoka 				ctrl->peer.ss_len, hbuf, sizeof(hbuf)));
8950fbf3537Syasuoka 			goto bad_packet;
8960fbf3537Syasuoka 		}
8970fbf3537Syasuoka 	}
8980fbf3537Syasuoka 	ctrl->last_rcv = curr_time;
8990fbf3537Syasuoka 	call = NULL;
9000fbf3537Syasuoka 	if (hdr.session_id != 0) {
901f0a4e295Syasuoka 		/* search l2tp_call by Session ID */
902f0a4e295Syasuoka 		/* linear search is enough for this purpose */
9030fbf3537Syasuoka 		len = slist_length(&ctrl->call_list);
9040fbf3537Syasuoka 		for (i = 0; i < len; i++) {
9050fbf3537Syasuoka 			call = slist_get(&ctrl->call_list, i);
9060fbf3537Syasuoka 			if (call->session_id == hdr.session_id)
9070fbf3537Syasuoka 				break;
9080fbf3537Syasuoka 			call = NULL;
9090fbf3537Syasuoka 		}
9100fbf3537Syasuoka 	}
9110fbf3537Syasuoka 	if (!is_ctrl) {
912e405d423Syasuoka 		int delayed = 0;
913e405d423Syasuoka 
914f0a4e295Syasuoka 		/* L2TP data */
9150fbf3537Syasuoka 		if (ctrl->state != L2TP_CTRL_STATE_ESTABLISHED) {
9160fbf3537Syasuoka 			l2tp_ctrl_log(ctrl, LOG_WARNING,
9170fbf3537Syasuoka 			    "Received Data packet in '%s'",
9180fbf3537Syasuoka 			    l2tp_ctrl_state_string(ctrl));
919f0a4e295Syasuoka 			goto fail;
9200fbf3537Syasuoka 		}
9210fbf3537Syasuoka 		if (call == NULL) {
9220fbf3537Syasuoka 			l2tp_ctrl_log(ctrl, LOG_WARNING,
9230fbf3537Syasuoka 			    "Received a data packet but it has no call.  "
9240fbf3537Syasuoka 			    "session_id=%u",  hdr.session_id);
925f0a4e295Syasuoka 			goto fail;
9260fbf3537Syasuoka 		}
9270fbf3537Syasuoka 		L2TP_CTRL_DBG((ctrl, DEBUG_LEVEL_2,
9280fbf3537Syasuoka 		    "call=%u RECV   ns=%u nr=%u snd_nxt=%u rcv_nxt=%u len=%d",
9290fbf3537Syasuoka 		    call->id, hdr.ns, hdr.nr, call->snd_nxt, call->rcv_nxt,
9300fbf3537Syasuoka 		    pktlen));
9310fbf3537Syasuoka 		if (call->state != L2TP_CALL_STATE_ESTABLISHED){
9320fbf3537Syasuoka 			l2tp_ctrl_log(ctrl, LOG_WARNING,
9330fbf3537Syasuoka 			    "Received a data packet but call is not "
9340fbf3537Syasuoka 			    "established");
935f0a4e295Syasuoka 			goto fail;
9360fbf3537Syasuoka 		}
9370fbf3537Syasuoka 
9380fbf3537Syasuoka 		if (hdr.s != 0) {
9390fbf3537Syasuoka 			if (SEQ_LT(hdr.ns, call->rcv_nxt)) {
940e405d423Syasuoka 				if (SEQ_LT(hdr.ns,
941e405d423Syasuoka 				    call->rcv_nxt - L2TP_CALL_DELAY_LIMIT)) {
942e405d423Syasuoka 					/* sequence number seems to be delayed */
943f0a4e295Syasuoka 					/* XXX: need to log? */
9440fbf3537Syasuoka 					L2TP_CTRL_DBG((ctrl, LOG_DEBUG,
945e405d423Syasuoka 					    "receive a out of sequence "
946e405d423Syasuoka 					    "data packet: %u < %u.",
947e405d423Syasuoka 					    hdr.ns, call->rcv_nxt));
9480fbf3537Syasuoka 					return;
9490fbf3537Syasuoka 				}
950e405d423Syasuoka 				delayed = 1;
951e405d423Syasuoka 			} else {
9520fbf3537Syasuoka 				call->rcv_nxt = hdr.ns + 1;
9530fbf3537Syasuoka 			}
954e405d423Syasuoka 		}
955e405d423Syasuoka 
956e405d423Syasuoka 		l2tp_call_ppp_input(call, pkt, pktlen, delayed);
9570fbf3537Syasuoka 
9580fbf3537Syasuoka 		return;
9590fbf3537Syasuoka 	}
9600fbf3537Syasuoka 	if (hdr.s != 0) {
9610fbf3537Syasuoka 		L2TP_CTRL_DBG((ctrl, DEBUG_LEVEL_2,
9620fbf3537Syasuoka 		    "RECV %s ns=%u nr=%u snd_nxt=%u snd_una=%u rcv_nxt=%u "
9630fbf3537Syasuoka 		    "len=%d", (is_ctrl)? "C" : "", hdr.ns, hdr.nr,
9640fbf3537Syasuoka 		    ctrl->snd_nxt, ctrl->snd_una, ctrl->rcv_nxt, pktlen));
9650fbf3537Syasuoka 
9660fbf3537Syasuoka 		if (pktlen <= 0)
9670fbf3537Syasuoka 			l2tp_ctrl_log(ctrl, LOG_INFO, "RecvZLB");
9680fbf3537Syasuoka 
9690fbf3537Syasuoka 		if (SEQ_GT(hdr.nr, ctrl->snd_una)) {
9700fbf3537Syasuoka 			if (hdr.nr == ctrl->snd_nxt ||
9710fbf3537Syasuoka 			    SEQ_LT(hdr.nr, ctrl->snd_nxt))
9720fbf3537Syasuoka 				ctrl->snd_una = hdr.nr;
9730fbf3537Syasuoka 			else {
9740fbf3537Syasuoka 				l2tp_ctrl_log(ctrl, LOG_INFO,
9750fbf3537Syasuoka 				    "Received message has bad Nr field: "
9760fbf3537Syasuoka 				    "%u < %u.", hdr.ns, ctrl->snd_nxt);
9770fbf3537Syasuoka 				/* XXX Drop with ZLB? */
978f0a4e295Syasuoka 				goto fail;
9790fbf3537Syasuoka 			}
9800fbf3537Syasuoka 		}
9810fbf3537Syasuoka 		if (l2tp_ctrl_txwin_size(ctrl) <= 0) {
982f0a4e295Syasuoka 			/* no waiting ack */
9830fbf3537Syasuoka 			if (ctrl->hello_wait_ack != 0) {
9840fbf3537Syasuoka 				/*
985f0a4e295Syasuoka 				 * Reset Hello state, as an ack for the Hello
986f0a4e295Syasuoka 				 * is recived.
9870fbf3537Syasuoka 				 */
9880fbf3537Syasuoka 				ctrl->hello_wait_ack = 0;
9890fbf3537Syasuoka 				ctrl->hello_io_time = curr_time;
9900fbf3537Syasuoka 			}
9910fbf3537Syasuoka 			switch (ctrl->state) {
9920fbf3537Syasuoka 			case L2TP_CTRL_STATE_CLEANUP_WAIT:
9930fbf3537Syasuoka 				l2tp_ctrl_stop(ctrl, 0);
9940fbf3537Syasuoka 				return;
9950fbf3537Syasuoka 			}
9960fbf3537Syasuoka 		}
9970fbf3537Syasuoka 		if (hdr.ns != ctrl->rcv_nxt) {
998f0a4e295Syasuoka 			/* there are remaining packet */
9990fbf3537Syasuoka 			if (l2tp_ctrl_resend_una_packets(ctrl) <= 0) {
1000f0a4e295Syasuoka 				/* resend or sent ZLB */
10010fbf3537Syasuoka 				l2tp_ctrl_send_ZLB(ctrl);
10020fbf3537Syasuoka 			}
10030fbf3537Syasuoka #ifdef	L2TP_CTRL_DEBUG
1004f0a4e295Syasuoka 			if (pktlen != 0) {	/* not ZLB */
10050fbf3537Syasuoka 				L2TP_CTRL_DBG((ctrl, LOG_DEBUG,
10060fbf3537Syasuoka 				    "receive out of sequence %u must be %u.  "
10070fbf3537Syasuoka 				    "mestype=%s", hdr.ns, ctrl->rcv_nxt,
10080fbf3537Syasuoka 				    avp_mes_type_string(mestype)));
10090fbf3537Syasuoka 			}
10100fbf3537Syasuoka #endif
10110fbf3537Syasuoka 			return;
10120fbf3537Syasuoka 		}
10130fbf3537Syasuoka 		if (pktlen <= 0)
10140fbf3537Syasuoka 			return;		/* ZLB */
10150fbf3537Syasuoka 
10160fbf3537Syasuoka 		if (l2tp_ctrl_txwin_is_full(ctrl)) {
10170fbf3537Syasuoka 			L2TP_CTRL_DBG((ctrl, LOG_DEBUG,
10180fbf3537Syasuoka 			    "Received message cannot be handled. "
10190fbf3537Syasuoka 			    "Transmission window is full."));
10200fbf3537Syasuoka 			l2tp_ctrl_send_ZLB(ctrl);
10210fbf3537Syasuoka 			return;
10220fbf3537Syasuoka 		}
10230fbf3537Syasuoka 
10240fbf3537Syasuoka 		ctrl->rcv_nxt++;
10250fbf3537Syasuoka 		if (avp == NULL) {
10260fbf3537Syasuoka 			l2tpd_log(_this, LOG_WARNING,
10270fbf3537Syasuoka 			    "bad control message: no message-type AVP.");
1028f0a4e295Syasuoka 			goto fail;
10290fbf3537Syasuoka 		}
10300fbf3537Syasuoka 	}
10310fbf3537Syasuoka 
10320fbf3537Syasuoka     /*
1033f0a4e295Syasuoka      * state machine (RFC2661 pp. 56-57)
10340fbf3537Syasuoka      */
10350fbf3537Syasuoka 	switch (ctrl->state) {
10360fbf3537Syasuoka 	case L2TP_CTRL_STATE_IDLE:
10370fbf3537Syasuoka 		switch (mestype) {
10380fbf3537Syasuoka 		case L2TP_AVP_MESSAGE_TYPE_SCCRQ:
10390fbf3537Syasuoka 			if (l2tp_ctrl_recv_SCCRQ(ctrl, pkt, pktlen, _this,
10400fbf3537Syasuoka 			    peer) == 0) {
1041f0a4e295Syasuoka 				/* acceptable */
10420fbf3537Syasuoka 				l2tp_ctrl_send_SCCRP(ctrl);
10430fbf3537Syasuoka 				ctrl->state = L2TP_CTRL_STATE_WAIT_CTL_CONN;
10440fbf3537Syasuoka 				return;
10450fbf3537Syasuoka 			}
10460fbf3537Syasuoka 			/*
1047f0a4e295Syasuoka 			 * in case un-acceptable, it was already processed
1048f0a4e295Syasuoka 			 * at l2tcp_ctrl_recv_SCCRQ
10490fbf3537Syasuoka 			 */
10500fbf3537Syasuoka 			return;
10510fbf3537Syasuoka 		case L2TP_AVP_MESSAGE_TYPE_SCCRP:
10520fbf3537Syasuoka 			/*
1053f0a4e295Syasuoka 			 * RFC specifies that sent of StopCCN in the state,
1054f0a4e295Syasuoka 			 * However as this implementation only support Passive
1055421b67a1Sjasper 			 * open, this packet will not received.
10560fbf3537Syasuoka 			 */
1057f0a4e295Syasuoka 			/* FALLTHROUGH */
10580fbf3537Syasuoka 		case L2TP_AVP_MESSAGE_TYPE_SCCCN:
10590fbf3537Syasuoka 		default:
10600fbf3537Syasuoka 			break;
10610fbf3537Syasuoka 		}
1062f0a4e295Syasuoka 		goto fsm_fail;
10630fbf3537Syasuoka 
10640fbf3537Syasuoka 	case L2TP_CTRL_STATE_WAIT_CTL_CONN:
10650fbf3537Syasuoka 	    /* Wait-Ctl-Conn */
10660fbf3537Syasuoka 		switch (mestype) {
10670fbf3537Syasuoka 		case L2TP_AVP_MESSAGE_TYPE_SCCCN:
10680fbf3537Syasuoka 			l2tp_ctrl_log(ctrl, LOG_INFO, "RecvSCCN");
10690fbf3537Syasuoka 			if (l2tp_ctrl_send_ZLB(ctrl) == 0) {
10700fbf3537Syasuoka 				ctrl->state = L2TP_CTRL_STATE_ESTABLISHED;
10710fbf3537Syasuoka 			}
10720fbf3537Syasuoka 			return;
10730fbf3537Syasuoka 		case L2TP_AVP_MESSAGE_TYPE_StopCCN:
10740fbf3537Syasuoka 			goto receive_stop_ccn;
10750fbf3537Syasuoka 		case L2TP_AVP_MESSAGE_TYPE_SCCRQ:
10760fbf3537Syasuoka 		case L2TP_AVP_MESSAGE_TYPE_SCCRP:
10770fbf3537Syasuoka 		default:
10780fbf3537Syasuoka 			break;
10790fbf3537Syasuoka 		}
1080f0a4e295Syasuoka 		break;	/* fsm_fail */
10810fbf3537Syasuoka 	case L2TP_CTRL_STATE_ESTABLISHED:
10820fbf3537Syasuoka 	    /* Established */
10830fbf3537Syasuoka 		switch (mestype) {
10840fbf3537Syasuoka 		case L2TP_AVP_MESSAGE_TYPE_SCCCN:
10850fbf3537Syasuoka 		case L2TP_AVP_MESSAGE_TYPE_SCCRQ:
10860fbf3537Syasuoka 		case L2TP_AVP_MESSAGE_TYPE_SCCRP:
10870fbf3537Syasuoka 			break;
10880fbf3537Syasuoka receive_stop_ccn:
10890fbf3537Syasuoka 		case L2TP_AVP_MESSAGE_TYPE_StopCCN:
10900fbf3537Syasuoka 			if (l2tp_ctrl_recv_StopCCN(ctrl, pkt, pktlen) == 0) {
10910fbf3537Syasuoka 				if (l2tp_ctrl_resend_una_packets(ctrl) <= 0)
10920fbf3537Syasuoka 					l2tp_ctrl_send_ZLB(ctrl);
10930fbf3537Syasuoka 				l2tp_ctrl_stop(ctrl, 0);
10940fbf3537Syasuoka 				return;
10950fbf3537Syasuoka 			}
10960fbf3537Syasuoka 			l2tp_ctrl_log(ctrl, LOG_ERR, "Received bad StopCCN");
10970fbf3537Syasuoka 			l2tp_ctrl_send_ZLB(ctrl);
10980fbf3537Syasuoka 			l2tp_ctrl_stop(ctrl, 0);
10990fbf3537Syasuoka 			return;
11000fbf3537Syasuoka 
11010fbf3537Syasuoka 		case L2TP_AVP_MESSAGE_TYPE_HELLO:
11020fbf3537Syasuoka 			if (l2tp_ctrl_resend_una_packets(ctrl) <= 0)
11030fbf3537Syasuoka 				l2tp_ctrl_send_ZLB(ctrl);
11040fbf3537Syasuoka 			return;
11050fbf3537Syasuoka 		case L2TP_AVP_MESSAGE_TYPE_CDN:
11060fbf3537Syasuoka 		case L2TP_AVP_MESSAGE_TYPE_ICRP:
11070fbf3537Syasuoka 		case L2TP_AVP_MESSAGE_TYPE_ICCN:
11080fbf3537Syasuoka 			if (call == NULL) {
11090fbf3537Syasuoka 				l2tp_ctrl_log(ctrl, LOG_INFO,
11100fbf3537Syasuoka 				    "Unknown call message: %s",
11110fbf3537Syasuoka 				    avp_mes_type_string(mestype));
1112f0a4e295Syasuoka 				goto fail;
11130fbf3537Syasuoka 			}
1114f0a4e295Syasuoka 			/* FALLTHROUGH */
11150fbf3537Syasuoka 		case L2TP_AVP_MESSAGE_TYPE_ICRQ:
11160fbf3537Syasuoka 			l2tp_call_recv_packet(ctrl, call, mestype, pkt,
11170fbf3537Syasuoka 			    pktlen);
11180fbf3537Syasuoka 			return;
11190fbf3537Syasuoka 		default:
11200fbf3537Syasuoka 			break;
11210fbf3537Syasuoka 		}
1122f0a4e295Syasuoka 		break;	/* fsm_fail */
11230fbf3537Syasuoka 	case L2TP_CTRL_STATE_CLEANUP_WAIT:
11240fbf3537Syasuoka 		if (mestype == L2TP_AVP_MESSAGE_TYPE_StopCCN) {
11250fbf3537Syasuoka 			/*
1126f0a4e295Syasuoka 			 * We left ESTABLISHED state, but the peer sent StopCCN.
11270fbf3537Syasuoka 			 */
11280fbf3537Syasuoka 			goto receive_stop_ccn;
11290fbf3537Syasuoka 		}
1130f0a4e295Syasuoka 		break;	/* fsm_fail */
11310fbf3537Syasuoka 	}
11320fbf3537Syasuoka 
1133f0a4e295Syasuoka fsm_fail:
1134f0a4e295Syasuoka 	/* state machine error */
11350fbf3537Syasuoka 	l2tp_ctrl_log(ctrl, LOG_WARNING, "Received %s in '%s' state",
11360fbf3537Syasuoka 	    avp_mes_type_string(mestype), l2tp_ctrl_state_string(ctrl));
11370fbf3537Syasuoka 	l2tp_ctrl_stop(ctrl, L2TP_STOP_CCN_RCODE_FSM_ERROR);
11380fbf3537Syasuoka 
11390fbf3537Syasuoka 	return;
1140f0a4e295Syasuoka fail:
11410fbf3537Syasuoka 	if (ctrl != NULL && mestype != 0) {
11420fbf3537Syasuoka 		l2tp_ctrl_log(ctrl, LOG_WARNING, "Received %s in '%s' state",
11430fbf3537Syasuoka 		    avp_mes_type_string(mestype), l2tp_ctrl_state_string(ctrl));
11440fbf3537Syasuoka 		l2tp_ctrl_stop(ctrl, L2TP_STOP_CCN_RCODE_GENERAL_ERROR);
11450fbf3537Syasuoka 	}
11460fbf3537Syasuoka 	return;
11470fbf3537Syasuoka 
11480fbf3537Syasuoka bad_packet:
1149886d2b78Syasuoka 	l2tpd_log(_this, LOG_INFO, "Received from=%s: %s",
1150886d2b78Syasuoka 	    addrport_tostring(peer, peer->sa_len, hbuf, sizeof(hbuf)), errmsg);
1151886d2b78Syasuoka 
11520fbf3537Syasuoka 	return;
11530fbf3537Syasuoka }
11540fbf3537Syasuoka 
11550fbf3537Syasuoka static inline int
11560fbf3537Syasuoka l2tp_ctrl_txwin_size(l2tp_ctrl *_this)
11570fbf3537Syasuoka {
11580fbf3537Syasuoka 	uint16_t sz;
11590fbf3537Syasuoka 
11600fbf3537Syasuoka 	sz = _this->snd_nxt - _this->snd_una;
11610fbf3537Syasuoka 
11620fbf3537Syasuoka 	L2TP_CTRL_ASSERT(sz <= _this->winsz);
11630fbf3537Syasuoka 
11640fbf3537Syasuoka 	return sz;
11650fbf3537Syasuoka }
11660fbf3537Syasuoka 
11670fbf3537Syasuoka static inline int
11680fbf3537Syasuoka l2tp_ctrl_txwin_is_full(l2tp_ctrl *_this)
11690fbf3537Syasuoka {
11700fbf3537Syasuoka 	return (l2tp_ctrl_txwin_size(_this) >= _this->winsz)? 1 : 0;
11710fbf3537Syasuoka }
11720fbf3537Syasuoka 
1173f0a4e295Syasuoka /* send control packet */
11740fbf3537Syasuoka int
11759a200ddfSyasuoka l2tp_ctrl_send_packet(l2tp_ctrl *_this, int call_id, bytebuffer *bytebuf)
11760fbf3537Syasuoka {
11770fbf3537Syasuoka 	struct l2tp_header *hdr;
11789a200ddfSyasuoka 	int rval;
11790fbf3537Syasuoka 	time_t curr_time;
11800fbf3537Syasuoka 
11810fbf3537Syasuoka 	curr_time = get_monosec();
11820fbf3537Syasuoka 
11830fbf3537Syasuoka 	bytebuffer_flip(bytebuf);
11840fbf3537Syasuoka 	hdr = (struct l2tp_header *)bytebuffer_pointer(bytebuf);
11850fbf3537Syasuoka 	memset(hdr, 0, sizeof(*hdr));
11860fbf3537Syasuoka 
11870fbf3537Syasuoka 	hdr->t = 1;
11880fbf3537Syasuoka 	hdr->ver = L2TP_HEADER_VERSION_RFC2661;
11890fbf3537Syasuoka 	hdr->l = 1;
11900fbf3537Syasuoka 	hdr->length = htons(bytebuffer_remaining(bytebuf));
11910fbf3537Syasuoka 	hdr->tunnel_id = htons(_this->peer_tunnel_id);
11920fbf3537Syasuoka 	hdr->session_id = htons(call_id);
11930fbf3537Syasuoka 
11940fbf3537Syasuoka 	hdr->s = 1;
11950fbf3537Syasuoka 	hdr->ns = htons(_this->snd_nxt);
11960fbf3537Syasuoka 	hdr->nr = htons(_this->rcv_nxt);
11970fbf3537Syasuoka 
11989a200ddfSyasuoka 	if (bytebuffer_remaining(bytebuf) > sizeof(struct l2tp_header))
11990fbf3537Syasuoka 		/* Not ZLB */
12000fbf3537Syasuoka 		_this->snd_nxt++;
12010fbf3537Syasuoka 
12020fbf3537Syasuoka 	L2TP_CTRL_DBG((_this, DEBUG_LEVEL_2,
12039a200ddfSyasuoka 	    "SEND C ns=%u nr=%u snd_nxt=%u snd_una=%u rcv_nxt=%u ",
12049a200ddfSyasuoka 	    ntohs(hdr->ns), htons(hdr->nr),
12050fbf3537Syasuoka 	    _this->snd_nxt, _this->snd_una, _this->rcv_nxt));
12060fbf3537Syasuoka 
12070fbf3537Syasuoka 	if (_this->l2tpd->ctrl_out_pktdump != 0) {
12080fbf3537Syasuoka 		l2tpd_log(_this->l2tpd, LOG_DEBUG,
12090fbf3537Syasuoka 		    "L2TP Control output packet dump");
12100fbf3537Syasuoka 		show_hd(debug_get_debugfp(), bytebuffer_pointer(bytebuf),
12110fbf3537Syasuoka 		    bytebuffer_remaining(bytebuf));
12120fbf3537Syasuoka 	}
12130fbf3537Syasuoka 
12140fbf3537Syasuoka 	if ((rval = l2tp_ctrl_send(_this, bytebuffer_pointer(bytebuf),
12150fbf3537Syasuoka 	    bytebuffer_remaining(bytebuf))) < 0) {
12160fbf3537Syasuoka 		L2TP_CTRL_DBG((_this, LOG_DEBUG, "sendto() failed: %m"));
12170fbf3537Syasuoka 	}
12180fbf3537Syasuoka 
12190fbf3537Syasuoka 	_this->last_snd_ctrl = curr_time;
12200fbf3537Syasuoka 
12210fbf3537Syasuoka 	return (rval == bytebuffer_remaining(bytebuf))? 0 : 1;
12220fbf3537Syasuoka }
12230fbf3537Syasuoka 
1224f0a4e295Syasuoka /*
1225f0a4e295Syasuoka  * receiver SCCRQ
12260fbf3537Syasuoka  */
12270fbf3537Syasuoka static int
12280fbf3537Syasuoka l2tp_ctrl_recv_SCCRQ(l2tp_ctrl *_this, u_char *pkt, int pktlen, l2tpd *_l2tpd,
12290fbf3537Syasuoka     struct sockaddr *peer)
12300fbf3537Syasuoka {
12310fbf3537Syasuoka 	int avpsz, len, protover, protorev, firmrev, result;
12320fbf3537Syasuoka 	struct l2tp_avp *avp;
12330fbf3537Syasuoka 	char host[NI_MAXHOST], serv[NI_MAXSERV];
12340fbf3537Syasuoka 	char buf[L2TP_AVP_MAXSIZ], emes[256], hostname[256], vendorname[256];
12350fbf3537Syasuoka 
12360fbf3537Syasuoka 	result = L2TP_STOP_CCN_RCODE_GENERAL_ERROR;
12370fbf3537Syasuoka 	strlcpy(hostname, "(no hostname)", sizeof(hostname));
12380fbf3537Syasuoka 	strlcpy(vendorname, "(no vendorname)", sizeof(vendorname));
12390fbf3537Syasuoka 
12400fbf3537Syasuoka 	firmrev = 0;
12410fbf3537Syasuoka 	protover = 0;
12420fbf3537Syasuoka 	protorev = 0;
12430fbf3537Syasuoka 	avp = (struct l2tp_avp *)buf;
12440fbf3537Syasuoka 	while (pktlen >= 6 && (avpsz = avp_enum(avp, pkt, pktlen, 1)) > 0) {
12450fbf3537Syasuoka 		pkt += avpsz;
12460fbf3537Syasuoka 		pktlen -= avpsz;
12470fbf3537Syasuoka 		if (avp->vendor_id != 0) {
12480fbf3537Syasuoka 			L2TP_CTRL_DBG((_this, LOG_DEBUG,
12490fbf3537Syasuoka 			    "Received a Vendor-specific AVP vendor-id=%d "
12500fbf3537Syasuoka 			    "type=%d", avp->vendor_id, avp->attr_type));
12510fbf3537Syasuoka 			continue;
12520fbf3537Syasuoka 		}
12530fbf3537Syasuoka 		switch (avp->attr_type) {
12540fbf3537Syasuoka 		case L2TP_AVP_TYPE_MESSAGE_TYPE:
12550fbf3537Syasuoka 			AVP_SIZE_CHECK(avp, ==, 8);
12560fbf3537Syasuoka 			continue;
12570fbf3537Syasuoka 		case L2TP_AVP_TYPE_PROTOCOL_VERSION:
12580fbf3537Syasuoka 			AVP_SIZE_CHECK(avp, ==, 8);
12590fbf3537Syasuoka 			protover = avp->attr_value[0];
12600fbf3537Syasuoka 			protorev = avp->attr_value[1];
12610fbf3537Syasuoka 
12620fbf3537Syasuoka 			if (protover != L2TP_RFC2661_VERSION ||
12630fbf3537Syasuoka 			    protorev != L2TP_RFC2661_REVISION) {
12640fbf3537Syasuoka 				result = L2TP_STOP_CCN_RCODE_GENERAL_ERROR;
12650fbf3537Syasuoka 				snprintf(emes, sizeof(emes),
12660fbf3537Syasuoka 				    "Peer's protocol version is not supported:"
12670fbf3537Syasuoka 				    " %d.%d", protover, protorev);
12680fbf3537Syasuoka 				goto not_acceptable;
12690fbf3537Syasuoka 			}
12700fbf3537Syasuoka 			continue;
12710fbf3537Syasuoka 		case L2TP_AVP_TYPE_FRAMING_CAPABILITIES:
12720fbf3537Syasuoka 			AVP_SIZE_CHECK(avp, ==, 10);
12730fbf3537Syasuoka 			if ((avp_get_val32(avp) & L2TP_FRAMING_CAP_FLAGS_SYNC)
12740fbf3537Syasuoka 			    == 0) {
12750fbf3537Syasuoka 				L2TP_CTRL_DBG((_this, LOG_DEBUG, "Peer doesn't "
12760fbf3537Syasuoka 				    "support synchronous framing"));
12770fbf3537Syasuoka 			}
12780fbf3537Syasuoka 			continue;
12790fbf3537Syasuoka 		case L2TP_AVP_TYPE_BEARER_CAPABILITIES:
12800fbf3537Syasuoka 			AVP_SIZE_CHECK(avp, ==, 10);
12810fbf3537Syasuoka 			continue;
12820fbf3537Syasuoka 		case L2TP_AVP_TYPE_TIE_BREAKER:
12830fbf3537Syasuoka 			AVP_SIZE_CHECK(avp, ==, 14);
12840fbf3537Syasuoka 			/*
1285f0a4e295Syasuoka 			 * As the implementation never send SCCRQ,
1286f0a4e295Syasuoka 			 * the peer is always winner
12870fbf3537Syasuoka 			 */
12880fbf3537Syasuoka 			continue;
12890fbf3537Syasuoka 		case L2TP_AVP_TYPE_FIRMWARE_REVISION:
12900fbf3537Syasuoka 			AVP_SIZE_CHECK(avp, >=, 6);
12910fbf3537Syasuoka 			firmrev = avp_get_val16(avp);
12920fbf3537Syasuoka 			continue;
12930fbf3537Syasuoka 		case L2TP_AVP_TYPE_HOST_NAME:
12940fbf3537Syasuoka 			AVP_SIZE_CHECK(avp, >, 4);
12950fbf3537Syasuoka 			len = MIN(sizeof(hostname) - 1, avp->length - 6);
12960fbf3537Syasuoka 			memcpy(hostname, avp->attr_value, len);
12970fbf3537Syasuoka 			hostname[len] = '\0';
12980fbf3537Syasuoka 			continue;
12990fbf3537Syasuoka 		case L2TP_AVP_TYPE_VENDOR_NAME:
13000fbf3537Syasuoka 			AVP_SIZE_CHECK(avp, >, 4);
13010fbf3537Syasuoka 			len = MIN(sizeof(vendorname) - 1, avp->length - 6);
13020fbf3537Syasuoka 			memcpy(vendorname, avp->attr_value, len);
13030fbf3537Syasuoka 			vendorname[len] = '\0';
13040fbf3537Syasuoka 			continue;
13050fbf3537Syasuoka 		case L2TP_AVP_TYPE_ASSINGED_TUNNEL_ID:
13060fbf3537Syasuoka 			AVP_SIZE_CHECK(avp, ==, 8);
13070fbf3537Syasuoka 			_this->peer_tunnel_id = avp_get_val16(avp);
13080fbf3537Syasuoka 			continue;
13090fbf3537Syasuoka 		case L2TP_AVP_TYPE_RECV_WINDOW_SIZE:
13100fbf3537Syasuoka 			AVP_SIZE_CHECK(avp, ==, 8);
13110fbf3537Syasuoka 			_this->peer_winsz = avp_get_val16(avp);
13120fbf3537Syasuoka 			continue;
13130fbf3537Syasuoka 		}
13140fbf3537Syasuoka 		if (avp->is_mandatory) {
13150fbf3537Syasuoka 			l2tp_ctrl_log(_this, LOG_WARNING,
13160fbf3537Syasuoka 			    "Received AVP (%s/%d) is not supported, but it's "
13170fbf3537Syasuoka 			    "mandatory", avp_attr_type_string(avp->attr_type),
13180fbf3537Syasuoka 			    avp->attr_type);
13190fbf3537Syasuoka #ifdef L2TP_CTRL_DEBUG
13200fbf3537Syasuoka 		} else {
13210fbf3537Syasuoka 			L2TP_CTRL_DBG((_this, LOG_DEBUG,
13220fbf3537Syasuoka 			    "AVP (%s/%d) is not handled",
13230fbf3537Syasuoka 			    avp_attr_type_string(avp->attr_type),
13240fbf3537Syasuoka 			    avp->attr_type));
13250fbf3537Syasuoka #endif
13260fbf3537Syasuoka 		}
13270fbf3537Syasuoka 	}
13280fbf3537Syasuoka 	if (getnameinfo((struct sockaddr *)&_this->peer, _this->peer.ss_len,
13290fbf3537Syasuoka 	    host, sizeof(host), serv, sizeof(serv),
13300fbf3537Syasuoka 	    NI_NUMERICHOST | NI_NUMERICSERV | NI_DGRAM) != 0) {
13310fbf3537Syasuoka 		l2tp_ctrl_log(_this, LOG_ERR,
13320fbf3537Syasuoka 		    "getnameinfo() failed at %s(): %m", __func__);
13330fbf3537Syasuoka 		strlcpy(host, "error", sizeof(host));
13340fbf3537Syasuoka 		strlcpy(serv, "error", sizeof(serv));
13350fbf3537Syasuoka 	}
13360fbf3537Syasuoka 	l2tp_ctrl_log(_this, LOG_NOTICE, "logtype=Started RecvSCCRQ "
13370fbf3537Syasuoka 	    "from=%s:%s/udp tunnel_id=%u/%u protocol=%d.%d winsize=%d "
13380fbf3537Syasuoka 	    "hostname=%s vendor=%s firm=%04X", host, serv, _this->tunnel_id,
13390fbf3537Syasuoka 	    _this->peer_tunnel_id, protover, protorev, _this->peer_winsz,
13400fbf3537Syasuoka 	    hostname, vendorname, firmrev);
13410fbf3537Syasuoka 
13420fbf3537Syasuoka 	return 0;
13430fbf3537Syasuoka not_acceptable:
13440fbf3537Syasuoka size_check_failed:
13450fbf3537Syasuoka 	l2tp_ctrl_log(_this, LOG_ERR, "Received bad SCCRQ: %s", emes);
13460fbf3537Syasuoka 	l2tp_ctrl_stop(_this, result);
13470fbf3537Syasuoka 
13480fbf3537Syasuoka 	return 1;
13490fbf3537Syasuoka }
13500fbf3537Syasuoka 
1351f0a4e295Syasuoka /*
1352f0a4e295Syasuoka  * send StopCCN
13530fbf3537Syasuoka  */
13540fbf3537Syasuoka static int
13550fbf3537Syasuoka l2tp_ctrl_send_StopCCN(l2tp_ctrl *_this, int result)
13560fbf3537Syasuoka {
13570fbf3537Syasuoka 	struct l2tp_avp *avp;
13580fbf3537Syasuoka 	char buf[L2TP_AVP_MAXSIZ];
13590fbf3537Syasuoka 	bytebuffer *bytebuf;
13600fbf3537Syasuoka 
13610fbf3537Syasuoka 	if ((bytebuf = l2tp_ctrl_prepare_snd_buffer(_this, 1)) == NULL) {
13620fbf3537Syasuoka 		l2tp_ctrl_log(_this, LOG_ERR,
13630fbf3537Syasuoka 		    "sending StopCCN failed: no buffer.");
13640fbf3537Syasuoka 		return -1;
13650fbf3537Syasuoka 	}
13660fbf3537Syasuoka 	avp = (struct l2tp_avp *)buf;
13670fbf3537Syasuoka 
13680fbf3537Syasuoka 	/* Message Type = StopCCN */
13690fbf3537Syasuoka 	memset(avp, 0, sizeof(*avp));
13700fbf3537Syasuoka 	avp->is_mandatory = 1;
13710fbf3537Syasuoka 	avp->attr_type = L2TP_AVP_TYPE_MESSAGE_TYPE;
13720fbf3537Syasuoka 	avp_set_val16(avp, L2TP_AVP_MESSAGE_TYPE_StopCCN);
13730fbf3537Syasuoka 	bytebuf_add_avp(bytebuf, avp, 2);
13740fbf3537Syasuoka 
13750fbf3537Syasuoka 	/* Assigned Tunnel Id */
13760fbf3537Syasuoka 	memset(avp, 0, sizeof(*avp));
13770fbf3537Syasuoka 	avp->is_mandatory = 1;
13780fbf3537Syasuoka 	avp->attr_type = L2TP_AVP_TYPE_ASSINGED_TUNNEL_ID;
13790fbf3537Syasuoka 	avp_set_val16(avp, _this->tunnel_id);
13800fbf3537Syasuoka 	bytebuf_add_avp(bytebuf, avp, 2);
13810fbf3537Syasuoka 
13820fbf3537Syasuoka 	/* Result Code */
13830fbf3537Syasuoka 	memset(avp, 0, sizeof(*avp));
13840fbf3537Syasuoka 	avp->is_mandatory = 1;
13850fbf3537Syasuoka 	avp->attr_type = L2TP_AVP_TYPE_RESULT_CODE;
13860fbf3537Syasuoka 	avp_set_val16(avp, result);
13870fbf3537Syasuoka 	bytebuf_add_avp(bytebuf, avp, 2);
13880fbf3537Syasuoka 
13899a200ddfSyasuoka 	if (l2tp_ctrl_send_packet(_this, 0, bytebuf) != 0) {
13909a200ddfSyasuoka 		l2tp_ctrl_log(_this, LOG_ERR, "sending StopCCN failed");
13910fbf3537Syasuoka 		return - 1;
13920fbf3537Syasuoka 	}
13930fbf3537Syasuoka 	l2tp_ctrl_log(_this, LOG_INFO, "SendStopCCN result=%d", result);
13940fbf3537Syasuoka 
13950fbf3537Syasuoka 	return 0;
13960fbf3537Syasuoka }
13970fbf3537Syasuoka 
1398f0a4e295Syasuoka /*
1399f0a4e295Syasuoka  * Receiver StopCCN
14000fbf3537Syasuoka  */
14010fbf3537Syasuoka static int
14020fbf3537Syasuoka l2tp_ctrl_recv_StopCCN(l2tp_ctrl *_this, u_char *pkt, int pktlen)
14030fbf3537Syasuoka {
1404*b01648a9Syasuoka 	int result, error, avpsz, len;
1405*b01648a9Syasuoka 	uint16_t tunid;
14060fbf3537Syasuoka 	struct l2tp_avp *avp;
1407*b01648a9Syasuoka 	char buf[L2TP_AVP_MAXSIZ + 16], emes[256], pmes[256];
14080fbf3537Syasuoka 
1409*b01648a9Syasuoka 	result = 0;
1410*b01648a9Syasuoka 	error = 0;
14110fbf3537Syasuoka 	tunid = 0;
1412*b01648a9Syasuoka 	pmes[0] = '\0';
14130fbf3537Syasuoka 	avp = (struct l2tp_avp *)buf;
14140fbf3537Syasuoka 	while (pktlen >= 6 && (avpsz = avp_enum(avp, pkt, pktlen, 1)) > 0) {
14150fbf3537Syasuoka 		pkt += avpsz;
14160fbf3537Syasuoka 		pktlen -= avpsz;
14170fbf3537Syasuoka 		if (avp->vendor_id != 0) {
14180fbf3537Syasuoka 			L2TP_CTRL_DBG((_this, LOG_DEBUG,
14190fbf3537Syasuoka 			    "Received a Vendor-specific AVP vendor-id=%d "
14200fbf3537Syasuoka 			    "type=%d", avp->vendor_id, avp->attr_type));
14210fbf3537Syasuoka 			continue;
14220fbf3537Syasuoka 		}
14230fbf3537Syasuoka 		if (avp->is_hidden != 0) {
14240fbf3537Syasuoka 			l2tp_ctrl_log(_this, LOG_WARNING,
14250fbf3537Syasuoka 			    "Received AVP (%s/%d) is hidden.  But we don't "
14260fbf3537Syasuoka 			    "share secret.",
14270fbf3537Syasuoka 			    avp_attr_type_string(avp->attr_type),
14280fbf3537Syasuoka 			    avp->attr_type);
14290fbf3537Syasuoka 			if (avp->is_mandatory != 0) {
14300fbf3537Syasuoka 				l2tp_ctrl_stop(_this,
14310fbf3537Syasuoka 				    L2TP_STOP_CCN_RCODE_GENERAL_ERROR |
14320fbf3537Syasuoka 				    L2TP_ECODE_UNKNOWN_MANDATORY_AVP);
14330fbf3537Syasuoka 				return 1;
14340fbf3537Syasuoka 			}
14350fbf3537Syasuoka 			continue;
14360fbf3537Syasuoka 		}
14370fbf3537Syasuoka 		switch (avp->attr_type) {
14380fbf3537Syasuoka 		case L2TP_AVP_TYPE_MESSAGE_TYPE:
14390fbf3537Syasuoka 			AVP_SIZE_CHECK(avp, ==, 8);
14400fbf3537Syasuoka 			continue;
14410fbf3537Syasuoka 		case L2TP_AVP_TYPE_RESULT_CODE:
1442*b01648a9Syasuoka 			AVP_SIZE_CHECK(avp, >=, 8);
1443*b01648a9Syasuoka 			result = avp->attr_value[0] << 8 | avp->attr_value[1];
1444*b01648a9Syasuoka 			if (avp->length >= 10) {
1445*b01648a9Syasuoka 				error = avp->attr_value[2] << 8 |
1446*b01648a9Syasuoka 				    avp->attr_value[3];
1447*b01648a9Syasuoka 				len = avp->length - 12;
1448*b01648a9Syasuoka 				if (len > 0) {
1449*b01648a9Syasuoka 					len = MIN(len, sizeof(pmes) - 1);
1450*b01648a9Syasuoka 					memcpy(pmes, &avp->attr_value[4], len);
1451*b01648a9Syasuoka 					pmes[len] = '\0';
1452*b01648a9Syasuoka 				}
14530fbf3537Syasuoka 			}
14540fbf3537Syasuoka 			continue;
14550fbf3537Syasuoka 		case L2TP_AVP_TYPE_ASSINGED_TUNNEL_ID:
14560fbf3537Syasuoka 			AVP_SIZE_CHECK(avp, ==, 8);
14570fbf3537Syasuoka 			tunid = avp_get_val16(avp);
14580fbf3537Syasuoka 			continue;
14590fbf3537Syasuoka 		default:
14600fbf3537Syasuoka 			if (avp->is_mandatory != 0) {
14610fbf3537Syasuoka 				l2tp_ctrl_log(_this, LOG_WARNING,
14620fbf3537Syasuoka 				    "Received AVP (%s/%d) is not supported, "
14630fbf3537Syasuoka 				    "but it's mandatory",
14640fbf3537Syasuoka 				    avp_attr_type_string(avp->attr_type),
14650fbf3537Syasuoka 				    avp->attr_type);
14660fbf3537Syasuoka #ifdef L2TP_CTRL_DEBUG
14670fbf3537Syasuoka 			} else {
14680fbf3537Syasuoka 				L2TP_CTRL_DBG((_this, LOG_DEBUG,
14690fbf3537Syasuoka 				    "AVP (%s/%d) is not handled",
14700fbf3537Syasuoka 				    avp_attr_type_string(avp->attr_type),
14710fbf3537Syasuoka 				    avp->attr_type));
14720fbf3537Syasuoka #endif
14730fbf3537Syasuoka 			}
14740fbf3537Syasuoka 		}
14750fbf3537Syasuoka 	}
14760fbf3537Syasuoka 
1477*b01648a9Syasuoka 	if (result == L2TP_CDN_RCODE_ERROR_CODE &&
1478*b01648a9Syasuoka 	    error == L2TP_ECODE_NO_RESOURCE) {
14790fbf3537Syasuoka 		/*
1480f0a4e295Syasuoka 		 * Memo:
1481f0a4e295Syasuoka 		 * This state may be happen in following state.
1482f0a4e295Syasuoka 		 * - lots of connect/disconect by long-running
1483f0a4e295Syasuoka 		 *   windows2000, sometimes it fall to this state.
1484f0a4e295Syasuoka 		 *   Once it fall to here, connection will fail till
1485f0a4e295Syasuoka 		 *   the windows rebooted
14860fbf3537Syasuoka 		 */
14870fbf3537Syasuoka 		l2tp_ctrl_log(_this, LOG_WARNING,
14880fbf3537Syasuoka 		    "Peer indicates \"No Resource\" error.");
14890fbf3537Syasuoka 	}
14900fbf3537Syasuoka 
14910fbf3537Syasuoka 	l2tp_ctrl_log(_this, LOG_INFO, "RecvStopCCN result=%s/%u "
14920fbf3537Syasuoka 	    "error=%s/%u tunnel_id=%u message=\"%s\"",
1493*b01648a9Syasuoka 	    l2tp_stopccn_rcode_string(result), result,
1494*b01648a9Syasuoka 	    l2tp_ecode_string(error), error, tunid, pmes);
14950fbf3537Syasuoka 
14960fbf3537Syasuoka 	return 0;
14970fbf3537Syasuoka 
14980fbf3537Syasuoka size_check_failed:
14990fbf3537Syasuoka 	l2tp_ctrl_log(_this, LOG_ERR, "Received bad StopCCN: %s", emes);
15000fbf3537Syasuoka 
15010fbf3537Syasuoka 	return -1;
15020fbf3537Syasuoka }
15030fbf3537Syasuoka 
1504f0a4e295Syasuoka /*
1505f0a4e295Syasuoka  * send SCCRP
15060fbf3537Syasuoka  */
15070fbf3537Syasuoka static void
15080fbf3537Syasuoka l2tp_ctrl_send_SCCRP(l2tp_ctrl *_this)
15090fbf3537Syasuoka {
15100fbf3537Syasuoka 	int len;
15110fbf3537Syasuoka 	struct l2tp_avp *avp;
15120fbf3537Syasuoka 	char buf[L2TP_AVP_MAXSIZ];
15130fbf3537Syasuoka 	const char *val;
15140fbf3537Syasuoka 	bytebuffer *bytebuf;
15150fbf3537Syasuoka 
15160fbf3537Syasuoka 	if ((bytebuf = l2tp_ctrl_prepare_snd_buffer(_this, 1)) == NULL) {
15170fbf3537Syasuoka 		l2tp_ctrl_log(_this, LOG_ERR,
15180fbf3537Syasuoka 		    "sending SCCRP failed: no buffer.");
15190fbf3537Syasuoka 		return;
15200fbf3537Syasuoka 	}
15210fbf3537Syasuoka 	avp = (struct l2tp_avp *)buf;
15220fbf3537Syasuoka 
15230fbf3537Syasuoka 	/* Message Type = SCCRP */
15240fbf3537Syasuoka 	memset(avp, 0, sizeof(*avp));
15250fbf3537Syasuoka 	avp->is_mandatory = 1;
15260fbf3537Syasuoka 	avp->attr_type = L2TP_AVP_TYPE_MESSAGE_TYPE;
15270fbf3537Syasuoka 	avp_set_val16(avp, L2TP_AVP_MESSAGE_TYPE_SCCRP);
15280fbf3537Syasuoka 	bytebuf_add_avp(bytebuf, avp, 2);
15290fbf3537Syasuoka 
15300fbf3537Syasuoka 	/* Protocol Version = 1.0 */
15310fbf3537Syasuoka 	memset(avp, 0, sizeof(*avp));
15320fbf3537Syasuoka 	avp->is_mandatory = 1;
15330fbf3537Syasuoka 	avp->attr_type = L2TP_AVP_TYPE_PROTOCOL_VERSION;
15340fbf3537Syasuoka 	avp->attr_value[0] = L2TP_RFC2661_VERSION;
15350fbf3537Syasuoka 	avp->attr_value[1] = L2TP_RFC2661_REVISION;
15360fbf3537Syasuoka 	bytebuf_add_avp(bytebuf, avp, 2);
15370fbf3537Syasuoka 
15380fbf3537Syasuoka 	/* Framing Capability = Async */
15390fbf3537Syasuoka 	memset(avp, 0, sizeof(*avp));
15400fbf3537Syasuoka 	avp->is_mandatory = 1;
15410fbf3537Syasuoka 	avp->attr_type = L2TP_AVP_TYPE_FRAMING_CAPABILITIES;
15420fbf3537Syasuoka 	avp_set_val32(avp, L2TP_FRAMING_CAP_FLAGS_SYNC);
15430fbf3537Syasuoka 	bytebuf_add_avp(bytebuf, avp, 4);
15440fbf3537Syasuoka 
15450fbf3537Syasuoka 	/* Host Name */
15460fbf3537Syasuoka 	memset(avp, 0, sizeof(*avp));
15470fbf3537Syasuoka 	avp->is_mandatory = 1;
15480fbf3537Syasuoka 	avp->attr_type = L2TP_AVP_TYPE_HOST_NAME;
15490fbf3537Syasuoka 
15500fbf3537Syasuoka 	if ((val = l2tp_ctrl_config_str(_this, "l2tp.host_name")) == NULL)
15510fbf3537Syasuoka 		val = _this->l2tpd->default_hostname;
15520fbf3537Syasuoka 	if (val[0] == '\0')
1553f0a4e295Syasuoka 		val = "G";	/* XXX magic word, why? ask yasuoka */
15540fbf3537Syasuoka 	len = strlen(val);
15550fbf3537Syasuoka 	memcpy(avp->attr_value, val, len);
15560fbf3537Syasuoka 	bytebuf_add_avp(bytebuf, avp, len);
15570fbf3537Syasuoka 
15580fbf3537Syasuoka 	/* Assigned Tunnel Id */
15590fbf3537Syasuoka 	memset(avp, 0, sizeof(*avp));
15600fbf3537Syasuoka 	avp->is_mandatory = 1;
15610fbf3537Syasuoka 	avp->attr_type = L2TP_AVP_TYPE_ASSINGED_TUNNEL_ID;
15620fbf3537Syasuoka 	avp_set_val16(avp, _this->tunnel_id);
15630fbf3537Syasuoka 	bytebuf_add_avp(bytebuf, avp, 2);
15640fbf3537Syasuoka 
15650fbf3537Syasuoka 	/* Bearer Capability
1566f0a4e295Syasuoka 	 * This implementation never act as LAC.
15670fbf3537Syasuoka 	 *
15680fbf3537Syasuoka 	memset(avp, 0, sizeof(*avp));
15690fbf3537Syasuoka 	avp->is_mandatory = 1;
15700fbf3537Syasuoka 	avp->attr_type = L2TP_AVP_TYPE_BEARER_CAPABILITIES;
15710fbf3537Syasuoka 	avp_set_val32(avp, 0);
15720fbf3537Syasuoka 	bytebuf_add_avp(bytebuf, avp, 4);
15730fbf3537Syasuoka 	 */
15740fbf3537Syasuoka 
15750fbf3537Syasuoka 	/* Firmware Revision */
15760fbf3537Syasuoka 	memset(avp, 0, sizeof(*avp));
15770fbf3537Syasuoka 	avp->is_mandatory = 1;
15780fbf3537Syasuoka 	avp->attr_type = L2TP_AVP_TYPE_FIRMWARE_REVISION;
15790fbf3537Syasuoka 	avp->attr_value[0] = MAJOR_VERSION;
15800fbf3537Syasuoka 	avp->attr_value[1] = MINOR_VERSION;
15810fbf3537Syasuoka 	bytebuf_add_avp(bytebuf, avp, 2);
15820fbf3537Syasuoka 
15830fbf3537Syasuoka 	/* Host Name */
15840fbf3537Syasuoka 	memset(avp, 0, sizeof(*avp));
15850fbf3537Syasuoka 	avp->is_mandatory = 1;
15860fbf3537Syasuoka 	avp->attr_type = L2TP_AVP_TYPE_VENDOR_NAME;
15870fbf3537Syasuoka 
15880fbf3537Syasuoka 	if ((val = l2tp_ctrl_config_str(_this, "l2tp.vendor_name")) == NULL)
15890fbf3537Syasuoka 		val =  L2TPD_VENDOR_NAME;
15900fbf3537Syasuoka 
15910fbf3537Syasuoka 	len = strlen(val);
15920fbf3537Syasuoka 	memcpy(avp->attr_value, val, len);
15930fbf3537Syasuoka 	bytebuf_add_avp(bytebuf, avp, len);
15940fbf3537Syasuoka 
15950fbf3537Syasuoka 	/* Window Size */
15960fbf3537Syasuoka 	memset(avp, 0, sizeof(*avp));
15970fbf3537Syasuoka 	avp->is_mandatory = 1;
15980fbf3537Syasuoka 	avp->attr_type = L2TP_AVP_TYPE_RECV_WINDOW_SIZE;
15990fbf3537Syasuoka 	avp_set_val16(avp, _this->winsz);
16000fbf3537Syasuoka 	bytebuf_add_avp(bytebuf, avp, 2);
16010fbf3537Syasuoka 
16029a200ddfSyasuoka 	if ((l2tp_ctrl_send_packet(_this, 0, bytebuf)) != 0) {
16030fbf3537Syasuoka 		l2tp_ctrl_log(_this, LOG_ERR, "sending SCCRP failed");
16040fbf3537Syasuoka 		l2tp_ctrl_stop(_this, L2TP_STOP_CCN_RCODE_GENERAL);
16050fbf3537Syasuoka 		return;
16060fbf3537Syasuoka 	}
16070fbf3537Syasuoka 	l2tp_ctrl_log(_this, LOG_INFO, "SendSCCRP");
16080fbf3537Syasuoka }
16090fbf3537Syasuoka 
16100fbf3537Syasuoka static int
16110fbf3537Syasuoka l2tp_ctrl_send_HELLO(l2tp_ctrl *_this)
16120fbf3537Syasuoka {
16130fbf3537Syasuoka 	struct l2tp_avp *avp;
16140fbf3537Syasuoka 	char buf[L2TP_AVP_MAXSIZ];
16150fbf3537Syasuoka 	bytebuffer *bytebuf;
16160fbf3537Syasuoka 
16170fbf3537Syasuoka 	if ((bytebuf = l2tp_ctrl_prepare_snd_buffer(_this, 1)) == NULL) {
16180fbf3537Syasuoka 		l2tp_ctrl_log(_this, LOG_ERR,
16190fbf3537Syasuoka 		    "sending SCCRP failed: no buffer.");
16200fbf3537Syasuoka 		return 1;
16210fbf3537Syasuoka 	}
16220fbf3537Syasuoka 	avp = (struct l2tp_avp *)buf;
16230fbf3537Syasuoka 
16240fbf3537Syasuoka 	/* Message Type = HELLO */
16250fbf3537Syasuoka 	memset(avp, 0, sizeof(*avp));
16260fbf3537Syasuoka 	avp->is_mandatory = 1;
16270fbf3537Syasuoka 	avp->attr_type = L2TP_AVP_TYPE_MESSAGE_TYPE;
16280fbf3537Syasuoka 	avp_set_val16(avp, L2TP_AVP_MESSAGE_TYPE_HELLO);
16290fbf3537Syasuoka 	bytebuf_add_avp(bytebuf, avp, 2);
16300fbf3537Syasuoka 
16319a200ddfSyasuoka 	if ((l2tp_ctrl_send_packet(_this, 0, bytebuf)) != 0) {
16320fbf3537Syasuoka 		l2tp_ctrl_log(_this, LOG_ERR, "sending HELLO failed");
16330fbf3537Syasuoka 		l2tp_ctrl_stop(_this, L2TP_STOP_CCN_RCODE_GENERAL);
16340fbf3537Syasuoka 		return 1;
16350fbf3537Syasuoka 	}
16360fbf3537Syasuoka 	l2tp_ctrl_log(_this, LOG_DEBUG, "SendHELLO");
16370fbf3537Syasuoka 
16380fbf3537Syasuoka 	return 0;
16390fbf3537Syasuoka }
16400fbf3537Syasuoka 
1641f0a4e295Syasuoka /* Send  ZLB */
16420fbf3537Syasuoka static int
16430fbf3537Syasuoka l2tp_ctrl_send_ZLB(l2tp_ctrl *_this)
16440fbf3537Syasuoka {
16450fbf3537Syasuoka 	int loglevel;
16460fbf3537Syasuoka 
16470fbf3537Syasuoka 	loglevel = (_this->state == L2TP_CTRL_STATE_ESTABLISHED)
16480fbf3537Syasuoka 	    ? LOG_DEBUG : LOG_INFO;
16490fbf3537Syasuoka 	l2tp_ctrl_log(_this, loglevel, "SendZLB");
16500fbf3537Syasuoka 	bytebuffer_clear(_this->zlb_buffer);
16510fbf3537Syasuoka 	bytebuffer_put(_this->zlb_buffer, BYTEBUFFER_PUT_DIRECT,
16520fbf3537Syasuoka 	    sizeof(struct l2tp_header));
16530fbf3537Syasuoka 
16549a200ddfSyasuoka 	return l2tp_ctrl_send_packet(_this, 0, _this->zlb_buffer);
16550fbf3537Syasuoka }
16560fbf3537Syasuoka 
1657f0a4e295Syasuoka /*
1658f0a4e295Syasuoka  * Utitlity
1659f0a4e295Syasuoka  */
1660f0a4e295Syasuoka 
16610fbf3537Syasuoka /**
1662f0a4e295Syasuoka  * Prepare send buffer
1663f0a4e295Syasuoka  * @return return Null when the send buffer exceed Window.
16640fbf3537Syasuoka  */
16650fbf3537Syasuoka bytebuffer *
16660fbf3537Syasuoka l2tp_ctrl_prepare_snd_buffer(l2tp_ctrl *_this, int with_seq)
16670fbf3537Syasuoka {
16680fbf3537Syasuoka 	bytebuffer *bytebuf;
16690fbf3537Syasuoka 
16700fbf3537Syasuoka 	L2TP_CTRL_ASSERT(_this != NULL);
16710fbf3537Syasuoka 
16720fbf3537Syasuoka 	if (l2tp_ctrl_txwin_is_full(_this)) {
16730fbf3537Syasuoka 		l2tp_ctrl_log(_this, LOG_INFO, "sending buffer is full.");
16740fbf3537Syasuoka 		return NULL;
16750fbf3537Syasuoka 	}
16760fbf3537Syasuoka 	bytebuf = _this->snd_buffers[_this->snd_nxt % _this->winsz];
16770fbf3537Syasuoka 	bytebuffer_clear(bytebuf);
16780fbf3537Syasuoka 	if (with_seq)
16790fbf3537Syasuoka 		bytebuffer_put(bytebuf, BYTEBUFFER_PUT_DIRECT,
16800fbf3537Syasuoka 		    sizeof(struct l2tp_header));
16810fbf3537Syasuoka 	else
16820fbf3537Syasuoka 		bytebuffer_put(bytebuf, BYTEBUFFER_PUT_DIRECT,
16830fbf3537Syasuoka 		    offsetof(struct l2tp_header, ns));
16840fbf3537Syasuoka 
16850fbf3537Syasuoka 	return bytebuf;
16860fbf3537Syasuoka }
16870fbf3537Syasuoka 
16880fbf3537Syasuoka /**
1689f0a4e295Syasuoka  * return current state as strings
16900fbf3537Syasuoka  */
16910fbf3537Syasuoka static inline const char *
16920fbf3537Syasuoka l2tp_ctrl_state_string(l2tp_ctrl *_this)
16930fbf3537Syasuoka {
16940fbf3537Syasuoka 	switch (_this->state) {
16950fbf3537Syasuoka 	case L2TP_CTRL_STATE_IDLE:		return "idle";
16960fbf3537Syasuoka 	case L2TP_CTRL_STATE_WAIT_CTL_CONN:	return "wait-ctl-conn";
16970fbf3537Syasuoka 	case L2TP_CTRL_STATE_WAIT_CTL_REPLY:	return "wait-ctl-reply";
16980fbf3537Syasuoka 	case L2TP_CTRL_STATE_ESTABLISHED:	return "established";
16990fbf3537Syasuoka 	case L2TP_CTRL_STATE_CLEANUP_WAIT:	return "cleanup-wait";
17000fbf3537Syasuoka 	}
17010fbf3537Syasuoka 	return "unknown";
17020fbf3537Syasuoka }
17030fbf3537Syasuoka 
1704f0a4e295Syasuoka /* logging with the label of the l2tp instance. */
17050fbf3537Syasuoka void
17060fbf3537Syasuoka l2tp_ctrl_log(l2tp_ctrl *_this, int prio, const char *fmt, ...)
17070fbf3537Syasuoka {
17080fbf3537Syasuoka 	char logbuf[BUFSIZ];
17090fbf3537Syasuoka 	va_list ap;
17100fbf3537Syasuoka 
17110fbf3537Syasuoka 	va_start(ap, fmt);
17127a7bab9dSyasuoka #ifdef	L2TPD_MULTIPLE
17130fbf3537Syasuoka 	snprintf(logbuf, sizeof(logbuf), "l2tpd id=%u ctrl=%u %s",
17140fbf3537Syasuoka 	    _this->l2tpd->id, _this->id, fmt);
17150fbf3537Syasuoka #else
17160fbf3537Syasuoka 	snprintf(logbuf, sizeof(logbuf), "l2tpd ctrl=%u %s", _this->id, fmt);
17170fbf3537Syasuoka #endif
17180fbf3537Syasuoka 	vlog_printf(prio, logbuf, ap);
17190fbf3537Syasuoka 	va_end(ap);
17200fbf3537Syasuoka }
1721