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