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