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