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