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