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