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