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