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