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