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