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