1 /* $OpenBSD: pipex.c,v 1.134 2021/07/20 16:44:55 mvs 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 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/mbuf.h> 32 #include <sys/socket.h> 33 #include <sys/ioctl.h> 34 #include <sys/select.h> 35 #include <sys/sysctl.h> 36 #include <sys/syslog.h> 37 #include <sys/conf.h> 38 #include <sys/time.h> 39 #include <sys/timeout.h> 40 #include <sys/kernel.h> 41 #include <sys/pool.h> 42 #include <sys/percpu.h> 43 44 #include <net/if.h> 45 #include <net/if_types.h> 46 #include <netinet/in.h> 47 #include <netinet/if_ether.h> 48 #include <net/if_dl.h> 49 50 #include <net/radix.h> 51 #include <net/route.h> 52 #include <net/ppp_defs.h> 53 #include <net/ppp-comp.h> 54 55 #include "pf.h" 56 #if NPF > 0 57 #include <net/pfvar.h> 58 #endif 59 60 #include "bpfilter.h" 61 #if NBPFILTER > 0 62 #include <net/bpf.h> 63 #endif 64 65 #include <netinet/ip.h> 66 #include <netinet/ip_var.h> 67 #ifdef INET6 68 #include <netinet/ip6.h> 69 #include <netinet6/ip6_var.h> 70 #endif 71 #include <netinet/tcp.h> 72 #include <netinet/udp.h> 73 #include <netinet/udp_var.h> 74 #include <crypto/arc4.h> 75 76 /* drop static for ddb debuggability */ 77 #define Static 78 79 #include <net/pipex.h> 80 #include "pipex_local.h" 81 82 struct pool pipex_session_pool; 83 struct pool mppe_key_pool; 84 85 /* 86 * Global data 87 * Locks used to protect global data 88 * A atomic operation 89 * I immutable after creation 90 * N net lock 91 */ 92 93 int pipex_enable = 0; /* [N] */ 94 struct pipex_hash_head 95 pipex_session_list, /* [N] master session list */ 96 pipex_close_wait_list, /* [N] expired session list */ 97 pipex_peer_addr_hashtable[PIPEX_HASH_SIZE], /* [N] peer's address hash */ 98 pipex_id_hashtable[PIPEX_HASH_SIZE]; /* [N] peer id hash */ 99 100 struct radix_node_head *pipex_rd_head4 = NULL; /* [N] */ 101 struct radix_node_head *pipex_rd_head6 = NULL; /* [N] */ 102 struct timeout pipex_timer_ch; /* callout timer context */ 103 int pipex_prune = 1; /* [I] walk list every seconds */ 104 105 /* borrow an mbuf pkthdr field */ 106 #define ph_ppp_proto ether_vtag 107 108 #ifdef PIPEX_DEBUG 109 int pipex_debug = 0; /* [A] systcl net.inet.ip.pipex_debug */ 110 #endif 111 112 /* PPP compression == MPPE is assumed, so don't answer CCP Reset-Request. */ 113 #define PIPEX_NO_CCP_RESETACK 1 114 115 /************************************************************************ 116 * Core functions 117 ************************************************************************/ 118 void 119 pipex_init(void) 120 { 121 int i; 122 static int pipex_init_done = 0; 123 124 if (pipex_init_done++) 125 return; 126 127 rn_init(sizeof(struct sockaddr_in6)); 128 129 pool_init(&pipex_session_pool, sizeof(struct pipex_session), 0, 130 IPL_SOFTNET, PR_WAITOK, "ppxss", NULL); 131 pool_init(&mppe_key_pool, PIPEX_MPPE_KEYLEN * PIPEX_MPPE_NOLDKEY, 0, 132 IPL_SOFTNET, PR_WAITOK, "mppekey", NULL); 133 134 LIST_INIT(&pipex_session_list); 135 LIST_INIT(&pipex_close_wait_list); 136 137 for (i = 0; i < nitems(pipex_id_hashtable); i++) 138 LIST_INIT(&pipex_id_hashtable[i]); 139 for (i = 0; i < nitems(pipex_peer_addr_hashtable); i++) 140 LIST_INIT(&pipex_peer_addr_hashtable[i]); 141 } 142 143 void 144 pipex_destroy_all_sessions(void *ownersc) 145 { 146 struct pipex_session *session, *session_tmp; 147 148 NET_ASSERT_LOCKED(); 149 150 LIST_FOREACH_SAFE(session, &pipex_session_list, session_list, 151 session_tmp) { 152 if (session->ownersc == ownersc) { 153 KASSERT(session->is_pppx == 0); 154 pipex_unlink_session(session); 155 pipex_rele_session(session); 156 } 157 } 158 } 159 160 int 161 pipex_ioctl(void *ownersc, u_long cmd, caddr_t data) 162 { 163 int ret = 0; 164 165 NET_ASSERT_LOCKED(); 166 switch (cmd) { 167 case PIPEXCSESSION: 168 ret = pipex_config_session( 169 (struct pipex_session_config_req *)data, ownersc); 170 break; 171 172 case PIPEXGSTAT: 173 ret = pipex_get_stat((struct pipex_session_stat_req *)data, 174 ownersc); 175 break; 176 177 case PIPEXGCLOSED: 178 ret = pipex_get_closed((struct pipex_session_list_req *)data, 179 ownersc); 180 break; 181 182 default: 183 ret = ENOTTY; 184 break; 185 } 186 187 return (ret); 188 } 189 190 /************************************************************************ 191 * Session management functions 192 ************************************************************************/ 193 int 194 pipex_init_session(struct pipex_session **rsession, 195 struct pipex_session_req *req) 196 { 197 struct pipex_session *session; 198 #ifdef PIPEX_PPPOE 199 struct ifnet *over_ifp = NULL; 200 #endif 201 202 /* Checks requeted parameters. */ 203 switch (req->pr_protocol) { 204 #ifdef PIPEX_PPPOE 205 case PIPEX_PROTO_PPPOE: 206 if (req->pr_peer_address.ss_family != AF_UNSPEC) 207 return (EINVAL); 208 break; 209 #endif 210 #if defined(PIPEX_L2TP) || defined(PIPEX_PPTP) 211 case PIPEX_PROTO_PPTP: 212 case PIPEX_PROTO_L2TP: 213 switch (req->pr_peer_address.ss_family) { 214 case AF_INET: 215 if (req->pr_peer_address.ss_len != 216 sizeof(struct sockaddr_in)) 217 return (EINVAL); 218 break; 219 #ifdef INET6 220 case AF_INET6: 221 if (req->pr_peer_address.ss_len != 222 sizeof(struct sockaddr_in6)) 223 return (EINVAL); 224 break; 225 #endif 226 default: 227 return (EPROTONOSUPPORT); 228 } 229 if (req->pr_peer_address.ss_family != 230 req->pr_local_address.ss_family || 231 req->pr_peer_address.ss_len != 232 req->pr_local_address.ss_len) 233 return (EINVAL); 234 break; 235 #endif /* defined(PIPEX_PPTP) || defined(PIPEX_L2TP) */ 236 default: 237 return (EPROTONOSUPPORT); 238 } 239 #ifdef PIPEX_MPPE 240 if ((req->pr_ppp_flags & PIPEX_PPP_MPPE_ACCEPTED) != 0) { 241 if (req->pr_mppe_recv.keylenbits <= 0) 242 return (EINVAL); 243 } 244 if ((req->pr_ppp_flags & PIPEX_PPP_MPPE_ENABLED) != 0) { 245 if (req->pr_mppe_send.keylenbits <= 0) 246 return (EINVAL); 247 } 248 if ((req->pr_ppp_flags & PIPEX_PPP_MPPE_REQUIRED) != 0) { 249 if ((req->pr_ppp_flags & 250 (PIPEX_PPP_MPPE_ACCEPTED | PIPEX_PPP_MPPE_ENABLED)) != 251 (PIPEX_PPP_MPPE_ACCEPTED | PIPEX_PPP_MPPE_ENABLED)) 252 return (EINVAL); 253 } 254 #endif 255 256 #ifdef PIPEX_PPPOE 257 if (req->pr_protocol == PIPEX_PROTO_PPPOE) { 258 over_ifp = if_unit(req->pr_proto.pppoe.over_ifname); 259 if (over_ifp == NULL) 260 return (EINVAL); 261 } 262 #endif 263 264 /* prepare a new session */ 265 session = pool_get(&pipex_session_pool, PR_WAITOK | PR_ZERO); 266 session->state = PIPEX_STATE_INITIAL; 267 session->protocol = req->pr_protocol; 268 session->session_id = req->pr_session_id; 269 session->peer_session_id = req->pr_peer_session_id; 270 session->peer_mru = req->pr_peer_mru; 271 session->timeout_sec = req->pr_timeout_sec; 272 session->ppp_flags = req->pr_ppp_flags; 273 session->ppp_id = req->pr_ppp_id; 274 275 session->ip_forward = 1; 276 277 session->stat_counters = counters_alloc(pxc_ncounters); 278 279 session->ip_address.sin_family = AF_INET; 280 session->ip_address.sin_len = sizeof(struct sockaddr_in); 281 session->ip_address.sin_addr = req->pr_ip_address; 282 283 session->ip_netmask.sin_family = AF_INET; 284 session->ip_netmask.sin_len = sizeof(struct sockaddr_in); 285 session->ip_netmask.sin_addr = req->pr_ip_netmask; 286 287 if (session->ip_netmask.sin_addr.s_addr == 0L) 288 session->ip_netmask.sin_addr.s_addr = 0xffffffffL; 289 session->ip_address.sin_addr.s_addr &= 290 session->ip_netmask.sin_addr.s_addr; 291 292 if (req->pr_peer_address.ss_len > 0) 293 memcpy(&session->peer, &req->pr_peer_address, 294 MIN(req->pr_peer_address.ss_len, sizeof(session->peer))); 295 if (req->pr_local_address.ss_len > 0) 296 memcpy(&session->local, &req->pr_local_address, 297 MIN(req->pr_local_address.ss_len, sizeof(session->local))); 298 #ifdef PIPEX_PPPOE 299 if (req->pr_protocol == PIPEX_PROTO_PPPOE) { 300 session->proto.pppoe.over_ifidx = over_ifp->if_index; 301 if_put(over_ifp); 302 } 303 #endif 304 #ifdef PIPEX_PPTP 305 if (req->pr_protocol == PIPEX_PROTO_PPTP) { 306 struct pipex_pptp_session *sess_pptp = &session->proto.pptp; 307 308 sess_pptp->snd_gap = 0; 309 sess_pptp->rcv_gap = 0; 310 sess_pptp->snd_una = req->pr_proto.pptp.snd_una; 311 sess_pptp->snd_nxt = req->pr_proto.pptp.snd_nxt; 312 sess_pptp->rcv_nxt = req->pr_proto.pptp.rcv_nxt; 313 sess_pptp->rcv_acked = req->pr_proto.pptp.rcv_acked; 314 315 sess_pptp->winsz = req->pr_proto.pptp.winsz; 316 sess_pptp->maxwinsz = req->pr_proto.pptp.maxwinsz; 317 sess_pptp->peer_maxwinsz = req->pr_proto.pptp.peer_maxwinsz; 318 /* last ack number */ 319 sess_pptp->ul_snd_una = sess_pptp->snd_una - 1; 320 } 321 #endif 322 #ifdef PIPEX_L2TP 323 if (req->pr_protocol == PIPEX_PROTO_L2TP) { 324 struct pipex_l2tp_session *sess_l2tp = &session->proto.l2tp; 325 326 /* session keys */ 327 sess_l2tp->tunnel_id = req->pr_proto.l2tp.tunnel_id; 328 sess_l2tp->peer_tunnel_id = req->pr_proto.l2tp.peer_tunnel_id; 329 330 /* protocol options */ 331 sess_l2tp->option_flags = req->pr_proto.l2tp.option_flags; 332 333 /* initial state of dynamic context */ 334 sess_l2tp->ns_gap = sess_l2tp->nr_gap = 0; 335 sess_l2tp->ns_nxt = req->pr_proto.l2tp.ns_nxt; 336 sess_l2tp->nr_nxt = req->pr_proto.l2tp.nr_nxt; 337 sess_l2tp->ns_una = req->pr_proto.l2tp.ns_una; 338 sess_l2tp->nr_acked = req->pr_proto.l2tp.nr_acked; 339 /* last ack number */ 340 sess_l2tp->ul_ns_una = sess_l2tp->ns_una - 1; 341 sess_l2tp->ipsecflowinfo = req->pr_proto.l2tp.ipsecflowinfo; 342 } 343 #endif 344 #ifdef PIPEX_MPPE 345 if ((req->pr_ppp_flags & PIPEX_PPP_MPPE_ACCEPTED) != 0) { 346 pipex_session_init_mppe_recv(session, 347 req->pr_mppe_recv.stateless, req->pr_mppe_recv.keylenbits, 348 req->pr_mppe_recv.master_key); 349 } 350 if ((req->pr_ppp_flags & PIPEX_PPP_MPPE_ENABLED) != 0) { 351 pipex_session_init_mppe_send(session, 352 req->pr_mppe_send.stateless, req->pr_mppe_send.keylenbits, 353 req->pr_mppe_send.master_key); 354 } 355 #endif 356 357 *rsession = session; 358 359 return 0; 360 } 361 362 void 363 pipex_rele_session(struct pipex_session *session) 364 { 365 if (session->mppe_recv.old_session_keys) 366 pool_put(&mppe_key_pool, session->mppe_recv.old_session_keys); 367 counters_free(session->stat_counters, pxc_ncounters); 368 pool_put(&pipex_session_pool, session); 369 } 370 371 int 372 pipex_link_session(struct pipex_session *session, struct ifnet *ifp, 373 void *ownersc) 374 { 375 struct pipex_hash_head *chain; 376 struct radix_node *rn; 377 378 NET_ASSERT_LOCKED(); 379 380 if (pipex_rd_head4 == NULL) { 381 if (!rn_inithead((void **)&pipex_rd_head4, 382 offsetof(struct sockaddr_in, sin_addr))) 383 panic("rn_inithead() failed on pipex_link_session()"); 384 } 385 if (pipex_rd_head6 == NULL) { 386 if (!rn_inithead((void **)&pipex_rd_head6, 387 offsetof(struct sockaddr_in6, sin6_addr))) 388 panic("rn_inithead() failed on pipex_link_session()"); 389 } 390 if (pipex_lookup_by_session_id(session->protocol, 391 session->session_id)) 392 return (EEXIST); 393 394 session->ownersc = ownersc; 395 session->ifindex = ifp->if_index; 396 if (ifp->if_flags & IFF_POINTOPOINT) 397 session->is_pppx = 1; 398 399 if (session->is_pppx == 0 && 400 !in_nullhost(session->ip_address.sin_addr)) { 401 if (pipex_lookup_by_ip_address(session->ip_address.sin_addr) 402 != NULL) 403 return (EADDRINUSE); 404 rn = rn_addroute(&session->ip_address, &session->ip_netmask, 405 pipex_rd_head4, session->ps4_rn, RTP_STATIC); 406 if (rn == NULL) 407 return (ENOMEM); 408 } 409 410 LIST_INSERT_HEAD(&pipex_session_list, session, session_list); 411 chain = PIPEX_ID_HASHTABLE(session->session_id); 412 LIST_INSERT_HEAD(chain, session, id_chain); 413 #if defined(PIPEX_PPTP) || defined(PIPEX_L2TP) 414 switch (session->protocol) { 415 case PIPEX_PROTO_PPTP: 416 case PIPEX_PROTO_L2TP: 417 chain = PIPEX_PEER_ADDR_HASHTABLE( 418 pipex_sockaddr_hash_key(&session->peer.sa)); 419 LIST_INSERT_HEAD(chain, session, peer_addr_chain); 420 } 421 #endif 422 423 /* if first session is added, start timer */ 424 if (LIST_NEXT(session, session_list) == NULL) 425 pipex_timer_start(); 426 session->state = PIPEX_STATE_OPENED; 427 428 return (0); 429 } 430 431 void 432 pipex_unlink_session(struct pipex_session *session) 433 { 434 struct radix_node *rn; 435 436 session->ifindex = 0; 437 438 NET_ASSERT_LOCKED(); 439 if (session->state == PIPEX_STATE_CLOSED) 440 return; 441 if (session->is_pppx == 0 && 442 !in_nullhost(session->ip_address.sin_addr)) { 443 KASSERT(pipex_rd_head4 != NULL); 444 rn = rn_delete(&session->ip_address, &session->ip_netmask, 445 pipex_rd_head4, (struct radix_node *)session); 446 KASSERT(rn != NULL); 447 } 448 449 LIST_REMOVE(session, id_chain); 450 #if defined(PIPEX_PPTP) || defined(PIPEX_L2TP) 451 switch (session->protocol) { 452 case PIPEX_PROTO_PPTP: 453 case PIPEX_PROTO_L2TP: 454 LIST_REMOVE(session, peer_addr_chain); 455 break; 456 } 457 #endif 458 if (session->state == PIPEX_STATE_CLOSE_WAIT) 459 LIST_REMOVE(session, state_list); 460 LIST_REMOVE(session, session_list); 461 session->state = PIPEX_STATE_CLOSED; 462 463 /* if final session is destroyed, stop timer */ 464 if (LIST_EMPTY(&pipex_session_list)) 465 pipex_timer_stop(); 466 } 467 468 int 469 pipex_notify_close_session(struct pipex_session *session) 470 { 471 NET_ASSERT_LOCKED(); 472 session->state = PIPEX_STATE_CLOSE_WAIT; 473 session->idle_time = 0; 474 LIST_INSERT_HEAD(&pipex_close_wait_list, session, state_list); 475 476 return (0); 477 } 478 479 void 480 pipex_export_session_stats(struct pipex_session *session, 481 struct pipex_statistics *stats) 482 { 483 uint64_t counters[pxc_ncounters]; 484 485 memset(stats, 0, sizeof(*stats)); 486 487 counters_read(session->stat_counters, counters, pxc_ncounters); 488 stats->ipackets = counters[pxc_ipackets]; 489 stats->ierrors = counters[pxc_ierrors]; 490 stats->ibytes = counters[pxc_ibytes]; 491 stats->opackets = counters[pxc_opackets]; 492 stats->oerrors = counters[pxc_oerrors]; 493 stats->obytes = counters[pxc_obytes]; 494 stats->idle_time = session->idle_time; 495 } 496 497 Static int 498 pipex_config_session(struct pipex_session_config_req *req, void *ownersc) 499 { 500 struct pipex_session *session; 501 502 NET_ASSERT_LOCKED(); 503 session = pipex_lookup_by_session_id(req->pcr_protocol, 504 req->pcr_session_id); 505 if (session == NULL) 506 return (EINVAL); 507 if (session->ownersc != ownersc) 508 return (EINVAL); 509 session->ip_forward = req->pcr_ip_forward; 510 511 return (0); 512 } 513 514 Static int 515 pipex_get_stat(struct pipex_session_stat_req *req, void *ownersc) 516 { 517 struct pipex_session *session; 518 519 NET_ASSERT_LOCKED(); 520 session = pipex_lookup_by_session_id(req->psr_protocol, 521 req->psr_session_id); 522 if (session == NULL) 523 return (EINVAL); 524 if (session->ownersc != ownersc) 525 return (EINVAL); 526 pipex_export_session_stats(session, &req->psr_stat); 527 528 return (0); 529 } 530 531 Static int 532 pipex_get_closed(struct pipex_session_list_req *req, void *ownersc) 533 { 534 struct pipex_session *session, *session_tmp; 535 536 NET_ASSERT_LOCKED(); 537 bzero(req, sizeof(*req)); 538 LIST_FOREACH_SAFE(session, &pipex_close_wait_list, state_list, 539 session_tmp) { 540 if (session->ownersc != ownersc) 541 continue; 542 req->plr_ppp_id[req->plr_ppp_id_count++] = session->ppp_id; 543 LIST_REMOVE(session, state_list); 544 session->state = PIPEX_STATE_CLOSE_WAIT2; 545 if (req->plr_ppp_id_count >= PIPEX_MAX_LISTREQ) { 546 if (!LIST_EMPTY(&pipex_close_wait_list)) 547 req->plr_flags |= PIPEX_LISTREQ_MORE; 548 break; 549 } 550 } 551 552 return (0); 553 } 554 555 Static struct pipex_session * 556 pipex_lookup_by_ip_address(struct in_addr addr) 557 { 558 struct pipex_session *session; 559 struct sockaddr_in pipex_in4, pipex_in4mask; 560 561 if (pipex_rd_head4 == NULL) 562 return (NULL); 563 bzero(&pipex_in4, sizeof(pipex_in4)); 564 pipex_in4.sin_addr = addr; 565 pipex_in4.sin_family = AF_INET; 566 pipex_in4.sin_len = sizeof(pipex_in4); 567 568 bzero(&pipex_in4mask, sizeof(pipex_in4mask)); 569 pipex_in4mask.sin_addr.s_addr = htonl(0xFFFFFFFFL); 570 pipex_in4mask.sin_family = AF_INET; 571 pipex_in4mask.sin_len = sizeof(pipex_in4mask); 572 573 session = (struct pipex_session *)rn_lookup(&pipex_in4, &pipex_in4mask, 574 pipex_rd_head4); 575 576 #ifdef PIPEX_DEBUG 577 if (session == NULL) { 578 char buf[INET_ADDRSTRLEN]; 579 580 PIPEX_DBG((NULL, LOG_DEBUG, "<%s> session not found (addr=%s)", 581 __func__, inet_ntop(AF_INET, &addr, buf, sizeof(buf)))); 582 } 583 #endif 584 585 return (session); 586 } 587 588 Static struct pipex_session * 589 pipex_lookup_by_session_id(int protocol, int session_id) 590 { 591 struct pipex_hash_head *list; 592 struct pipex_session *session; 593 594 NET_ASSERT_LOCKED(); 595 list = PIPEX_ID_HASHTABLE(session_id); 596 LIST_FOREACH(session, list, id_chain) { 597 if (session->protocol == protocol && 598 session->session_id == session_id) 599 break; 600 } 601 602 #ifdef PIPEX_DEBUG 603 if (session == NULL) 604 PIPEX_DBG((NULL, LOG_DEBUG, 605 "<%s> session not found (session_id=%d)", __func__, 606 session_id)); 607 #endif 608 609 return (session); 610 } 611 612 /*********************************************************************** 613 * Timer functions 614 ***********************************************************************/ 615 Static void 616 pipex_timer_start(void) 617 { 618 timeout_set_proc(&pipex_timer_ch, pipex_timer, NULL); 619 timeout_add_sec(&pipex_timer_ch, pipex_prune); 620 } 621 622 Static void 623 pipex_timer_stop(void) 624 { 625 timeout_del(&pipex_timer_ch); 626 } 627 628 Static void 629 pipex_timer(void *ignored_arg) 630 { 631 struct pipex_session *session, *session_tmp; 632 633 timeout_add_sec(&pipex_timer_ch, pipex_prune); 634 635 NET_LOCK(); 636 /* walk through */ 637 LIST_FOREACH_SAFE(session, &pipex_session_list, session_list, 638 session_tmp) { 639 switch (session->state) { 640 case PIPEX_STATE_OPENED: 641 if (session->timeout_sec == 0) 642 continue; 643 644 session->idle_time++; 645 if (session->idle_time < session->timeout_sec) 646 continue; 647 648 pipex_notify_close_session(session); 649 break; 650 651 case PIPEX_STATE_CLOSE_WAIT: 652 case PIPEX_STATE_CLOSE_WAIT2: 653 /* Waiting PIPEXDSESSION from userland */ 654 session->idle_time++; 655 if (session->idle_time < PIPEX_CLOSE_TIMEOUT) 656 continue; 657 /* Release the sessions when timeout */ 658 pipex_unlink_session(session); 659 KASSERTMSG(session->is_pppx == 0, 660 "FIXME session must not be released when pppx"); 661 pipex_rele_session(session); 662 break; 663 664 default: 665 break; 666 } 667 } 668 669 NET_UNLOCK(); 670 } 671 672 /*********************************************************************** 673 * Common network I/O functions. (tunnel protocol independent) 674 ***********************************************************************/ 675 Static void 676 pipex_ip_output(struct mbuf *m0, struct pipex_session *session) 677 { 678 int is_idle; 679 680 if (session->is_multicast == 0) { 681 /* 682 * Multicast packet is a idle packet and it's not TCP. 683 */ 684 if (session->ip_forward == 0 && session->ip6_forward == 0) 685 goto drop; 686 /* reset idle timer */ 687 if (session->timeout_sec != 0) { 688 is_idle = 0; 689 m0 = ip_is_idle_packet(m0, &is_idle); 690 if (m0 == NULL) 691 goto dropped; 692 if (is_idle == 0) 693 /* update expire time */ 694 session->idle_time = 0; 695 } 696 697 /* adjust tcpmss */ 698 if ((session->ppp_flags & PIPEX_PPP_ADJUST_TCPMSS) != 0) { 699 m0 = adjust_tcp_mss(m0, session->peer_mru); 700 if (m0 == NULL) 701 goto dropped; 702 } 703 704 pipex_ppp_output(m0, session, PPP_IP); 705 } else { 706 struct pipex_session *session_tmp; 707 struct mbuf *m; 708 709 m0->m_flags &= ~(M_BCAST|M_MCAST); 710 711 LIST_FOREACH(session_tmp, &pipex_session_list, session_list) { 712 if (session_tmp->ownersc != session->ownersc) 713 continue; 714 if (session_tmp->ip_forward == 0 && 715 session_tmp->ip6_forward == 0) 716 continue; 717 m = m_copym(m0, 0, M_COPYALL, M_NOWAIT); 718 if (m == NULL) { 719 counters_inc(session->stat_counters, 720 pxc_oerrors); 721 continue; 722 } 723 pipex_ppp_output(m, session_tmp, PPP_IP); 724 } 725 m_freem(m0); 726 } 727 728 return; 729 drop: 730 m_freem(m0); 731 dropped: 732 counters_inc(session->stat_counters, pxc_oerrors); 733 } 734 735 Static void 736 pipex_ppp_output(struct mbuf *m0, struct pipex_session *session, int proto) 737 { 738 u_char *cp, hdr[16]; 739 740 NET_ASSERT_LOCKED(); 741 742 #ifdef PIPEX_MPPE 743 if (pipex_session_is_mppe_enabled(session)) { 744 if (proto == PPP_IP) { 745 pipex_mppe_output(m0, session, PPP_IP); 746 return; 747 } 748 } 749 #endif /* PIPEX_MPPE */ 750 cp = hdr; 751 if (session->protocol != PIPEX_PROTO_PPPOE) { 752 /* PPPoE has not address and control field */ 753 PUTCHAR(PPP_ALLSTATIONS, cp); 754 PUTCHAR(PPP_UI, cp); 755 } 756 PUTSHORT(proto, cp); 757 758 M_PREPEND(m0, cp - hdr, M_NOWAIT); 759 if (m0 == NULL) 760 goto drop; 761 memcpy(mtod(m0, u_char *), hdr, cp - hdr); 762 763 switch (session->protocol) { 764 #ifdef PIPEX_PPPOE 765 case PIPEX_PROTO_PPPOE: 766 pipex_pppoe_output(m0, session); 767 break; 768 #endif 769 #ifdef PIPEX_PPTP 770 case PIPEX_PROTO_PPTP: 771 pipex_pptp_output(m0, session, 1, 1); 772 break; 773 #endif 774 #ifdef PIPEX_L2TP 775 case PIPEX_PROTO_L2TP: 776 pipex_l2tp_output(m0, session); 777 break; 778 #endif 779 default: 780 goto drop; 781 } 782 783 return; 784 drop: 785 m_freem(m0); 786 counters_inc(session->stat_counters, pxc_oerrors); 787 } 788 789 Static void 790 pipex_ppp_input(struct mbuf *m0, struct pipex_session *session, int decrypted) 791 { 792 int proto, hlen = 0; 793 struct mbuf *n; 794 795 KASSERT(m0->m_pkthdr.len >= PIPEX_PPPMINLEN); 796 proto = pipex_ppp_proto(m0, session, 0, &hlen); 797 #ifdef PIPEX_MPPE 798 if (proto == PPP_COMP) { 799 if (decrypted) 800 goto drop; 801 802 /* checked this on ppp_common_input() already. */ 803 KASSERT(pipex_session_is_mppe_accepted(session)); 804 805 m_adj(m0, hlen); 806 pipex_mppe_input(m0, session); 807 return; 808 } 809 if (proto == PPP_CCP) { 810 if (decrypted) 811 goto drop; 812 813 #if NBPFILTER > 0 814 { 815 struct ifnet *ifp; 816 817 if ((ifp = if_get(session->ifindex)) != NULL) { 818 if (ifp->if_bpf && ifp->if_type == IFT_PPP) 819 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_IN); 820 } 821 if_put(ifp); 822 } 823 #endif 824 m_adj(m0, hlen); 825 pipex_ccp_input(m0, session); 826 return; 827 } 828 #endif 829 m_adj(m0, hlen); 830 if (!ALIGNED_POINTER(mtod(m0, caddr_t), uint32_t)) { 831 n = m_dup_pkt(m0, 0, M_NOWAIT); 832 if (n == NULL) 833 goto drop; 834 m_freem(m0); 835 m0 = n; 836 } 837 838 switch (proto) { 839 case PPP_IP: 840 if (session->ip_forward == 0) 841 goto drop; 842 if (!decrypted && pipex_session_is_mppe_required(session)) 843 /* 844 * if ip packet received when mppe 845 * is required, discard it. 846 */ 847 goto drop; 848 pipex_ip_input(m0, session); 849 return; 850 #ifdef INET6 851 case PPP_IPV6: 852 if (session->ip6_forward == 0) 853 goto drop; 854 if (!decrypted && pipex_session_is_mppe_required(session)) 855 /* 856 * if ip packet received when mppe 857 * is required, discard it. 858 */ 859 goto drop; 860 pipex_ip6_input(m0, session); 861 return; 862 #endif 863 default: 864 if (decrypted) 865 goto drop; 866 /* protocol must be checked on pipex_common_input() already */ 867 KASSERT(0); 868 goto drop; 869 } 870 871 return; 872 drop: 873 m_freem(m0); 874 counters_inc(session->stat_counters, pxc_ierrors); 875 } 876 877 Static void 878 pipex_ip_input(struct mbuf *m0, struct pipex_session *session) 879 { 880 struct ifnet *ifp; 881 struct ip *ip; 882 int len; 883 int is_idle; 884 885 /* change recvif */ 886 m0->m_pkthdr.ph_ifidx = session->ifindex; 887 888 if (ISSET(session->ppp_flags, PIPEX_PPP_INGRESS_FILTER)) { 889 PIPEX_PULLUP(m0, sizeof(struct ip)); 890 if (m0 == NULL) 891 goto drop; 892 /* ingress filter */ 893 ip = mtod(m0, struct ip *); 894 if ((ip->ip_src.s_addr & session->ip_netmask.sin_addr.s_addr) != 895 session->ip_address.sin_addr.s_addr) { 896 char src[INET_ADDRSTRLEN]; 897 898 pipex_session_log(session, LOG_DEBUG, 899 "ip packet discarded by ingress filter (src %s)", 900 inet_ntop(AF_INET, &ip->ip_src, src, sizeof(src))); 901 goto drop; 902 } 903 } 904 905 /* idle timer */ 906 if (session->timeout_sec != 0) { 907 is_idle = 0; 908 m0 = ip_is_idle_packet(m0, &is_idle); 909 if (m0 == NULL) 910 goto drop; 911 if (is_idle == 0) 912 /* update expire time */ 913 session->idle_time = 0; 914 } 915 916 /* adjust tcpmss */ 917 if (session->ppp_flags & PIPEX_PPP_ADJUST_TCPMSS) { 918 m0 = adjust_tcp_mss(m0, session->peer_mru); 919 if (m0 == NULL) 920 goto drop; 921 } 922 923 #if NPF > 0 924 pf_pkt_addr_changed(m0); 925 #endif 926 927 len = m0->m_pkthdr.len; 928 929 if ((ifp = if_get(session->ifindex)) == NULL) 930 goto drop; 931 932 #if NBPFILTER > 0 933 if (ifp->if_bpf) 934 bpf_mtap_af(ifp->if_bpf, AF_INET, m0, BPF_DIRECTION_IN); 935 #endif 936 937 counters_pkt(ifp->if_counters, ifc_ipackets, ifc_ibytes, len); 938 counters_pkt(session->stat_counters, pxc_ipackets, pxc_ibytes, len); 939 ipv4_input(ifp, m0); 940 941 if_put(ifp); 942 943 return; 944 drop: 945 m_freem(m0); 946 counters_inc(session->stat_counters, pxc_ierrors); 947 } 948 949 #ifdef INET6 950 Static void 951 pipex_ip6_input(struct mbuf *m0, struct pipex_session *session) 952 { 953 struct ifnet *ifp; 954 int len; 955 956 /* change recvif */ 957 m0->m_pkthdr.ph_ifidx = session->ifindex; 958 959 /* 960 * XXX: what is reasonable ingress filter ??? 961 * only one address is enough ?? 962 */ 963 964 /* XXX: we must define idle packet for IPv6(ICMPv6). */ 965 966 /* 967 * XXX: tcpmss adjustment for IPv6 is required??? 968 * We may use PMTUD in IPv6.... 969 */ 970 971 #if NPF > 0 972 pf_pkt_addr_changed(m0); 973 #endif 974 975 len = m0->m_pkthdr.len; 976 977 if ((ifp = if_get(session->ifindex)) == NULL) 978 goto drop; 979 980 #if NBPFILTER > 0 981 if (ifp->if_bpf) 982 bpf_mtap_af(ifp->if_bpf, AF_INET6, m0, BPF_DIRECTION_IN); 983 #endif 984 985 counters_pkt(ifp->if_counters, ifc_ipackets, ifc_ibytes, len); 986 counters_pkt(session->stat_counters, pxc_ipackets, pxc_ibytes, len); 987 ipv6_input(ifp, m0); 988 989 if_put(ifp); 990 991 return; 992 drop: 993 m_freem(m0); 994 counters_inc(session->stat_counters, pxc_ierrors); 995 } 996 #endif 997 998 Static struct mbuf * 999 pipex_common_input(struct pipex_session *session, struct mbuf *m0, int hlen, 1000 int plen) 1001 { 1002 int proto, ppphlen; 1003 u_char code; 1004 1005 if ((m0->m_pkthdr.len < hlen + PIPEX_PPPMINLEN) || 1006 (plen < PIPEX_PPPMINLEN)) 1007 goto drop; 1008 1009 proto = pipex_ppp_proto(m0, session, hlen, &ppphlen); 1010 switch (proto) { 1011 #ifdef PIPEX_MPPE 1012 case PPP_CCP: 1013 code = 0; 1014 KASSERT(m0->m_pkthdr.len >= hlen + ppphlen + 1); 1015 m_copydata(m0, hlen + ppphlen, 1, &code); 1016 if (code != CCP_RESETREQ && code != CCP_RESETACK) 1017 goto not_ours; 1018 break; 1019 1020 case PPP_COMP: 1021 if (pipex_session_is_mppe_accepted(session)) 1022 break; 1023 goto not_ours; 1024 #endif 1025 case PPP_IP: 1026 #ifdef INET6 1027 case PPP_IPV6: 1028 #endif 1029 break; 1030 default: 1031 goto not_ours; 1032 } 1033 1034 /* ok, The packet is for PIPEX */ 1035 m_adj(m0, hlen);/* cut off the tunnle protocol header */ 1036 1037 /* ensure the mbuf length equals the PPP frame length */ 1038 if (m0->m_pkthdr.len < plen) 1039 goto drop; 1040 if (m0->m_pkthdr.len > plen) { 1041 if (m0->m_len == m0->m_pkthdr.len) { 1042 m0->m_len = plen; 1043 m0->m_pkthdr.len = plen; 1044 } else 1045 m_adj(m0, plen - m0->m_pkthdr.len); 1046 } 1047 1048 pipex_ppp_input(m0, session, 0); 1049 1050 return (NULL); 1051 1052 drop: 1053 m_freem(m0); 1054 counters_inc(session->stat_counters, pxc_ierrors); 1055 return (NULL); 1056 1057 not_ours: 1058 return (m0); /* Not to be handled by PIPEX */ 1059 } 1060 1061 /* 1062 * pipex_ppp_proto 1063 */ 1064 Static int 1065 pipex_ppp_proto(struct mbuf *m0, struct pipex_session *session, int off, 1066 int *hlenp) 1067 { 1068 int proto; 1069 u_char *cp, pktbuf[4]; 1070 1071 KASSERT(m0->m_pkthdr.len > sizeof(pktbuf)); 1072 m_copydata(m0, off, sizeof(pktbuf), pktbuf); 1073 cp = pktbuf; 1074 1075 if (pipex_session_has_acf(session)) { 1076 if (cp[0] == PPP_ALLSTATIONS && cp[1] == PPP_UI) 1077 cp += 2; 1078 #ifdef PIPEX_DEBUG 1079 else if (!pipex_session_is_acfc_accepted(session)) 1080 PIPEX_DBG((session, LOG_DEBUG, 1081 "no acf but acfc is not accepted by the peer.")); 1082 #endif 1083 } 1084 if ((*cp & 0x01) != 0) { 1085 if (!pipex_session_is_pfc_accepted(session)) { 1086 PIPEX_DBG((session, LOG_DEBUG, "Received a broken ppp " 1087 "frame. No protocol field. %02x-%02x", 1088 cp[0], cp[1])); 1089 return (-1); 1090 } 1091 GETCHAR(proto, cp); 1092 } else 1093 GETSHORT(proto, cp); 1094 1095 if (hlenp != NULL) 1096 *hlenp = cp - pktbuf; 1097 1098 return (proto); 1099 } 1100 1101 #ifdef PIPEX_PPPOE 1102 /*********************************************************************** 1103 * PPPoE 1104 ***********************************************************************/ 1105 Static u_char pipex_pppoe_padding[ETHERMIN]; 1106 /* 1107 * pipex_pppoe_lookup_session 1108 */ 1109 struct pipex_session * 1110 pipex_pppoe_lookup_session(struct mbuf *m0) 1111 { 1112 struct pipex_session *session; 1113 struct pipex_pppoe_header pppoe; 1114 1115 /* short packet */ 1116 if (m0->m_pkthdr.len < (sizeof(struct ether_header) + sizeof(pppoe))) 1117 return (NULL); 1118 1119 m_copydata(m0, sizeof(struct ether_header), 1120 sizeof(struct pipex_pppoe_header), &pppoe); 1121 pppoe.session_id = ntohs(pppoe.session_id); 1122 session = pipex_lookup_by_session_id(PIPEX_PROTO_PPPOE, 1123 pppoe.session_id); 1124 #ifdef PIPEX_DEBUG 1125 if (session == NULL) 1126 PIPEX_DBG((NULL, LOG_DEBUG, "<%s> session not found (id=%d)", 1127 __func__, pppoe.session_id)); 1128 #endif 1129 if (session && session->proto.pppoe.over_ifidx != m0->m_pkthdr.ph_ifidx) 1130 session = NULL; 1131 1132 return (session); 1133 } 1134 1135 struct mbuf * 1136 pipex_pppoe_input(struct mbuf *m0, struct pipex_session *session) 1137 { 1138 int hlen; 1139 struct pipex_pppoe_header pppoe; 1140 1141 NET_ASSERT_LOCKED(); 1142 /* already checked at pipex_pppoe_lookup_session */ 1143 KASSERT(m0->m_pkthdr.len >= (sizeof(struct ether_header) + 1144 sizeof(pppoe))); 1145 1146 m_copydata(m0, sizeof(struct ether_header), 1147 sizeof(struct pipex_pppoe_header), &pppoe); 1148 1149 hlen = sizeof(struct ether_header) + sizeof(struct pipex_pppoe_header); 1150 if ((m0 = pipex_common_input(session, m0, hlen, ntohs(pppoe.length))) 1151 == NULL) 1152 return (NULL); 1153 m_freem(m0); 1154 counters_inc(session->stat_counters, pxc_ierrors); 1155 return (NULL); 1156 } 1157 1158 /* 1159 * pipex_ppope_output 1160 */ 1161 Static void 1162 pipex_pppoe_output(struct mbuf *m0, struct pipex_session *session) 1163 { 1164 struct pipex_pppoe_header *pppoe; 1165 struct ifnet *ifp; 1166 int len, padlen; 1167 1168 /* save length for pppoe header */ 1169 len = m0->m_pkthdr.len; 1170 1171 /* prepend protocol header */ 1172 M_PREPEND(m0, sizeof(struct pipex_pppoe_header), M_NOWAIT); 1173 if (m0 == NULL) { 1174 PIPEX_DBG((NULL, LOG_ERR, 1175 "<%s> cannot prepend header.", __func__)); 1176 counters_inc(session->stat_counters, pxc_oerrors); 1177 return; 1178 } 1179 padlen = ETHERMIN - m0->m_pkthdr.len; 1180 if (padlen > 0) 1181 m_copyback(m0, m0->m_pkthdr.len, padlen, pipex_pppoe_padding, 1182 M_NOWAIT); 1183 1184 /* setup pppoe header information */ 1185 pppoe = mtod(m0, struct pipex_pppoe_header *); 1186 pppoe->vertype = PIPEX_PPPOE_VERTYPE; 1187 pppoe->code = PIPEX_PPPOE_CODE_SESSION; 1188 pppoe->session_id = htons(session->session_id); 1189 pppoe->length = htons(len); 1190 1191 m0->m_pkthdr.ph_ifidx = session->proto.pppoe.over_ifidx; 1192 m0->m_flags &= ~(M_BCAST|M_MCAST); 1193 1194 ifp = if_get(session->proto.pppoe.over_ifidx); 1195 if (ifp != NULL) { 1196 ifp->if_output(ifp, m0, &session->peer.sa, NULL); 1197 counters_pkt(session->stat_counters, pxc_opackets, 1198 pxc_obytes, len); 1199 } else { 1200 m_freem(m0); 1201 counters_inc(session->stat_counters, pxc_oerrors); 1202 } 1203 if_put(ifp); 1204 } 1205 #endif /* PIPEX_PPPOE */ 1206 1207 #ifdef PIPEX_PPTP 1208 /*********************************************************************** 1209 * PPTP 1210 ***********************************************************************/ 1211 Static void 1212 pipex_pptp_output(struct mbuf *m0, struct pipex_session *session, 1213 int has_seq, int has_ack) 1214 { 1215 int len, reqlen; 1216 struct pipex_gre_header *gre = NULL; 1217 struct ip *ip; 1218 u_char *cp; 1219 1220 reqlen = PIPEX_IPGRE_HDRLEN + (has_seq + has_ack) * 4; 1221 1222 len = 0; 1223 if (m0 != NULL) { 1224 /* save length for gre header */ 1225 len = m0->m_pkthdr.len; 1226 /* prepend protocol header */ 1227 M_PREPEND(m0, reqlen, M_NOWAIT); 1228 if (m0 == NULL) 1229 goto drop; 1230 } else { 1231 MGETHDR(m0, M_DONTWAIT, MT_DATA); 1232 if (m0 && reqlen > MHLEN) { 1233 MCLGET(m0, M_DONTWAIT); 1234 if ((m0->m_flags & M_EXT) == 0) { 1235 m_freem(m0); 1236 m0 = NULL; 1237 } 1238 } 1239 if (m0 == NULL) 1240 goto drop; 1241 m0->m_pkthdr.len = m0->m_len = reqlen; 1242 } 1243 1244 /* setup ip header information */ 1245 ip = mtod(m0, struct ip *); 1246 1247 ip->ip_len = htons(m0->m_pkthdr.len); 1248 ip->ip_off = 0; 1249 ip->ip_ttl = MAXTTL; 1250 ip->ip_p = IPPROTO_GRE; 1251 ip->ip_tos = 0; 1252 1253 ip->ip_src = session->local.sin4.sin_addr; 1254 ip->ip_dst = session->peer.sin4.sin_addr; 1255 #if NPF > 0 1256 pf_pkt_addr_changed(m0); 1257 #endif 1258 1259 /* setup gre(ver1) header information */ 1260 gre = PIPEX_SEEK_NEXTHDR(ip, sizeof(struct ip), 1261 struct pipex_gre_header *); 1262 gre->type = htons(PIPEX_GRE_PROTO_PPP); 1263 gre->call_id = htons(session->peer_session_id); 1264 gre->flags = PIPEX_GRE_KFLAG | PIPEX_GRE_VER; /* do htons later */ 1265 gre->len = htons(len); 1266 1267 cp = PIPEX_SEEK_NEXTHDR(gre, sizeof(struct pipex_gre_header),u_char *); 1268 if (has_seq) { 1269 gre->flags |= PIPEX_GRE_SFLAG; 1270 PUTLONG(session->proto.pptp.snd_nxt, cp); 1271 session->proto.pptp.snd_nxt++; 1272 session->proto.pptp.snd_gap++; 1273 } 1274 if (has_ack) { 1275 gre->flags |= PIPEX_GRE_AFLAG; 1276 session->proto.pptp.rcv_acked = session->proto.pptp.rcv_nxt - 1; 1277 PUTLONG(session->proto.pptp.rcv_acked, cp); 1278 } 1279 gre->flags = htons(gre->flags); 1280 1281 m0->m_pkthdr.ph_ifidx = session->ifindex; 1282 ip_send(m0); 1283 if (len > 0) { /* network layer only */ 1284 /* countup statistics */ 1285 counters_pkt(session->stat_counters, pxc_opackets, 1286 pxc_obytes, len); 1287 } 1288 1289 return; 1290 drop: 1291 counters_inc(session->stat_counters, pxc_oerrors); 1292 } 1293 1294 struct pipex_session * 1295 pipex_pptp_lookup_session(struct mbuf *m0) 1296 { 1297 struct pipex_session *session; 1298 struct pipex_gre_header gre; 1299 struct ip ip; 1300 uint16_t flags; 1301 uint16_t id; 1302 int hlen; 1303 1304 if (m0->m_pkthdr.len < PIPEX_IPGRE_HDRLEN) { 1305 PIPEX_DBG((NULL, LOG_DEBUG, 1306 "<%s> packet length is too short", __func__)); 1307 goto not_ours; 1308 } 1309 1310 /* get ip header info */ 1311 m_copydata(m0, 0, sizeof(struct ip), &ip); 1312 hlen = ip.ip_hl << 2; 1313 1314 /* 1315 * m0 has already passed ip_input(), so there is 1316 * no necessity for ip packet inspection. 1317 */ 1318 1319 /* get gre flags */ 1320 m_copydata(m0, hlen, sizeof(gre), &gre); 1321 flags = ntohs(gre.flags); 1322 1323 /* gre version must be '1' */ 1324 if ((flags & PIPEX_GRE_VERMASK) != PIPEX_GRE_VER) { 1325 PIPEX_DBG((NULL, LOG_DEBUG, 1326 "<%s> gre header wrong version.", __func__)); 1327 goto not_ours; 1328 } 1329 1330 /* gre keys must be present */ 1331 if ((flags & PIPEX_GRE_KFLAG) == 0) { 1332 PIPEX_DBG((NULL, LOG_DEBUG, 1333 "<%s> gre header has no keys.", __func__)); 1334 goto not_ours; 1335 } 1336 1337 /* flag check */ 1338 if ((flags & PIPEX_GRE_UNUSEDFLAGS) != 0) { 1339 PIPEX_DBG((NULL, LOG_DEBUG, 1340 "<%s> gre header has unused flags at pptp.", __func__)); 1341 goto not_ours; 1342 } 1343 1344 /* lookup pipex session table */ 1345 id = ntohs(gre.call_id); 1346 session = pipex_lookup_by_session_id(PIPEX_PROTO_PPTP, id); 1347 #ifdef PIPEX_DEBUG 1348 if (session == NULL) { 1349 PIPEX_DBG((NULL, LOG_DEBUG, 1350 "<%s> session not found (id=%d)", __func__, id)); 1351 goto not_ours; 1352 } 1353 #endif 1354 1355 return (session); 1356 1357 not_ours: 1358 return (NULL); 1359 } 1360 1361 struct mbuf * 1362 pipex_pptp_input(struct mbuf *m0, struct pipex_session *session) 1363 { 1364 int hlen, has_seq, has_ack, nseq; 1365 const char *reason = ""; 1366 u_char *cp, *seqp = NULL, *ackp = NULL; 1367 uint32_t flags, seq = 0, ack = 0; 1368 struct ip *ip; 1369 struct pipex_gre_header *gre; 1370 struct pipex_pptp_session *pptp_session; 1371 int rewind = 0; 1372 1373 NET_ASSERT_LOCKED(); 1374 KASSERT(m0->m_pkthdr.len >= PIPEX_IPGRE_HDRLEN); 1375 pptp_session = &session->proto.pptp; 1376 1377 /* get ip header */ 1378 ip = mtod(m0, struct ip *); 1379 hlen = ip->ip_hl << 2; 1380 1381 /* seek gre header */ 1382 gre = PIPEX_SEEK_NEXTHDR(ip, hlen, struct pipex_gre_header *); 1383 flags = ntohs(gre->flags); 1384 1385 /* pullup for seek sequences in header */ 1386 has_seq = (flags & PIPEX_GRE_SFLAG) ? 1 : 0; 1387 has_ack = (flags & PIPEX_GRE_AFLAG) ? 1 : 0; 1388 hlen = PIPEX_IPGRE_HDRLEN + 4 * (has_seq + has_ack); 1389 if (m0->m_len < hlen) { 1390 m0 = m_pullup(m0, hlen); 1391 if (m0 == NULL) { 1392 PIPEX_DBG((session, LOG_DEBUG, "pullup failed.")); 1393 goto drop; 1394 } 1395 } 1396 1397 /* check sequence */ 1398 cp = PIPEX_SEEK_NEXTHDR(gre, sizeof(struct pipex_gre_header),u_char *); 1399 if (has_seq) { 1400 seqp = cp; 1401 GETLONG(seq, cp); 1402 } 1403 if (has_ack) { 1404 ackp = cp; 1405 GETLONG(ack, cp); 1406 if (ack + 1 == pptp_session->snd_una) { 1407 /* ack has not changed before */ 1408 } else if (SEQ32_LT(ack, pptp_session->snd_una)) { 1409 /* OoO ack packets should not be dropped. */ 1410 rewind = 1; 1411 } else if (SEQ32_GT(ack, pptp_session->snd_nxt)) { 1412 reason = "ack for unknown sequence"; 1413 goto out_seq; 1414 } else 1415 pptp_session->snd_una = ack + 1; 1416 } 1417 if (!has_seq) { 1418 /* ack only packet */ 1419 goto not_ours; 1420 } 1421 if (SEQ32_LT(seq, pptp_session->rcv_nxt)) { 1422 rewind = 1; 1423 if (SEQ32_LT(seq, 1424 pptp_session->rcv_nxt - PIPEX_REWIND_LIMIT)) { 1425 reason = "out of sequence"; 1426 goto out_seq; 1427 } 1428 } else if (SEQ32_GE(seq, pptp_session->rcv_nxt + 1429 pptp_session->maxwinsz)) { 1430 pipex_session_log(session, LOG_DEBUG, 1431 "received packet caused window overflow. seq=%u(%u-%u)" 1432 "may lost %d packets.", seq, pptp_session->rcv_nxt, 1433 pptp_session->rcv_nxt + pptp_session->maxwinsz, 1434 (int)SEQ32_SUB(seq, pptp_session->rcv_nxt)); 1435 } 1436 1437 seq++; 1438 nseq = SEQ32_SUB(seq, pptp_session->rcv_nxt); 1439 if (!rewind) { 1440 pptp_session->rcv_nxt = seq; 1441 if (SEQ32_SUB(seq, pptp_session->rcv_acked) > 1442 roundup(pptp_session->winsz, 2) / 2) /* Send ack only packet. */ 1443 pipex_pptp_output(NULL, session, 0, 1); 1444 } 1445 1446 if ((m0 = pipex_common_input(session, m0, hlen, ntohs(gre->len))) 1447 == NULL) { 1448 /* ok, The packet is for PIPEX */ 1449 if (!rewind) 1450 session->proto.pptp.rcv_gap += nseq; 1451 return (NULL); 1452 } 1453 1454 if (rewind) 1455 goto out_seq; 1456 1457 not_ours: 1458 seq--; /* revert original seq value */ 1459 1460 /* 1461 * overwrite sequence numbers to adjust a gap between pipex and 1462 * userland. 1463 */ 1464 if (seqp != NULL) { 1465 seq -= pptp_session->rcv_gap; 1466 PUTLONG(seq, seqp); 1467 } 1468 if (ackp != NULL) { 1469 if (pptp_session->snd_nxt == pptp_session->snd_una) { 1470 ack -= session->proto.pptp.snd_gap; 1471 pptp_session->ul_snd_una = ack; 1472 } else { 1473 /* 1474 * There are sending packets they are not acked. 1475 * In this situation, (ack - snd_gap) may points 1476 * before sending window of userland. So we don't 1477 * update the ack number. 1478 */ 1479 ack = pptp_session->ul_snd_una; 1480 } 1481 PUTLONG(ack, ackp); 1482 } 1483 1484 return (m0); 1485 out_seq: 1486 pipex_session_log(session, LOG_DEBUG, 1487 "Received bad data packet: %s: seq=%u(%u-%u) ack=%u(%u-%u)", 1488 reason, seq, pptp_session->rcv_nxt, 1489 pptp_session->rcv_nxt + pptp_session->maxwinsz, 1490 ack, pptp_session->snd_una, 1491 pptp_session->snd_nxt); 1492 1493 /* FALLTHROUGH */ 1494 drop: 1495 m_freem(m0); 1496 counters_inc(session->stat_counters, pxc_ierrors); 1497 1498 return (NULL); 1499 } 1500 1501 struct pipex_session * 1502 pipex_pptp_userland_lookup_session_ipv4(struct mbuf *m0, struct in_addr dst) 1503 { 1504 struct sockaddr_in sin; 1505 1506 memset(&sin, 0, sizeof(sin)); 1507 sin.sin_len = sizeof(sin); 1508 sin.sin_family = AF_INET; 1509 sin.sin_addr = dst; 1510 1511 return pipex_pptp_userland_lookup_session(m0, sintosa(&sin)); 1512 } 1513 1514 #ifdef INET6 1515 struct pipex_session * 1516 pipex_pptp_userland_lookup_session_ipv6(struct mbuf *m0, struct in6_addr dst) 1517 { 1518 struct sockaddr_in6 sin6; 1519 1520 memset(&sin6, 0, sizeof(sin6)); 1521 sin6.sin6_len = sizeof(sin6); 1522 sin6.sin6_family = AF_INET6; 1523 in6_recoverscope(&sin6, &dst); 1524 1525 return pipex_pptp_userland_lookup_session(m0, sin6tosa(&sin6)); 1526 } 1527 #endif 1528 1529 Static struct pipex_session * 1530 pipex_pptp_userland_lookup_session(struct mbuf *m0, struct sockaddr *sa) 1531 { 1532 struct pipex_gre_header gre; 1533 struct pipex_hash_head *list; 1534 struct pipex_session *session; 1535 uint16_t id, flags; 1536 1537 /* pullup */ 1538 if (m0->m_pkthdr.len < sizeof(gre)) { 1539 PIPEX_DBG((NULL, LOG_DEBUG, 1540 "<%s> packet length is too short", __func__)); 1541 return (NULL); 1542 } 1543 1544 /* get flags */ 1545 m_copydata(m0, 0, sizeof(struct pipex_gre_header), &gre); 1546 flags = ntohs(gre.flags); 1547 1548 /* gre version must be '1' */ 1549 if ((flags & PIPEX_GRE_VERMASK) != PIPEX_GRE_VER) { 1550 PIPEX_DBG((NULL, LOG_DEBUG, 1551 "<%s> gre header wrong version.", __func__)); 1552 return (NULL); 1553 } 1554 1555 /* gre keys must be present */ 1556 if ((flags & PIPEX_GRE_KFLAG) == 0) { 1557 PIPEX_DBG((NULL, LOG_DEBUG, 1558 "<%s> gre header has no keys.", __func__)); 1559 return (NULL); 1560 } 1561 1562 /* lookup pipex session table */ 1563 id = ntohs(gre.call_id); 1564 1565 list = PIPEX_PEER_ADDR_HASHTABLE(pipex_sockaddr_hash_key(sa)); 1566 LIST_FOREACH(session, list, peer_addr_chain) { 1567 if (pipex_sockaddr_compar_addr(&session->peer.sa, sa) != 0) 1568 continue; 1569 if (session->peer_session_id == id) 1570 break; 1571 } 1572 #ifdef PIPEX_DEBUG 1573 if (session == NULL) { 1574 PIPEX_DBG((NULL, LOG_DEBUG, 1575 "<%s> session not found (,call_id=%d)", 1576 __func__, (int)gre.call_id)); 1577 } 1578 #endif 1579 return (session); 1580 } 1581 1582 /* 1583 * pipex_pptp_userland_output 1584 */ 1585 struct mbuf * 1586 pipex_pptp_userland_output(struct mbuf *m0, struct pipex_session *session) 1587 { 1588 int len; 1589 struct pipex_gre_header *gre, gre0; 1590 uint16_t flags; 1591 u_char *cp, *cp0; 1592 uint32_t val32; 1593 1594 len = sizeof(struct pipex_gre_header); 1595 m_copydata(m0, 0, len, &gre0); 1596 gre = &gre0; 1597 flags = ntohs(gre->flags); 1598 if ((flags & PIPEX_GRE_SFLAG) != 0) 1599 len += 4; 1600 if ((flags & PIPEX_GRE_AFLAG) != 0) 1601 len += 4; 1602 1603 /* check length */ 1604 PIPEX_PULLUP(m0, len); 1605 if (m0 == NULL) { 1606 PIPEX_DBG((session, LOG_DEBUG, "gre header is too short.")); 1607 return (NULL); 1608 } 1609 1610 gre = mtod(m0, struct pipex_gre_header *); 1611 cp = PIPEX_SEEK_NEXTHDR(gre, sizeof(struct pipex_gre_header), u_char *); 1612 1613 /* 1614 * overwrite sequence numbers to adjust a gap between pipex and 1615 * userland. 1616 */ 1617 if ((flags & PIPEX_GRE_SFLAG) != 0) { 1618 cp0 = cp; 1619 GETLONG(val32, cp); 1620 val32 += session->proto.pptp.snd_gap; 1621 PUTLONG(val32, cp0); 1622 session->proto.pptp.snd_nxt++; 1623 } 1624 if ((flags & PIPEX_GRE_AFLAG) != 0) { 1625 cp0 = cp; 1626 GETLONG(val32, cp); 1627 val32 += session->proto.pptp.rcv_gap; 1628 PUTLONG(val32, cp0); 1629 if (SEQ32_GT(val32, session->proto.pptp.rcv_acked)) 1630 session->proto.pptp.rcv_acked = val32; 1631 } 1632 1633 return (m0); 1634 } 1635 #endif /* PIPEX_PPTP */ 1636 1637 #ifdef PIPEX_L2TP 1638 /*********************************************************************** 1639 * L2TP support 1640 ***********************************************************************/ 1641 Static void 1642 pipex_l2tp_output(struct mbuf *m0, struct pipex_session *session) 1643 { 1644 int hlen, plen, datalen; 1645 struct pipex_l2tp_header *l2tp = NULL; 1646 struct pipex_l2tp_seq_header *seq = NULL; 1647 struct udphdr *udp; 1648 struct ip *ip; 1649 #ifdef INET6 1650 struct ip6_hdr *ip6; 1651 #endif 1652 struct m_tag *mtag; 1653 1654 hlen = sizeof(struct pipex_l2tp_header) + 1655 ((pipex_session_is_l2tp_data_sequencing_on(session)) 1656 ? sizeof(struct pipex_l2tp_seq_header) : 0) + 1657 sizeof(struct udphdr) + 1658 #ifdef INET6 1659 ((session->peer.sin6.sin6_family == AF_INET6) 1660 ? sizeof(struct ip6_hdr) : sizeof(struct ip)); 1661 #else 1662 sizeof(struct ip); 1663 #endif 1664 1665 datalen = 0; 1666 if (m0 != NULL) { 1667 datalen = m0->m_pkthdr.len; 1668 M_PREPEND(m0, hlen, M_NOWAIT); 1669 if (m0 == NULL) 1670 goto drop; 1671 } else { 1672 MGETHDR(m0, M_DONTWAIT, MT_DATA); 1673 if (m0 == NULL) 1674 goto drop; 1675 KASSERT(hlen <= MHLEN); 1676 m0->m_pkthdr.len = m0->m_len = hlen; 1677 } 1678 1679 #ifdef INET6 1680 hlen = (session->peer.sin6.sin6_family == AF_INET6) 1681 ? sizeof(struct ip6_hdr) : sizeof(struct ip); 1682 #else 1683 hlen = sizeof(struct ip); 1684 #endif 1685 plen = datalen + sizeof(struct pipex_l2tp_header) + 1686 ((pipex_session_is_l2tp_data_sequencing_on(session)) 1687 ? sizeof(struct pipex_l2tp_seq_header) : 0); 1688 1689 l2tp = (struct pipex_l2tp_header *) 1690 (mtod(m0, caddr_t) + hlen + sizeof(struct udphdr)); 1691 l2tp->flagsver = PIPEX_L2TP_VER | PIPEX_L2TP_FLAG_LENGTH; 1692 l2tp->length = htons(plen); 1693 l2tp->tunnel_id = htons(session->proto.l2tp.peer_tunnel_id); 1694 l2tp->session_id = htons(session->peer_session_id); 1695 if (pipex_session_is_l2tp_data_sequencing_on(session)) { 1696 seq = (struct pipex_l2tp_seq_header *)(l2tp + 1); 1697 l2tp->flagsver |= PIPEX_L2TP_FLAG_SEQUENCE; 1698 seq->ns = htons(session->proto.l2tp.ns_nxt); 1699 session->proto.l2tp.ns_nxt++; 1700 session->proto.l2tp.ns_gap++; 1701 session->proto.l2tp.nr_acked = session->proto.l2tp.nr_nxt - 1; 1702 seq->nr = htons(session->proto.l2tp.nr_acked); 1703 } 1704 l2tp->flagsver = htons(l2tp->flagsver); 1705 1706 plen += sizeof(struct udphdr); 1707 udp = (struct udphdr *)(mtod(m0, caddr_t) + hlen); 1708 udp->uh_sport = session->local.sin6.sin6_port; 1709 udp->uh_dport = session->peer.sin6.sin6_port; 1710 udp->uh_ulen = htons(plen); 1711 udp->uh_sum = 0; 1712 1713 m0->m_pkthdr.csum_flags |= M_UDP_CSUM_OUT; 1714 m0->m_pkthdr.ph_ifidx = session->ifindex; 1715 #if NPF > 0 1716 pf_pkt_addr_changed(m0); 1717 #endif 1718 switch (session->peer.sin6.sin6_family) { 1719 case AF_INET: 1720 ip = mtod(m0, struct ip *); 1721 ip->ip_p = IPPROTO_UDP; 1722 ip->ip_src = session->local.sin4.sin_addr; 1723 ip->ip_dst = session->peer.sin4.sin_addr; 1724 ip->ip_len = htons(hlen + plen); 1725 ip->ip_ttl = MAXTTL; 1726 ip->ip_tos = 0; 1727 ip->ip_off = 0; 1728 1729 if (session->proto.l2tp.ipsecflowinfo > 0) { 1730 if ((mtag = m_tag_get(PACKET_TAG_IPSEC_FLOWINFO, 1731 sizeof(u_int32_t), M_NOWAIT)) == NULL) 1732 goto drop; 1733 *(u_int32_t *)(mtag + 1) = 1734 session->proto.l2tp.ipsecflowinfo; 1735 m_tag_prepend(m0, mtag); 1736 } 1737 1738 ip_send(m0); 1739 break; 1740 #ifdef INET6 1741 case AF_INET6: 1742 ip6 = mtod(m0, struct ip6_hdr *); 1743 1744 ip6->ip6_flow = 0; 1745 ip6->ip6_vfc &= ~IPV6_VERSION_MASK; 1746 ip6->ip6_vfc |= IPV6_VERSION; 1747 ip6->ip6_nxt = IPPROTO_UDP; 1748 ip6->ip6_src = session->local.sin6.sin6_addr; 1749 (void)in6_embedscope(&ip6->ip6_dst, 1750 &session->peer.sin6, NULL); 1751 /* ip6->ip6_plen will be filled in ip6_output. */ 1752 1753 ip6_send(m0); 1754 break; 1755 #endif 1756 } 1757 udpstat_inc(udps_opackets); 1758 1759 if (datalen > 0) { /* network layer only */ 1760 /* countup statistics */ 1761 counters_pkt(session->stat_counters, pxc_opackets, 1762 pxc_obytes, datalen); 1763 } 1764 1765 return; 1766 drop: 1767 m_freem(m0); 1768 counters_inc(session->stat_counters, pxc_oerrors); 1769 } 1770 1771 struct pipex_session * 1772 pipex_l2tp_lookup_session(struct mbuf *m0, int off) 1773 { 1774 struct pipex_session *session; 1775 uint16_t flags, session_id, ver; 1776 u_char *cp, buf[PIPEX_L2TP_MINLEN]; 1777 1778 if (m0->m_pkthdr.len < off + PIPEX_L2TP_MINLEN) { 1779 PIPEX_DBG((NULL, LOG_DEBUG, 1780 "<%s> packet length is too short", __func__)); 1781 goto not_ours; 1782 } 1783 1784 /* get first 16bits of L2TP */ 1785 m_copydata(m0, off, sizeof(buf), buf); 1786 cp = buf; 1787 GETSHORT(flags, cp); 1788 ver = flags & PIPEX_L2TP_VER_MASK; 1789 1790 /* l2tp version must be '2' */ 1791 if (ver != PIPEX_L2TP_VER) { 1792 PIPEX_DBG((NULL, LOG_DEBUG, 1793 "<%s> l2tp header wrong version %u.", __func__, ver)); 1794 goto not_ours; 1795 } 1796 if ((flags & PIPEX_L2TP_FLAG_TYPE) != 0) 1797 goto not_ours; 1798 1799 if (flags & PIPEX_L2TP_FLAG_LENGTH) 1800 cp += 2; /* skip length field */ 1801 cp += 2; /* skip tunnel-id field */ 1802 GETSHORT(session_id, cp); /* get session-id field */ 1803 1804 /* lookup pipex session table */ 1805 session = pipex_lookup_by_session_id(PIPEX_PROTO_L2TP, session_id); 1806 #ifdef PIPEX_DEBUG 1807 if (session == NULL) { 1808 PIPEX_DBG((NULL, LOG_DEBUG, 1809 "<%s> session not found (id=%d)", __func__, session_id)); 1810 goto not_ours; 1811 } 1812 #endif 1813 1814 return (session); 1815 1816 not_ours: 1817 return (NULL); 1818 } 1819 1820 struct mbuf * 1821 pipex_l2tp_input(struct mbuf *m0, int off0, struct pipex_session *session, 1822 uint32_t ipsecflowinfo) 1823 { 1824 struct pipex_l2tp_session *l2tp_session; 1825 int length, offset, hlen, nseq; 1826 u_char *cp, *nsp, *nrp; 1827 uint16_t flags, ns = 0, nr = 0; 1828 int rewind = 0; 1829 1830 NET_ASSERT_LOCKED(); 1831 length = offset = ns = nr = 0; 1832 l2tp_session = &session->proto.l2tp; 1833 l2tp_session->ipsecflowinfo = ipsecflowinfo; 1834 nsp = nrp = NULL; 1835 1836 m_copydata(m0, off0, sizeof(flags), &flags); 1837 1838 flags = ntohs(flags) & PIPEX_L2TP_FLAG_MASK; 1839 KASSERT((flags & PIPEX_L2TP_FLAG_TYPE) == 0); 1840 1841 hlen = 2; /* flags and version fields */ 1842 if (flags & PIPEX_L2TP_FLAG_LENGTH) /* length */ 1843 hlen += 2; 1844 hlen += 4; /* tunnel-id and session-id */ 1845 if (flags & PIPEX_L2TP_FLAG_SEQUENCE) /* ns and nr */ 1846 hlen += 4; 1847 if (flags & PIPEX_L2TP_FLAG_OFFSET) /* offset */ 1848 hlen += 2; 1849 1850 PIPEX_PULLUP(m0, off0 + hlen); 1851 if (m0 == NULL) 1852 goto drop; 1853 1854 cp = mtod(m0, u_char *) + off0; 1855 cp += 2; /* flags and version */ 1856 if (flags & PIPEX_L2TP_FLAG_LENGTH) 1857 GETSHORT(length, cp); 1858 else 1859 length = m0->m_pkthdr.len - off0; 1860 cp += 4; /* skip tunnel-id and session-id field */ 1861 1862 /* pullup for seek sequences in header */ 1863 nseq = 0; 1864 if (flags & PIPEX_L2TP_FLAG_SEQUENCE) { 1865 nsp = cp; 1866 GETSHORT(ns, cp); 1867 nrp = cp; 1868 GETSHORT(nr, cp); 1869 1870 nr++; 1871 if (SEQ16_GT(nr, l2tp_session->ns_una) && 1872 SEQ16_LE(nr, l2tp_session->ns_nxt)) 1873 /* update 'ns_una' only if the ns is in valid range */ 1874 l2tp_session->ns_una = nr; 1875 if (SEQ16_LT(ns, l2tp_session->nr_nxt)) { 1876 rewind = 1; 1877 if (SEQ16_LT(ns, 1878 l2tp_session->nr_nxt - PIPEX_REWIND_LIMIT)) 1879 goto out_seq; 1880 } 1881 1882 ns++; 1883 nseq = SEQ16_SUB(ns, l2tp_session->nr_nxt); 1884 if (!rewind) 1885 l2tp_session->nr_nxt = ns; 1886 } 1887 if (flags & PIPEX_L2TP_FLAG_OFFSET) 1888 GETSHORT(offset, cp); 1889 1890 length -= hlen + offset; 1891 hlen += off0 + offset; 1892 if ((m0 = pipex_common_input(session, m0, hlen, length)) == NULL) { 1893 /* ok, The packet is for PIPEX */ 1894 if (!rewind) 1895 session->proto.l2tp.nr_gap += nseq; 1896 return (NULL); 1897 } 1898 1899 if (rewind) 1900 goto out_seq; 1901 1902 /* 1903 * overwrite sequence numbers to adjust a gap between pipex and 1904 * userland. 1905 */ 1906 if (flags & PIPEX_L2TP_FLAG_SEQUENCE) { 1907 --ns; --nr; /* revert original values */ 1908 ns -= l2tp_session->nr_gap; 1909 PUTSHORT(ns, nsp); 1910 1911 if (l2tp_session->ns_nxt == l2tp_session->ns_una) { 1912 nr -= l2tp_session->ns_gap; 1913 l2tp_session->ul_ns_una = nr; 1914 } else { 1915 /* 1916 * There are sending packets they are not acked. 1917 * In this situation, (ack - snd_gap) may points 1918 * before sending window of userland. So we don't 1919 * update the ack number. 1920 */ 1921 nr = l2tp_session->ul_ns_una; 1922 } 1923 PUTSHORT(nr, nrp); 1924 } 1925 1926 return (m0); 1927 out_seq: 1928 pipex_session_log(session, LOG_DEBUG, 1929 "Received bad data packet: out of sequence: seq=%u(%u-) " 1930 "ack=%u(%u-%u)", ns, l2tp_session->nr_nxt, nr, l2tp_session->ns_una, 1931 l2tp_session->ns_nxt); 1932 1933 /* FALLTHROUGH */ 1934 drop: 1935 m_freem(m0); 1936 counters_inc(session->stat_counters, pxc_ierrors); 1937 1938 return (NULL); 1939 } 1940 1941 struct pipex_session * 1942 pipex_l2tp_userland_lookup_session_ipv4(struct mbuf *m0, struct in_addr dst) 1943 { 1944 struct sockaddr_in sin; 1945 1946 memset(&sin, 0, sizeof(sin)); 1947 sin.sin_len = sizeof(sin); 1948 sin.sin_family = AF_INET; 1949 sin.sin_addr = dst; 1950 1951 return pipex_l2tp_userland_lookup_session(m0, sintosa(&sin)); 1952 } 1953 1954 #ifdef INET6 1955 struct pipex_session * 1956 pipex_l2tp_userland_lookup_session_ipv6(struct mbuf *m0, struct in6_addr dst) 1957 { 1958 struct sockaddr_in6 sin6; 1959 1960 memset(&sin6, 0, sizeof(sin6)); 1961 sin6.sin6_len = sizeof(sin6); 1962 sin6.sin6_family = AF_INET6; 1963 in6_recoverscope(&sin6, &dst); 1964 1965 return pipex_l2tp_userland_lookup_session(m0, sin6tosa(&sin6)); 1966 } 1967 #endif 1968 1969 struct pipex_session * 1970 pipex_l2tp_userland_lookup_session(struct mbuf *m0, struct sockaddr *sa) 1971 { 1972 struct pipex_l2tp_header l2tp; 1973 struct pipex_hash_head *list; 1974 struct pipex_session *session; 1975 uint16_t session_id, tunnel_id, flags; 1976 1977 if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6) 1978 return (NULL); 1979 1980 /* pullup */ 1981 if (m0->m_pkthdr.len < sizeof(l2tp)) { 1982 PIPEX_DBG((NULL, LOG_DEBUG, 1983 "<%s> packet length is too short", __func__)); 1984 return (NULL); 1985 } 1986 1987 /* get flags */ 1988 m_copydata(m0, 0, sizeof(l2tp), &l2tp); 1989 flags = ntohs(l2tp.flagsver); 1990 1991 /* l2tp version must be '2' */ 1992 if ((flags & PIPEX_L2TP_VER_MASK) != PIPEX_L2TP_VER) { 1993 PIPEX_DBG((NULL, LOG_DEBUG, 1994 "<%s> l2tp header wrong version.", __func__)); 1995 return (NULL); 1996 } 1997 /* We need L2TP data messages only */ 1998 if ((flags & PIPEX_L2TP_FLAG_TYPE) != 0) 1999 return (NULL); 2000 /* No need to hook packets that don't have the sequence field */ 2001 if ((flags & PIPEX_L2TP_FLAG_SEQUENCE) == 0) 2002 return (NULL); 2003 2004 session_id = ntohs(l2tp.session_id); 2005 tunnel_id = ntohs(l2tp.tunnel_id); 2006 2007 list = PIPEX_PEER_ADDR_HASHTABLE(pipex_sockaddr_hash_key(sa)); 2008 LIST_FOREACH(session, list, peer_addr_chain) { 2009 if (pipex_sockaddr_compar_addr(&session->peer.sa, sa) != 0) 2010 continue; 2011 if (session->proto.l2tp.peer_tunnel_id != tunnel_id) 2012 continue; 2013 if (session->peer_session_id == session_id) 2014 break; 2015 } 2016 #ifdef PIPEX_DEBUG 2017 if (session == NULL) { 2018 PIPEX_DBG((NULL, LOG_DEBUG, "<%s> session not found " 2019 "(tunnel_id=%d, session_id=%d)", __func__, 2020 tunnel_id, session_id)); 2021 } 2022 #endif 2023 2024 return (session); 2025 } 2026 2027 struct mbuf * 2028 pipex_l2tp_userland_output(struct mbuf *m0, struct pipex_session *session) 2029 { 2030 struct pipex_l2tp_header *l2tp; 2031 struct pipex_l2tp_seq_header *seq; 2032 uint16_t ns, nr; 2033 2034 /* check length */ 2035 PIPEX_PULLUP(m0, sizeof(struct pipex_l2tp_header) + 2036 sizeof(struct pipex_l2tp_seq_header)); 2037 if (m0 == NULL) 2038 return (NULL); 2039 2040 l2tp = mtod(m0, struct pipex_l2tp_header *); 2041 KASSERT(ntohs(l2tp->flagsver) & PIPEX_L2TP_FLAG_SEQUENCE); 2042 2043 /* 2044 * overwrite sequence numbers to adjust a gap between pipex and 2045 * userland. 2046 */ 2047 seq = (struct pipex_l2tp_seq_header *)(l2tp + 1); 2048 ns = ntohs(seq->ns); 2049 nr = ntohs(seq->nr); 2050 2051 ns += session->proto.l2tp.ns_gap; 2052 seq->ns = htons(ns); 2053 session->proto.l2tp.ns_nxt++; 2054 2055 nr += session->proto.l2tp.nr_gap; 2056 seq->nr = htons(nr); 2057 if (SEQ16_GT(nr, session->proto.l2tp.nr_acked)) 2058 session->proto.l2tp.nr_acked = nr; 2059 2060 return (m0); 2061 } 2062 #endif /* PIPEX_L2TP */ 2063 2064 #ifdef PIPEX_MPPE 2065 /********************************************************************** 2066 * MPPE 2067 ***********************************************************************/ 2068 #define PIPEX_COHERENCY_CNT_MASK 0x0fff 2069 2070 static inline int 2071 pipex_mppe_setkey(struct pipex_mppe *mppe) 2072 { 2073 rc4_keysetup(&mppe->rc4ctx, mppe->session_key, mppe->keylen); 2074 2075 return (0); 2076 } 2077 2078 static inline int 2079 pipex_mppe_setoldkey(struct pipex_mppe *mppe, uint16_t coher_cnt) 2080 { 2081 KASSERT(mppe->old_session_keys != NULL); 2082 2083 rc4_keysetup(&mppe->rc4ctx, 2084 mppe->old_session_keys[coher_cnt & PIPEX_MPPE_OLDKEYMASK], 2085 mppe->keylen); 2086 2087 return (0); 2088 } 2089 2090 static inline void 2091 pipex_mppe_crypt(struct pipex_mppe *mppe, int len, u_char *indata, 2092 u_char *outdata) 2093 { 2094 rc4_crypt(&mppe->rc4ctx, indata, outdata, len); 2095 } 2096 2097 Static void 2098 pipex_mppe_init(struct pipex_mppe *mppe, int stateless, int keylenbits, 2099 u_char *master_key, int has_oldkey) 2100 { 2101 memset(mppe, 0, sizeof(struct pipex_mppe)); 2102 if (stateless) 2103 mppe->stateless = 1; 2104 if (has_oldkey) 2105 mppe->old_session_keys = 2106 pool_get(&mppe_key_pool, PR_WAITOK); 2107 else 2108 mppe->old_session_keys = NULL; 2109 memcpy(mppe->master_key, master_key, sizeof(mppe->master_key)); 2110 2111 mppe->keylenbits = keylenbits; 2112 switch (keylenbits) { 2113 case 40: 2114 case 56: 2115 mppe->keylen = 8; 2116 break; 2117 case 128: 2118 mppe->keylen = 16; 2119 break; 2120 } 2121 2122 GetNewKeyFromSHA(mppe->master_key, mppe->master_key, mppe->keylen, 2123 mppe->session_key); 2124 pipex_mppe_reduce_key(mppe); 2125 pipex_mppe_setkey(mppe); 2126 } 2127 2128 void 2129 pipex_session_init_mppe_recv(struct pipex_session *session, int stateless, 2130 int keylenbits, u_char *master_key) 2131 { 2132 pipex_mppe_init(&session->mppe_recv, stateless, keylenbits, 2133 master_key, stateless); 2134 session->ppp_flags |= PIPEX_PPP_MPPE_ACCEPTED; 2135 } 2136 2137 void 2138 pipex_session_init_mppe_send(struct pipex_session *session, int stateless, 2139 int keylenbits, u_char *master_key) 2140 { 2141 pipex_mppe_init(&session->mppe_send, stateless, keylenbits, 2142 master_key, 0); 2143 session->ppp_flags |= PIPEX_PPP_MPPE_ENABLED; 2144 } 2145 2146 #include <crypto/sha1.h> 2147 2148 static u_char SHAPad1[] = { 2149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2154 }, SHAPad2[] = { 2155 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 2156 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 2157 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 2158 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 2159 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 2160 }; 2161 2162 Static void 2163 GetNewKeyFromSHA(u_char *StartKey, u_char *SessionKey, int SessionKeyLength, 2164 u_char *InterimKey) 2165 { 2166 u_char Digest[20]; 2167 SHA1_CTX Context; 2168 2169 SHA1Init(&Context); 2170 SHA1Update(&Context, StartKey, SessionKeyLength); 2171 SHA1Update(&Context, SHAPad1, 40); 2172 SHA1Update(&Context, SessionKey, SessionKeyLength); 2173 SHA1Update(&Context, SHAPad2, 40); 2174 SHA1Final(Digest, &Context); 2175 2176 memcpy(InterimKey, Digest, SessionKeyLength); 2177 } 2178 2179 Static void 2180 pipex_mppe_reduce_key(struct pipex_mppe *mppe) 2181 { 2182 switch (mppe->keylenbits) { 2183 case 40: 2184 mppe->session_key[0] = 0xd1; 2185 mppe->session_key[1] = 0x26; 2186 mppe->session_key[2] = 0x9e; 2187 break; 2188 case 56: 2189 mppe->session_key[0] = 0xd1; 2190 break; 2191 } 2192 } 2193 2194 Static void 2195 mppe_key_change(struct pipex_mppe *mppe) 2196 { 2197 u_char interim[16]; 2198 struct rc4_ctx keychg; 2199 2200 memset(&keychg, 0, sizeof(keychg)); 2201 2202 GetNewKeyFromSHA(mppe->master_key, mppe->session_key, mppe->keylen, 2203 interim); 2204 2205 rc4_keysetup(&keychg, interim, mppe->keylen); 2206 rc4_crypt(&keychg, interim, mppe->session_key, mppe->keylen); 2207 2208 pipex_mppe_reduce_key(mppe); 2209 2210 if (mppe->old_session_keys) { 2211 int idx = mppe->coher_cnt & PIPEX_MPPE_OLDKEYMASK; 2212 memcpy(mppe->old_session_keys[idx], 2213 mppe->session_key, PIPEX_MPPE_KEYLEN); 2214 } 2215 } 2216 2217 Static void 2218 pipex_mppe_input(struct mbuf *m0, struct pipex_session *session) 2219 { 2220 int pktloss, encrypt, flushed, m, n, len; 2221 struct pipex_mppe *mppe; 2222 uint16_t coher_cnt; 2223 struct mbuf *m1; 2224 u_char *cp; 2225 int rewind = 0; 2226 2227 /* pullup */ 2228 PIPEX_PULLUP(m0, sizeof(coher_cnt)); 2229 if (m0 == NULL) 2230 goto drop; 2231 2232 mppe = &session->mppe_recv; 2233 /* get header information */ 2234 cp = mtod(m0, u_char *); 2235 GETSHORT(coher_cnt, cp); 2236 flushed = ((coher_cnt & 0x8000) != 0) ? 1 : 0; 2237 encrypt = ((coher_cnt & 0x1000) != 0) ? 1 : 0; 2238 coher_cnt &= PIPEX_COHERENCY_CNT_MASK; 2239 pktloss = 0; 2240 2241 PIPEX_MPPE_DBG((session, LOG_DEBUG, "in coher_cnt=%03x %s%s", 2242 mppe->coher_cnt, (flushed) ? "[flushed]" : "", 2243 (encrypt) ? "[encrypt]" : "")); 2244 2245 if (encrypt == 0) { 2246 pipex_session_log(session, LOG_DEBUG, 2247 "Received unexpected MPPE packet.(no ecrypt)"); 2248 goto drop; 2249 } 2250 2251 /* adjust mbuf */ 2252 m_adj(m0, sizeof(coher_cnt)); 2253 2254 /* 2255 * L2TP data session may be used without sequencing, PPP frames may 2256 * arrive in disorder. The 'coherency counter' of MPPE detects such 2257 * situations, but we cannot distinguish between 'disorder' and 2258 * 'packet loss' exactly. 2259 * 2260 * When 'coherency counter' detects lost packets greater than 2261 * (4096 - 256), we treat as 'disorder' otherwise treat as 2262 * 'packet loss'. 2263 */ 2264 { 2265 int coher_cnt0; 2266 2267 coher_cnt0 = coher_cnt; 2268 if (coher_cnt < mppe->coher_cnt) 2269 coher_cnt0 += 0x1000; 2270 if (coher_cnt0 - mppe->coher_cnt > 0x0f00) { 2271 if (!mppe->stateless || 2272 coher_cnt0 - mppe->coher_cnt 2273 <= 0x1000 - PIPEX_MPPE_NOLDKEY) { 2274 pipex_session_log(session, LOG_DEBUG, 2275 "Workaround the out-of-sequence PPP framing problem: " 2276 "%d => %d", mppe->coher_cnt, coher_cnt); 2277 goto drop; 2278 } 2279 rewind = 1; 2280 } 2281 } 2282 2283 if (mppe->stateless != 0) { 2284 if (!rewind) { 2285 mppe_key_change(mppe); 2286 while (mppe->coher_cnt != coher_cnt) { 2287 mppe->coher_cnt++; 2288 mppe->coher_cnt &= PIPEX_COHERENCY_CNT_MASK; 2289 mppe_key_change(mppe); 2290 pktloss++; 2291 } 2292 } 2293 pipex_mppe_setoldkey(mppe, coher_cnt); 2294 } else { 2295 if (flushed) { 2296 if (coher_cnt < mppe->coher_cnt) { 2297 coher_cnt += 0x1000; 2298 } 2299 pktloss += coher_cnt - mppe->coher_cnt; 2300 m = mppe->coher_cnt / 256; 2301 n = coher_cnt / 256; 2302 while (m++ < n) 2303 mppe_key_change(mppe); 2304 2305 coher_cnt &= PIPEX_COHERENCY_CNT_MASK; 2306 mppe->coher_cnt = coher_cnt; 2307 } else if (mppe->coher_cnt != coher_cnt) { 2308 /* Send CCP ResetReq */ 2309 PIPEX_DBG((session, LOG_DEBUG, "CCP SendResetReq")); 2310 pipex_ccp_output(session, CCP_RESETREQ, 2311 session->ccp_id++); 2312 goto drop; 2313 } 2314 if ((coher_cnt & 0xff) == 0xff) { 2315 mppe_key_change(mppe); 2316 flushed = 1; 2317 } 2318 if (flushed) 2319 pipex_mppe_setkey(mppe); 2320 } 2321 2322 if (pktloss > 1000) { 2323 pipex_session_log(session, LOG_DEBUG, 2324 "%d packets loss.", pktloss); 2325 } 2326 2327 /* decrypt ppp payload */ 2328 for (m1 = m0; m1; m1 = m1->m_next) { 2329 cp = mtod(m1, u_char *); 2330 len = m1->m_len; 2331 pipex_mppe_crypt(mppe, len, cp, cp); 2332 } 2333 2334 if (!rewind) { 2335 /* update coher_cnt */ 2336 mppe->coher_cnt++; 2337 mppe->coher_cnt &= PIPEX_COHERENCY_CNT_MASK; 2338 } 2339 if (m0->m_pkthdr.len < PIPEX_PPPMINLEN) 2340 goto drop; 2341 2342 pipex_ppp_input(m0, session, 1); 2343 2344 return; 2345 drop: 2346 m_freem(m0); 2347 counters_inc(session->stat_counters, pxc_ierrors); 2348 } 2349 2350 Static void 2351 pipex_mppe_output(struct mbuf *m0, struct pipex_session *session, 2352 uint16_t protocol) 2353 { 2354 int encrypt, flushed, len; 2355 struct mppe_header { 2356 uint16_t coher_cnt; 2357 uint16_t protocol; 2358 } __packed *hdr; 2359 u_char *cp; 2360 struct pipex_mppe *mppe; 2361 struct mbuf *m; 2362 2363 mppe = &session->mppe_send; 2364 2365 /* 2366 * create a deep-copy if the mbuf has a shared mbuf cluster. 2367 * this is required to handle cases of tcp retransmission. 2368 */ 2369 for (m = m0; m != NULL; m = m->m_next) { 2370 if (M_READONLY(m)) { 2371 m = m_dup_pkt(m0, max_linkhdr, M_NOWAIT); 2372 m_freem(m0); 2373 if (m == NULL) 2374 goto drop; 2375 m0 = m; 2376 break; 2377 } 2378 } 2379 /* prepend mppe header */ 2380 M_PREPEND(m0, sizeof(struct mppe_header), M_NOWAIT); 2381 if (m0 == NULL) 2382 goto drop; 2383 hdr = mtod(m0, struct mppe_header *); 2384 hdr->protocol = protocol; 2385 2386 /* check coherency counter */ 2387 flushed = 0; 2388 encrypt = 1; 2389 2390 if (mppe->stateless != 0) { 2391 flushed = 1; 2392 mppe_key_change(mppe); 2393 } else { 2394 if ((mppe->coher_cnt % 0x100) == 0xff) { 2395 flushed = 1; 2396 mppe_key_change(mppe); 2397 } else if (mppe->resetreq != 0) { 2398 flushed = 1; 2399 mppe->resetreq = 0; 2400 } 2401 } 2402 2403 if (flushed) 2404 pipex_mppe_setkey(mppe); 2405 2406 PIPEX_MPPE_DBG((session, LOG_DEBUG, "out coher_cnt=%03x %s%s", 2407 mppe->coher_cnt, (flushed) ? "[flushed]" : "", 2408 (encrypt) ? "[encrypt]" : "")); 2409 2410 /* setup header information */ 2411 hdr->coher_cnt = (mppe->coher_cnt++) & PIPEX_COHERENCY_CNT_MASK; 2412 hdr->coher_cnt &= PIPEX_COHERENCY_CNT_MASK; 2413 if (flushed) 2414 hdr->coher_cnt |= 0x8000; 2415 if (encrypt) 2416 hdr->coher_cnt |= 0x1000; 2417 2418 hdr->protocol = htons(hdr->protocol); 2419 hdr->coher_cnt = htons(hdr->coher_cnt); 2420 2421 /* encrypt chain */ 2422 for (m = m0; m; m = m->m_next) { 2423 cp = mtod(m, u_char *); 2424 len = m->m_len; 2425 if (m == m0 && len > offsetof(struct mppe_header, protocol)) { 2426 len -= offsetof(struct mppe_header, protocol); 2427 cp += offsetof(struct mppe_header, protocol); 2428 } 2429 pipex_mppe_crypt(mppe, len, cp, cp); 2430 } 2431 2432 pipex_ppp_output(m0, session, PPP_COMP); 2433 2434 return; 2435 drop: 2436 counters_inc(session->stat_counters, pxc_oerrors); 2437 } 2438 2439 Static void 2440 pipex_ccp_input(struct mbuf *m0, struct pipex_session *session) 2441 { 2442 u_char *cp; 2443 int code, id, len; 2444 2445 if (m0->m_pkthdr.len < PPP_HDRLEN) 2446 goto drop; 2447 if ((m0 = m_pullup(m0, PPP_HDRLEN)) == NULL) 2448 goto drop; 2449 2450 cp = mtod(m0, u_char *); 2451 GETCHAR(code, cp); 2452 GETCHAR(id, cp); 2453 GETSHORT(len, cp); 2454 2455 switch (code) { 2456 case CCP_RESETREQ: 2457 PIPEX_DBG((session, LOG_DEBUG, "CCP RecvResetReq")); 2458 session->mppe_send.resetreq = 1; 2459 #ifndef PIPEX_NO_CCP_RESETACK 2460 PIPEX_DBG((session, LOG_DEBUG, "CCP SendResetAck")); 2461 pipex_ccp_output(session, CCP_RESETACK, id); 2462 #endif 2463 /* ignore error */ 2464 break; 2465 case CCP_RESETACK: 2466 PIPEX_DBG((session, LOG_DEBUG, "CCP RecvResetAck")); 2467 break; 2468 default: 2469 PIPEX_DBG((session, LOG_DEBUG, "CCP Recv code=%d", code)); 2470 goto drop; 2471 } 2472 m_freem(m0); 2473 2474 return; 2475 drop: 2476 m_freem(m0); 2477 counters_inc(session->stat_counters, pxc_ierrors); 2478 } 2479 2480 Static int 2481 pipex_ccp_output(struct pipex_session *session, int code, int id) 2482 { 2483 u_char *cp; 2484 struct mbuf *m; 2485 2486 MGETHDR(m, M_DONTWAIT, MT_DATA); 2487 if (m == NULL) { 2488 counters_inc(session->stat_counters, pxc_oerrors); 2489 return (1); 2490 } 2491 m->m_pkthdr.len = m->m_len = 4; 2492 cp = mtod(m, u_char *); 2493 PUTCHAR(code, cp); 2494 PUTCHAR(id, cp); 2495 PUTSHORT(4, cp); 2496 2497 pipex_ppp_output(m, session, PPP_CCP); 2498 2499 return (0); 2500 } 2501 #endif 2502 /*********************************************************************** 2503 * Miscellaneous functions 2504 ***********************************************************************/ 2505 /* adapted from FreeBSD:src/usr.sbin/ppp/tcpmss.c */ 2506 /* 2507 * Copyright (c) 2000 Ruslan Ermilov and Brian Somers <brian@Awfulhak.org> 2508 * All rights reserved. 2509 * 2510 * Redistribution and use in source and binary forms, with or without 2511 * modification, are permitted provided that the following conditions 2512 * are met: 2513 * 1. Redistributions of source code must retain the above copyright 2514 * notice, this list of conditions and the following disclaimer. 2515 * 2. Redistributions in binary form must reproduce the above copyright 2516 * notice, this list of conditions and the following disclaimer in the 2517 * documentation and/or other materials provided with the distribution. 2518 * 2519 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2520 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2521 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2522 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2523 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2524 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2525 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2526 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2527 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2528 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2529 * SUCH DAMAGE. 2530 * 2531 * $FreeBSD: src/usr.sbin/ppp/tcpmss.c,v 1.1.4.3 2001/07/19 11:39:54 brian Exp $ 2532 */ 2533 #define TCP_OPTLEN_IN_SEGMENT 12 /* timestamp option and padding */ 2534 #define MAXMSS(mtu) (mtu - sizeof(struct ip) - sizeof(struct tcphdr) - \ 2535 TCP_OPTLEN_IN_SEGMENT) 2536 /* 2537 * The following macro is used to update an internet checksum. "acc" is a 2538 * 32-bit accumulation of all the changes to the checksum (adding in old 2539 * 16-bit words and subtracting out new words), and "cksum" is the checksum 2540 * value to be updated. 2541 */ 2542 #define ADJUST_CHECKSUM(acc, cksum) { \ 2543 acc += cksum; \ 2544 if (acc < 0) { \ 2545 acc = -acc; \ 2546 acc = (acc >> 16) + (acc & 0xffff); \ 2547 acc += acc >> 16; \ 2548 cksum = (u_short) ~acc; \ 2549 } else { \ 2550 acc = (acc >> 16) + (acc & 0xffff); \ 2551 acc += acc >> 16; \ 2552 cksum = (u_short) acc; \ 2553 } \ 2554 } 2555 2556 /* 2557 * Rewrite max-segment-size TCP option to avoid PMTU blackhole issues. 2558 * The mtu parameter should be the MTU bottleneck (as far as we know) 2559 * on the link between the source and the destination. 2560 */ 2561 Static struct mbuf * 2562 adjust_tcp_mss(struct mbuf *m0, int mtu) 2563 { 2564 int opt, optlen, acc, mss, maxmss, lpktp; 2565 struct ip *pip; 2566 struct tcphdr *th; 2567 u_char *pktp, *mssp; 2568 u_int16_t ip_off; 2569 2570 lpktp = sizeof(struct ip) + sizeof(struct tcphdr) + PIPEX_TCP_OPTLEN; 2571 lpktp = MIN(lpktp, m0->m_pkthdr.len); 2572 2573 PIPEX_PULLUP(m0, lpktp); 2574 if (m0 == NULL) 2575 goto drop; 2576 2577 pktp = mtod(m0, char *); 2578 pip = (struct ip *)pktp; 2579 ip_off = ntohs(pip->ip_off); 2580 2581 /* Non TCP or fragmented packet must not have a MSS option */ 2582 if (pip->ip_p != IPPROTO_TCP || 2583 (ip_off & IP_MF) != 0 || (ip_off & IP_OFFMASK) != 0) 2584 goto handled; 2585 2586 pktp += pip->ip_hl << 2; 2587 lpktp -= pip->ip_hl << 2; 2588 2589 /* packet is broken */ 2590 if (sizeof(struct tcphdr) > lpktp) 2591 goto drop; 2592 th = (struct tcphdr *)pktp; 2593 2594 /* 2595 * As RFC 973, a MSS field must only be sent in the initial 2596 * connection request(it must be with SYN). 2597 */ 2598 if ((th->th_flags & TH_SYN) == 0) 2599 goto handled; 2600 2601 lpktp = MIN(th->th_off << 4, lpktp); 2602 2603 pktp += sizeof(struct tcphdr); 2604 lpktp -= sizeof(struct tcphdr); 2605 while (lpktp >= TCPOLEN_MAXSEG) { 2606 GETCHAR(opt, pktp); 2607 switch (opt) { 2608 case TCPOPT_MAXSEG: 2609 GETCHAR(optlen, pktp); 2610 mssp = pktp; /* mss place holder */ 2611 GETSHORT(mss, pktp); 2612 maxmss = MAXMSS(mtu); 2613 if (mss > maxmss) { 2614 PIPEX_DBG((NULL, LOG_DEBUG, 2615 "change tcp-mss %d => %d", mss, maxmss)); 2616 PUTSHORT(maxmss, mssp); 2617 acc = htons(mss); 2618 acc -= htons(maxmss); 2619 ADJUST_CHECKSUM(acc, th->th_sum); 2620 } 2621 goto handled; 2622 /* NOTREACHED */ 2623 case TCPOPT_EOL: 2624 goto handled; 2625 /* NOTREACHED */ 2626 case TCPOPT_NOP: 2627 lpktp--; 2628 break; 2629 default: 2630 GETCHAR(optlen, pktp); 2631 if (optlen < 2) /* packet is broken */ 2632 goto drop; 2633 pktp += optlen - 2; 2634 lpktp -= optlen; 2635 break; 2636 } 2637 } 2638 2639 handled: 2640 return (m0); 2641 2642 drop: 2643 m_freem(m0); 2644 return (NULL); 2645 } 2646 2647 /* 2648 * Check whether a packet should reset idle timer 2649 * Returns 1 to don't reset timer (i.e. the packet is "idle" packet) 2650 */ 2651 Static struct mbuf * 2652 ip_is_idle_packet(struct mbuf *m0, int *ris_idle) 2653 { 2654 u_int16_t ip_off; 2655 const struct udphdr *uh; 2656 struct ip *pip; 2657 int len; 2658 2659 /* pullup ip header */ 2660 len = sizeof(struct ip); 2661 PIPEX_PULLUP(m0, len); 2662 if (m0 == NULL) 2663 goto error; 2664 pip = mtod(m0, struct ip *); 2665 2666 /* 2667 * the packet which fragmentations was not the idle packet. 2668 */ 2669 ip_off = ntohs(pip->ip_off); 2670 if ((ip_off & IP_MF) || ((ip_off & IP_OFFMASK) != 0)) 2671 goto is_active; 2672 2673 switch (pip->ip_p) { 2674 case IPPROTO_IGMP: 2675 goto is_active; 2676 case IPPROTO_ICMP: 2677 len = pip->ip_hl * 4 + 8; 2678 PIPEX_PULLUP(m0, len); 2679 if (m0 == NULL) 2680 goto error; 2681 pip = mtod(m0, struct ip *); 2682 2683 switch (((unsigned char *) pip)[pip->ip_hl * 4]) { 2684 case 0: /* Echo Reply */ 2685 case 8: /* Echo Request */ 2686 goto is_active; 2687 default: 2688 goto is_idle; 2689 } 2690 2691 case IPPROTO_UDP: 2692 case IPPROTO_TCP: 2693 len = pip->ip_hl * 4 + sizeof(struct udphdr); 2694 PIPEX_PULLUP(m0, len); 2695 if (m0 == NULL) 2696 goto error; 2697 pip = mtod(m0, struct ip *); 2698 uh = (struct udphdr *)(mtod(m0, caddr_t) + pip->ip_hl * 4); 2699 2700 switch (ntohs(uh->uh_sport)) { 2701 case 53: /* DOMAIN */ 2702 case 67: /* BOOTPS */ 2703 case 68: /* BOOTPC */ 2704 case 123: /* NTP */ 2705 case 137: /* NETBIOS-NS */ 2706 case 520: /* RIP */ 2707 goto is_idle; 2708 } 2709 switch (ntohs(uh->uh_dport)) { 2710 case 53: /* DOMAIN */ 2711 case 67: /* BOOTPS */ 2712 case 68: /* BOOTPC */ 2713 case 123: /* NTP */ 2714 case 137: /* NETBIOS-NS */ 2715 case 520: /* RIP */ 2716 goto is_idle; 2717 } 2718 goto is_active; 2719 default: 2720 goto is_active; 2721 } 2722 2723 is_active: 2724 *ris_idle = 0; 2725 return (m0); 2726 2727 is_idle: 2728 *ris_idle = 1; 2729 return (m0); 2730 2731 error: 2732 return (NULL); 2733 } 2734 2735 Static void 2736 pipex_session_log(struct pipex_session *session, int prio, const char *fmt, ...) 2737 { 2738 char logbuf[1024]; 2739 va_list ap; 2740 2741 logpri(prio); 2742 if (session != NULL) { 2743 struct ifnet *ifp; 2744 2745 ifp = if_get(session->ifindex); 2746 addlog("pipex: ppp=%d iface=%s protocol=%s id=%d ", 2747 session->ppp_id, 2748 ifp? ifp->if_xname : "Unknown", 2749 (session->protocol == PIPEX_PROTO_PPPOE)? "PPPoE" : 2750 (session->protocol == PIPEX_PROTO_PPTP)? "PPTP" : 2751 (session->protocol == PIPEX_PROTO_L2TP) ? "L2TP" : 2752 "Unknown", session->session_id); 2753 if_put(ifp); 2754 } else 2755 addlog("pipex: "); 2756 2757 va_start(ap, fmt); 2758 vsnprintf(logbuf, sizeof(logbuf), fmt, ap); 2759 va_end(ap); 2760 addlog("%s\n", logbuf); 2761 } 2762 2763 Static uint32_t 2764 pipex_sockaddr_hash_key(struct sockaddr *sa) 2765 { 2766 switch (sa->sa_family) { 2767 case AF_INET: 2768 return ntohl(satosin(sa)->sin_addr.s_addr); 2769 case AF_INET6: 2770 return ntohl(satosin6(sa)->sin6_addr.s6_addr32[3]); 2771 } 2772 panic("pipex_sockaddr_hash_key: unknown address family"); 2773 return (0); 2774 } 2775 2776 /* 2777 * Compare struct sockaddr_in{,6} with the address only. 2778 * The port number is not covered. 2779 */ 2780 Static int 2781 pipex_sockaddr_compar_addr(struct sockaddr *a, struct sockaddr *b) 2782 { 2783 int cmp; 2784 2785 cmp = b->sa_family - a->sa_family; 2786 if (cmp != 0) 2787 return cmp; 2788 switch (a->sa_family) { 2789 case AF_INET: 2790 return (satosin(b)->sin_addr.s_addr - 2791 satosin(a)->sin_addr.s_addr); 2792 case AF_INET6: 2793 cmp = (satosin6(b)->sin6_scope_id - satosin6(a)->sin6_scope_id); 2794 if (cmp != 0) 2795 return cmp; 2796 return (memcmp(&satosin6(a)->sin6_addr, 2797 &satosin6(b)->sin6_addr, 2798 sizeof(struct in6_addr))); 2799 } 2800 panic("pipex_sockaddr_compar_addr: unknown address family"); 2801 2802 return (-1); 2803 } 2804 2805 int 2806 pipex_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 2807 size_t newlen) 2808 { 2809 switch (name[0]) { 2810 case PIPEXCTL_ENABLE: 2811 if (namelen != 1) 2812 return (ENOTDIR); 2813 return (sysctl_int_bounded(oldp, oldlenp, newp, newlen, 2814 &pipex_enable, 0, 1)); 2815 default: 2816 return (ENOPROTOOPT); 2817 } 2818 /* NOTREACHED */ 2819 } 2820