1*4781c8ecSyasuoka /* $OpenBSD: l2tp_ctrl.c,v 1.20 2015/06/24 05:20:16 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*4781c8ecSyasuoka /* $Id: l2tp_ctrl.c,v 1.20 2015/06/24 05:20:16 yasuoka Exp $ */ 300fbf3537Syasuoka #include <sys/types.h> 310fbf3537Syasuoka #include <sys/time.h> 320fbf3537Syasuoka #include <sys/socket.h> 330fbf3537Syasuoka #include <netinet/in.h> 340fbf3537Syasuoka #include <net/if.h> 350fbf3537Syasuoka #include <arpa/inet.h> 36be9b7050Sguenther #include <endian.h> 379a200ddfSyasuoka #include <errno.h> 380fbf3537Syasuoka #include <event.h> 390fbf3537Syasuoka #include <ifaddrs.h> 409a200ddfSyasuoka #include <netdb.h> 419a200ddfSyasuoka #include <stdarg.h> 429a200ddfSyasuoka #include <stddef.h> 439a200ddfSyasuoka #include <stdio.h> 449a200ddfSyasuoka #include <stdlib.h> 459a200ddfSyasuoka #include <string.h> 469a200ddfSyasuoka #include <syslog.h> 479a200ddfSyasuoka #include <time.h> 48dd8fd9c3Syasuoka #include <unistd.h> 49dbad4650Sderaadt #include <limits.h> 500fbf3537Syasuoka 510fbf3537Syasuoka #ifdef USE_LIBSOCKUTIL 520fbf3537Syasuoka #include <seil/sockfromto.h> 530fbf3537Syasuoka #endif 540fbf3537Syasuoka 550fbf3537Syasuoka #include "time_utils.h" 560fbf3537Syasuoka #include "ipsec_util.h" 570fbf3537Syasuoka #include "bytebuf.h" 580fbf3537Syasuoka #include "hash.h" 590fbf3537Syasuoka #include "debugutil.h" 600fbf3537Syasuoka #include "slist.h" 610fbf3537Syasuoka #include "l2tp.h" 620fbf3537Syasuoka #include "l2tp_local.h" 630fbf3537Syasuoka #include "l2tp_subr.h" 640fbf3537Syasuoka #include "net_utils.h" 650fbf3537Syasuoka #include "version.h" 6659b96086Syasuoka #include "recvfromto.h" 670fbf3537Syasuoka 68dbad4650Sderaadt #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) 69dbad4650Sderaadt 700fbf3537Syasuoka static int l2tp_ctrl_init (l2tp_ctrl *, l2tpd *, struct sockaddr *, struct sockaddr *, void *); 710fbf3537Syasuoka static void l2tp_ctrl_reload (l2tp_ctrl *); 720fbf3537Syasuoka static int l2tp_ctrl_send_disconnect_notify (l2tp_ctrl *); 730fbf3537Syasuoka #if 0 740fbf3537Syasuoka static void l2tp_ctrl_purge_ipsec_sa (l2tp_ctrl *); 750fbf3537Syasuoka #endif 760fbf3537Syasuoka static void l2tp_ctrl_timeout (int, short, void *); 770fbf3537Syasuoka static int l2tp_ctrl_resend_una_packets (l2tp_ctrl *); 780fbf3537Syasuoka static void l2tp_ctrl_destroy_all_calls (l2tp_ctrl *); 79*4781c8ecSyasuoka static int l2tp_ctrl_disconnect_all_calls (l2tp_ctrl *, int); 800fbf3537Syasuoka static void l2tp_ctrl_reset_timeout (l2tp_ctrl *); 810fbf3537Syasuoka static inline int l2tp_ctrl_txwin_size (l2tp_ctrl *); 820fbf3537Syasuoka static inline int l2tp_ctrl_txwin_is_full (l2tp_ctrl *); 830fbf3537Syasuoka static int l2tp_ctrl_recv_SCCRQ (l2tp_ctrl *, u_char *, int, l2tpd *, struct sockaddr *); 840fbf3537Syasuoka static int l2tp_ctrl_send_StopCCN (l2tp_ctrl *, int); 850fbf3537Syasuoka static int l2tp_ctrl_recv_StopCCN (l2tp_ctrl *, u_char *, int); 860fbf3537Syasuoka static void l2tp_ctrl_send_SCCRP (l2tp_ctrl *); 870fbf3537Syasuoka static int l2tp_ctrl_send_HELLO (l2tp_ctrl *); 880fbf3537Syasuoka static int l2tp_ctrl_send_ZLB (l2tp_ctrl *); 890fbf3537Syasuoka static inline const char *l2tp_ctrl_state_string (l2tp_ctrl *); 900fbf3537Syasuoka 910fbf3537Syasuoka #ifdef L2TP_CTRL_DEBUG 920fbf3537Syasuoka #define L2TP_CTRL_ASSERT(x) ASSERT(x) 930fbf3537Syasuoka #define L2TP_CTRL_DBG(x) l2tp_ctrl_log x 940fbf3537Syasuoka #else 950fbf3537Syasuoka #define L2TP_CTRL_ASSERT(x) 960fbf3537Syasuoka #define L2TP_CTRL_DBG(x) 970fbf3537Syasuoka #endif 980fbf3537Syasuoka 99f0a4e295Syasuoka /* Sequence # of l2tp_ctrl ID */ 100c46ae403Syasuoka static u_int l2tp_ctrl_id_seq = 0; 1010fbf3537Syasuoka 1020fbf3537Syasuoka #define SEQ_LT(a,b) ((int16_t)((a) - (b)) < 0) 1030fbf3537Syasuoka #define SEQ_GT(a,b) ((int16_t)((a) - (b)) > 0) 1040fbf3537Syasuoka 1050fbf3537Syasuoka /** 106f0a4e295Syasuoka * Build instance of {@link ::_l2tp_ctrl L2TP LNS control connection} 1070fbf3537Syasuoka */ 1080fbf3537Syasuoka l2tp_ctrl * 1090fbf3537Syasuoka l2tp_ctrl_create(void) 1100fbf3537Syasuoka { 1110fbf3537Syasuoka 1129e298f67Stedu return calloc(1, sizeof(l2tp_ctrl)); 1130fbf3537Syasuoka } 1140fbf3537Syasuoka 1150fbf3537Syasuoka /** 116f0a4e295Syasuoka * initialize and startup of {@link ::_l2tp_ctrl L2TP LNS control connection} 117f0a4e295Syasuoka * instance 1180fbf3537Syasuoka */ 1190fbf3537Syasuoka static int 1200fbf3537Syasuoka l2tp_ctrl_init(l2tp_ctrl *_this, l2tpd *_l2tpd, struct sockaddr *peer, 1210fbf3537Syasuoka struct sockaddr *sock, void *nat_t_ctx) 1220fbf3537Syasuoka { 1230fbf3537Syasuoka int tunid, i; 1240fbf3537Syasuoka bytebuffer *bytebuf; 1250fbf3537Syasuoka time_t curr_time; 1260fbf3537Syasuoka 1270fbf3537Syasuoka memset(_this, 0, sizeof(l2tp_ctrl)); 1280fbf3537Syasuoka 1290fbf3537Syasuoka curr_time = get_monosec(); 1300fbf3537Syasuoka _this->l2tpd = _l2tpd; 1310fbf3537Syasuoka _this->state = L2TP_CTRL_STATE_IDLE; 1320fbf3537Syasuoka _this->last_snd_ctrl = curr_time; 1330fbf3537Syasuoka 1340fbf3537Syasuoka slist_init(&_this->call_list); 135f0a4e295Syasuoka 136f0a4e295Syasuoka /* seek a free tunnel ID */ 1370fbf3537Syasuoka i = 0; 1380fbf3537Syasuoka _this->id = ++l2tp_ctrl_id_seq; 1390fbf3537Syasuoka for (i = 0, tunid = _this->id; ; i++, tunid++) { 1400fbf3537Syasuoka tunid &= 0xffff; 1410fbf3537Syasuoka _this->tunnel_id = l2tp_ctrl_id_seq & 0xffff; 1420fbf3537Syasuoka if (tunid == 0) 1430fbf3537Syasuoka continue; 1440fbf3537Syasuoka if (l2tpd_get_ctrl(_l2tpd, tunid) == NULL) 1450fbf3537Syasuoka break; 1460fbf3537Syasuoka if (i > 80000) { 147f0a4e295Syasuoka /* this must be happen, just log it. */ 1480fbf3537Syasuoka l2tpd_log(_l2tpd, LOG_ERR, "Too many l2tp controls"); 1490fbf3537Syasuoka return -1; 1500fbf3537Syasuoka } 1510fbf3537Syasuoka } 1520fbf3537Syasuoka 1530fbf3537Syasuoka _this->tunnel_id = tunid; 1540fbf3537Syasuoka 1550fbf3537Syasuoka L2TP_CTRL_ASSERT(peer != NULL); 1560fbf3537Syasuoka L2TP_CTRL_ASSERT(sock != NULL); 1570fbf3537Syasuoka memcpy(&_this->peer, peer, peer->sa_len); 1580fbf3537Syasuoka memcpy(&_this->sock, sock, sock->sa_len); 1590fbf3537Syasuoka 160f0a4e295Syasuoka /* prepare send buffer */ 1610fbf3537Syasuoka _this->winsz = L2TPD_DEFAULT_SEND_WINSZ; 1620fbf3537Syasuoka if ((_this->snd_buffers = calloc(_this->winsz, sizeof(bytebuffer *))) 1630fbf3537Syasuoka == NULL) { 1640fbf3537Syasuoka l2tpd_log(_l2tpd, LOG_ERR, 1650fbf3537Syasuoka "calloc() failed in %s(): %m", __func__); 166f0a4e295Syasuoka goto fail; 1670fbf3537Syasuoka } 1680fbf3537Syasuoka for (i = 0; i < _this->winsz; i++) { 1690fbf3537Syasuoka if ((bytebuf = bytebuffer_create(L2TPD_SND_BUFSIZ)) == NULL) { 1700fbf3537Syasuoka l2tpd_log(_l2tpd, LOG_ERR, 1710fbf3537Syasuoka "bytebuffer_create() failed in %s(): %m", __func__); 172f0a4e295Syasuoka goto fail; 1730fbf3537Syasuoka } 1740fbf3537Syasuoka _this->snd_buffers[i] = bytebuf; 1750fbf3537Syasuoka } 1760fbf3537Syasuoka if ((_this->zlb_buffer = bytebuffer_create(sizeof(struct l2tp_header) 1770fbf3537Syasuoka + 128)) == NULL) { 1780fbf3537Syasuoka l2tpd_log(_l2tpd, LOG_ERR, 1790fbf3537Syasuoka "bytebuffer_create() failed in %s(): %m", __func__); 180f0a4e295Syasuoka goto fail; 1810fbf3537Syasuoka } 182b56612b6Smarkus #if defined(USE_LIBSOCKUTIL) || defined(USE_SA_COOKIE) 1830fbf3537Syasuoka if (nat_t_ctx != NULL) { 1840fbf3537Syasuoka if ((_this->sa_cookie = malloc( 1850fbf3537Syasuoka sizeof(struct in_ipsec_sa_cookie))) != NULL) { 1860fbf3537Syasuoka *(struct in_ipsec_sa_cookie *)_this->sa_cookie = 1870fbf3537Syasuoka *(struct in_ipsec_sa_cookie *)nat_t_ctx; 1880fbf3537Syasuoka } else { 1890fbf3537Syasuoka l2tpd_log(_l2tpd, LOG_ERR, 1900fbf3537Syasuoka "creating sa_cookie failed: %m"); 191f0a4e295Syasuoka goto fail; 1920fbf3537Syasuoka } 1930fbf3537Syasuoka } 1940fbf3537Syasuoka #endif 1950fbf3537Syasuoka _this->hello_interval = L2TP_CTRL_DEFAULT_HELLO_INTERVAL; 1960fbf3537Syasuoka _this->hello_timeout = L2TP_CTRL_DEFAULT_HELLO_TIMEOUT; 1970fbf3537Syasuoka _this->hello_io_time = curr_time; 1980fbf3537Syasuoka 199f0a4e295Syasuoka /* initialize timeout timer */ 2000fbf3537Syasuoka l2tp_ctrl_reset_timeout(_this); 2010fbf3537Syasuoka 202f0a4e295Syasuoka /* register l2tp context */ 2030fbf3537Syasuoka l2tpd_add_ctrl(_l2tpd, _this); 2040fbf3537Syasuoka return 0; 205f0a4e295Syasuoka fail: 2060fbf3537Syasuoka l2tp_ctrl_stop(_this, 0); 2070fbf3537Syasuoka return -1; 2080fbf3537Syasuoka } 2090fbf3537Syasuoka 210f0a4e295Syasuoka /* 211f0a4e295Syasuoka * setup {@link ::_l2tp_ctrl L2TP LNS control connection} instance 2120fbf3537Syasuoka */ 2130fbf3537Syasuoka static void 2140fbf3537Syasuoka l2tp_ctrl_reload(l2tp_ctrl *_this) 2150fbf3537Syasuoka { 216821f7c56Syasuoka _this->data_use_seq = L2TP_CTRL_CONF(_this)->data_use_seq; 217821f7c56Syasuoka if (L2TP_CTRL_CONF(_this)->hello_interval != 0) 218821f7c56Syasuoka _this->hello_interval = L2TP_CTRL_CONF(_this)->hello_interval; 219821f7c56Syasuoka if (L2TP_CTRL_CONF(_this)->hello_timeout != 0) 220821f7c56Syasuoka _this->hello_timeout = L2TP_CTRL_CONF(_this)->hello_timeout; 2210fbf3537Syasuoka } 2220fbf3537Syasuoka 223f0a4e295Syasuoka /* 224f0a4e295Syasuoka * free {@link ::_l2tp_ctrl L2TP LNS control connection} instance 2250fbf3537Syasuoka */ 2260fbf3537Syasuoka void 2270fbf3537Syasuoka l2tp_ctrl_destroy(l2tp_ctrl *_this) 2280fbf3537Syasuoka { 2290fbf3537Syasuoka L2TP_CTRL_ASSERT(_this != NULL); 230b56612b6Smarkus #if defined(USE_LIBSOCKUTIL) || defined(USE_SA_COOKIE) 2310fbf3537Syasuoka if (_this->sa_cookie != NULL) 2320fbf3537Syasuoka free(_this->sa_cookie); 2330fbf3537Syasuoka #endif 2340fbf3537Syasuoka free(_this); 2350fbf3537Syasuoka } 2360fbf3537Syasuoka 237f0a4e295Syasuoka /* 238f0a4e295Syasuoka * nortify disconnection to peer 2390fbf3537Syasuoka * 240f0a4e295Syasuoka * @return 0: all CDN and StopCCN have been sent. 241f0a4e295Syasuoka * N: if the remaining calls which still not sent CDN exist, 242f0a4e295Syasuoka * return # of the calls. 243f0a4e295Syasuoka * -1: when try to send of StopCCN failed. 2440fbf3537Syasuoka */ 2450fbf3537Syasuoka static int 2460fbf3537Syasuoka l2tp_ctrl_send_disconnect_notify(l2tp_ctrl *_this) 2470fbf3537Syasuoka { 2480fbf3537Syasuoka int ncalls; 2490fbf3537Syasuoka 2500fbf3537Syasuoka L2TP_CTRL_ASSERT(_this != NULL) 2510fbf3537Syasuoka L2TP_CTRL_ASSERT(_this->state == L2TP_CTRL_STATE_ESTABLISHED || 2520fbf3537Syasuoka _this->state == L2TP_CTRL_STATE_CLEANUP_WAIT); 2530fbf3537Syasuoka 2547a7bab9dSyasuoka /* this control is not actively closing or StopCCN have been sent */ 2550fbf3537Syasuoka if (_this->active_closing == 0) 2560fbf3537Syasuoka return 0; 2570fbf3537Syasuoka 2587a7bab9dSyasuoka /* Send CDN all Calls */ 2590fbf3537Syasuoka ncalls = 0; 2600fbf3537Syasuoka if (slist_length(&_this->call_list) != 0) { 261*4781c8ecSyasuoka ncalls = l2tp_ctrl_disconnect_all_calls(_this, 0); 2620fbf3537Syasuoka if (ncalls > 0) { 2630fbf3537Syasuoka /* 2647a7bab9dSyasuoka * Call the function again to check whether the 2657a7bab9dSyasuoka * sending window is fulled. In case ncalls == 0, 2667a7bab9dSyasuoka * it means we've sent CDN for all calls. 2670fbf3537Syasuoka */ 268*4781c8ecSyasuoka ncalls = l2tp_ctrl_disconnect_all_calls(_this, 0); 2690fbf3537Syasuoka } 2700fbf3537Syasuoka } 2710fbf3537Syasuoka if (ncalls > 0) 2720fbf3537Syasuoka return ncalls; 2730fbf3537Syasuoka 2740fbf3537Syasuoka if (l2tp_ctrl_send_StopCCN(_this, _this->active_closing) != 0) 2750fbf3537Syasuoka return -1; 2760fbf3537Syasuoka _this->active_closing = 0; 2770fbf3537Syasuoka 2780fbf3537Syasuoka return 0; 2790fbf3537Syasuoka } 2800fbf3537Syasuoka 281f0a4e295Syasuoka /* 282f0a4e295Syasuoka * Terminate the control connection 2830fbf3537Syasuoka * 2840fbf3537Syasuoka * <p> 2857a7bab9dSyasuoka * please specify an appropriate value to result( >0 ) for 286f0a4e295Syasuoka * StopCCN ResultCode AVP, when to sent Active Close (which 287f0a4e295Syasuoka * require StopCCN sent).</p> 2880fbf3537Syasuoka * <p> 289f0a4e295Syasuoka * When the return value of this function is zero, the _this 290f0a4e295Syasuoka * is already released. The lt2p_ctrl process that was bound to it 291f0a4e295Syasuoka * could not contine. 292f0a4e295Syasuoka * When the return value of this function is one, the timer 293f0a4e295Syasuoka * is reset.</p> 2940fbf3537Syasuoka * 295f0a4e295Syasuoka * @return return 0 if terminate process was completed. 2960fbf3537Syasuoka */ 2970fbf3537Syasuoka int 2980fbf3537Syasuoka l2tp_ctrl_stop(l2tp_ctrl *_this, int result) 2990fbf3537Syasuoka { 3000fbf3537Syasuoka int i; 3010fbf3537Syasuoka l2tpd *_l2tpd; 3020fbf3537Syasuoka 3030fbf3537Syasuoka L2TP_CTRL_ASSERT(_this != NULL); 3040fbf3537Syasuoka 3050fbf3537Syasuoka switch (_this->state) { 3060fbf3537Syasuoka case L2TP_CTRL_STATE_ESTABLISHED: 3070fbf3537Syasuoka _this->state = L2TP_CTRL_STATE_CLEANUP_WAIT; 3080fbf3537Syasuoka if (result > 0) { 3090fbf3537Syasuoka _this->active_closing = result; 3100fbf3537Syasuoka l2tp_ctrl_send_disconnect_notify(_this); 3110fbf3537Syasuoka break; 3120fbf3537Syasuoka } 3130fbf3537Syasuoka goto cleanup; 3140fbf3537Syasuoka default: 3150fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_DEBUG, "%s() unexpected state=%s", 3160fbf3537Syasuoka __func__, l2tp_ctrl_state_string(_this)); 317f0a4e295Syasuoka /* FALLTHROUGH */ 3180fbf3537Syasuoka case L2TP_CTRL_STATE_WAIT_CTL_CONN: 319f0a4e295Syasuoka /* FALLTHROUGH */ 3200fbf3537Syasuoka case L2TP_CTRL_STATE_CLEANUP_WAIT: 3210fbf3537Syasuoka cleanup: 3220fbf3537Syasuoka if (slist_length(&_this->call_list) != 0) { 323*4781c8ecSyasuoka if (l2tp_ctrl_disconnect_all_calls(_this, 1) > 0) 3240fbf3537Syasuoka break; 3250fbf3537Syasuoka } 3260fbf3537Syasuoka #if 0 327821f7c56Syasuoka if (L2TP_CTRL_CONF(_this)e_ipsec_sa != 0) 3280fbf3537Syasuoka l2tp_ctrl_purge_ipsec_sa(_this); 3290fbf3537Syasuoka #endif 3300fbf3537Syasuoka 3310fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_NOTICE, "logtype=Finished"); 3320fbf3537Syasuoka 3330fbf3537Syasuoka evtimer_del(&_this->ev_timeout); 3340fbf3537Syasuoka 335f0a4e295Syasuoka /* free send buffer */ 3360fbf3537Syasuoka if (_this->snd_buffers != NULL) { 3370fbf3537Syasuoka for (i = 0; i < _this->winsz; i++) 3380fbf3537Syasuoka bytebuffer_destroy(_this->snd_buffers[i]); 3390fbf3537Syasuoka free(_this->snd_buffers); 3400fbf3537Syasuoka _this->snd_buffers = NULL; 3410fbf3537Syasuoka } 3420fbf3537Syasuoka if (_this->zlb_buffer != NULL) { 3430fbf3537Syasuoka bytebuffer_destroy(_this->zlb_buffer); 3440fbf3537Syasuoka _this->zlb_buffer = NULL; 3450fbf3537Syasuoka } 346f0a4e295Syasuoka 347f0a4e295Syasuoka /* free l2tp_call */ 3480fbf3537Syasuoka l2tp_ctrl_destroy_all_calls(_this); 3490fbf3537Syasuoka slist_fini(&_this->call_list); 3500fbf3537Syasuoka 3510fbf3537Syasuoka l2tpd_remove_ctrl(_this->l2tpd, _this->tunnel_id); 3520fbf3537Syasuoka 3530fbf3537Syasuoka _l2tpd = _this->l2tpd; 3540fbf3537Syasuoka l2tp_ctrl_destroy(_this); 3550fbf3537Syasuoka 3560fbf3537Syasuoka l2tpd_ctrl_finished_notify(_l2tpd); 357f0a4e295Syasuoka return 0; /* stopped */ 3580fbf3537Syasuoka } 3590fbf3537Syasuoka l2tp_ctrl_reset_timeout(_this); 3600fbf3537Syasuoka 3610fbf3537Syasuoka return 1; 3620fbf3537Syasuoka } 3630fbf3537Syasuoka 3640fbf3537Syasuoka #if 0 3650fbf3537Syasuoka /** Delete the IPsec SA for disconnection */ 3660fbf3537Syasuoka static void 3670fbf3537Syasuoka l2tp_ctrl_purge_ipsec_sa(l2tp_ctrl *_this) 3680fbf3537Syasuoka { 3690fbf3537Syasuoka int is_natt, proto; 370886d2b78Syasuoka struct sockaddr_storage peer, sock; 3710fbf3537Syasuoka hash_link *hl; 3720fbf3537Syasuoka #ifdef USE_LIBSOCKUTIL 3730fbf3537Syasuoka struct in_ipsec_sa_cookie *ipsec_sa_cookie; 3740fbf3537Syasuoka #endif 3750fbf3537Syasuoka l2tp_ctrl *anot; 3760fbf3537Syasuoka 3770fbf3537Syasuoka /* 3780fbf3537Syasuoka * Search another tunnel that uses the same IPsec SA 3790fbf3537Syasuoka * by lineer. 3800fbf3537Syasuoka */ 3810fbf3537Syasuoka for (hl = hash_first(_this->l2tpd->ctrl_map); 3820fbf3537Syasuoka hl != NULL; hl = hash_next(_this->l2tpd->ctrl_map)) { 3830fbf3537Syasuoka anot = hl->item; 3840fbf3537Syasuoka if (anot == _this) 3850fbf3537Syasuoka continue; 3860fbf3537Syasuoka 387886d2b78Syasuoka if (_this->peer.ss_family != anot->peer.ss_family) 388886d2b78Syasuoka continue; 389886d2b78Syasuoka if (_this->peer.ss_family == AF_INET) { 390886d2b78Syasuoka if (SIN(&_this->peer)->sin_addr.s_addr != 391886d2b78Syasuoka SIN(&anot->peer)->sin_addr.s_addr) 392886d2b78Syasuoka continue; 393886d2b78Syasuoka } else if (_this->peer.ss_family == AF_INET6) { 394886d2b78Syasuoka if (!IN6_ARE_ADDR_EQUAL( 395886d2b78Syasuoka &(SIN6(&_this->peer)->sin6_addr), 396886d2b78Syasuoka &(SIN6(&anot->peer)->sin6_addr))) 397886d2b78Syasuoka continue; 3980fbf3537Syasuoka } 3990fbf3537Syasuoka #ifdef USE_LIBSOCKUTIL 400886d2b78Syasuoka if (_this->sa_cookie != NULL && anot->sa_cookie != NULL) { 4010fbf3537Syasuoka /* Both tunnels belong the same NAT box. */ 4020fbf3537Syasuoka 4030fbf3537Syasuoka if (memcmp(_this->sa_cookie, anot->sa_cookie, 4040fbf3537Syasuoka sizeof(struct in_ipsec_sa_cookie)) != 0) 4050fbf3537Syasuoka /* Different hosts behind the NAT box. */ 4060fbf3537Syasuoka continue; 4070fbf3537Syasuoka 4080fbf3537Syasuoka /* The SA is shared by another tunnels by one host. */ 4090fbf3537Syasuoka return; /* don't purge the sa */ 4100fbf3537Syasuoka 411886d2b78Syasuoka } else if (_this->sa_cookie != NULL || anot->sa_cookie != NULL) 4120fbf3537Syasuoka /* Only one is behind the NAT */ 4130fbf3537Syasuoka continue; 4140fbf3537Syasuoka #endif 4150fbf3537Syasuoka return; /* don't purge the sa */ 4160fbf3537Syasuoka } 4170fbf3537Syasuoka 4189a200ddfSyasuoka #if defined(USE_LIBSOCKUTIL) && defined(IP_IPSEC_SA_COOKIE) 4190fbf3537Syasuoka is_natt = (_this->sa_cookie != NULL)? 1 : 0; 4200fbf3537Syasuoka #else 4210fbf3537Syasuoka is_natt = 0; 4220fbf3537Syasuoka #endif 4239a200ddfSyasuoka proto = 0; 424886d2b78Syasuoka memcpy(&peer, &_this->peer, _this->peer.ss_len); 425886d2b78Syasuoka memcpy(&sock, &_this->sock, _this->sock.ss_len); 4269a200ddfSyasuoka if (!is_natt) 427886d2b78Syasuoka SIN(&peer)->sin_port = SIN(&sock)->sin_port = 0; 4289a200ddfSyasuoka #if defined(USE_LIBSOCKUTIL) && defined(IP_IPSEC_SA_COOKIE) 4290fbf3537Syasuoka else { 4300fbf3537Syasuoka ipsec_sa_cookie = _this->sa_cookie; 431886d2b78Syasuoka SIN(&peer)->sin_port = ipsec_sa_cookie->remote_port; 432886d2b78Syasuoka SIN(&sock)->sin_port = ipsec_sa_cookie->local_port; 4330fbf3537Syasuoka #if 1 4340fbf3537Syasuoka /* 4350fbf3537Syasuoka * XXX: As RFC 2367, protocol sould be specified if the port 4360fbf3537Syasuoka * XXX: number is non-zero. 4370fbf3537Syasuoka */ 4380fbf3537Syasuoka proto = 0; 4390fbf3537Syasuoka #else 4400fbf3537Syasuoka proto = IPPROTO_UDP; 4410fbf3537Syasuoka #endif 4420fbf3537Syasuoka } 4430fbf3537Syasuoka #endif 4440fbf3537Syasuoka if (ipsec_util_purge_transport_sa((struct sockaddr *)&peer, 445886d2b78Syasuoka (struct sockaddr *)&sock, proto, IPSEC_UTIL_DIRECTION_BOTH) != 0) 4460fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_NOTICE, "failed to purge IPSec SA"); 4470fbf3537Syasuoka } 4480fbf3537Syasuoka #endif 4490fbf3537Syasuoka 450f0a4e295Syasuoka /* timeout processing */ 4510fbf3537Syasuoka static void 4520fbf3537Syasuoka l2tp_ctrl_timeout(int fd, short evtype, void *ctx) 4530fbf3537Syasuoka { 4540fbf3537Syasuoka int next_timeout, need_resend; 4550fbf3537Syasuoka time_t curr_time; 4560fbf3537Syasuoka l2tp_ctrl *_this; 4570fbf3537Syasuoka l2tp_call *call; 4580fbf3537Syasuoka 4590fbf3537Syasuoka /* 460f0a4e295Syasuoka * the timer must be reset, when leave this function. 461f0a4e295Syasuoka * MEMO: l2tp_ctrl_stop() will reset the timer in it. 462f0a4e295Syasuoka * and please remember that the l2tp_ctrl_stop() may free _this. 4630fbf3537Syasuoka */ 4640fbf3537Syasuoka _this = ctx; 4650fbf3537Syasuoka L2TP_CTRL_ASSERT(_this != NULL); 4660fbf3537Syasuoka 4670fbf3537Syasuoka curr_time = get_monosec(); 4680fbf3537Syasuoka 4690fbf3537Syasuoka next_timeout = 2; 4700fbf3537Syasuoka need_resend = 0; 4710fbf3537Syasuoka 4720fbf3537Syasuoka if (l2tp_ctrl_txwin_size(_this) > 0) { 4730fbf3537Syasuoka if (_this->state == L2TP_CTRL_STATE_ESTABLISHED) { 4740fbf3537Syasuoka if (_this->hello_wait_ack != 0) { 475f0a4e295Syasuoka /* wait Hello reply */ 4760fbf3537Syasuoka if (curr_time - _this->hello_io_time >= 4770fbf3537Syasuoka _this->hello_timeout) { 4780fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_NOTICE, 4790fbf3537Syasuoka "timeout waiting ack for hello " 4800fbf3537Syasuoka "packets."); 4810fbf3537Syasuoka l2tp_ctrl_stop(_this, 4820fbf3537Syasuoka L2TP_STOP_CCN_RCODE_GENERAL); 4830fbf3537Syasuoka return; 4840fbf3537Syasuoka } 4850fbf3537Syasuoka } 4860fbf3537Syasuoka } else if (curr_time - _this->last_snd_ctrl >= 4870fbf3537Syasuoka L2TP_CTRL_CTRL_PKT_TIMEOUT) { 4880fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_NOTICE, 4890fbf3537Syasuoka "timeout waiting ack for ctrl packets."); 4900fbf3537Syasuoka l2tp_ctrl_stop(_this, 4910fbf3537Syasuoka L2TP_STOP_CCN_RCODE_GENERAL); 4920fbf3537Syasuoka return; 4930fbf3537Syasuoka } 4940fbf3537Syasuoka need_resend = 1; 4950fbf3537Syasuoka } else { 4960fbf3537Syasuoka for (slist_itr_first(&_this->call_list); 4970fbf3537Syasuoka slist_itr_has_next(&_this->call_list);) { 4980fbf3537Syasuoka call = slist_itr_next(&_this->call_list); 4990fbf3537Syasuoka if (call->state == L2TP_CALL_STATE_CLEANUP_WAIT) { 5000fbf3537Syasuoka l2tp_call_destroy(call, 1); 5010fbf3537Syasuoka slist_itr_remove(&_this->call_list); 5020fbf3537Syasuoka } 5030fbf3537Syasuoka } 5040fbf3537Syasuoka } 5050fbf3537Syasuoka 5060fbf3537Syasuoka switch (_this->state) { 5070fbf3537Syasuoka case L2TP_CTRL_STATE_IDLE: 5080fbf3537Syasuoka /* 509f0a4e295Syasuoka * idle: 510f0a4e295Syasuoka * XXX: never happen in current implementation 5110fbf3537Syasuoka */ 5120fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_ERR, 5130fbf3537Syasuoka "Internal error, timeout on illegal state=idle"); 5140fbf3537Syasuoka l2tp_ctrl_stop(_this, L2TP_STOP_CCN_RCODE_GENERAL); 5150fbf3537Syasuoka break; 5160fbf3537Syasuoka case L2TP_CTRL_STATE_WAIT_CTL_CONN: 5170fbf3537Syasuoka /* 518f0a4e295Syasuoka * wait-ctrl-conn: 519f0a4e295Syasuoka * if there is no ack for SCCRP, the peer will 520f0a4e295Syasuoka * resend SCCRQ. however this implementation can 521f0a4e295Syasuoka * not recognize that the SCCRQ was resent or not. 522f0a4e295Syasuoka * Therefore, never resent from this side. 5230fbf3537Syasuoka */ 5240fbf3537Syasuoka need_resend = 0; 5250fbf3537Syasuoka break; 5260fbf3537Syasuoka case L2TP_CTRL_STATE_ESTABLISHED: 5270fbf3537Syasuoka if (slist_length(&_this->call_list) == 0 && 5280fbf3537Syasuoka curr_time - _this->last_snd_ctrl >= 5290fbf3537Syasuoka L2TP_CTRL_WAIT_CALL_TIMEOUT) { 5300fbf3537Syasuoka if (_this->ncalls == 0) 531421b67a1Sjasper /* fail to receive first call */ 5320fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_WARNING, 5330fbf3537Syasuoka "timeout waiting call"); 5340fbf3537Syasuoka l2tp_ctrl_stop(_this, 5350fbf3537Syasuoka L2TP_STOP_CCN_RCODE_GENERAL); 5360fbf3537Syasuoka return; 5370fbf3537Syasuoka } 5380fbf3537Syasuoka if (_this->hello_wait_ack == 0 && _this->hello_interval > 0) { 539f0a4e295Syasuoka /* send Hello */ 5400fbf3537Syasuoka if (curr_time - _this->hello_interval >= 5410fbf3537Syasuoka _this->hello_io_time) { 5420fbf3537Syasuoka if (l2tp_ctrl_send_HELLO(_this) == 0) 543f0a4e295Syasuoka /* success */ 5440fbf3537Syasuoka _this->hello_wait_ack = 1; 5450fbf3537Syasuoka _this->hello_io_time = curr_time; 5460fbf3537Syasuoka need_resend = 0; 5470fbf3537Syasuoka } 5480fbf3537Syasuoka } 5490fbf3537Syasuoka break; 5500fbf3537Syasuoka case L2TP_CTRL_STATE_CLEANUP_WAIT: 5510fbf3537Syasuoka if (curr_time - _this->last_snd_ctrl >= 5520fbf3537Syasuoka L2TP_CTRL_CLEANUP_WAIT_TIME) { 5530fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_NOTICE, 5540fbf3537Syasuoka "Cleanup timeout state=%d", _this->state); 5550fbf3537Syasuoka l2tp_ctrl_stop(_this, 0); 5560fbf3537Syasuoka return; 5570fbf3537Syasuoka } 5580fbf3537Syasuoka if (_this->active_closing != 0) 5590fbf3537Syasuoka l2tp_ctrl_send_disconnect_notify(_this); 5600fbf3537Syasuoka break; 5610fbf3537Syasuoka default: 5620fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_ERR, 5630fbf3537Syasuoka "Internal error, timeout on illegal state=%d", 5640fbf3537Syasuoka _this->state); 5650fbf3537Syasuoka l2tp_ctrl_stop(_this, L2TP_STOP_CCN_RCODE_GENERAL); 5660fbf3537Syasuoka return; 5670fbf3537Syasuoka } 568f0a4e295Syasuoka /* resend if required */ 5690fbf3537Syasuoka if (need_resend) 5700fbf3537Syasuoka l2tp_ctrl_resend_una_packets(_this); 5710fbf3537Syasuoka l2tp_ctrl_reset_timeout(_this); 5720fbf3537Syasuoka } 5730fbf3537Syasuoka 5740fbf3537Syasuoka int 5750fbf3537Syasuoka l2tp_ctrl_send(l2tp_ctrl *_this, const void *msg, int len) 5760fbf3537Syasuoka { 5770fbf3537Syasuoka int rval; 5780fbf3537Syasuoka 5790fbf3537Syasuoka #ifdef USE_LIBSOCKUTIL 5800fbf3537Syasuoka if (_this->sa_cookie != NULL) 5810fbf3537Syasuoka rval = sendfromto_nat_t(LISTENER_SOCK(_this), msg, len, 0, 5820fbf3537Syasuoka (struct sockaddr *)&_this->sock, 5830fbf3537Syasuoka (struct sockaddr *)&_this->peer, _this->sa_cookie); 5840fbf3537Syasuoka else 5850fbf3537Syasuoka rval = sendfromto(LISTENER_SOCK(_this), msg, len, 0, 5860fbf3537Syasuoka (struct sockaddr *)&_this->sock, 5870fbf3537Syasuoka (struct sockaddr *)&_this->peer); 5880fbf3537Syasuoka #else 589b56612b6Smarkus #ifdef USE_SA_COOKIE 590b56612b6Smarkus if (_this->sa_cookie != NULL) 591b56612b6Smarkus rval = sendto_nat_t(LISTENER_SOCK(_this), msg, len, 0, 592b56612b6Smarkus (struct sockaddr *)&_this->peer, _this->peer.ss_len, 593b56612b6Smarkus _this->sa_cookie); 594b56612b6Smarkus else 595b56612b6Smarkus #endif 5960fbf3537Syasuoka rval = sendto(LISTENER_SOCK(_this), msg, len, 0, 5970fbf3537Syasuoka (struct sockaddr *)&_this->peer, _this->peer.ss_len); 5980fbf3537Syasuoka #endif 5990fbf3537Syasuoka return rval; 6000fbf3537Syasuoka } 6010fbf3537Syasuoka 602f0a4e295Syasuoka /* resend una packets */ 6030fbf3537Syasuoka static int 6040fbf3537Syasuoka l2tp_ctrl_resend_una_packets(l2tp_ctrl *_this) 6050fbf3537Syasuoka { 6060fbf3537Syasuoka uint16_t seq; 6070fbf3537Syasuoka bytebuffer *bytebuf; 6080fbf3537Syasuoka struct l2tp_header *header; 6090fbf3537Syasuoka int nsend; 6100fbf3537Syasuoka 6110fbf3537Syasuoka nsend = 0; 6120fbf3537Syasuoka for (seq = _this->snd_una; SEQ_LT(seq, _this->snd_nxt); seq++) { 6130fbf3537Syasuoka bytebuf = _this->snd_buffers[seq % _this->winsz]; 6140fbf3537Syasuoka header = bytebuffer_pointer(bytebuf); 6150fbf3537Syasuoka header->nr = htons(_this->rcv_nxt); 6160fbf3537Syasuoka #ifdef L2TP_CTRL_DEBUG 6170fbf3537Syasuoka if (debuglevel >= 3) { 6180fbf3537Syasuoka l2tp_ctrl_log(_this, DEBUG_LEVEL_3, "RESEND seq=%u", 6190fbf3537Syasuoka ntohs(header->ns)); 6200fbf3537Syasuoka show_hd(debug_get_debugfp(), 6210fbf3537Syasuoka bytebuffer_pointer(bytebuf), 6220fbf3537Syasuoka bytebuffer_remaining(bytebuf)); 6230fbf3537Syasuoka } 6240fbf3537Syasuoka #endif 6250fbf3537Syasuoka if (l2tp_ctrl_send(_this, bytebuffer_pointer(bytebuf), 6260fbf3537Syasuoka bytebuffer_remaining(bytebuf)) < 0) { 6270fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_ERR, 6280fbf3537Syasuoka "sendto() failed in %s: %m", __func__); 6290fbf3537Syasuoka return -1; 6300fbf3537Syasuoka } 6310fbf3537Syasuoka nsend++; 6320fbf3537Syasuoka } 6330fbf3537Syasuoka return nsend; 6340fbf3537Syasuoka } 6350fbf3537Syasuoka 636f0a4e295Syasuoka /* free all calls */ 6370fbf3537Syasuoka static void 6380fbf3537Syasuoka l2tp_ctrl_destroy_all_calls(l2tp_ctrl *_this) 6390fbf3537Syasuoka { 6400fbf3537Syasuoka l2tp_call *call; 6410fbf3537Syasuoka 6420fbf3537Syasuoka L2TP_CTRL_ASSERT(_this != NULL); 6430fbf3537Syasuoka 6440fbf3537Syasuoka while ((call = slist_remove_first(&_this->call_list)) != NULL) 6450fbf3537Syasuoka l2tp_call_destroy(call, 1); 6460fbf3537Syasuoka } 6470fbf3537Syasuoka 648f0a4e295Syasuoka 649f0a4e295Syasuoka /* disconnect all calls on the control context 650f0a4e295Syasuoka * @return return # of calls that is not waiting cleanup. 6510fbf3537Syasuoka */ 6520fbf3537Syasuoka static int 653*4781c8ecSyasuoka l2tp_ctrl_disconnect_all_calls(l2tp_ctrl *_this, int drop) 6540fbf3537Syasuoka { 6550fbf3537Syasuoka int i, len, ncalls; 6560fbf3537Syasuoka l2tp_call *call; 6570fbf3537Syasuoka 6580fbf3537Syasuoka L2TP_CTRL_ASSERT(_this != NULL); 6590fbf3537Syasuoka 6600fbf3537Syasuoka ncalls = 0; 6610fbf3537Syasuoka len = slist_length(&_this->call_list); 6620fbf3537Syasuoka for (i = 0; i < len; i++) { 6630fbf3537Syasuoka call = slist_get(&_this->call_list, i); 6640fbf3537Syasuoka if (call->state != L2TP_CALL_STATE_CLEANUP_WAIT) { 6650fbf3537Syasuoka ncalls++; 6660fbf3537Syasuoka if (l2tp_ctrl_txwin_is_full(_this)) { 6670fbf3537Syasuoka L2TP_CTRL_DBG((_this, LOG_INFO, 6680fbf3537Syasuoka "Too many calls. Sending window is not " 6690fbf3537Syasuoka "enough to send CDN to all clients.")); 670*4781c8ecSyasuoka if (drop) 671*4781c8ecSyasuoka l2tp_call_drop(call); 6720fbf3537Syasuoka } else 6730fbf3537Syasuoka l2tp_call_admin_disconnect(call); 6740fbf3537Syasuoka } 6750fbf3537Syasuoka } 6760fbf3537Syasuoka return ncalls; 6770fbf3537Syasuoka } 6780fbf3537Syasuoka 679f0a4e295Syasuoka /* reset timeout */ 6800fbf3537Syasuoka static void 6810fbf3537Syasuoka l2tp_ctrl_reset_timeout(l2tp_ctrl *_this) 6820fbf3537Syasuoka { 6830fbf3537Syasuoka int intvl; 6840fbf3537Syasuoka struct timeval tv0; 6850fbf3537Syasuoka 6860fbf3537Syasuoka L2TP_CTRL_ASSERT(_this != NULL); 6870fbf3537Syasuoka 6880fbf3537Syasuoka if (evtimer_initialized(&_this->ev_timeout)) 6890fbf3537Syasuoka evtimer_del(&_this->ev_timeout); 6900fbf3537Syasuoka 6910fbf3537Syasuoka switch (_this->state) { 6920fbf3537Syasuoka case L2TP_CTRL_STATE_CLEANUP_WAIT: 6930fbf3537Syasuoka intvl = 1; 6940fbf3537Syasuoka break; 6950fbf3537Syasuoka default: 6960fbf3537Syasuoka intvl = 2; 6970fbf3537Syasuoka break; 6980fbf3537Syasuoka } 6990fbf3537Syasuoka tv0.tv_usec = 0; 7000fbf3537Syasuoka tv0.tv_sec = intvl; 7010fbf3537Syasuoka if (!evtimer_initialized(&_this->ev_timeout)) 7020fbf3537Syasuoka evtimer_set(&_this->ev_timeout, l2tp_ctrl_timeout, _this); 7030fbf3537Syasuoka evtimer_add(&_this->ev_timeout, &tv0); 7040fbf3537Syasuoka } 7050fbf3537Syasuoka 706f0a4e295Syasuoka /* 707f0a4e295Syasuoka * protocols / send and receive 7080fbf3537Syasuoka */ 709421b67a1Sjasper /* Receive packet */ 7100fbf3537Syasuoka void 7110fbf3537Syasuoka l2tp_ctrl_input(l2tpd *_this, int listener_index, struct sockaddr *peer, 7120fbf3537Syasuoka struct sockaddr *sock, void *nat_t_ctx, u_char *pkt, int pktlen) 7130fbf3537Syasuoka { 7140fbf3537Syasuoka int i, len, offsiz, reqlen, is_ctrl; 7150fbf3537Syasuoka uint16_t mestype; 7160fbf3537Syasuoka struct l2tp_avp *avp, *avp0; 7170fbf3537Syasuoka l2tp_ctrl *ctrl; 7180fbf3537Syasuoka l2tp_call *call; 7190fbf3537Syasuoka char buf[L2TP_AVP_MAXSIZ], errmsg[256]; 7200fbf3537Syasuoka time_t curr_time; 7210fbf3537Syasuoka u_char *pkt0; 7220fbf3537Syasuoka struct l2tp_header hdr; 723886d2b78Syasuoka char hbuf[NI_MAXHOST + NI_MAXSERV + 16]; 7240fbf3537Syasuoka 7250fbf3537Syasuoka ctrl = NULL; 7260fbf3537Syasuoka curr_time = get_monosec(); 7270fbf3537Syasuoka pkt0 = pkt; 7280fbf3537Syasuoka 729886d2b78Syasuoka L2TP_CTRL_ASSERT(peer->sa_family == sock->sa_family); 730886d2b78Syasuoka L2TP_CTRL_ASSERT(peer->sa_family == AF_INET || 731886d2b78Syasuoka peer->sa_family == AF_INET6) 7320fbf3537Syasuoka /* 7330fbf3537Syasuoka * Parse L2TP Header 7340fbf3537Syasuoka */ 7350fbf3537Syasuoka memset(&hdr, 0, sizeof(hdr)); 7360fbf3537Syasuoka if (pktlen < 2) { 7370fbf3537Syasuoka snprintf(errmsg, sizeof(errmsg), "a short packet. " 7380fbf3537Syasuoka "length=%d", pktlen); 7390fbf3537Syasuoka goto bad_packet; 7400fbf3537Syasuoka } 7410fbf3537Syasuoka memcpy(&hdr, pkt, 2); 7420fbf3537Syasuoka pkt += 2; 7430fbf3537Syasuoka if (hdr.ver != L2TP_HEADER_VERSION_RFC2661) { 744f0a4e295Syasuoka /* XXX: only RFC2661 is supported */ 7450fbf3537Syasuoka snprintf(errmsg, sizeof(errmsg), 7460fbf3537Syasuoka "Unsupported version at header = %d", hdr.ver); 7470fbf3537Syasuoka goto bad_packet; 7480fbf3537Syasuoka } 7490fbf3537Syasuoka is_ctrl = (hdr.t != 0)? 1 : 0; 7500fbf3537Syasuoka 7510fbf3537Syasuoka /* calc required length */ 7520fbf3537Syasuoka reqlen = 6; /* for Flags, Tunnel-Id, Session-Id field */ 7530fbf3537Syasuoka if (hdr.l) reqlen += 2; /* for Length field (opt) */ 7540fbf3537Syasuoka if (hdr.s) reqlen += 4; /* for Ns, Nr field (opt) */ 7550fbf3537Syasuoka if (hdr.o) reqlen += 2; /* for Offset Size field (opt) */ 7560fbf3537Syasuoka if (reqlen > pktlen) { 7570fbf3537Syasuoka snprintf(errmsg, sizeof(errmsg), 7580fbf3537Syasuoka "a short packet. length=%d", pktlen); 7590fbf3537Syasuoka goto bad_packet; 7600fbf3537Syasuoka } 7610fbf3537Syasuoka 7620fbf3537Syasuoka if (hdr.l != 0) { 7630fbf3537Syasuoka GETSHORT(hdr.length, pkt); 7640fbf3537Syasuoka if (hdr.length > pktlen) { 7650fbf3537Syasuoka snprintf(errmsg, sizeof(errmsg), 7660fbf3537Syasuoka "Actual packet size is smaller than the length " 7670fbf3537Syasuoka "field %d < %d", pktlen, hdr.length); 7680fbf3537Syasuoka goto bad_packet; 7690fbf3537Syasuoka } 7700fbf3537Syasuoka pktlen = hdr.length; /* remove trailing trash */ 7710fbf3537Syasuoka } 7720fbf3537Syasuoka GETSHORT(hdr.tunnel_id, pkt); 7730fbf3537Syasuoka GETSHORT(hdr.session_id, pkt); 7740fbf3537Syasuoka if (hdr.s != 0) { 7750fbf3537Syasuoka GETSHORT(hdr.ns, pkt); 7760fbf3537Syasuoka GETSHORT(hdr.nr, pkt); 7770fbf3537Syasuoka } 7780fbf3537Syasuoka if (hdr.o != 0) { 7790fbf3537Syasuoka GETSHORT(offsiz, pkt); 7800fbf3537Syasuoka if (pktlen < offsiz) { 7810fbf3537Syasuoka snprintf(errmsg, sizeof(errmsg), 7820fbf3537Syasuoka "offset field is bigger than remaining packet " 7830fbf3537Syasuoka "length %d > %d", offsiz, pktlen); 7840fbf3537Syasuoka goto bad_packet; 7850fbf3537Syasuoka } 7860fbf3537Syasuoka pkt += offsiz; 7870fbf3537Syasuoka } 7880fbf3537Syasuoka L2TP_CTRL_ASSERT(pkt - pkt0 == reqlen); 7890fbf3537Syasuoka pktlen -= (pkt - pkt0); /* cut down the length of header */ 7900fbf3537Syasuoka 7910fbf3537Syasuoka ctrl = NULL; 7920fbf3537Syasuoka memset(buf, 0, sizeof(buf)); 7930fbf3537Syasuoka mestype = 0; 7940fbf3537Syasuoka avp = NULL; 7950fbf3537Syasuoka 7960fbf3537Syasuoka if (is_ctrl) { 7970fbf3537Syasuoka avp0 = (struct l2tp_avp *)buf; 7980fbf3537Syasuoka avp = avp_find_message_type_avp(avp0, pkt, pktlen); 7990fbf3537Syasuoka if (avp != NULL) 8000fbf3537Syasuoka mestype = avp->attr_value[0] << 8 | avp->attr_value[1]; 8010fbf3537Syasuoka } 8020fbf3537Syasuoka ctrl = l2tpd_get_ctrl(_this, hdr.tunnel_id); 8030fbf3537Syasuoka 8040fbf3537Syasuoka if (ctrl == NULL) { 805f0a4e295Syasuoka /* new control */ 8060fbf3537Syasuoka if (!is_ctrl) { 8070fbf3537Syasuoka snprintf(errmsg, sizeof(errmsg), 8080fbf3537Syasuoka "bad data message: tunnelId=%d is not " 8090fbf3537Syasuoka "found.", hdr.tunnel_id); 8100fbf3537Syasuoka goto bad_packet; 8110fbf3537Syasuoka } 8120fbf3537Syasuoka if (mestype != L2TP_AVP_MESSAGE_TYPE_SCCRQ) { 8130fbf3537Syasuoka snprintf(errmsg, sizeof(errmsg), 8140fbf3537Syasuoka "bad control message: tunnelId=%d is not " 8150fbf3537Syasuoka "found. mestype=%s", hdr.tunnel_id, 8160fbf3537Syasuoka avp_mes_type_string(mestype)); 8170fbf3537Syasuoka goto bad_packet; 8180fbf3537Syasuoka } 8190fbf3537Syasuoka 8200fbf3537Syasuoka if ((ctrl = l2tp_ctrl_create()) == NULL) { 8210fbf3537Syasuoka l2tp_ctrl_log(ctrl, LOG_ERR, 8220fbf3537Syasuoka "l2tp_ctrl_create() failed: %m"); 823f0a4e295Syasuoka goto fail; 8240fbf3537Syasuoka } 825821f7c56Syasuoka 8260fbf3537Syasuoka if (l2tp_ctrl_init(ctrl, _this, peer, sock, nat_t_ctx) != 0) { 8270fbf3537Syasuoka l2tp_ctrl_log(ctrl, LOG_ERR, 8280fbf3537Syasuoka "l2tp_ctrl_start() failed: %m"); 829f0a4e295Syasuoka goto fail; 8300fbf3537Syasuoka } 8310fbf3537Syasuoka 8320fbf3537Syasuoka ctrl->listener_index = listener_index; 8330fbf3537Syasuoka l2tp_ctrl_reload(ctrl); 8340fbf3537Syasuoka } else { 8350fbf3537Syasuoka /* 836f0a4e295Syasuoka * treat as an error if src address and port is not 837f0a4e295Syasuoka * match. (because it is potentially DoS attach) 8380fbf3537Syasuoka */ 839886d2b78Syasuoka int notmatch = 0; 8400fbf3537Syasuoka 841886d2b78Syasuoka if (ctrl->peer.ss_family != peer->sa_family) 842886d2b78Syasuoka notmatch = 1; 843886d2b78Syasuoka else if (peer->sa_family == AF_INET) { 844886d2b78Syasuoka if (SIN(peer)->sin_addr.s_addr != 845886d2b78Syasuoka SIN(&ctrl->peer)->sin_addr.s_addr || 846886d2b78Syasuoka SIN(peer)->sin_port != SIN(&ctrl->peer)->sin_port) 847886d2b78Syasuoka notmatch = 1; 848886d2b78Syasuoka } else if (peer->sa_family == AF_INET6) { 849886d2b78Syasuoka if (!IN6_ARE_ADDR_EQUAL(&(SIN6(peer)->sin6_addr), 850886d2b78Syasuoka &(SIN6(&ctrl->peer)->sin6_addr)) || 851886d2b78Syasuoka SIN6(peer)->sin6_port != 852886d2b78Syasuoka SIN6(&ctrl->peer)->sin6_port) 853886d2b78Syasuoka notmatch = 1; 854886d2b78Syasuoka } 855886d2b78Syasuoka if (notmatch) { 8560fbf3537Syasuoka snprintf(errmsg, sizeof(errmsg), 857886d2b78Syasuoka "tunnelId=%u is already assigned for %s", 858886d2b78Syasuoka hdr.tunnel_id, addrport_tostring( 859886d2b78Syasuoka (struct sockaddr *)&ctrl->peer, 860886d2b78Syasuoka ctrl->peer.ss_len, hbuf, sizeof(hbuf))); 8610fbf3537Syasuoka goto bad_packet; 8620fbf3537Syasuoka } 8630fbf3537Syasuoka } 8640fbf3537Syasuoka ctrl->last_rcv = curr_time; 8650fbf3537Syasuoka call = NULL; 8660fbf3537Syasuoka if (hdr.session_id != 0) { 867f0a4e295Syasuoka /* search l2tp_call by Session ID */ 868f0a4e295Syasuoka /* linear search is enough for this purpose */ 8690fbf3537Syasuoka len = slist_length(&ctrl->call_list); 8700fbf3537Syasuoka for (i = 0; i < len; i++) { 8710fbf3537Syasuoka call = slist_get(&ctrl->call_list, i); 8720fbf3537Syasuoka if (call->session_id == hdr.session_id) 8730fbf3537Syasuoka break; 8740fbf3537Syasuoka call = NULL; 8750fbf3537Syasuoka } 8760fbf3537Syasuoka } 8770fbf3537Syasuoka if (!is_ctrl) { 878e405d423Syasuoka int delayed = 0; 879e405d423Syasuoka 880f0a4e295Syasuoka /* L2TP data */ 8810fbf3537Syasuoka if (ctrl->state != L2TP_CTRL_STATE_ESTABLISHED) { 8820fbf3537Syasuoka l2tp_ctrl_log(ctrl, LOG_WARNING, 8830fbf3537Syasuoka "Received Data packet in '%s'", 8840fbf3537Syasuoka l2tp_ctrl_state_string(ctrl)); 885f0a4e295Syasuoka goto fail; 8860fbf3537Syasuoka } 8870fbf3537Syasuoka if (call == NULL) { 8880fbf3537Syasuoka l2tp_ctrl_log(ctrl, LOG_WARNING, 8890fbf3537Syasuoka "Received a data packet but it has no call. " 8900fbf3537Syasuoka "session_id=%u", hdr.session_id); 891f0a4e295Syasuoka goto fail; 8920fbf3537Syasuoka } 8930fbf3537Syasuoka L2TP_CTRL_DBG((ctrl, DEBUG_LEVEL_2, 8940fbf3537Syasuoka "call=%u RECV ns=%u nr=%u snd_nxt=%u rcv_nxt=%u len=%d", 8950fbf3537Syasuoka call->id, hdr.ns, hdr.nr, call->snd_nxt, call->rcv_nxt, 8960fbf3537Syasuoka pktlen)); 8970fbf3537Syasuoka if (call->state != L2TP_CALL_STATE_ESTABLISHED){ 8980fbf3537Syasuoka l2tp_ctrl_log(ctrl, LOG_WARNING, 8990fbf3537Syasuoka "Received a data packet but call is not " 9000fbf3537Syasuoka "established"); 901f0a4e295Syasuoka goto fail; 9020fbf3537Syasuoka } 9030fbf3537Syasuoka 9040fbf3537Syasuoka if (hdr.s != 0) { 9050fbf3537Syasuoka if (SEQ_LT(hdr.ns, call->rcv_nxt)) { 906e405d423Syasuoka if (SEQ_LT(hdr.ns, 907e405d423Syasuoka call->rcv_nxt - L2TP_CALL_DELAY_LIMIT)) { 908e405d423Syasuoka /* sequence number seems to be delayed */ 909f0a4e295Syasuoka /* XXX: need to log? */ 9100fbf3537Syasuoka L2TP_CTRL_DBG((ctrl, LOG_DEBUG, 911e405d423Syasuoka "receive a out of sequence " 912e405d423Syasuoka "data packet: %u < %u.", 913e405d423Syasuoka hdr.ns, call->rcv_nxt)); 9140fbf3537Syasuoka return; 9150fbf3537Syasuoka } 916e405d423Syasuoka delayed = 1; 917e405d423Syasuoka } else { 9180fbf3537Syasuoka call->rcv_nxt = hdr.ns + 1; 9190fbf3537Syasuoka } 920e405d423Syasuoka } 921e405d423Syasuoka 922e405d423Syasuoka l2tp_call_ppp_input(call, pkt, pktlen, delayed); 9230fbf3537Syasuoka 9240fbf3537Syasuoka return; 9250fbf3537Syasuoka } 9260fbf3537Syasuoka if (hdr.s != 0) { 9270fbf3537Syasuoka L2TP_CTRL_DBG((ctrl, DEBUG_LEVEL_2, 9280fbf3537Syasuoka "RECV %s ns=%u nr=%u snd_nxt=%u snd_una=%u rcv_nxt=%u " 9290fbf3537Syasuoka "len=%d", (is_ctrl)? "C" : "", hdr.ns, hdr.nr, 9300fbf3537Syasuoka ctrl->snd_nxt, ctrl->snd_una, ctrl->rcv_nxt, pktlen)); 9310fbf3537Syasuoka 9320fbf3537Syasuoka if (pktlen <= 0) 9330fbf3537Syasuoka l2tp_ctrl_log(ctrl, LOG_INFO, "RecvZLB"); 9340fbf3537Syasuoka 9350fbf3537Syasuoka if (SEQ_GT(hdr.nr, ctrl->snd_una)) { 9360fbf3537Syasuoka if (hdr.nr == ctrl->snd_nxt || 9370fbf3537Syasuoka SEQ_LT(hdr.nr, ctrl->snd_nxt)) 9380fbf3537Syasuoka ctrl->snd_una = hdr.nr; 9390fbf3537Syasuoka else { 9400fbf3537Syasuoka l2tp_ctrl_log(ctrl, LOG_INFO, 9410fbf3537Syasuoka "Received message has bad Nr field: " 9420fbf3537Syasuoka "%u < %u.", hdr.ns, ctrl->snd_nxt); 9430fbf3537Syasuoka /* XXX Drop with ZLB? */ 944f0a4e295Syasuoka goto fail; 9450fbf3537Syasuoka } 9460fbf3537Syasuoka } 9470fbf3537Syasuoka if (l2tp_ctrl_txwin_size(ctrl) <= 0) { 948f0a4e295Syasuoka /* no waiting ack */ 9490fbf3537Syasuoka if (ctrl->hello_wait_ack != 0) { 9500fbf3537Syasuoka /* 951f0a4e295Syasuoka * Reset Hello state, as an ack for the Hello 952f0a4e295Syasuoka * is recived. 9530fbf3537Syasuoka */ 9540fbf3537Syasuoka ctrl->hello_wait_ack = 0; 9550fbf3537Syasuoka ctrl->hello_io_time = curr_time; 9560fbf3537Syasuoka } 9570fbf3537Syasuoka switch (ctrl->state) { 9580fbf3537Syasuoka case L2TP_CTRL_STATE_CLEANUP_WAIT: 9590fbf3537Syasuoka l2tp_ctrl_stop(ctrl, 0); 9600fbf3537Syasuoka return; 9610fbf3537Syasuoka } 9620fbf3537Syasuoka } 9630fbf3537Syasuoka if (hdr.ns != ctrl->rcv_nxt) { 964f0a4e295Syasuoka /* there are remaining packet */ 9650fbf3537Syasuoka if (l2tp_ctrl_resend_una_packets(ctrl) <= 0) { 966f0a4e295Syasuoka /* resend or sent ZLB */ 9670fbf3537Syasuoka l2tp_ctrl_send_ZLB(ctrl); 9680fbf3537Syasuoka } 9690fbf3537Syasuoka #ifdef L2TP_CTRL_DEBUG 970f0a4e295Syasuoka if (pktlen != 0) { /* not ZLB */ 9710fbf3537Syasuoka L2TP_CTRL_DBG((ctrl, LOG_DEBUG, 9720fbf3537Syasuoka "receive out of sequence %u must be %u. " 9730fbf3537Syasuoka "mestype=%s", hdr.ns, ctrl->rcv_nxt, 9740fbf3537Syasuoka avp_mes_type_string(mestype))); 9750fbf3537Syasuoka } 9760fbf3537Syasuoka #endif 9770fbf3537Syasuoka return; 9780fbf3537Syasuoka } 9790fbf3537Syasuoka if (pktlen <= 0) 9800fbf3537Syasuoka return; /* ZLB */ 9810fbf3537Syasuoka 9820fbf3537Syasuoka if (l2tp_ctrl_txwin_is_full(ctrl)) { 9830fbf3537Syasuoka L2TP_CTRL_DBG((ctrl, LOG_DEBUG, 9840fbf3537Syasuoka "Received message cannot be handled. " 9850fbf3537Syasuoka "Transmission window is full.")); 9860fbf3537Syasuoka l2tp_ctrl_send_ZLB(ctrl); 9870fbf3537Syasuoka return; 9880fbf3537Syasuoka } 9890fbf3537Syasuoka 9900fbf3537Syasuoka ctrl->rcv_nxt++; 9910fbf3537Syasuoka if (avp == NULL) { 9920fbf3537Syasuoka l2tpd_log(_this, LOG_WARNING, 9930fbf3537Syasuoka "bad control message: no message-type AVP."); 994f0a4e295Syasuoka goto fail; 9950fbf3537Syasuoka } 9960fbf3537Syasuoka } 9970fbf3537Syasuoka 9980fbf3537Syasuoka /* 999f0a4e295Syasuoka * state machine (RFC2661 pp. 56-57) 10000fbf3537Syasuoka */ 10010fbf3537Syasuoka switch (ctrl->state) { 10020fbf3537Syasuoka case L2TP_CTRL_STATE_IDLE: 10030fbf3537Syasuoka switch (mestype) { 10040fbf3537Syasuoka case L2TP_AVP_MESSAGE_TYPE_SCCRQ: 10050fbf3537Syasuoka if (l2tp_ctrl_recv_SCCRQ(ctrl, pkt, pktlen, _this, 10060fbf3537Syasuoka peer) == 0) { 1007f0a4e295Syasuoka /* acceptable */ 10080fbf3537Syasuoka l2tp_ctrl_send_SCCRP(ctrl); 10090fbf3537Syasuoka ctrl->state = L2TP_CTRL_STATE_WAIT_CTL_CONN; 10100fbf3537Syasuoka return; 10110fbf3537Syasuoka } 10120fbf3537Syasuoka /* 1013f0a4e295Syasuoka * in case un-acceptable, it was already processed 1014f0a4e295Syasuoka * at l2tcp_ctrl_recv_SCCRQ 10150fbf3537Syasuoka */ 10160fbf3537Syasuoka return; 10170fbf3537Syasuoka case L2TP_AVP_MESSAGE_TYPE_SCCRP: 10180fbf3537Syasuoka /* 1019f0a4e295Syasuoka * RFC specifies that sent of StopCCN in the state, 1020f0a4e295Syasuoka * However as this implementation only support Passive 1021421b67a1Sjasper * open, this packet will not received. 10220fbf3537Syasuoka */ 1023f0a4e295Syasuoka /* FALLTHROUGH */ 10240fbf3537Syasuoka case L2TP_AVP_MESSAGE_TYPE_SCCCN: 10250fbf3537Syasuoka default: 10260fbf3537Syasuoka break; 10270fbf3537Syasuoka } 1028f0a4e295Syasuoka goto fsm_fail; 10290fbf3537Syasuoka 10300fbf3537Syasuoka case L2TP_CTRL_STATE_WAIT_CTL_CONN: 10310fbf3537Syasuoka /* Wait-Ctl-Conn */ 10320fbf3537Syasuoka switch (mestype) { 10330fbf3537Syasuoka case L2TP_AVP_MESSAGE_TYPE_SCCCN: 10340fbf3537Syasuoka l2tp_ctrl_log(ctrl, LOG_INFO, "RecvSCCN"); 10350fbf3537Syasuoka if (l2tp_ctrl_send_ZLB(ctrl) == 0) { 10360fbf3537Syasuoka ctrl->state = L2TP_CTRL_STATE_ESTABLISHED; 10370fbf3537Syasuoka } 10380fbf3537Syasuoka return; 10390fbf3537Syasuoka case L2TP_AVP_MESSAGE_TYPE_StopCCN: 10400fbf3537Syasuoka goto receive_stop_ccn; 10410fbf3537Syasuoka case L2TP_AVP_MESSAGE_TYPE_SCCRQ: 10420fbf3537Syasuoka case L2TP_AVP_MESSAGE_TYPE_SCCRP: 10430fbf3537Syasuoka default: 10440fbf3537Syasuoka break; 10450fbf3537Syasuoka } 1046f0a4e295Syasuoka break; /* fsm_fail */ 10470fbf3537Syasuoka case L2TP_CTRL_STATE_ESTABLISHED: 10480fbf3537Syasuoka /* Established */ 10490fbf3537Syasuoka switch (mestype) { 10500fbf3537Syasuoka case L2TP_AVP_MESSAGE_TYPE_SCCCN: 10510fbf3537Syasuoka case L2TP_AVP_MESSAGE_TYPE_SCCRQ: 10520fbf3537Syasuoka case L2TP_AVP_MESSAGE_TYPE_SCCRP: 10530fbf3537Syasuoka break; 10540fbf3537Syasuoka receive_stop_ccn: 10550fbf3537Syasuoka case L2TP_AVP_MESSAGE_TYPE_StopCCN: 10560fbf3537Syasuoka if (l2tp_ctrl_recv_StopCCN(ctrl, pkt, pktlen) == 0) { 10570fbf3537Syasuoka if (l2tp_ctrl_resend_una_packets(ctrl) <= 0) 10580fbf3537Syasuoka l2tp_ctrl_send_ZLB(ctrl); 10590fbf3537Syasuoka l2tp_ctrl_stop(ctrl, 0); 10600fbf3537Syasuoka return; 10610fbf3537Syasuoka } 10620fbf3537Syasuoka l2tp_ctrl_log(ctrl, LOG_ERR, "Received bad StopCCN"); 10630fbf3537Syasuoka l2tp_ctrl_send_ZLB(ctrl); 10640fbf3537Syasuoka l2tp_ctrl_stop(ctrl, 0); 10650fbf3537Syasuoka return; 10660fbf3537Syasuoka 10670fbf3537Syasuoka case L2TP_AVP_MESSAGE_TYPE_HELLO: 10680fbf3537Syasuoka if (l2tp_ctrl_resend_una_packets(ctrl) <= 0) 10690fbf3537Syasuoka l2tp_ctrl_send_ZLB(ctrl); 10700fbf3537Syasuoka return; 10710fbf3537Syasuoka case L2TP_AVP_MESSAGE_TYPE_CDN: 10720fbf3537Syasuoka case L2TP_AVP_MESSAGE_TYPE_ICRP: 10730fbf3537Syasuoka case L2TP_AVP_MESSAGE_TYPE_ICCN: 10740fbf3537Syasuoka if (call == NULL) { 10750fbf3537Syasuoka l2tp_ctrl_log(ctrl, LOG_INFO, 10760fbf3537Syasuoka "Unknown call message: %s", 10770fbf3537Syasuoka avp_mes_type_string(mestype)); 1078f0a4e295Syasuoka goto fail; 10790fbf3537Syasuoka } 1080f0a4e295Syasuoka /* FALLTHROUGH */ 10810fbf3537Syasuoka case L2TP_AVP_MESSAGE_TYPE_ICRQ: 10820fbf3537Syasuoka l2tp_call_recv_packet(ctrl, call, mestype, pkt, 10830fbf3537Syasuoka pktlen); 10840fbf3537Syasuoka return; 10850fbf3537Syasuoka default: 10860fbf3537Syasuoka break; 10870fbf3537Syasuoka } 1088f0a4e295Syasuoka break; /* fsm_fail */ 10890fbf3537Syasuoka case L2TP_CTRL_STATE_CLEANUP_WAIT: 10900fbf3537Syasuoka if (mestype == L2TP_AVP_MESSAGE_TYPE_StopCCN) { 10910fbf3537Syasuoka /* 1092f0a4e295Syasuoka * We left ESTABLISHED state, but the peer sent StopCCN. 10930fbf3537Syasuoka */ 10940fbf3537Syasuoka goto receive_stop_ccn; 10950fbf3537Syasuoka } 1096f0a4e295Syasuoka break; /* fsm_fail */ 10970fbf3537Syasuoka } 10980fbf3537Syasuoka 1099f0a4e295Syasuoka fsm_fail: 1100f0a4e295Syasuoka /* state machine error */ 11010fbf3537Syasuoka l2tp_ctrl_log(ctrl, LOG_WARNING, "Received %s in '%s' state", 11020fbf3537Syasuoka avp_mes_type_string(mestype), l2tp_ctrl_state_string(ctrl)); 11030fbf3537Syasuoka l2tp_ctrl_stop(ctrl, L2TP_STOP_CCN_RCODE_FSM_ERROR); 11040fbf3537Syasuoka 11050fbf3537Syasuoka return; 1106f0a4e295Syasuoka fail: 11070fbf3537Syasuoka if (ctrl != NULL && mestype != 0) { 11080fbf3537Syasuoka l2tp_ctrl_log(ctrl, LOG_WARNING, "Received %s in '%s' state", 11090fbf3537Syasuoka avp_mes_type_string(mestype), l2tp_ctrl_state_string(ctrl)); 11100fbf3537Syasuoka l2tp_ctrl_stop(ctrl, L2TP_STOP_CCN_RCODE_GENERAL_ERROR); 11110fbf3537Syasuoka } 11120fbf3537Syasuoka return; 11130fbf3537Syasuoka 11140fbf3537Syasuoka bad_packet: 1115886d2b78Syasuoka l2tpd_log(_this, LOG_INFO, "Received from=%s: %s", 1116886d2b78Syasuoka addrport_tostring(peer, peer->sa_len, hbuf, sizeof(hbuf)), errmsg); 1117886d2b78Syasuoka 11180fbf3537Syasuoka return; 11190fbf3537Syasuoka } 11200fbf3537Syasuoka 11210fbf3537Syasuoka static inline int 11220fbf3537Syasuoka l2tp_ctrl_txwin_size(l2tp_ctrl *_this) 11230fbf3537Syasuoka { 11240fbf3537Syasuoka uint16_t sz; 11250fbf3537Syasuoka 11260fbf3537Syasuoka sz = _this->snd_nxt - _this->snd_una; 11270fbf3537Syasuoka 11280fbf3537Syasuoka L2TP_CTRL_ASSERT(sz <= _this->winsz); 11290fbf3537Syasuoka 11300fbf3537Syasuoka return sz; 11310fbf3537Syasuoka } 11320fbf3537Syasuoka 11330fbf3537Syasuoka static inline int 11340fbf3537Syasuoka l2tp_ctrl_txwin_is_full(l2tp_ctrl *_this) 11350fbf3537Syasuoka { 11360fbf3537Syasuoka return (l2tp_ctrl_txwin_size(_this) >= _this->winsz)? 1 : 0; 11370fbf3537Syasuoka } 11380fbf3537Syasuoka 1139f0a4e295Syasuoka /* send control packet */ 11400fbf3537Syasuoka int 11419a200ddfSyasuoka l2tp_ctrl_send_packet(l2tp_ctrl *_this, int call_id, bytebuffer *bytebuf) 11420fbf3537Syasuoka { 11430fbf3537Syasuoka struct l2tp_header *hdr; 11449a200ddfSyasuoka int rval; 11450fbf3537Syasuoka time_t curr_time; 11460fbf3537Syasuoka 11470fbf3537Syasuoka curr_time = get_monosec(); 11480fbf3537Syasuoka 11490fbf3537Syasuoka bytebuffer_flip(bytebuf); 11500fbf3537Syasuoka hdr = (struct l2tp_header *)bytebuffer_pointer(bytebuf); 11510fbf3537Syasuoka memset(hdr, 0, sizeof(*hdr)); 11520fbf3537Syasuoka 11530fbf3537Syasuoka hdr->t = 1; 11540fbf3537Syasuoka hdr->ver = L2TP_HEADER_VERSION_RFC2661; 11550fbf3537Syasuoka hdr->l = 1; 11560fbf3537Syasuoka hdr->length = htons(bytebuffer_remaining(bytebuf)); 11570fbf3537Syasuoka hdr->tunnel_id = htons(_this->peer_tunnel_id); 11580fbf3537Syasuoka hdr->session_id = htons(call_id); 11590fbf3537Syasuoka 11600fbf3537Syasuoka hdr->s = 1; 11610fbf3537Syasuoka hdr->ns = htons(_this->snd_nxt); 11620fbf3537Syasuoka hdr->nr = htons(_this->rcv_nxt); 11630fbf3537Syasuoka 11649a200ddfSyasuoka if (bytebuffer_remaining(bytebuf) > sizeof(struct l2tp_header)) 11650fbf3537Syasuoka /* Not ZLB */ 11660fbf3537Syasuoka _this->snd_nxt++; 11670fbf3537Syasuoka 11680fbf3537Syasuoka L2TP_CTRL_DBG((_this, DEBUG_LEVEL_2, 11699a200ddfSyasuoka "SEND C ns=%u nr=%u snd_nxt=%u snd_una=%u rcv_nxt=%u ", 11709a200ddfSyasuoka ntohs(hdr->ns), htons(hdr->nr), 11710fbf3537Syasuoka _this->snd_nxt, _this->snd_una, _this->rcv_nxt)); 11720fbf3537Syasuoka 1173821f7c56Syasuoka if (L2TP_CTRL_CONF(_this)->ctrl_out_pktdump != 0) { 11740fbf3537Syasuoka l2tpd_log(_this->l2tpd, LOG_DEBUG, 11750fbf3537Syasuoka "L2TP Control output packet dump"); 11760fbf3537Syasuoka show_hd(debug_get_debugfp(), bytebuffer_pointer(bytebuf), 11770fbf3537Syasuoka bytebuffer_remaining(bytebuf)); 11780fbf3537Syasuoka } 11790fbf3537Syasuoka 11800fbf3537Syasuoka if ((rval = l2tp_ctrl_send(_this, bytebuffer_pointer(bytebuf), 11810fbf3537Syasuoka bytebuffer_remaining(bytebuf))) < 0) { 11820fbf3537Syasuoka L2TP_CTRL_DBG((_this, LOG_DEBUG, "sendto() failed: %m")); 11830fbf3537Syasuoka } 11840fbf3537Syasuoka 11850fbf3537Syasuoka _this->last_snd_ctrl = curr_time; 11860fbf3537Syasuoka 11870fbf3537Syasuoka return (rval == bytebuffer_remaining(bytebuf))? 0 : 1; 11880fbf3537Syasuoka } 11890fbf3537Syasuoka 1190f0a4e295Syasuoka /* 1191f0a4e295Syasuoka * receiver SCCRQ 11920fbf3537Syasuoka */ 11930fbf3537Syasuoka static int 11940fbf3537Syasuoka l2tp_ctrl_recv_SCCRQ(l2tp_ctrl *_this, u_char *pkt, int pktlen, l2tpd *_l2tpd, 11950fbf3537Syasuoka struct sockaddr *peer) 11960fbf3537Syasuoka { 11970fbf3537Syasuoka int avpsz, len, protover, protorev, firmrev, result; 11980fbf3537Syasuoka struct l2tp_avp *avp; 11990fbf3537Syasuoka char host[NI_MAXHOST], serv[NI_MAXSERV]; 12000fbf3537Syasuoka char buf[L2TP_AVP_MAXSIZ], emes[256], hostname[256], vendorname[256]; 12010fbf3537Syasuoka 12020fbf3537Syasuoka result = L2TP_STOP_CCN_RCODE_GENERAL_ERROR; 12030fbf3537Syasuoka strlcpy(hostname, "(no hostname)", sizeof(hostname)); 12040fbf3537Syasuoka strlcpy(vendorname, "(no vendorname)", sizeof(vendorname)); 12050fbf3537Syasuoka 12060fbf3537Syasuoka firmrev = 0; 12070fbf3537Syasuoka protover = 0; 12080fbf3537Syasuoka protorev = 0; 12090fbf3537Syasuoka avp = (struct l2tp_avp *)buf; 12100fbf3537Syasuoka while (pktlen >= 6 && (avpsz = avp_enum(avp, pkt, pktlen, 1)) > 0) { 12110fbf3537Syasuoka pkt += avpsz; 12120fbf3537Syasuoka pktlen -= avpsz; 12130fbf3537Syasuoka if (avp->vendor_id != 0) { 12140fbf3537Syasuoka L2TP_CTRL_DBG((_this, LOG_DEBUG, 12150fbf3537Syasuoka "Received a Vendor-specific AVP vendor-id=%d " 12160fbf3537Syasuoka "type=%d", avp->vendor_id, avp->attr_type)); 12170fbf3537Syasuoka continue; 12180fbf3537Syasuoka } 12190fbf3537Syasuoka switch (avp->attr_type) { 12200fbf3537Syasuoka case L2TP_AVP_TYPE_MESSAGE_TYPE: 12210fbf3537Syasuoka AVP_SIZE_CHECK(avp, ==, 8); 12220fbf3537Syasuoka continue; 12230fbf3537Syasuoka case L2TP_AVP_TYPE_PROTOCOL_VERSION: 12240fbf3537Syasuoka AVP_SIZE_CHECK(avp, ==, 8); 12250fbf3537Syasuoka protover = avp->attr_value[0]; 12260fbf3537Syasuoka protorev = avp->attr_value[1]; 12270fbf3537Syasuoka 12280fbf3537Syasuoka if (protover != L2TP_RFC2661_VERSION || 12290fbf3537Syasuoka protorev != L2TP_RFC2661_REVISION) { 12300fbf3537Syasuoka result = L2TP_STOP_CCN_RCODE_GENERAL_ERROR; 12310fbf3537Syasuoka snprintf(emes, sizeof(emes), 12320fbf3537Syasuoka "Peer's protocol version is not supported:" 12330fbf3537Syasuoka " %d.%d", protover, protorev); 12340fbf3537Syasuoka goto not_acceptable; 12350fbf3537Syasuoka } 12360fbf3537Syasuoka continue; 12370fbf3537Syasuoka case L2TP_AVP_TYPE_FRAMING_CAPABILITIES: 12380fbf3537Syasuoka AVP_SIZE_CHECK(avp, ==, 10); 12390fbf3537Syasuoka if ((avp_get_val32(avp) & L2TP_FRAMING_CAP_FLAGS_SYNC) 12400fbf3537Syasuoka == 0) { 12410fbf3537Syasuoka L2TP_CTRL_DBG((_this, LOG_DEBUG, "Peer doesn't " 12420fbf3537Syasuoka "support synchronous framing")); 12430fbf3537Syasuoka } 12440fbf3537Syasuoka continue; 12450fbf3537Syasuoka case L2TP_AVP_TYPE_BEARER_CAPABILITIES: 12460fbf3537Syasuoka AVP_SIZE_CHECK(avp, ==, 10); 12470fbf3537Syasuoka continue; 12480fbf3537Syasuoka case L2TP_AVP_TYPE_TIE_BREAKER: 12490fbf3537Syasuoka AVP_SIZE_CHECK(avp, ==, 14); 12500fbf3537Syasuoka /* 1251f0a4e295Syasuoka * As the implementation never send SCCRQ, 1252f0a4e295Syasuoka * the peer is always winner 12530fbf3537Syasuoka */ 12540fbf3537Syasuoka continue; 12550fbf3537Syasuoka case L2TP_AVP_TYPE_FIRMWARE_REVISION: 12560fbf3537Syasuoka AVP_SIZE_CHECK(avp, >=, 6); 12570fbf3537Syasuoka firmrev = avp_get_val16(avp); 12580fbf3537Syasuoka continue; 12590fbf3537Syasuoka case L2TP_AVP_TYPE_HOST_NAME: 12600fbf3537Syasuoka AVP_SIZE_CHECK(avp, >, 4); 1261dbad4650Sderaadt len = MINIMUM(sizeof(hostname) - 1, avp->length - 6); 12620fbf3537Syasuoka memcpy(hostname, avp->attr_value, len); 12630fbf3537Syasuoka hostname[len] = '\0'; 12640fbf3537Syasuoka continue; 12650fbf3537Syasuoka case L2TP_AVP_TYPE_VENDOR_NAME: 12660fbf3537Syasuoka AVP_SIZE_CHECK(avp, >, 4); 1267dbad4650Sderaadt len = MINIMUM(sizeof(vendorname) - 1, avp->length - 6); 12680fbf3537Syasuoka memcpy(vendorname, avp->attr_value, len); 12690fbf3537Syasuoka vendorname[len] = '\0'; 12700fbf3537Syasuoka continue; 12710fbf3537Syasuoka case L2TP_AVP_TYPE_ASSINGED_TUNNEL_ID: 12720fbf3537Syasuoka AVP_SIZE_CHECK(avp, ==, 8); 12730fbf3537Syasuoka _this->peer_tunnel_id = avp_get_val16(avp); 12740fbf3537Syasuoka continue; 12750fbf3537Syasuoka case L2TP_AVP_TYPE_RECV_WINDOW_SIZE: 12760fbf3537Syasuoka AVP_SIZE_CHECK(avp, ==, 8); 12770fbf3537Syasuoka _this->peer_winsz = avp_get_val16(avp); 12780fbf3537Syasuoka continue; 12790fbf3537Syasuoka } 12800fbf3537Syasuoka if (avp->is_mandatory) { 12810fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_WARNING, 12820fbf3537Syasuoka "Received AVP (%s/%d) is not supported, but it's " 12830fbf3537Syasuoka "mandatory", avp_attr_type_string(avp->attr_type), 12840fbf3537Syasuoka avp->attr_type); 12850fbf3537Syasuoka #ifdef L2TP_CTRL_DEBUG 12860fbf3537Syasuoka } else { 12870fbf3537Syasuoka L2TP_CTRL_DBG((_this, LOG_DEBUG, 12880fbf3537Syasuoka "AVP (%s/%d) is not handled", 12890fbf3537Syasuoka avp_attr_type_string(avp->attr_type), 12900fbf3537Syasuoka avp->attr_type)); 12910fbf3537Syasuoka #endif 12920fbf3537Syasuoka } 12930fbf3537Syasuoka } 12940fbf3537Syasuoka if (getnameinfo((struct sockaddr *)&_this->peer, _this->peer.ss_len, 12950fbf3537Syasuoka host, sizeof(host), serv, sizeof(serv), 12960fbf3537Syasuoka NI_NUMERICHOST | NI_NUMERICSERV | NI_DGRAM) != 0) { 12970fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_ERR, 12980fbf3537Syasuoka "getnameinfo() failed at %s(): %m", __func__); 12990fbf3537Syasuoka strlcpy(host, "error", sizeof(host)); 13000fbf3537Syasuoka strlcpy(serv, "error", sizeof(serv)); 13010fbf3537Syasuoka } 13020fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_NOTICE, "logtype=Started RecvSCCRQ " 13030fbf3537Syasuoka "from=%s:%s/udp tunnel_id=%u/%u protocol=%d.%d winsize=%d " 13040fbf3537Syasuoka "hostname=%s vendor=%s firm=%04X", host, serv, _this->tunnel_id, 13050fbf3537Syasuoka _this->peer_tunnel_id, protover, protorev, _this->peer_winsz, 13060fbf3537Syasuoka hostname, vendorname, firmrev); 13070fbf3537Syasuoka 13080fbf3537Syasuoka return 0; 13090fbf3537Syasuoka not_acceptable: 13100fbf3537Syasuoka size_check_failed: 13110fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_ERR, "Received bad SCCRQ: %s", emes); 13120fbf3537Syasuoka l2tp_ctrl_stop(_this, result); 13130fbf3537Syasuoka 13140fbf3537Syasuoka return 1; 13150fbf3537Syasuoka } 13160fbf3537Syasuoka 1317f0a4e295Syasuoka /* 1318f0a4e295Syasuoka * send StopCCN 13190fbf3537Syasuoka */ 13200fbf3537Syasuoka static int 13210fbf3537Syasuoka l2tp_ctrl_send_StopCCN(l2tp_ctrl *_this, int result) 13220fbf3537Syasuoka { 13230fbf3537Syasuoka struct l2tp_avp *avp; 13240fbf3537Syasuoka char buf[L2TP_AVP_MAXSIZ]; 13250fbf3537Syasuoka bytebuffer *bytebuf; 13260fbf3537Syasuoka 13270fbf3537Syasuoka if ((bytebuf = l2tp_ctrl_prepare_snd_buffer(_this, 1)) == NULL) { 13280fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_ERR, 13290fbf3537Syasuoka "sending StopCCN failed: no buffer."); 13300fbf3537Syasuoka return -1; 13310fbf3537Syasuoka } 13320fbf3537Syasuoka avp = (struct l2tp_avp *)buf; 13330fbf3537Syasuoka 13340fbf3537Syasuoka /* Message Type = StopCCN */ 13350fbf3537Syasuoka memset(avp, 0, sizeof(*avp)); 13360fbf3537Syasuoka avp->is_mandatory = 1; 13370fbf3537Syasuoka avp->attr_type = L2TP_AVP_TYPE_MESSAGE_TYPE; 13380fbf3537Syasuoka avp_set_val16(avp, L2TP_AVP_MESSAGE_TYPE_StopCCN); 13390fbf3537Syasuoka bytebuf_add_avp(bytebuf, avp, 2); 13400fbf3537Syasuoka 13410fbf3537Syasuoka /* Assigned Tunnel Id */ 13420fbf3537Syasuoka memset(avp, 0, sizeof(*avp)); 13430fbf3537Syasuoka avp->is_mandatory = 1; 13440fbf3537Syasuoka avp->attr_type = L2TP_AVP_TYPE_ASSINGED_TUNNEL_ID; 13450fbf3537Syasuoka avp_set_val16(avp, _this->tunnel_id); 13460fbf3537Syasuoka bytebuf_add_avp(bytebuf, avp, 2); 13470fbf3537Syasuoka 13480fbf3537Syasuoka /* Result Code */ 13490fbf3537Syasuoka memset(avp, 0, sizeof(*avp)); 13500fbf3537Syasuoka avp->is_mandatory = 1; 13510fbf3537Syasuoka avp->attr_type = L2TP_AVP_TYPE_RESULT_CODE; 13520fbf3537Syasuoka avp_set_val16(avp, result); 13530fbf3537Syasuoka bytebuf_add_avp(bytebuf, avp, 2); 13540fbf3537Syasuoka 13559a200ddfSyasuoka if (l2tp_ctrl_send_packet(_this, 0, bytebuf) != 0) { 13569a200ddfSyasuoka l2tp_ctrl_log(_this, LOG_ERR, "sending StopCCN failed"); 13570fbf3537Syasuoka return - 1; 13580fbf3537Syasuoka } 13590fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_INFO, "SendStopCCN result=%d", result); 13600fbf3537Syasuoka 13610fbf3537Syasuoka return 0; 13620fbf3537Syasuoka } 13630fbf3537Syasuoka 1364f0a4e295Syasuoka /* 1365f0a4e295Syasuoka * Receiver StopCCN 13660fbf3537Syasuoka */ 13670fbf3537Syasuoka static int 13680fbf3537Syasuoka l2tp_ctrl_recv_StopCCN(l2tp_ctrl *_this, u_char *pkt, int pktlen) 13690fbf3537Syasuoka { 1370b01648a9Syasuoka int result, error, avpsz, len; 1371b01648a9Syasuoka uint16_t tunid; 13720fbf3537Syasuoka struct l2tp_avp *avp; 1373b01648a9Syasuoka char buf[L2TP_AVP_MAXSIZ + 16], emes[256], pmes[256]; 13740fbf3537Syasuoka 1375b01648a9Syasuoka result = 0; 1376b01648a9Syasuoka error = 0; 13770fbf3537Syasuoka tunid = 0; 1378b01648a9Syasuoka pmes[0] = '\0'; 13790fbf3537Syasuoka avp = (struct l2tp_avp *)buf; 13800fbf3537Syasuoka while (pktlen >= 6 && (avpsz = avp_enum(avp, pkt, pktlen, 1)) > 0) { 13810fbf3537Syasuoka pkt += avpsz; 13820fbf3537Syasuoka pktlen -= avpsz; 13830fbf3537Syasuoka if (avp->vendor_id != 0) { 13840fbf3537Syasuoka L2TP_CTRL_DBG((_this, LOG_DEBUG, 13850fbf3537Syasuoka "Received a Vendor-specific AVP vendor-id=%d " 13860fbf3537Syasuoka "type=%d", avp->vendor_id, avp->attr_type)); 13870fbf3537Syasuoka continue; 13880fbf3537Syasuoka } 13890fbf3537Syasuoka if (avp->is_hidden != 0) { 13900fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_WARNING, 13910fbf3537Syasuoka "Received AVP (%s/%d) is hidden. But we don't " 13920fbf3537Syasuoka "share secret.", 13930fbf3537Syasuoka avp_attr_type_string(avp->attr_type), 13940fbf3537Syasuoka avp->attr_type); 13950fbf3537Syasuoka if (avp->is_mandatory != 0) { 13960fbf3537Syasuoka l2tp_ctrl_stop(_this, 13970fbf3537Syasuoka L2TP_STOP_CCN_RCODE_GENERAL_ERROR | 13980fbf3537Syasuoka L2TP_ECODE_UNKNOWN_MANDATORY_AVP); 13990fbf3537Syasuoka return 1; 14000fbf3537Syasuoka } 14010fbf3537Syasuoka continue; 14020fbf3537Syasuoka } 14030fbf3537Syasuoka switch (avp->attr_type) { 14040fbf3537Syasuoka case L2TP_AVP_TYPE_MESSAGE_TYPE: 14050fbf3537Syasuoka AVP_SIZE_CHECK(avp, ==, 8); 14060fbf3537Syasuoka continue; 14070fbf3537Syasuoka case L2TP_AVP_TYPE_RESULT_CODE: 1408b01648a9Syasuoka AVP_SIZE_CHECK(avp, >=, 8); 1409b01648a9Syasuoka result = avp->attr_value[0] << 8 | avp->attr_value[1]; 1410b01648a9Syasuoka if (avp->length >= 10) { 1411b01648a9Syasuoka error = avp->attr_value[2] << 8 | 1412b01648a9Syasuoka avp->attr_value[3]; 1413b01648a9Syasuoka len = avp->length - 12; 1414b01648a9Syasuoka if (len > 0) { 1415dbad4650Sderaadt len = MINIMUM(len, sizeof(pmes) - 1); 1416b01648a9Syasuoka memcpy(pmes, &avp->attr_value[4], len); 1417b01648a9Syasuoka pmes[len] = '\0'; 1418b01648a9Syasuoka } 14190fbf3537Syasuoka } 14200fbf3537Syasuoka continue; 14210fbf3537Syasuoka case L2TP_AVP_TYPE_ASSINGED_TUNNEL_ID: 14220fbf3537Syasuoka AVP_SIZE_CHECK(avp, ==, 8); 14230fbf3537Syasuoka tunid = avp_get_val16(avp); 14240fbf3537Syasuoka continue; 14250fbf3537Syasuoka default: 14260fbf3537Syasuoka if (avp->is_mandatory != 0) { 14270fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_WARNING, 14280fbf3537Syasuoka "Received AVP (%s/%d) is not supported, " 14290fbf3537Syasuoka "but it's mandatory", 14300fbf3537Syasuoka avp_attr_type_string(avp->attr_type), 14310fbf3537Syasuoka avp->attr_type); 14320fbf3537Syasuoka #ifdef L2TP_CTRL_DEBUG 14330fbf3537Syasuoka } else { 14340fbf3537Syasuoka L2TP_CTRL_DBG((_this, LOG_DEBUG, 14350fbf3537Syasuoka "AVP (%s/%d) is not handled", 14360fbf3537Syasuoka avp_attr_type_string(avp->attr_type), 14370fbf3537Syasuoka avp->attr_type)); 14380fbf3537Syasuoka #endif 14390fbf3537Syasuoka } 14400fbf3537Syasuoka } 14410fbf3537Syasuoka } 14420fbf3537Syasuoka 1443b01648a9Syasuoka if (result == L2TP_CDN_RCODE_ERROR_CODE && 1444b01648a9Syasuoka error == L2TP_ECODE_NO_RESOURCE) { 14450fbf3537Syasuoka /* 1446f0a4e295Syasuoka * Memo: 1447f0a4e295Syasuoka * This state may be happen in following state. 1448f0a4e295Syasuoka * - lots of connect/disconect by long-running 1449f0a4e295Syasuoka * windows2000, sometimes it fall to this state. 1450f0a4e295Syasuoka * Once it fall to here, connection will fail till 1451f0a4e295Syasuoka * the windows rebooted 14520fbf3537Syasuoka */ 14530fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_WARNING, 14540fbf3537Syasuoka "Peer indicates \"No Resource\" error."); 14550fbf3537Syasuoka } 14560fbf3537Syasuoka 14570fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_INFO, "RecvStopCCN result=%s/%u " 14580fbf3537Syasuoka "error=%s/%u tunnel_id=%u message=\"%s\"", 1459b01648a9Syasuoka l2tp_stopccn_rcode_string(result), result, 1460b01648a9Syasuoka l2tp_ecode_string(error), error, tunid, pmes); 14610fbf3537Syasuoka 14620fbf3537Syasuoka return 0; 14630fbf3537Syasuoka 14640fbf3537Syasuoka size_check_failed: 14650fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_ERR, "Received bad StopCCN: %s", emes); 14660fbf3537Syasuoka 14670fbf3537Syasuoka return -1; 14680fbf3537Syasuoka } 14690fbf3537Syasuoka 1470f0a4e295Syasuoka /* 1471f0a4e295Syasuoka * send SCCRP 14720fbf3537Syasuoka */ 14730fbf3537Syasuoka static void 14740fbf3537Syasuoka l2tp_ctrl_send_SCCRP(l2tp_ctrl *_this) 14750fbf3537Syasuoka { 14760fbf3537Syasuoka int len; 14770fbf3537Syasuoka struct l2tp_avp *avp; 1478dbad4650Sderaadt char buf[L2TP_AVP_MAXSIZ], hbuf[HOST_NAME_MAX+1]; 14790fbf3537Syasuoka const char *val; 14800fbf3537Syasuoka bytebuffer *bytebuf; 14810fbf3537Syasuoka 14820fbf3537Syasuoka if ((bytebuf = l2tp_ctrl_prepare_snd_buffer(_this, 1)) == NULL) { 14830fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_ERR, 14840fbf3537Syasuoka "sending SCCRP failed: no buffer."); 14850fbf3537Syasuoka return; 14860fbf3537Syasuoka } 14870fbf3537Syasuoka avp = (struct l2tp_avp *)buf; 14880fbf3537Syasuoka 14890fbf3537Syasuoka /* Message Type = SCCRP */ 14900fbf3537Syasuoka memset(avp, 0, sizeof(*avp)); 14910fbf3537Syasuoka avp->is_mandatory = 1; 14920fbf3537Syasuoka avp->attr_type = L2TP_AVP_TYPE_MESSAGE_TYPE; 14930fbf3537Syasuoka avp_set_val16(avp, L2TP_AVP_MESSAGE_TYPE_SCCRP); 14940fbf3537Syasuoka bytebuf_add_avp(bytebuf, avp, 2); 14950fbf3537Syasuoka 14960fbf3537Syasuoka /* Protocol Version = 1.0 */ 14970fbf3537Syasuoka memset(avp, 0, sizeof(*avp)); 14980fbf3537Syasuoka avp->is_mandatory = 1; 14990fbf3537Syasuoka avp->attr_type = L2TP_AVP_TYPE_PROTOCOL_VERSION; 15000fbf3537Syasuoka avp->attr_value[0] = L2TP_RFC2661_VERSION; 15010fbf3537Syasuoka avp->attr_value[1] = L2TP_RFC2661_REVISION; 15020fbf3537Syasuoka bytebuf_add_avp(bytebuf, avp, 2); 15030fbf3537Syasuoka 15040fbf3537Syasuoka /* Framing Capability = Async */ 15050fbf3537Syasuoka memset(avp, 0, sizeof(*avp)); 15060fbf3537Syasuoka avp->is_mandatory = 1; 15070fbf3537Syasuoka avp->attr_type = L2TP_AVP_TYPE_FRAMING_CAPABILITIES; 15080fbf3537Syasuoka avp_set_val32(avp, L2TP_FRAMING_CAP_FLAGS_SYNC); 15090fbf3537Syasuoka bytebuf_add_avp(bytebuf, avp, 4); 15100fbf3537Syasuoka 15110fbf3537Syasuoka /* Host Name */ 15120fbf3537Syasuoka memset(avp, 0, sizeof(*avp)); 15130fbf3537Syasuoka avp->is_mandatory = 1; 15140fbf3537Syasuoka avp->attr_type = L2TP_AVP_TYPE_HOST_NAME; 151582c6995aSyasuoka if ((val = L2TP_CTRL_CONF(_this)->hostname) == NULL) { 151682c6995aSyasuoka gethostname(hbuf, sizeof(hbuf)); 151782c6995aSyasuoka val = hbuf; 151882c6995aSyasuoka } 15190fbf3537Syasuoka len = strlen(val); 15200fbf3537Syasuoka memcpy(avp->attr_value, val, len); 15210fbf3537Syasuoka bytebuf_add_avp(bytebuf, avp, len); 15220fbf3537Syasuoka 15230fbf3537Syasuoka /* Assigned Tunnel Id */ 15240fbf3537Syasuoka memset(avp, 0, sizeof(*avp)); 15250fbf3537Syasuoka avp->is_mandatory = 1; 15260fbf3537Syasuoka avp->attr_type = L2TP_AVP_TYPE_ASSINGED_TUNNEL_ID; 15270fbf3537Syasuoka avp_set_val16(avp, _this->tunnel_id); 15280fbf3537Syasuoka bytebuf_add_avp(bytebuf, avp, 2); 15290fbf3537Syasuoka 15300fbf3537Syasuoka /* Bearer Capability 1531f0a4e295Syasuoka * This implementation never act as LAC. 15320fbf3537Syasuoka * 15330fbf3537Syasuoka memset(avp, 0, sizeof(*avp)); 15340fbf3537Syasuoka avp->is_mandatory = 1; 15350fbf3537Syasuoka avp->attr_type = L2TP_AVP_TYPE_BEARER_CAPABILITIES; 15360fbf3537Syasuoka avp_set_val32(avp, 0); 15370fbf3537Syasuoka bytebuf_add_avp(bytebuf, avp, 4); 15380fbf3537Syasuoka */ 15390fbf3537Syasuoka 15400fbf3537Syasuoka /* Firmware Revision */ 15410fbf3537Syasuoka memset(avp, 0, sizeof(*avp)); 154282c6995aSyasuoka avp->is_mandatory = 0; 15430fbf3537Syasuoka avp->attr_type = L2TP_AVP_TYPE_FIRMWARE_REVISION; 15440fbf3537Syasuoka avp->attr_value[0] = MAJOR_VERSION; 15450fbf3537Syasuoka avp->attr_value[1] = MINOR_VERSION; 15460fbf3537Syasuoka bytebuf_add_avp(bytebuf, avp, 2); 15470fbf3537Syasuoka 154882c6995aSyasuoka /* Vendor Name */ 154982c6995aSyasuoka if ((val = L2TP_CTRL_CONF(_this)->vendor_name) != NULL) { 15500fbf3537Syasuoka memset(avp, 0, sizeof(*avp)); 155182c6995aSyasuoka avp->is_mandatory = 0; 15520fbf3537Syasuoka avp->attr_type = L2TP_AVP_TYPE_VENDOR_NAME; 15530fbf3537Syasuoka 15540fbf3537Syasuoka len = strlen(val); 15550fbf3537Syasuoka memcpy(avp->attr_value, val, len); 15560fbf3537Syasuoka bytebuf_add_avp(bytebuf, avp, len); 155782c6995aSyasuoka } 15580fbf3537Syasuoka 15590fbf3537Syasuoka /* Window Size */ 15600fbf3537Syasuoka memset(avp, 0, sizeof(*avp)); 15610fbf3537Syasuoka avp->is_mandatory = 1; 15620fbf3537Syasuoka avp->attr_type = L2TP_AVP_TYPE_RECV_WINDOW_SIZE; 15630fbf3537Syasuoka avp_set_val16(avp, _this->winsz); 15640fbf3537Syasuoka bytebuf_add_avp(bytebuf, avp, 2); 15650fbf3537Syasuoka 15669a200ddfSyasuoka if ((l2tp_ctrl_send_packet(_this, 0, bytebuf)) != 0) { 15670fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_ERR, "sending SCCRP failed"); 15680fbf3537Syasuoka l2tp_ctrl_stop(_this, L2TP_STOP_CCN_RCODE_GENERAL); 15690fbf3537Syasuoka return; 15700fbf3537Syasuoka } 15710fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_INFO, "SendSCCRP"); 15720fbf3537Syasuoka } 15730fbf3537Syasuoka 15740fbf3537Syasuoka static int 15750fbf3537Syasuoka l2tp_ctrl_send_HELLO(l2tp_ctrl *_this) 15760fbf3537Syasuoka { 15770fbf3537Syasuoka struct l2tp_avp *avp; 15780fbf3537Syasuoka char buf[L2TP_AVP_MAXSIZ]; 15790fbf3537Syasuoka bytebuffer *bytebuf; 15800fbf3537Syasuoka 15810fbf3537Syasuoka if ((bytebuf = l2tp_ctrl_prepare_snd_buffer(_this, 1)) == NULL) { 15820fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_ERR, 15830fbf3537Syasuoka "sending SCCRP failed: no buffer."); 15840fbf3537Syasuoka return 1; 15850fbf3537Syasuoka } 15860fbf3537Syasuoka avp = (struct l2tp_avp *)buf; 15870fbf3537Syasuoka 15880fbf3537Syasuoka /* Message Type = HELLO */ 15890fbf3537Syasuoka memset(avp, 0, sizeof(*avp)); 15900fbf3537Syasuoka avp->is_mandatory = 1; 15910fbf3537Syasuoka avp->attr_type = L2TP_AVP_TYPE_MESSAGE_TYPE; 15920fbf3537Syasuoka avp_set_val16(avp, L2TP_AVP_MESSAGE_TYPE_HELLO); 15930fbf3537Syasuoka bytebuf_add_avp(bytebuf, avp, 2); 15940fbf3537Syasuoka 15959a200ddfSyasuoka if ((l2tp_ctrl_send_packet(_this, 0, bytebuf)) != 0) { 15960fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_ERR, "sending HELLO failed"); 15970fbf3537Syasuoka l2tp_ctrl_stop(_this, L2TP_STOP_CCN_RCODE_GENERAL); 15980fbf3537Syasuoka return 1; 15990fbf3537Syasuoka } 16000fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_DEBUG, "SendHELLO"); 16010fbf3537Syasuoka 16020fbf3537Syasuoka return 0; 16030fbf3537Syasuoka } 16040fbf3537Syasuoka 1605f0a4e295Syasuoka /* Send ZLB */ 16060fbf3537Syasuoka static int 16070fbf3537Syasuoka l2tp_ctrl_send_ZLB(l2tp_ctrl *_this) 16080fbf3537Syasuoka { 16090fbf3537Syasuoka int loglevel; 16100fbf3537Syasuoka 16110fbf3537Syasuoka loglevel = (_this->state == L2TP_CTRL_STATE_ESTABLISHED) 16120fbf3537Syasuoka ? LOG_DEBUG : LOG_INFO; 16130fbf3537Syasuoka l2tp_ctrl_log(_this, loglevel, "SendZLB"); 16140fbf3537Syasuoka bytebuffer_clear(_this->zlb_buffer); 16150fbf3537Syasuoka bytebuffer_put(_this->zlb_buffer, BYTEBUFFER_PUT_DIRECT, 16160fbf3537Syasuoka sizeof(struct l2tp_header)); 16170fbf3537Syasuoka 16189a200ddfSyasuoka return l2tp_ctrl_send_packet(_this, 0, _this->zlb_buffer); 16190fbf3537Syasuoka } 16200fbf3537Syasuoka 1621f0a4e295Syasuoka /* 1622f0a4e295Syasuoka * Utitlity 1623f0a4e295Syasuoka */ 1624f0a4e295Syasuoka 16250fbf3537Syasuoka /** 1626f0a4e295Syasuoka * Prepare send buffer 1627f0a4e295Syasuoka * @return return Null when the send buffer exceed Window. 16280fbf3537Syasuoka */ 16290fbf3537Syasuoka bytebuffer * 16300fbf3537Syasuoka l2tp_ctrl_prepare_snd_buffer(l2tp_ctrl *_this, int with_seq) 16310fbf3537Syasuoka { 16320fbf3537Syasuoka bytebuffer *bytebuf; 16330fbf3537Syasuoka 16340fbf3537Syasuoka L2TP_CTRL_ASSERT(_this != NULL); 16350fbf3537Syasuoka 16360fbf3537Syasuoka if (l2tp_ctrl_txwin_is_full(_this)) { 16370fbf3537Syasuoka l2tp_ctrl_log(_this, LOG_INFO, "sending buffer is full."); 16380fbf3537Syasuoka return NULL; 16390fbf3537Syasuoka } 16400fbf3537Syasuoka bytebuf = _this->snd_buffers[_this->snd_nxt % _this->winsz]; 16410fbf3537Syasuoka bytebuffer_clear(bytebuf); 16420fbf3537Syasuoka if (with_seq) 16430fbf3537Syasuoka bytebuffer_put(bytebuf, BYTEBUFFER_PUT_DIRECT, 16440fbf3537Syasuoka sizeof(struct l2tp_header)); 16450fbf3537Syasuoka else 16460fbf3537Syasuoka bytebuffer_put(bytebuf, BYTEBUFFER_PUT_DIRECT, 16470fbf3537Syasuoka offsetof(struct l2tp_header, ns)); 16480fbf3537Syasuoka 16490fbf3537Syasuoka return bytebuf; 16500fbf3537Syasuoka } 16510fbf3537Syasuoka 16520fbf3537Syasuoka /** 1653f0a4e295Syasuoka * return current state as strings 16540fbf3537Syasuoka */ 16550fbf3537Syasuoka static inline const char * 16560fbf3537Syasuoka l2tp_ctrl_state_string(l2tp_ctrl *_this) 16570fbf3537Syasuoka { 16580fbf3537Syasuoka switch (_this->state) { 16590fbf3537Syasuoka case L2TP_CTRL_STATE_IDLE: return "idle"; 16600fbf3537Syasuoka case L2TP_CTRL_STATE_WAIT_CTL_CONN: return "wait-ctl-conn"; 16610fbf3537Syasuoka case L2TP_CTRL_STATE_WAIT_CTL_REPLY: return "wait-ctl-reply"; 16620fbf3537Syasuoka case L2TP_CTRL_STATE_ESTABLISHED: return "established"; 16630fbf3537Syasuoka case L2TP_CTRL_STATE_CLEANUP_WAIT: return "cleanup-wait"; 16640fbf3537Syasuoka } 16650fbf3537Syasuoka return "unknown"; 16660fbf3537Syasuoka } 16670fbf3537Syasuoka 1668f0a4e295Syasuoka /* logging with the label of the l2tp instance. */ 16690fbf3537Syasuoka void 16700fbf3537Syasuoka l2tp_ctrl_log(l2tp_ctrl *_this, int prio, const char *fmt, ...) 16710fbf3537Syasuoka { 16720fbf3537Syasuoka char logbuf[BUFSIZ]; 16730fbf3537Syasuoka va_list ap; 16740fbf3537Syasuoka 16750fbf3537Syasuoka va_start(ap, fmt); 16767a7bab9dSyasuoka #ifdef L2TPD_MULTIPLE 16770fbf3537Syasuoka snprintf(logbuf, sizeof(logbuf), "l2tpd id=%u ctrl=%u %s", 16780fbf3537Syasuoka _this->l2tpd->id, _this->id, fmt); 16790fbf3537Syasuoka #else 16800fbf3537Syasuoka snprintf(logbuf, sizeof(logbuf), "l2tpd ctrl=%u %s", _this->id, fmt); 16810fbf3537Syasuoka #endif 16820fbf3537Syasuoka vlog_printf(prio, logbuf, ap); 16830fbf3537Syasuoka va_end(ap); 16840fbf3537Syasuoka } 1685