1 /* $OpenBSD: pipex.c,v 1.127 2020/08/30 19:48:16 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 PIPEXSMODE: 167 break; 168 169 case PIPEXGMODE: 170 *(int *)data = 1; 171 break; 172 173 case PIPEXCSESSION: 174 ret = pipex_config_session( 175 (struct pipex_session_config_req *)data, ownersc); 176 break; 177 178 case PIPEXGSTAT: 179 ret = pipex_get_stat((struct pipex_session_stat_req *)data, 180 ownersc); 181 break; 182 183 case PIPEXGCLOSED: 184 ret = pipex_get_closed((struct pipex_session_list_req *)data, 185 ownersc); 186 break; 187 188 default: 189 ret = ENOTTY; 190 break; 191 } 192 193 return (ret); 194 } 195 196 /************************************************************************ 197 * Session management functions 198 ************************************************************************/ 199 int 200 pipex_init_session(struct pipex_session **rsession, 201 struct pipex_session_req *req) 202 { 203 struct pipex_session *session; 204 #ifdef PIPEX_PPPOE 205 struct ifnet *over_ifp = NULL; 206 #endif 207 208 /* Checks requeted parameters. */ 209 switch (req->pr_protocol) { 210 #ifdef PIPEX_PPPOE 211 case PIPEX_PROTO_PPPOE: 212 over_ifp = ifunit(req->pr_proto.pppoe.over_ifname); 213 if (over_ifp == NULL) 214 return (EINVAL); 215 if (req->pr_peer_address.ss_family != AF_UNSPEC) 216 return (EINVAL); 217 break; 218 #endif 219 #if defined(PIPEX_L2TP) || defined(PIPEX_PPTP) 220 case PIPEX_PROTO_PPTP: 221 case PIPEX_PROTO_L2TP: 222 switch (req->pr_peer_address.ss_family) { 223 case AF_INET: 224 if (req->pr_peer_address.ss_len != 225 sizeof(struct sockaddr_in)) 226 return (EINVAL); 227 break; 228 #ifdef INET6 229 case AF_INET6: 230 if (req->pr_peer_address.ss_len != 231 sizeof(struct sockaddr_in6)) 232 return (EINVAL); 233 break; 234 #endif 235 default: 236 return (EPROTONOSUPPORT); 237 } 238 if (req->pr_peer_address.ss_family != 239 req->pr_local_address.ss_family || 240 req->pr_peer_address.ss_len != 241 req->pr_local_address.ss_len) 242 return (EINVAL); 243 break; 244 #endif /* defined(PIPEX_PPTP) || defined(PIPEX_L2TP) */ 245 default: 246 return (EPROTONOSUPPORT); 247 } 248 #ifdef PIPEX_MPPE 249 if ((req->pr_ppp_flags & PIPEX_PPP_MPPE_ACCEPTED) != 0) { 250 if (req->pr_mppe_recv.keylenbits <= 0) 251 return (EINVAL); 252 } 253 if ((req->pr_ppp_flags & PIPEX_PPP_MPPE_ENABLED) != 0) { 254 if (req->pr_mppe_send.keylenbits <= 0) 255 return (EINVAL); 256 } 257 if ((req->pr_ppp_flags & PIPEX_PPP_MPPE_REQUIRED) != 0) { 258 if ((req->pr_ppp_flags & 259 (PIPEX_PPP_MPPE_ACCEPTED | PIPEX_PPP_MPPE_ENABLED)) != 260 (PIPEX_PPP_MPPE_ACCEPTED | PIPEX_PPP_MPPE_ENABLED)) 261 return (EINVAL); 262 } 263 #endif 264 265 /* prepare a new session */ 266 session = pool_get(&pipex_session_pool, PR_WAITOK | PR_ZERO); 267 session->state = PIPEX_STATE_INITIAL; 268 session->protocol = req->pr_protocol; 269 session->session_id = req->pr_session_id; 270 session->peer_session_id = req->pr_peer_session_id; 271 session->peer_mru = req->pr_peer_mru; 272 session->timeout_sec = req->pr_timeout_sec; 273 session->ppp_flags = req->pr_ppp_flags; 274 session->ppp_id = req->pr_ppp_id; 275 276 session->ip_forward = 1; 277 278 session->ip_address.sin_family = AF_INET; 279 session->ip_address.sin_len = sizeof(struct sockaddr_in); 280 session->ip_address.sin_addr = req->pr_ip_address; 281 282 session->ip_netmask.sin_family = AF_INET; 283 session->ip_netmask.sin_len = sizeof(struct sockaddr_in); 284 session->ip_netmask.sin_addr = req->pr_ip_netmask; 285 286 if (session->ip_netmask.sin_addr.s_addr == 0L) 287 session->ip_netmask.sin_addr.s_addr = 0xffffffffL; 288 session->ip_address.sin_addr.s_addr &= 289 session->ip_netmask.sin_addr.s_addr; 290 291 if (req->pr_peer_address.ss_len > 0) 292 memcpy(&session->peer, &req->pr_peer_address, 293 MIN(req->pr_peer_address.ss_len, sizeof(session->peer))); 294 if (req->pr_local_address.ss_len > 0) 295 memcpy(&session->local, &req->pr_local_address, 296 MIN(req->pr_local_address.ss_len, sizeof(session->local))); 297 #ifdef PIPEX_PPPOE 298 if (req->pr_protocol == PIPEX_PROTO_PPPOE) 299 session->proto.pppoe.over_ifidx = over_ifp->if_index; 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, (caddr_t)&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), (caddr_t)&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), (caddr_t)&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), (caddr_t)&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), (caddr_t)&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), (caddr_t)&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, (caddr_t)&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 1632 hlen = sizeof(struct pipex_l2tp_header) + 1633 ((pipex_session_is_l2tp_data_sequencing_on(session)) 1634 ? sizeof(struct pipex_l2tp_seq_header) : 0) + 1635 sizeof(struct udphdr) + 1636 #ifdef INET6 1637 ((session->peer.sin6.sin6_family == AF_INET6) 1638 ? sizeof(struct ip6_hdr) : sizeof(struct ip)); 1639 #else 1640 sizeof(struct ip); 1641 #endif 1642 1643 datalen = 0; 1644 if (m0 != NULL) { 1645 datalen = m0->m_pkthdr.len; 1646 M_PREPEND(m0, hlen, M_NOWAIT); 1647 if (m0 == NULL) 1648 goto drop; 1649 } else { 1650 MGETHDR(m0, M_DONTWAIT, MT_DATA); 1651 if (m0 == NULL) 1652 goto drop; 1653 KASSERT(hlen <= MHLEN); 1654 m0->m_pkthdr.len = m0->m_len = hlen; 1655 } 1656 1657 #ifdef INET6 1658 hlen = (session->peer.sin6.sin6_family == AF_INET6) 1659 ? sizeof(struct ip6_hdr) : sizeof(struct ip); 1660 #else 1661 hlen = sizeof(struct ip); 1662 #endif 1663 plen = datalen + sizeof(struct pipex_l2tp_header) + 1664 ((pipex_session_is_l2tp_data_sequencing_on(session)) 1665 ? sizeof(struct pipex_l2tp_seq_header) : 0); 1666 1667 l2tp = (struct pipex_l2tp_header *) 1668 (mtod(m0, caddr_t) + hlen + sizeof(struct udphdr)); 1669 l2tp->flagsver = PIPEX_L2TP_VER | PIPEX_L2TP_FLAG_LENGTH; 1670 l2tp->length = htons(plen); 1671 l2tp->tunnel_id = htons(session->proto.l2tp.peer_tunnel_id); 1672 l2tp->session_id = htons(session->peer_session_id); 1673 if (pipex_session_is_l2tp_data_sequencing_on(session)) { 1674 seq = (struct pipex_l2tp_seq_header *)(l2tp + 1); 1675 l2tp->flagsver |= PIPEX_L2TP_FLAG_SEQUENCE; 1676 seq->ns = htons(session->proto.l2tp.ns_nxt); 1677 session->proto.l2tp.ns_nxt++; 1678 session->proto.l2tp.ns_gap++; 1679 session->proto.l2tp.nr_acked = session->proto.l2tp.nr_nxt - 1; 1680 seq->nr = htons(session->proto.l2tp.nr_acked); 1681 } 1682 l2tp->flagsver = htons(l2tp->flagsver); 1683 1684 plen += sizeof(struct udphdr); 1685 udp = (struct udphdr *)(mtod(m0, caddr_t) + hlen); 1686 udp->uh_sport = session->local.sin6.sin6_port; 1687 udp->uh_dport = session->peer.sin6.sin6_port; 1688 udp->uh_ulen = htons(plen); 1689 udp->uh_sum = 0; 1690 1691 m0->m_pkthdr.csum_flags |= M_UDP_CSUM_OUT; 1692 m0->m_pkthdr.ph_ifidx = session->ifindex; 1693 #if NPF > 0 1694 pf_pkt_addr_changed(m0); 1695 #endif 1696 switch (session->peer.sin6.sin6_family) { 1697 case AF_INET: 1698 ip = mtod(m0, struct ip *); 1699 ip->ip_p = IPPROTO_UDP; 1700 ip->ip_src = session->local.sin4.sin_addr; 1701 ip->ip_dst = session->peer.sin4.sin_addr; 1702 ip->ip_len = htons(hlen + plen); 1703 ip->ip_ttl = MAXTTL; 1704 ip->ip_tos = 0; 1705 ip->ip_off = 0; 1706 1707 ip_send(m0); 1708 break; 1709 #ifdef INET6 1710 case AF_INET6: 1711 ip6 = mtod(m0, struct ip6_hdr *); 1712 1713 ip6->ip6_flow = 0; 1714 ip6->ip6_vfc &= ~IPV6_VERSION_MASK; 1715 ip6->ip6_vfc |= IPV6_VERSION; 1716 ip6->ip6_nxt = IPPROTO_UDP; 1717 ip6->ip6_src = session->local.sin6.sin6_addr; 1718 (void)in6_embedscope(&ip6->ip6_dst, 1719 &session->peer.sin6, NULL); 1720 /* ip6->ip6_plen will be filled in ip6_output. */ 1721 1722 ip6_send(m0); 1723 break; 1724 #endif 1725 } 1726 udpstat_inc(udps_opackets); 1727 1728 if (datalen > 0) { /* network layer only */ 1729 /* countup statistics */ 1730 session->stat.opackets++; 1731 session->stat.obytes += datalen; 1732 } 1733 1734 return; 1735 drop: 1736 session->stat.oerrors++; 1737 } 1738 1739 struct pipex_session * 1740 pipex_l2tp_lookup_session(struct mbuf *m0, int off) 1741 { 1742 struct pipex_session *session; 1743 uint16_t flags, session_id, ver; 1744 u_char *cp, buf[PIPEX_L2TP_MINLEN]; 1745 1746 if (m0->m_pkthdr.len < off + PIPEX_L2TP_MINLEN) { 1747 PIPEX_DBG((NULL, LOG_DEBUG, 1748 "<%s> packet length is too short", __func__)); 1749 goto not_ours; 1750 } 1751 1752 /* get first 16bits of L2TP */ 1753 m_copydata(m0, off, sizeof(buf), buf); 1754 cp = buf; 1755 GETSHORT(flags, cp); 1756 ver = flags & PIPEX_L2TP_VER_MASK; 1757 1758 /* l2tp version must be '2' */ 1759 if (ver != PIPEX_L2TP_VER) { 1760 PIPEX_DBG((NULL, LOG_DEBUG, 1761 "<%s> l2tp header wrong version %u.", __func__, ver)); 1762 goto not_ours; 1763 } 1764 if ((flags & PIPEX_L2TP_FLAG_TYPE) != 0) 1765 goto not_ours; 1766 1767 if (flags & PIPEX_L2TP_FLAG_LENGTH) 1768 cp += 2; /* skip length field */ 1769 cp += 2; /* skip tunnel-id field */ 1770 GETSHORT(session_id, cp); /* get session-id field */ 1771 1772 /* lookup pipex session table */ 1773 session = pipex_lookup_by_session_id(PIPEX_PROTO_L2TP, session_id); 1774 #ifdef PIPEX_DEBUG 1775 if (session == NULL) { 1776 PIPEX_DBG((NULL, LOG_DEBUG, 1777 "<%s> session not found (id=%d)", __func__, session_id)); 1778 goto not_ours; 1779 } 1780 #endif 1781 1782 return (session); 1783 1784 not_ours: 1785 return (NULL); 1786 } 1787 1788 struct mbuf * 1789 pipex_l2tp_input(struct mbuf *m0, int off0, struct pipex_session *session, 1790 uint32_t ipsecflowinfo) 1791 { 1792 struct pipex_l2tp_session *l2tp_session; 1793 int length, offset, hlen, nseq; 1794 u_char *cp, *nsp, *nrp; 1795 uint16_t flags, ns = 0, nr = 0; 1796 int rewind = 0; 1797 1798 NET_ASSERT_LOCKED(); 1799 length = offset = ns = nr = 0; 1800 l2tp_session = &session->proto.l2tp; 1801 l2tp_session->ipsecflowinfo = ipsecflowinfo; 1802 nsp = nrp = NULL; 1803 1804 m_copydata(m0, off0, sizeof(flags), (caddr_t)&flags); 1805 1806 flags = ntohs(flags) & PIPEX_L2TP_FLAG_MASK; 1807 KASSERT((flags & PIPEX_L2TP_FLAG_TYPE) == 0); 1808 1809 hlen = 2; /* flags and version fields */ 1810 if (flags & PIPEX_L2TP_FLAG_LENGTH) /* length */ 1811 hlen += 2; 1812 hlen += 4; /* tunnel-id and session-id */ 1813 if (flags & PIPEX_L2TP_FLAG_SEQUENCE) /* ns and nr */ 1814 hlen += 4; 1815 if (flags & PIPEX_L2TP_FLAG_OFFSET) /* offset */ 1816 hlen += 2; 1817 1818 PIPEX_PULLUP(m0, off0 + hlen); 1819 if (m0 == NULL) 1820 goto drop; 1821 1822 cp = mtod(m0, u_char *) + off0; 1823 cp += 2; /* flags and version */ 1824 if (flags & PIPEX_L2TP_FLAG_LENGTH) 1825 GETSHORT(length, cp); 1826 else 1827 length = m0->m_pkthdr.len - off0; 1828 cp += 4; /* skip tunnel-id and session-id field */ 1829 1830 /* pullup for seek sequences in header */ 1831 nseq = 0; 1832 if (flags & PIPEX_L2TP_FLAG_SEQUENCE) { 1833 nsp = cp; 1834 GETSHORT(ns, cp); 1835 nrp = cp; 1836 GETSHORT(nr, cp); 1837 1838 nr++; 1839 if (SEQ16_GT(nr, l2tp_session->ns_una) && 1840 SEQ16_LE(nr, l2tp_session->ns_nxt)) 1841 /* update 'ns_una' only if the ns is in valid range */ 1842 l2tp_session->ns_una = nr; 1843 if (SEQ16_LT(ns, l2tp_session->nr_nxt)) { 1844 rewind = 1; 1845 if (SEQ16_LT(ns, 1846 l2tp_session->nr_nxt - PIPEX_REWIND_LIMIT)) 1847 goto out_seq; 1848 } 1849 1850 ns++; 1851 nseq = SEQ16_SUB(ns, l2tp_session->nr_nxt); 1852 if (!rewind) 1853 l2tp_session->nr_nxt = ns; 1854 } 1855 if (flags & PIPEX_L2TP_FLAG_OFFSET) 1856 GETSHORT(offset, cp); 1857 1858 length -= hlen + offset; 1859 hlen += off0 + offset; 1860 if ((m0 = pipex_common_input(session, m0, hlen, length)) == NULL) { 1861 /* ok, The packet is for PIPEX */ 1862 if (!rewind) 1863 session->proto.l2tp.nr_gap += nseq; 1864 return (NULL); 1865 } 1866 1867 if (rewind) 1868 goto out_seq; 1869 1870 /* 1871 * overwrite sequence numbers to adjust a gap between pipex and 1872 * userland. 1873 */ 1874 if (flags & PIPEX_L2TP_FLAG_SEQUENCE) { 1875 --ns; --nr; /* revert original values */ 1876 ns -= l2tp_session->nr_gap; 1877 PUTSHORT(ns, nsp); 1878 1879 if (l2tp_session->ns_nxt == l2tp_session->ns_una) { 1880 nr -= l2tp_session->ns_gap; 1881 l2tp_session->ul_ns_una = nr; 1882 } else { 1883 /* 1884 * There are sending packets they are not acked. 1885 * In this situation, (ack - snd_gap) may points 1886 * before sending window of userland. So we don't 1887 * update the ack number. 1888 */ 1889 nr = l2tp_session->ul_ns_una; 1890 } 1891 PUTSHORT(nr, nrp); 1892 } 1893 1894 return (m0); 1895 out_seq: 1896 pipex_session_log(session, LOG_DEBUG, 1897 "Received bad data packet: out of sequence: seq=%u(%u-) " 1898 "ack=%u(%u-%u)", ns, l2tp_session->nr_nxt, nr, l2tp_session->ns_una, 1899 l2tp_session->ns_nxt); 1900 1901 /* FALLTHROUGH */ 1902 drop: 1903 m_freem(m0); 1904 session->stat.ierrors++; 1905 1906 return (NULL); 1907 } 1908 1909 struct pipex_session * 1910 pipex_l2tp_userland_lookup_session_ipv4(struct mbuf *m0, struct in_addr dst) 1911 { 1912 struct sockaddr_in sin; 1913 1914 memset(&sin, 0, sizeof(sin)); 1915 sin.sin_len = sizeof(sin); 1916 sin.sin_family = AF_INET; 1917 sin.sin_addr = dst; 1918 1919 return pipex_l2tp_userland_lookup_session(m0, sintosa(&sin)); 1920 } 1921 1922 #ifdef INET6 1923 struct pipex_session * 1924 pipex_l2tp_userland_lookup_session_ipv6(struct mbuf *m0, struct in6_addr dst) 1925 { 1926 struct sockaddr_in6 sin6; 1927 1928 memset(&sin6, 0, sizeof(sin6)); 1929 sin6.sin6_len = sizeof(sin6); 1930 sin6.sin6_family = AF_INET6; 1931 in6_recoverscope(&sin6, &dst); 1932 1933 return pipex_l2tp_userland_lookup_session(m0, sin6tosa(&sin6)); 1934 } 1935 #endif 1936 1937 struct pipex_session * 1938 pipex_l2tp_userland_lookup_session(struct mbuf *m0, struct sockaddr *sa) 1939 { 1940 struct pipex_l2tp_header l2tp; 1941 struct pipex_hash_head *list; 1942 struct pipex_session *session; 1943 uint16_t session_id, tunnel_id, flags; 1944 1945 if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6) 1946 return (NULL); 1947 1948 /* pullup */ 1949 if (m0->m_pkthdr.len < sizeof(l2tp)) { 1950 PIPEX_DBG((NULL, LOG_DEBUG, 1951 "<%s> packet length is too short", __func__)); 1952 return (NULL); 1953 } 1954 1955 /* get flags */ 1956 m_copydata(m0, 0, sizeof(l2tp), (caddr_t)&l2tp); 1957 flags = ntohs(l2tp.flagsver); 1958 1959 /* l2tp version must be '2' */ 1960 if ((flags & PIPEX_L2TP_VER_MASK) != PIPEX_L2TP_VER) { 1961 PIPEX_DBG((NULL, LOG_DEBUG, 1962 "<%s> l2tp header wrong version.", __func__)); 1963 return (NULL); 1964 } 1965 /* We need L2TP data messages only */ 1966 if ((flags & PIPEX_L2TP_FLAG_TYPE) != 0) 1967 return (NULL); 1968 /* No need to hook packets that don't have the sequence field */ 1969 if ((flags & PIPEX_L2TP_FLAG_SEQUENCE) == 0) 1970 return (NULL); 1971 1972 session_id = ntohs(l2tp.session_id); 1973 tunnel_id = ntohs(l2tp.tunnel_id); 1974 1975 list = PIPEX_PEER_ADDR_HASHTABLE(pipex_sockaddr_hash_key(sa)); 1976 LIST_FOREACH(session, list, peer_addr_chain) { 1977 if (pipex_sockaddr_compar_addr(&session->peer.sa, sa) != 0) 1978 continue; 1979 if (session->proto.l2tp.peer_tunnel_id != tunnel_id) 1980 continue; 1981 if (session->peer_session_id == session_id) 1982 break; 1983 } 1984 #ifdef PIPEX_DEBUG 1985 if (session == NULL) { 1986 PIPEX_DBG((NULL, LOG_DEBUG, "<%s> session not found " 1987 "(tunnel_id=%d, session_id=%d)", __func__, 1988 tunnel_id, session_id)); 1989 } 1990 #endif 1991 1992 return (session); 1993 } 1994 1995 struct mbuf * 1996 pipex_l2tp_userland_output(struct mbuf *m0, struct pipex_session *session) 1997 { 1998 struct pipex_l2tp_header *l2tp; 1999 struct pipex_l2tp_seq_header *seq; 2000 uint16_t ns, nr; 2001 2002 /* check length */ 2003 PIPEX_PULLUP(m0, sizeof(struct pipex_l2tp_header) + 2004 sizeof(struct pipex_l2tp_seq_header)); 2005 if (m0 == NULL) 2006 return (NULL); 2007 2008 l2tp = mtod(m0, struct pipex_l2tp_header *); 2009 KASSERT(ntohs(l2tp->flagsver) & PIPEX_L2TP_FLAG_SEQUENCE); 2010 2011 /* 2012 * overwrite sequence numbers to adjust a gap between pipex and 2013 * userland. 2014 */ 2015 seq = (struct pipex_l2tp_seq_header *)(l2tp + 1); 2016 ns = ntohs(seq->ns); 2017 nr = ntohs(seq->nr); 2018 2019 ns += session->proto.l2tp.ns_gap; 2020 seq->ns = htons(ns); 2021 session->proto.l2tp.ns_nxt++; 2022 2023 nr += session->proto.l2tp.nr_gap; 2024 seq->nr = htons(nr); 2025 if (SEQ16_GT(nr, session->proto.l2tp.nr_acked)) 2026 session->proto.l2tp.nr_acked = nr; 2027 2028 return (m0); 2029 } 2030 #endif /* PIPEX_L2TP */ 2031 2032 #ifdef PIPEX_MPPE 2033 /********************************************************************** 2034 * MPPE 2035 ***********************************************************************/ 2036 #define PIPEX_COHERENCY_CNT_MASK 0x0fff 2037 2038 static inline int 2039 pipex_mppe_setkey(struct pipex_mppe *mppe) 2040 { 2041 rc4_keysetup(&mppe->rc4ctx, mppe->session_key, mppe->keylen); 2042 2043 return (0); 2044 } 2045 2046 static inline int 2047 pipex_mppe_setoldkey(struct pipex_mppe *mppe, uint16_t coher_cnt) 2048 { 2049 KASSERT(mppe->old_session_keys != NULL); 2050 2051 rc4_keysetup(&mppe->rc4ctx, 2052 mppe->old_session_keys[coher_cnt & PIPEX_MPPE_OLDKEYMASK], 2053 mppe->keylen); 2054 2055 return (0); 2056 } 2057 2058 static inline void 2059 pipex_mppe_crypt(struct pipex_mppe *mppe, int len, u_char *indata, 2060 u_char *outdata) 2061 { 2062 rc4_crypt(&mppe->rc4ctx, indata, outdata, len); 2063 } 2064 2065 Static void 2066 pipex_mppe_init(struct pipex_mppe *mppe, int stateless, int keylenbits, 2067 u_char *master_key, int has_oldkey) 2068 { 2069 memset(mppe, 0, sizeof(struct pipex_mppe)); 2070 if (stateless) 2071 mppe->stateless = 1; 2072 if (has_oldkey) 2073 mppe->old_session_keys = 2074 pool_get(&mppe_key_pool, PR_WAITOK); 2075 else 2076 mppe->old_session_keys = NULL; 2077 memcpy(mppe->master_key, master_key, sizeof(mppe->master_key)); 2078 2079 mppe->keylenbits = keylenbits; 2080 switch (keylenbits) { 2081 case 40: 2082 case 56: 2083 mppe->keylen = 8; 2084 break; 2085 case 128: 2086 mppe->keylen = 16; 2087 break; 2088 } 2089 2090 GetNewKeyFromSHA(mppe->master_key, mppe->master_key, mppe->keylen, 2091 mppe->session_key); 2092 pipex_mppe_reduce_key(mppe); 2093 pipex_mppe_setkey(mppe); 2094 } 2095 2096 void 2097 pipex_session_init_mppe_recv(struct pipex_session *session, int stateless, 2098 int keylenbits, u_char *master_key) 2099 { 2100 pipex_mppe_init(&session->mppe_recv, stateless, keylenbits, 2101 master_key, stateless); 2102 session->ppp_flags |= PIPEX_PPP_MPPE_ACCEPTED; 2103 } 2104 2105 void 2106 pipex_session_init_mppe_send(struct pipex_session *session, int stateless, 2107 int keylenbits, u_char *master_key) 2108 { 2109 pipex_mppe_init(&session->mppe_send, stateless, keylenbits, 2110 master_key, 0); 2111 session->ppp_flags |= PIPEX_PPP_MPPE_ENABLED; 2112 } 2113 2114 #include <crypto/sha1.h> 2115 2116 static u_char SHAPad1[] = { 2117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2122 }, SHAPad2[] = { 2123 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 2124 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 2125 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 2126 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 2127 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 2128 }; 2129 2130 Static void 2131 GetNewKeyFromSHA(u_char *StartKey, u_char *SessionKey, int SessionKeyLength, 2132 u_char *InterimKey) 2133 { 2134 u_char Digest[20]; 2135 SHA1_CTX Context; 2136 2137 SHA1Init(&Context); 2138 SHA1Update(&Context, StartKey, SessionKeyLength); 2139 SHA1Update(&Context, SHAPad1, 40); 2140 SHA1Update(&Context, SessionKey, SessionKeyLength); 2141 SHA1Update(&Context, SHAPad2, 40); 2142 SHA1Final(Digest, &Context); 2143 2144 memcpy(InterimKey, Digest, SessionKeyLength); 2145 } 2146 2147 Static void 2148 pipex_mppe_reduce_key(struct pipex_mppe *mppe) 2149 { 2150 switch (mppe->keylenbits) { 2151 case 40: 2152 mppe->session_key[0] = 0xd1; 2153 mppe->session_key[1] = 0x26; 2154 mppe->session_key[2] = 0x9e; 2155 break; 2156 case 56: 2157 mppe->session_key[0] = 0xd1; 2158 break; 2159 } 2160 } 2161 2162 Static void 2163 mppe_key_change(struct pipex_mppe *mppe) 2164 { 2165 u_char interim[16]; 2166 struct rc4_ctx keychg; 2167 2168 memset(&keychg, 0, sizeof(keychg)); 2169 2170 GetNewKeyFromSHA(mppe->master_key, mppe->session_key, mppe->keylen, 2171 interim); 2172 2173 rc4_keysetup(&keychg, interim, mppe->keylen); 2174 rc4_crypt(&keychg, interim, mppe->session_key, mppe->keylen); 2175 2176 pipex_mppe_reduce_key(mppe); 2177 2178 if (mppe->old_session_keys) { 2179 int idx = mppe->coher_cnt & PIPEX_MPPE_OLDKEYMASK; 2180 memcpy(mppe->old_session_keys[idx], 2181 mppe->session_key, PIPEX_MPPE_KEYLEN); 2182 } 2183 } 2184 2185 Static void 2186 pipex_mppe_input(struct mbuf *m0, struct pipex_session *session) 2187 { 2188 int pktloss, encrypt, flushed, m, n, len; 2189 struct pipex_mppe *mppe; 2190 uint16_t coher_cnt; 2191 struct mbuf *m1; 2192 u_char *cp; 2193 int rewind = 0; 2194 2195 /* pullup */ 2196 PIPEX_PULLUP(m0, sizeof(coher_cnt)); 2197 if (m0 == NULL) 2198 goto drop; 2199 2200 mppe = &session->mppe_recv; 2201 /* get header information */ 2202 cp = mtod(m0, u_char *); 2203 GETSHORT(coher_cnt, cp); 2204 flushed = ((coher_cnt & 0x8000) != 0) ? 1 : 0; 2205 encrypt = ((coher_cnt & 0x1000) != 0) ? 1 : 0; 2206 coher_cnt &= PIPEX_COHERENCY_CNT_MASK; 2207 pktloss = 0; 2208 2209 PIPEX_MPPE_DBG((session, LOG_DEBUG, "in coher_cnt=%03x %s%s", 2210 mppe->coher_cnt, (flushed) ? "[flushed]" : "", 2211 (encrypt) ? "[encrypt]" : "")); 2212 2213 if (encrypt == 0) { 2214 pipex_session_log(session, LOG_DEBUG, 2215 "Received unexpected MPPE packet.(no ecrypt)"); 2216 goto drop; 2217 } 2218 2219 /* adjust mbuf */ 2220 m_adj(m0, sizeof(coher_cnt)); 2221 2222 /* 2223 * L2TP data session may be used without sequencing, PPP frames may 2224 * arrive in disorder. The 'coherency counter' of MPPE detects such 2225 * situations, but we cannot distinguish between 'disorder' and 2226 * 'packet loss' exactly. 2227 * 2228 * When 'coherency counter' detects lost packets greater than 2229 * (4096 - 256), we treat as 'disorder' otherwise treat as 2230 * 'packet loss'. 2231 */ 2232 { 2233 int coher_cnt0; 2234 2235 coher_cnt0 = coher_cnt; 2236 if (coher_cnt < mppe->coher_cnt) 2237 coher_cnt0 += 0x1000; 2238 if (coher_cnt0 - mppe->coher_cnt > 0x0f00) { 2239 if (!mppe->stateless || 2240 coher_cnt0 - mppe->coher_cnt 2241 <= 0x1000 - PIPEX_MPPE_NOLDKEY) { 2242 pipex_session_log(session, LOG_DEBUG, 2243 "Workaround the out-of-sequence PPP framing problem: " 2244 "%d => %d", mppe->coher_cnt, coher_cnt); 2245 goto drop; 2246 } 2247 rewind = 1; 2248 } 2249 } 2250 2251 if (mppe->stateless != 0) { 2252 if (!rewind) { 2253 mppe_key_change(mppe); 2254 while (mppe->coher_cnt != coher_cnt) { 2255 mppe->coher_cnt++; 2256 mppe->coher_cnt &= PIPEX_COHERENCY_CNT_MASK; 2257 mppe_key_change(mppe); 2258 pktloss++; 2259 } 2260 } 2261 pipex_mppe_setoldkey(mppe, coher_cnt); 2262 } else { 2263 if (flushed) { 2264 if (coher_cnt < mppe->coher_cnt) { 2265 coher_cnt += 0x1000; 2266 } 2267 pktloss += coher_cnt - mppe->coher_cnt; 2268 m = mppe->coher_cnt / 256; 2269 n = coher_cnt / 256; 2270 while (m++ < n) 2271 mppe_key_change(mppe); 2272 2273 coher_cnt &= PIPEX_COHERENCY_CNT_MASK; 2274 mppe->coher_cnt = coher_cnt; 2275 } else if (mppe->coher_cnt != coher_cnt) { 2276 /* Send CCP ResetReq */ 2277 PIPEX_DBG((session, LOG_DEBUG, "CCP SendResetReq")); 2278 pipex_ccp_output(session, CCP_RESETREQ, 2279 session->ccp_id++); 2280 goto drop; 2281 } 2282 if ((coher_cnt & 0xff) == 0xff) { 2283 mppe_key_change(mppe); 2284 flushed = 1; 2285 } 2286 if (flushed) 2287 pipex_mppe_setkey(mppe); 2288 } 2289 2290 if (pktloss > 1000) { 2291 pipex_session_log(session, LOG_DEBUG, 2292 "%d packets loss.", pktloss); 2293 } 2294 2295 /* decrypt ppp payload */ 2296 for (m1 = m0; m1; m1 = m1->m_next) { 2297 cp = mtod(m1, u_char *); 2298 len = m1->m_len; 2299 pipex_mppe_crypt(mppe, len, cp, cp); 2300 } 2301 2302 if (!rewind) { 2303 /* update coher_cnt */ 2304 mppe->coher_cnt++; 2305 mppe->coher_cnt &= PIPEX_COHERENCY_CNT_MASK; 2306 } 2307 if (m0->m_pkthdr.len < PIPEX_PPPMINLEN) 2308 goto drop; 2309 2310 pipex_ppp_input(m0, session, 1); 2311 2312 return; 2313 drop: 2314 m_freem(m0); 2315 session->stat.ierrors++; 2316 } 2317 2318 Static void 2319 pipex_mppe_output(struct mbuf *m0, struct pipex_session *session, 2320 uint16_t protocol) 2321 { 2322 int encrypt, flushed, len; 2323 struct mppe_header { 2324 uint16_t coher_cnt; 2325 uint16_t protocol; 2326 } __packed *hdr; 2327 u_char *cp; 2328 struct pipex_mppe *mppe; 2329 struct mbuf *m; 2330 2331 mppe = &session->mppe_send; 2332 2333 /* 2334 * create a deep-copy if the mbuf has a shared mbuf cluster. 2335 * this is required to handle cases of tcp retransmition. 2336 */ 2337 for (m = m0; m != NULL; m = m->m_next) { 2338 if (M_READONLY(m)) { 2339 m = m_dup_pkt(m0, max_linkhdr, M_NOWAIT); 2340 m_freem(m0); 2341 if (m == NULL) 2342 goto drop; 2343 m0 = m; 2344 break; 2345 } 2346 } 2347 /* prepend mppe header */ 2348 M_PREPEND(m0, sizeof(struct mppe_header), M_NOWAIT); 2349 if (m0 == NULL) 2350 goto drop; 2351 hdr = mtod(m0, struct mppe_header *); 2352 hdr->protocol = protocol; 2353 2354 /* check coherency counter */ 2355 flushed = 0; 2356 encrypt = 1; 2357 2358 if (mppe->stateless != 0) { 2359 flushed = 1; 2360 mppe_key_change(mppe); 2361 } else { 2362 if ((mppe->coher_cnt % 0x100) == 0xff) { 2363 flushed = 1; 2364 mppe_key_change(mppe); 2365 } else if (mppe->resetreq != 0) { 2366 flushed = 1; 2367 mppe->resetreq = 0; 2368 } 2369 } 2370 2371 if (flushed) 2372 pipex_mppe_setkey(mppe); 2373 2374 PIPEX_MPPE_DBG((session, LOG_DEBUG, "out coher_cnt=%03x %s%s", 2375 mppe->coher_cnt, (flushed) ? "[flushed]" : "", 2376 (encrypt) ? "[encrypt]" : "")); 2377 2378 /* setup header information */ 2379 hdr->coher_cnt = (mppe->coher_cnt++) & PIPEX_COHERENCY_CNT_MASK; 2380 hdr->coher_cnt &= PIPEX_COHERENCY_CNT_MASK; 2381 if (flushed) 2382 hdr->coher_cnt |= 0x8000; 2383 if (encrypt) 2384 hdr->coher_cnt |= 0x1000; 2385 2386 hdr->protocol = htons(hdr->protocol); 2387 hdr->coher_cnt = htons(hdr->coher_cnt); 2388 2389 /* encrypt chain */ 2390 for (m = m0; m; m = m->m_next) { 2391 cp = mtod(m, u_char *); 2392 len = m->m_len; 2393 if (m == m0 && len > offsetof(struct mppe_header, protocol)) { 2394 len -= offsetof(struct mppe_header, protocol); 2395 cp += offsetof(struct mppe_header, protocol); 2396 } 2397 pipex_mppe_crypt(mppe, len, cp, cp); 2398 } 2399 2400 pipex_ppp_output(m0, session, PPP_COMP); 2401 2402 return; 2403 drop: 2404 session->stat.oerrors++; 2405 } 2406 2407 Static void 2408 pipex_ccp_input(struct mbuf *m0, struct pipex_session *session) 2409 { 2410 u_char *cp; 2411 int code, id, len; 2412 2413 if (m0->m_pkthdr.len < PPP_HDRLEN) 2414 goto drop; 2415 if ((m0 = m_pullup(m0, PPP_HDRLEN)) == NULL) 2416 goto drop; 2417 2418 cp = mtod(m0, u_char *); 2419 GETCHAR(code, cp); 2420 GETCHAR(id, cp); 2421 GETSHORT(len, cp); 2422 2423 switch (code) { 2424 case CCP_RESETREQ: 2425 PIPEX_DBG((session, LOG_DEBUG, "CCP RecvResetReq")); 2426 session->mppe_send.resetreq = 1; 2427 #ifndef PIPEX_NO_CCP_RESETACK 2428 PIPEX_DBG((session, LOG_DEBUG, "CCP SendResetAck")); 2429 pipex_ccp_output(session, CCP_RESETACK, id); 2430 #endif 2431 /* ignore error */ 2432 break; 2433 case CCP_RESETACK: 2434 PIPEX_DBG((session, LOG_DEBUG, "CCP RecvResetAck")); 2435 break; 2436 default: 2437 PIPEX_DBG((session, LOG_DEBUG, "CCP Recv code=%d", code)); 2438 goto drop; 2439 } 2440 m_freem(m0); 2441 2442 return; 2443 drop: 2444 m_freem(m0); 2445 session->stat.ierrors++; 2446 } 2447 2448 Static int 2449 pipex_ccp_output(struct pipex_session *session, int code, int id) 2450 { 2451 u_char *cp; 2452 struct mbuf *m; 2453 2454 MGETHDR(m, M_DONTWAIT, MT_DATA); 2455 if (m == NULL) { 2456 session->stat.oerrors++; 2457 return (1); 2458 } 2459 m->m_pkthdr.len = m->m_len = 4; 2460 cp = mtod(m, u_char *); 2461 PUTCHAR(code, cp); 2462 PUTCHAR(id, cp); 2463 PUTSHORT(4, cp); 2464 2465 pipex_ppp_output(m, session, PPP_CCP); 2466 2467 return (0); 2468 } 2469 #endif 2470 /*********************************************************************** 2471 * Miscellaneous fuctions 2472 ***********************************************************************/ 2473 /* adapted from FreeBSD:src/usr.sbin/ppp/tcpmss.c */ 2474 /* 2475 * Copyright (c) 2000 Ruslan Ermilov and Brian Somers <brian@Awfulhak.org> 2476 * All rights reserved. 2477 * 2478 * Redistribution and use in source and binary forms, with or without 2479 * modification, are permitted provided that the following conditions 2480 * are met: 2481 * 1. Redistributions of source code must retain the above copyright 2482 * notice, this list of conditions and the following disclaimer. 2483 * 2. Redistributions in binary form must reproduce the above copyright 2484 * notice, this list of conditions and the following disclaimer in the 2485 * documentation and/or other materials provided with the distribution. 2486 * 2487 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2488 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2489 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2490 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2491 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2492 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2493 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2494 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2495 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2496 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2497 * SUCH DAMAGE. 2498 * 2499 * $FreeBSD: src/usr.sbin/ppp/tcpmss.c,v 1.1.4.3 2001/07/19 11:39:54 brian Exp $ 2500 */ 2501 #define TCP_OPTLEN_IN_SEGMENT 12 /* timestamp option and padding */ 2502 #define MAXMSS(mtu) (mtu - sizeof(struct ip) - sizeof(struct tcphdr) - \ 2503 TCP_OPTLEN_IN_SEGMENT) 2504 /* 2505 * The following macro is used to update an internet checksum. "acc" is a 2506 * 32-bit accumulation of all the changes to the checksum (adding in old 2507 * 16-bit words and subtracting out new words), and "cksum" is the checksum 2508 * value to be updated. 2509 */ 2510 #define ADJUST_CHECKSUM(acc, cksum) { \ 2511 acc += cksum; \ 2512 if (acc < 0) { \ 2513 acc = -acc; \ 2514 acc = (acc >> 16) + (acc & 0xffff); \ 2515 acc += acc >> 16; \ 2516 cksum = (u_short) ~acc; \ 2517 } else { \ 2518 acc = (acc >> 16) + (acc & 0xffff); \ 2519 acc += acc >> 16; \ 2520 cksum = (u_short) acc; \ 2521 } \ 2522 } 2523 2524 /* 2525 * Rewrite max-segment-size TCP option to avoid PMTU blackhole issues. 2526 * The mtu parameter should be the MTU bottleneck (as far as we know) 2527 * on the link between the source and the destination. 2528 */ 2529 Static struct mbuf * 2530 adjust_tcp_mss(struct mbuf *m0, int mtu) 2531 { 2532 int opt, optlen, acc, mss, maxmss, lpktp; 2533 struct ip *pip; 2534 struct tcphdr *th; 2535 u_char *pktp, *mssp; 2536 u_int16_t ip_off; 2537 2538 lpktp = sizeof(struct ip) + sizeof(struct tcphdr) + PIPEX_TCP_OPTLEN; 2539 lpktp = MIN(lpktp, m0->m_pkthdr.len); 2540 2541 PIPEX_PULLUP(m0, lpktp); 2542 if (m0 == NULL) 2543 goto drop; 2544 2545 pktp = mtod(m0, char *); 2546 pip = (struct ip *)pktp; 2547 ip_off = ntohs(pip->ip_off); 2548 2549 /* Non TCP or fragmented packet must not have a MSS option */ 2550 if (pip->ip_p != IPPROTO_TCP || 2551 (ip_off & IP_MF) != 0 || (ip_off & IP_OFFMASK) != 0) 2552 goto handled; 2553 2554 pktp += pip->ip_hl << 2; 2555 lpktp -= pip->ip_hl << 2; 2556 2557 /* packet is broken */ 2558 if (sizeof(struct tcphdr) > lpktp) 2559 goto drop; 2560 th = (struct tcphdr *)pktp; 2561 2562 /* 2563 * As RFC 973, a MSS field must only be sent in the initial 2564 * connection request(it must be with SYN). 2565 */ 2566 if ((th->th_flags & TH_SYN) == 0) 2567 goto handled; 2568 2569 lpktp = MIN(th->th_off << 4, lpktp); 2570 2571 pktp += sizeof(struct tcphdr); 2572 lpktp -= sizeof(struct tcphdr); 2573 while (lpktp >= TCPOLEN_MAXSEG) { 2574 GETCHAR(opt, pktp); 2575 switch (opt) { 2576 case TCPOPT_MAXSEG: 2577 GETCHAR(optlen, pktp); 2578 mssp = pktp; /* mss place holder */ 2579 GETSHORT(mss, pktp); 2580 maxmss = MAXMSS(mtu); 2581 if (mss > maxmss) { 2582 PIPEX_DBG((NULL, LOG_DEBUG, 2583 "change tcp-mss %d => %d", mss, maxmss)); 2584 PUTSHORT(maxmss, mssp); 2585 acc = htons(mss); 2586 acc -= htons(maxmss); 2587 ADJUST_CHECKSUM(acc, th->th_sum); 2588 } 2589 goto handled; 2590 /* NOTREACHED */ 2591 case TCPOPT_EOL: 2592 goto handled; 2593 /* NOTREACHED */ 2594 case TCPOPT_NOP: 2595 lpktp--; 2596 break; 2597 default: 2598 GETCHAR(optlen, pktp); 2599 if (optlen < 2) /* packet is broken */ 2600 goto drop; 2601 pktp += optlen - 2; 2602 lpktp -= optlen; 2603 break; 2604 } 2605 } 2606 2607 handled: 2608 return (m0); 2609 2610 drop: 2611 m_freem(m0); 2612 return (NULL); 2613 } 2614 2615 /* 2616 * Check whether a packet should reset idle timer 2617 * Returns 1 to don't reset timer (i.e. the packet is "idle" packet) 2618 */ 2619 Static struct mbuf * 2620 ip_is_idle_packet(struct mbuf *m0, int *ris_idle) 2621 { 2622 u_int16_t ip_off; 2623 const struct udphdr *uh; 2624 struct ip *pip; 2625 int len; 2626 2627 /* pullup ip header */ 2628 len = sizeof(struct ip); 2629 PIPEX_PULLUP(m0, len); 2630 if (m0 == NULL) 2631 goto error; 2632 pip = mtod(m0, struct ip *); 2633 2634 /* 2635 * the packet which fragmentations was not the idle packet. 2636 */ 2637 ip_off = ntohs(pip->ip_off); 2638 if ((ip_off & IP_MF) || ((ip_off & IP_OFFMASK) != 0)) 2639 goto is_active; 2640 2641 switch (pip->ip_p) { 2642 case IPPROTO_IGMP: 2643 goto is_active; 2644 case IPPROTO_ICMP: 2645 len = pip->ip_hl * 4 + 8; 2646 PIPEX_PULLUP(m0, len); 2647 if (m0 == NULL) 2648 goto error; 2649 pip = mtod(m0, struct ip *); 2650 2651 switch (((unsigned char *) pip)[pip->ip_hl * 4]) { 2652 case 0: /* Echo Reply */ 2653 case 8: /* Echo Request */ 2654 goto is_active; 2655 default: 2656 goto is_idle; 2657 } 2658 2659 case IPPROTO_UDP: 2660 case IPPROTO_TCP: 2661 len = pip->ip_hl * 4 + sizeof(struct udphdr); 2662 PIPEX_PULLUP(m0, len); 2663 if (m0 == NULL) 2664 goto error; 2665 pip = mtod(m0, struct ip *); 2666 uh = (struct udphdr *)(mtod(m0, caddr_t) + pip->ip_hl * 4); 2667 2668 switch (ntohs(uh->uh_sport)) { 2669 case 53: /* DOMAIN */ 2670 case 67: /* BOOTPS */ 2671 case 68: /* BOOTPC */ 2672 case 123: /* NTP */ 2673 case 137: /* NETBIOS-NS */ 2674 case 520: /* RIP */ 2675 goto is_idle; 2676 } 2677 switch (ntohs(uh->uh_dport)) { 2678 case 53: /* DOMAIN */ 2679 case 67: /* BOOTPS */ 2680 case 68: /* BOOTPC */ 2681 case 123: /* NTP */ 2682 case 137: /* NETBIOS-NS */ 2683 case 520: /* RIP */ 2684 goto is_idle; 2685 } 2686 goto is_active; 2687 default: 2688 goto is_active; 2689 } 2690 2691 is_active: 2692 *ris_idle = 0; 2693 return (m0); 2694 2695 is_idle: 2696 *ris_idle = 1; 2697 return (m0); 2698 2699 error: 2700 return (NULL); 2701 } 2702 2703 Static void 2704 pipex_session_log(struct pipex_session *session, int prio, const char *fmt, ...) 2705 { 2706 char logbuf[1024]; 2707 va_list ap; 2708 2709 logpri(prio); 2710 if (session != NULL) { 2711 struct ifnet *ifp; 2712 2713 ifp = if_get(session->ifindex); 2714 addlog("pipex: ppp=%d iface=%s protocol=%s id=%d ", 2715 session->ppp_id, 2716 ifp? ifp->if_xname : "Unknown", 2717 (session->protocol == PIPEX_PROTO_PPPOE)? "PPPoE" : 2718 (session->protocol == PIPEX_PROTO_PPTP)? "PPTP" : 2719 (session->protocol == PIPEX_PROTO_L2TP) ? "L2TP" : 2720 "Unknown", session->session_id); 2721 if_put(ifp); 2722 } else 2723 addlog("pipex: "); 2724 2725 va_start(ap, fmt); 2726 vsnprintf(logbuf, sizeof(logbuf), fmt, ap); 2727 va_end(ap); 2728 addlog("%s\n", logbuf); 2729 } 2730 2731 Static uint32_t 2732 pipex_sockaddr_hash_key(struct sockaddr *sa) 2733 { 2734 switch (sa->sa_family) { 2735 case AF_INET: 2736 return ntohl(satosin(sa)->sin_addr.s_addr); 2737 case AF_INET6: 2738 return ntohl(satosin6(sa)->sin6_addr.s6_addr32[3]); 2739 } 2740 panic("pipex_sockaddr_hash_key: unknown address family"); 2741 return (0); 2742 } 2743 2744 /* 2745 * Compare struct sockaddr_in{,6} with the address only. 2746 * The port number is not covered. 2747 */ 2748 Static int 2749 pipex_sockaddr_compar_addr(struct sockaddr *a, struct sockaddr *b) 2750 { 2751 int cmp; 2752 2753 cmp = b->sa_family - a->sa_family; 2754 if (cmp != 0) 2755 return cmp; 2756 switch (a->sa_family) { 2757 case AF_INET: 2758 return (satosin(b)->sin_addr.s_addr - 2759 satosin(a)->sin_addr.s_addr); 2760 case AF_INET6: 2761 cmp = (satosin6(b)->sin6_scope_id - satosin6(a)->sin6_scope_id); 2762 if (cmp != 0) 2763 return cmp; 2764 return (memcmp(&satosin6(a)->sin6_addr, 2765 &satosin6(b)->sin6_addr, 2766 sizeof(struct in6_addr))); 2767 } 2768 panic("pipex_sockaddr_compar_addr: unknown address family"); 2769 2770 return (-1); 2771 } 2772 2773 int 2774 pipex_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 2775 size_t newlen) 2776 { 2777 switch (name[0]) { 2778 case PIPEXCTL_ENABLE: 2779 if (namelen != 1) 2780 return (ENOTDIR); 2781 return (sysctl_int(oldp, oldlenp, newp, newlen, 2782 &pipex_enable)); 2783 default: 2784 return (ENOPROTOOPT); 2785 } 2786 /* NOTREACHED */ 2787 } 2788