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