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