1 /* $NetBSD: if_ppp.c,v 1.151 2016/04/28 00:16:56 ozaki-r Exp $ */ 2 /* Id: if_ppp.c,v 1.6 1997/03/04 03:33:00 paulus Exp */ 3 4 /* 5 * if_ppp.c - Point-to-Point Protocol (PPP) Asynchronous driver. 6 * 7 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The name "Carnegie Mellon University" must not be used to 22 * endorse or promote products derived from this software without 23 * prior written permission. For permission or any legal 24 * details, please contact 25 * Office of Technology Transfer 26 * Carnegie Mellon University 27 * 5000 Forbes Avenue 28 * Pittsburgh, PA 15213-3890 29 * (412) 268-4387, fax: (412) 268-7395 30 * tech-transfer@andrew.cmu.edu 31 * 32 * 4. Redistributions of any form whatsoever must retain the following 33 * acknowledgment: 34 * "This product includes software developed by Computing Services 35 * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 36 * 37 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 38 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 39 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 40 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 41 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 42 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 43 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 44 * 45 * Based on: 46 * @(#)if_sl.c 7.6.1.2 (Berkeley) 2/15/89 47 * 48 * Copyright (c) 1987 Regents of the University of California. 49 * All rights reserved. 50 * 51 * Redistribution and use in source and binary forms are permitted 52 * provided that the above copyright notice and this paragraph are 53 * duplicated in all such forms and that any documentation, 54 * advertising materials, and other materials related to such 55 * distribution and use acknowledge that the software was developed 56 * by the University of California, Berkeley. The name of the 57 * University may not be used to endorse or promote products derived 58 * from this software without specific prior written permission. 59 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 60 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 61 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 62 * 63 * Serial Line interface 64 * 65 * Rick Adams 66 * Center for Seismic Studies 67 * 1300 N 17th Street, Suite 1450 68 * Arlington, Virginia 22209 69 * (703)276-7900 70 * rick@seismo.ARPA 71 * seismo!rick 72 * 73 * Pounded on heavily by Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris). 74 * Converted to 4.3BSD Beta by Chris Torek. 75 * Other changes made at Berkeley, based in part on code by Kirk Smith. 76 * 77 * Converted to 4.3BSD+ 386BSD by Brad Parker (brad@cayman.com) 78 * Added VJ tcp header compression; more unified ioctls 79 * 80 * Extensively modified by Paul Mackerras (paulus@cs.anu.edu.au). 81 * Cleaned up a lot of the mbuf-related code to fix bugs that 82 * caused system crashes and packet corruption. Changed pppstart 83 * so that it doesn't just give up with a collision if the whole 84 * packet doesn't fit in the output ring buffer. 85 * 86 * Added priority queueing for interactive IP packets, following 87 * the model of if_sl.c, plus hooks for bpf. 88 * Paul Mackerras (paulus@cs.anu.edu.au). 89 */ 90 91 /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */ 92 /* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */ 93 94 /* 95 * XXX IMP ME HARDER 96 * 97 * This is an explanation of that comment. This code used to use 98 * splimp() to block both network and tty interrupts. However, 99 * that call is deprecated. So, we have replaced the uses of 100 * splimp() with splhigh() in order to applomplish what it needs 101 * to accomplish, and added that happy little comment. 102 */ 103 104 #include <sys/cdefs.h> 105 __KERNEL_RCSID(0, "$NetBSD: if_ppp.c,v 1.151 2016/04/28 00:16:56 ozaki-r Exp $"); 106 107 #include "ppp.h" 108 109 #ifdef _KERNEL_OPT 110 #include "opt_inet.h" 111 #include "opt_gateway.h" 112 #include "opt_ppp.h" 113 #endif 114 115 #ifdef INET 116 #define VJC 117 #endif 118 #define PPP_COMPRESS 119 120 #include <sys/param.h> 121 #include <sys/proc.h> 122 #include <sys/mbuf.h> 123 #include <sys/socket.h> 124 #include <sys/ioctl.h> 125 #include <sys/kernel.h> 126 #include <sys/systm.h> 127 #include <sys/time.h> 128 #include <sys/malloc.h> 129 #include <sys/module.h> 130 #include <sys/mutex.h> 131 #include <sys/once.h> 132 #include <sys/conf.h> 133 #include <sys/kauth.h> 134 #include <sys/intr.h> 135 #include <sys/socketvar.h> 136 137 #include <net/if.h> 138 #include <net/if_types.h> 139 #include <net/netisr.h> 140 #include <net/route.h> 141 #ifdef PPP_FILTER 142 #include <net/bpf.h> 143 #endif 144 145 #include <netinet/in.h> 146 #include <netinet/in_systm.h> 147 #include <netinet/in_var.h> 148 #ifdef INET 149 #include <netinet/ip.h> 150 #endif 151 152 #include <net/bpf.h> 153 154 #include <net/slip.h> 155 156 #ifdef VJC 157 #include <net/slcompress.h> 158 #endif 159 160 #include <net/ppp_defs.h> 161 #include <net/if_ppp.h> 162 #include <net/if_pppvar.h> 163 #include <sys/cpu.h> 164 165 #ifdef PPP_COMPRESS 166 #define PACKETPTR struct mbuf * 167 #include <net/ppp-comp.h> 168 #endif 169 170 #include "ioconf.h" 171 172 static int pppsioctl(struct ifnet *, u_long, void *); 173 static void ppp_requeue(struct ppp_softc *); 174 static void ppp_ccp(struct ppp_softc *, struct mbuf *m, int rcvd); 175 static void ppp_ccp_closed(struct ppp_softc *); 176 static void ppp_inproc(struct ppp_softc *, struct mbuf *); 177 static void pppdumpm(struct mbuf *m0); 178 #ifdef ALTQ 179 static void ppp_ifstart(struct ifnet *ifp); 180 #endif 181 182 static void pppintr(void *); 183 184 /* 185 * Some useful mbuf macros not in mbuf.h. 186 */ 187 #define M_IS_CLUSTER(m) ((m)->m_flags & M_EXT) 188 189 #define M_DATASTART(m) \ 190 (M_IS_CLUSTER(m) ? (m)->m_ext.ext_buf : \ 191 (m)->m_flags & M_PKTHDR ? (m)->m_pktdat : (m)->m_dat) 192 193 #define M_DATASIZE(m) \ 194 (M_IS_CLUSTER(m) ? (m)->m_ext.ext_size : \ 195 (m)->m_flags & M_PKTHDR ? MHLEN: MLEN) 196 197 /* 198 * We define two link layer specific mbuf flags, to mark high-priority 199 * packets for output, and received packets following lost/corrupted 200 * packets. 201 */ 202 #define M_HIGHPRI M_LINK0 /* output packet for sc_fastq */ 203 #define M_ERRMARK M_LINK1 /* rx packet following lost/corrupted pkt */ 204 205 static int ppp_clone_create(struct if_clone *, int); 206 static int ppp_clone_destroy(struct ifnet *); 207 208 static struct ppp_softc *ppp_create(const char *, int); 209 210 static LIST_HEAD(, ppp_softc) ppp_softc_list; 211 static kmutex_t ppp_list_lock; 212 213 struct if_clone ppp_cloner = 214 IF_CLONE_INITIALIZER("ppp", ppp_clone_create, ppp_clone_destroy); 215 216 #ifdef PPP_COMPRESS 217 ONCE_DECL(ppp_compressor_mtx_init); 218 static LIST_HEAD(, compressor) ppp_compressors = { NULL }; 219 static kmutex_t ppp_compressors_mtx; 220 221 static int ppp_compressor_init(void); 222 static struct compressor *ppp_get_compressor(uint8_t); 223 static void ppp_compressor_rele(struct compressor *); 224 #endif /* PPP_COMPRESS */ 225 226 227 /* 228 * Called from boot code to establish ppp interfaces. 229 */ 230 void 231 pppattach(int n __unused) 232 { 233 extern struct linesw ppp_disc; 234 235 if (ttyldisc_attach(&ppp_disc) != 0) 236 panic("pppattach"); 237 238 mutex_init(&ppp_list_lock, MUTEX_DEFAULT, IPL_NONE); 239 LIST_INIT(&ppp_softc_list); 240 if_clone_attach(&ppp_cloner); 241 RUN_ONCE(&ppp_compressor_mtx_init, ppp_compressor_init); 242 } 243 244 static struct ppp_softc * 245 ppp_create(const char *name, int unit) 246 { 247 struct ppp_softc *sc, *sci, *scl = NULL; 248 249 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAIT|M_ZERO); 250 251 mutex_enter(&ppp_list_lock); 252 if (unit == -1) { 253 int i = 0; 254 LIST_FOREACH(sci, &ppp_softc_list, sc_iflist) { 255 scl = sci; 256 if (i < sci->sc_unit) { 257 unit = i; 258 break; 259 } else { 260 #ifdef DIAGNOSTIC 261 KASSERT(i == sci->sc_unit); 262 #endif 263 i++; 264 } 265 } 266 if (unit == -1) 267 unit = i; 268 } else { 269 LIST_FOREACH(sci, &ppp_softc_list, sc_iflist) { 270 scl = sci; 271 if (unit < sci->sc_unit) 272 break; 273 else if (unit == sci->sc_unit) { 274 free(sc, M_DEVBUF); 275 return NULL; 276 } 277 } 278 } 279 280 if (sci != NULL) 281 LIST_INSERT_BEFORE(sci, sc, sc_iflist); 282 else if (scl != NULL) 283 LIST_INSERT_AFTER(scl, sc, sc_iflist); 284 else 285 LIST_INSERT_HEAD(&ppp_softc_list, sc, sc_iflist); 286 287 mutex_exit(&ppp_list_lock); 288 289 if_initname(&sc->sc_if, name, sc->sc_unit = unit); 290 callout_init(&sc->sc_timo_ch, 0); 291 sc->sc_if.if_softc = sc; 292 sc->sc_if.if_mtu = PPP_MTU; 293 sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST; 294 sc->sc_if.if_type = IFT_PPP; 295 sc->sc_if.if_hdrlen = PPP_HDRLEN; 296 sc->sc_if.if_dlt = DLT_NULL; 297 sc->sc_if.if_ioctl = pppsioctl; 298 sc->sc_if.if_output = pppoutput; 299 #ifdef ALTQ 300 sc->sc_if.if_start = ppp_ifstart; 301 #endif 302 IFQ_SET_MAXLEN(&sc->sc_if.if_snd, IFQ_MAXLEN); 303 sc->sc_inq.ifq_maxlen = IFQ_MAXLEN; 304 sc->sc_fastq.ifq_maxlen = IFQ_MAXLEN; 305 sc->sc_rawq.ifq_maxlen = IFQ_MAXLEN; 306 /* Ratio of 1:2 packets between the regular and the fast queue */ 307 sc->sc_maxfastq = 2; 308 IFQ_SET_READY(&sc->sc_if.if_snd); 309 if_attach(&sc->sc_if); 310 if_alloc_sadl(&sc->sc_if); 311 bpf_attach(&sc->sc_if, DLT_NULL, 0); 312 return sc; 313 } 314 315 static int 316 ppp_clone_create(struct if_clone *ifc, int unit) 317 { 318 return ppp_create(ifc->ifc_name, unit) == NULL ? EEXIST : 0; 319 } 320 321 static int 322 ppp_clone_destroy(struct ifnet *ifp) 323 { 324 struct ppp_softc *sc = (struct ppp_softc *)ifp->if_softc; 325 326 if (sc->sc_devp != NULL) 327 return EBUSY; /* Not removing it */ 328 329 mutex_enter(&ppp_list_lock); 330 LIST_REMOVE(sc, sc_iflist); 331 mutex_exit(&ppp_list_lock); 332 333 bpf_detach(ifp); 334 if_detach(ifp); 335 336 free(sc, M_DEVBUF); 337 return 0; 338 } 339 340 /* 341 * Allocate a ppp interface unit and initialize it. 342 */ 343 struct ppp_softc * 344 pppalloc(pid_t pid) 345 { 346 struct ppp_softc *sc = NULL, *scf; 347 int i; 348 349 mutex_enter(&ppp_list_lock); 350 LIST_FOREACH(scf, &ppp_softc_list, sc_iflist) { 351 if (scf->sc_xfer == pid) { 352 scf->sc_xfer = 0; 353 mutex_exit(&ppp_list_lock); 354 return scf; 355 } 356 if (scf->sc_devp == NULL && sc == NULL) 357 sc = scf; 358 } 359 mutex_exit(&ppp_list_lock); 360 361 if (sc == NULL) 362 sc = ppp_create(ppp_cloner.ifc_name, -1); 363 364 sc->sc_si = softint_establish(SOFTINT_NET, pppintr, sc); 365 if (sc->sc_si == NULL) { 366 printf("%s: unable to establish softintr\n", 367 sc->sc_if.if_xname); 368 return (NULL); 369 } 370 sc->sc_flags = 0; 371 sc->sc_mru = PPP_MRU; 372 sc->sc_relinq = NULL; 373 (void)memset(&sc->sc_stats, 0, sizeof(sc->sc_stats)); 374 #ifdef VJC 375 sc->sc_comp = malloc(sizeof(struct slcompress), M_DEVBUF, M_NOWAIT); 376 if (sc->sc_comp) 377 sl_compress_init(sc->sc_comp); 378 #endif 379 #ifdef PPP_COMPRESS 380 sc->sc_xc_state = NULL; 381 sc->sc_rc_state = NULL; 382 #endif /* PPP_COMPRESS */ 383 for (i = 0; i < NUM_NP; ++i) 384 sc->sc_npmode[i] = NPMODE_ERROR; 385 sc->sc_npqueue = NULL; 386 sc->sc_npqtail = &sc->sc_npqueue; 387 sc->sc_last_sent = sc->sc_last_recv = time_second; 388 389 return sc; 390 } 391 392 /* 393 * Deallocate a ppp unit. Must be called at splsoftnet or higher. 394 */ 395 void 396 pppdealloc(struct ppp_softc *sc) 397 { 398 struct mbuf *m; 399 400 softint_disestablish(sc->sc_si); 401 if_down(&sc->sc_if); 402 sc->sc_if.if_flags &= ~(IFF_UP|IFF_RUNNING); 403 sc->sc_devp = NULL; 404 sc->sc_xfer = 0; 405 for (;;) { 406 IF_DEQUEUE(&sc->sc_rawq, m); 407 if (m == NULL) 408 break; 409 m_freem(m); 410 } 411 for (;;) { 412 IF_DEQUEUE(&sc->sc_inq, m); 413 if (m == NULL) 414 break; 415 m_freem(m); 416 } 417 for (;;) { 418 IF_DEQUEUE(&sc->sc_fastq, m); 419 if (m == NULL) 420 break; 421 m_freem(m); 422 } 423 while ((m = sc->sc_npqueue) != NULL) { 424 sc->sc_npqueue = m->m_nextpkt; 425 m_freem(m); 426 } 427 if (sc->sc_togo != NULL) { 428 m_freem(sc->sc_togo); 429 sc->sc_togo = NULL; 430 } 431 #ifdef PPP_COMPRESS 432 ppp_ccp_closed(sc); 433 sc->sc_xc_state = NULL; 434 sc->sc_rc_state = NULL; 435 #endif /* PPP_COMPRESS */ 436 #ifdef PPP_FILTER 437 if (sc->sc_pass_filt_in.bf_insns != 0) { 438 free(sc->sc_pass_filt_in.bf_insns, M_DEVBUF); 439 sc->sc_pass_filt_in.bf_insns = 0; 440 sc->sc_pass_filt_in.bf_len = 0; 441 } 442 if (sc->sc_pass_filt_out.bf_insns != 0) { 443 free(sc->sc_pass_filt_out.bf_insns, M_DEVBUF); 444 sc->sc_pass_filt_out.bf_insns = 0; 445 sc->sc_pass_filt_out.bf_len = 0; 446 } 447 if (sc->sc_active_filt_in.bf_insns != 0) { 448 free(sc->sc_active_filt_in.bf_insns, M_DEVBUF); 449 sc->sc_active_filt_in.bf_insns = 0; 450 sc->sc_active_filt_in.bf_len = 0; 451 } 452 if (sc->sc_active_filt_out.bf_insns != 0) { 453 free(sc->sc_active_filt_out.bf_insns, M_DEVBUF); 454 sc->sc_active_filt_out.bf_insns = 0; 455 sc->sc_active_filt_out.bf_len = 0; 456 } 457 #endif /* PPP_FILTER */ 458 #ifdef VJC 459 if (sc->sc_comp != 0) { 460 free(sc->sc_comp, M_DEVBUF); 461 sc->sc_comp = 0; 462 } 463 #endif 464 (void)ppp_clone_destroy(&sc->sc_if); 465 } 466 467 /* 468 * Ioctl routine for generic ppp devices. 469 */ 470 int 471 pppioctl(struct ppp_softc *sc, u_long cmd, void *data, int flag, 472 struct lwp *l) 473 { 474 int s, error, flags, mru, npx; 475 u_int nb; 476 struct ppp_option_data *odp; 477 struct compressor *cp; 478 struct npioctl *npi; 479 time_t t; 480 #ifdef PPP_FILTER 481 struct bpf_program *bp, *nbp; 482 struct bpf_insn *newcode, *oldcode; 483 int newcodelen; 484 #endif /* PPP_FILTER */ 485 #ifdef PPP_COMPRESS 486 u_char ccp_option[CCP_MAX_OPTION_LENGTH]; 487 #endif 488 489 switch (cmd) { 490 case PPPIOCSFLAGS: 491 case PPPIOCSMRU: 492 case PPPIOCSMAXCID: 493 case PPPIOCSCOMPRESS: 494 case PPPIOCSNPMODE: 495 if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE, 496 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, &sc->sc_if, 497 KAUTH_ARG(cmd), NULL) != 0) 498 return (EPERM); 499 break; 500 case PPPIOCXFERUNIT: 501 /* XXX: Why is this privileged?! */ 502 if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE, 503 KAUTH_REQ_NETWORK_INTERFACE_GETPRIV, &sc->sc_if, 504 KAUTH_ARG(cmd), NULL) != 0) 505 return (EPERM); 506 break; 507 default: 508 break; 509 } 510 511 switch (cmd) { 512 case FIONREAD: 513 *(int *)data = sc->sc_inq.ifq_len; 514 break; 515 516 case PPPIOCGUNIT: 517 *(int *)data = sc->sc_unit; 518 break; 519 520 case PPPIOCGFLAGS: 521 *(u_int *)data = sc->sc_flags; 522 break; 523 524 case PPPIOCGRAWIN: 525 { 526 struct ppp_rawin *rwin = (struct ppp_rawin *)data; 527 u_char c, q = 0; 528 529 for (c = sc->sc_rawin_start; c < sizeof(sc->sc_rawin.buf);) 530 rwin->buf[q++] = sc->sc_rawin.buf[c++]; 531 532 for (c = 0; c < sc->sc_rawin_start;) 533 rwin->buf[q++] = sc->sc_rawin.buf[c++]; 534 535 rwin->count = sc->sc_rawin.count; 536 } 537 break; 538 539 case PPPIOCSFLAGS: 540 flags = *(int *)data & SC_MASK; 541 s = splsoftnet(); 542 #ifdef PPP_COMPRESS 543 if (sc->sc_flags & SC_CCP_OPEN && !(flags & SC_CCP_OPEN)) 544 ppp_ccp_closed(sc); 545 #endif 546 splhigh(); /* XXX IMP ME HARDER */ 547 sc->sc_flags = (sc->sc_flags & ~SC_MASK) | flags; 548 splx(s); 549 break; 550 551 case PPPIOCSMRU: 552 mru = *(int *)data; 553 if (mru >= PPP_MINMRU && mru <= PPP_MAXMRU) 554 sc->sc_mru = mru; 555 break; 556 557 case PPPIOCGMRU: 558 *(int *)data = sc->sc_mru; 559 break; 560 561 #ifdef VJC 562 case PPPIOCSMAXCID: 563 if (sc->sc_comp) { 564 s = splsoftnet(); 565 sl_compress_setup(sc->sc_comp, *(int *)data); 566 splx(s); 567 } 568 break; 569 #endif 570 571 case PPPIOCXFERUNIT: 572 sc->sc_xfer = l->l_proc->p_pid; 573 break; 574 575 #ifdef PPP_COMPRESS 576 case PPPIOCSCOMPRESS: 577 odp = (struct ppp_option_data *) data; 578 nb = odp->length; 579 if (nb > sizeof(ccp_option)) 580 nb = sizeof(ccp_option); 581 if ((error = copyin(odp->ptr, ccp_option, nb)) != 0) 582 return (error); 583 /* preliminary check on the length byte */ 584 if (ccp_option[1] < 2) 585 return (EINVAL); 586 cp = ppp_get_compressor(ccp_option[0]); 587 if (cp == NULL) { 588 if (sc->sc_flags & SC_DEBUG) 589 printf("%s: no compressor for [%x %x %x], %x\n", 590 sc->sc_if.if_xname, ccp_option[0], 591 ccp_option[1], ccp_option[2], nb); 592 return (EINVAL); /* no handler found */ 593 } 594 /* 595 * Found a handler for the protocol - try to allocate 596 * a compressor or decompressor. 597 */ 598 error = 0; 599 if (odp->transmit) { 600 s = splsoftnet(); 601 if (sc->sc_xc_state != NULL) { 602 (*sc->sc_xcomp->comp_free)(sc->sc_xc_state); 603 ppp_compressor_rele(sc->sc_xcomp); 604 } 605 sc->sc_xcomp = cp; 606 sc->sc_xc_state = cp->comp_alloc(ccp_option, nb); 607 if (sc->sc_xc_state == NULL) { 608 if (sc->sc_flags & SC_DEBUG) 609 printf("%s: comp_alloc failed\n", 610 sc->sc_if.if_xname); 611 error = ENOBUFS; 612 } 613 splhigh(); /* XXX IMP ME HARDER */ 614 sc->sc_flags &= ~SC_COMP_RUN; 615 splx(s); 616 } else { 617 s = splsoftnet(); 618 if (sc->sc_rc_state != NULL) { 619 (*sc->sc_rcomp->decomp_free)(sc->sc_rc_state); 620 ppp_compressor_rele(sc->sc_rcomp); 621 } 622 sc->sc_rcomp = cp; 623 sc->sc_rc_state = cp->decomp_alloc(ccp_option, nb); 624 if (sc->sc_rc_state == NULL) { 625 if (sc->sc_flags & SC_DEBUG) 626 printf("%s: decomp_alloc failed\n", 627 sc->sc_if.if_xname); 628 error = ENOBUFS; 629 } 630 splhigh(); /* XXX IMP ME HARDER */ 631 sc->sc_flags &= ~SC_DECOMP_RUN; 632 splx(s); 633 } 634 return (error); 635 #endif /* PPP_COMPRESS */ 636 637 case PPPIOCGNPMODE: 638 case PPPIOCSNPMODE: 639 npi = (struct npioctl *) data; 640 switch (npi->protocol) { 641 case PPP_IP: 642 npx = NP_IP; 643 break; 644 case PPP_IPV6: 645 npx = NP_IPV6; 646 break; 647 default: 648 return EINVAL; 649 } 650 if (cmd == PPPIOCGNPMODE) { 651 npi->mode = sc->sc_npmode[npx]; 652 } else { 653 if (npi->mode != sc->sc_npmode[npx]) { 654 s = splnet(); 655 sc->sc_npmode[npx] = npi->mode; 656 if (npi->mode != NPMODE_QUEUE) { 657 ppp_requeue(sc); 658 ppp_restart(sc); 659 } 660 splx(s); 661 } 662 } 663 break; 664 665 case PPPIOCGIDLE: 666 s = splsoftnet(); 667 t = time_second; 668 ((struct ppp_idle *)data)->xmit_idle = t - sc->sc_last_sent; 669 ((struct ppp_idle *)data)->recv_idle = t - sc->sc_last_recv; 670 splx(s); 671 break; 672 673 #ifdef PPP_FILTER 674 case PPPIOCSPASS: 675 case PPPIOCSACTIVE: 676 /* These are no longer supported. */ 677 return EOPNOTSUPP; 678 679 case PPPIOCSIPASS: 680 case PPPIOCSOPASS: 681 case PPPIOCSIACTIVE: 682 case PPPIOCSOACTIVE: 683 nbp = (struct bpf_program *) data; 684 if ((unsigned) nbp->bf_len > BPF_MAXINSNS) 685 return EINVAL; 686 newcodelen = nbp->bf_len * sizeof(struct bpf_insn); 687 if (newcodelen != 0) { 688 newcode = malloc(newcodelen, M_DEVBUF, M_WAITOK); 689 /* WAITOK -- malloc() never fails. */ 690 if ((error = copyin((void *)nbp->bf_insns, 691 (void *)newcode, newcodelen)) != 0) { 692 free(newcode, M_DEVBUF); 693 return error; 694 } 695 if (!bpf_validate(newcode, nbp->bf_len)) { 696 free(newcode, M_DEVBUF); 697 return EINVAL; 698 } 699 } else 700 newcode = 0; 701 switch (cmd) { 702 case PPPIOCSIPASS: 703 bp = &sc->sc_pass_filt_in; 704 break; 705 706 case PPPIOCSOPASS: 707 bp = &sc->sc_pass_filt_out; 708 break; 709 710 case PPPIOCSIACTIVE: 711 bp = &sc->sc_active_filt_in; 712 break; 713 714 case PPPIOCSOACTIVE: 715 bp = &sc->sc_active_filt_out; 716 break; 717 default: 718 free(newcode, M_DEVBUF); 719 return (EPASSTHROUGH); 720 } 721 oldcode = bp->bf_insns; 722 s = splnet(); 723 bp->bf_len = nbp->bf_len; 724 bp->bf_insns = newcode; 725 splx(s); 726 if (oldcode != 0) 727 free(oldcode, M_DEVBUF); 728 break; 729 #endif /* PPP_FILTER */ 730 731 default: 732 return (EPASSTHROUGH); 733 } 734 return (0); 735 } 736 737 /* 738 * Process an ioctl request to the ppp network interface. 739 */ 740 static int 741 pppsioctl(struct ifnet *ifp, u_long cmd, void *data) 742 { 743 struct ppp_softc *sc = ifp->if_softc; 744 struct ifaddr *ifa = (struct ifaddr *)data; 745 struct ifreq *ifr = (struct ifreq *)data; 746 struct ppp_stats *psp; 747 #ifdef PPP_COMPRESS 748 struct ppp_comp_stats *pcp; 749 #endif 750 int s = splnet(), error = 0; 751 752 switch (cmd) { 753 case SIOCSIFFLAGS: 754 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 755 break; 756 if ((ifp->if_flags & IFF_RUNNING) == 0) 757 ifp->if_flags &= ~IFF_UP; 758 break; 759 760 case SIOCINITIFADDR: 761 switch (ifa->ifa_addr->sa_family) { 762 #ifdef INET 763 case AF_INET: 764 break; 765 #endif 766 #ifdef INET6 767 case AF_INET6: 768 break; 769 #endif 770 default: 771 error = EAFNOSUPPORT; 772 break; 773 } 774 ifa->ifa_rtrequest = p2p_rtrequest; 775 break; 776 777 case SIOCADDMULTI: 778 case SIOCDELMULTI: 779 if (ifr == NULL) { 780 error = EAFNOSUPPORT; 781 break; 782 } 783 switch (ifreq_getaddr(cmd, ifr)->sa_family) { 784 #ifdef INET 785 case AF_INET: 786 break; 787 #endif 788 #ifdef INET6 789 case AF_INET6: 790 break; 791 #endif 792 default: 793 error = EAFNOSUPPORT; 794 break; 795 } 796 break; 797 798 case SIOCGPPPSTATS: 799 psp = &((struct ifpppstatsreq *) data)->stats; 800 memset(psp, 0, sizeof(*psp)); 801 psp->p = sc->sc_stats; 802 #if defined(VJC) && !defined(SL_NO_STATS) 803 if (sc->sc_comp) { 804 psp->vj.vjs_packets = sc->sc_comp->sls_packets; 805 psp->vj.vjs_compressed = sc->sc_comp->sls_compressed; 806 psp->vj.vjs_searches = sc->sc_comp->sls_searches; 807 psp->vj.vjs_misses = sc->sc_comp->sls_misses; 808 psp->vj.vjs_uncompressedin = sc->sc_comp->sls_uncompressedin; 809 psp->vj.vjs_compressedin = sc->sc_comp->sls_compressedin; 810 psp->vj.vjs_errorin = sc->sc_comp->sls_errorin; 811 psp->vj.vjs_tossed = sc->sc_comp->sls_tossed; 812 } 813 #endif /* VJC */ 814 break; 815 816 #ifdef PPP_COMPRESS 817 case SIOCGPPPCSTATS: 818 pcp = &((struct ifpppcstatsreq *) data)->stats; 819 memset(pcp, 0, sizeof(*pcp)); 820 if (sc->sc_xc_state != NULL) 821 (*sc->sc_xcomp->comp_stat)(sc->sc_xc_state, &pcp->c); 822 if (sc->sc_rc_state != NULL) 823 (*sc->sc_rcomp->decomp_stat)(sc->sc_rc_state, &pcp->d); 824 break; 825 #endif /* PPP_COMPRESS */ 826 827 default: 828 if ((error = ifioctl_common(&sc->sc_if, cmd, data)) == ENETRESET) 829 error = 0; 830 break; 831 } 832 splx(s); 833 return (error); 834 } 835 836 /* 837 * Queue a packet. Start transmission if not active. 838 * Packet is placed in Information field of PPP frame. 839 */ 840 int 841 pppoutput(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst, 842 const struct rtentry *rtp) 843 { 844 struct ppp_softc *sc = ifp->if_softc; 845 int protocol, address, control; 846 u_char *cp; 847 int s, error; 848 #ifdef INET 849 struct ip *ip; 850 #endif 851 struct ifqueue *ifq; 852 enum NPmode mode; 853 int len; 854 855 if (sc->sc_devp == NULL || (ifp->if_flags & IFF_RUNNING) == 0 856 || ((ifp->if_flags & IFF_UP) == 0 && dst->sa_family != AF_UNSPEC)) { 857 error = ENETDOWN; /* sort of */ 858 goto bad; 859 } 860 861 IFQ_CLASSIFY(&ifp->if_snd, m0, dst->sa_family); 862 863 /* 864 * Compute PPP header. 865 */ 866 m0->m_flags &= ~M_HIGHPRI; 867 switch (dst->sa_family) { 868 #ifdef INET 869 case AF_INET: 870 address = PPP_ALLSTATIONS; 871 control = PPP_UI; 872 protocol = PPP_IP; 873 mode = sc->sc_npmode[NP_IP]; 874 875 /* 876 * If this packet has the "low delay" bit set in the IP header, 877 * put it on the fastq instead. 878 */ 879 ip = mtod(m0, struct ip *); 880 if (ip->ip_tos & IPTOS_LOWDELAY) 881 m0->m_flags |= M_HIGHPRI; 882 break; 883 #endif 884 #ifdef INET6 885 case AF_INET6: 886 address = PPP_ALLSTATIONS; /*XXX*/ 887 control = PPP_UI; /*XXX*/ 888 protocol = PPP_IPV6; 889 mode = sc->sc_npmode[NP_IPV6]; 890 891 #if 0 /* XXX flowinfo/traffic class, maybe? */ 892 /* 893 * If this packet has the "low delay" bit set in the IP header, 894 * put it on the fastq instead. 895 */ 896 ip = mtod(m0, struct ip *); 897 if (ip->ip_tos & IPTOS_LOWDELAY) 898 m0->m_flags |= M_HIGHPRI; 899 #endif 900 break; 901 #endif 902 case AF_UNSPEC: 903 address = PPP_ADDRESS(dst->sa_data); 904 control = PPP_CONTROL(dst->sa_data); 905 protocol = PPP_PROTOCOL(dst->sa_data); 906 mode = NPMODE_PASS; 907 break; 908 default: 909 printf("%s: af%d not supported\n", ifp->if_xname, 910 dst->sa_family); 911 error = EAFNOSUPPORT; 912 goto bad; 913 } 914 915 /* 916 * Drop this packet, or return an error, if necessary. 917 */ 918 if (mode == NPMODE_ERROR) { 919 error = ENETDOWN; 920 goto bad; 921 } 922 if (mode == NPMODE_DROP) { 923 error = 0; 924 goto bad; 925 } 926 927 /* 928 * Add PPP header. 929 */ 930 M_PREPEND(m0, PPP_HDRLEN, M_DONTWAIT); 931 if (m0 == NULL) { 932 error = ENOBUFS; 933 goto bad; 934 } 935 936 cp = mtod(m0, u_char *); 937 *cp++ = address; 938 *cp++ = control; 939 *cp++ = protocol >> 8; 940 *cp++ = protocol & 0xff; 941 942 len = m_length(m0); 943 944 if (sc->sc_flags & SC_LOG_OUTPKT) { 945 printf("%s output: ", ifp->if_xname); 946 pppdumpm(m0); 947 } 948 949 if ((protocol & 0x8000) == 0) { 950 #ifdef PPP_FILTER 951 /* 952 * Apply the pass and active filters to the packet, 953 * but only if it is a data packet. 954 */ 955 if (sc->sc_pass_filt_out.bf_insns != 0 956 && bpf_filter(sc->sc_pass_filt_out.bf_insns, 957 (u_char *)m0, len, 0) == 0) { 958 error = 0; /* drop this packet */ 959 goto bad; 960 } 961 962 /* 963 * Update the time we sent the most recent packet. 964 */ 965 if (sc->sc_active_filt_out.bf_insns == 0 966 || bpf_filter(sc->sc_active_filt_out.bf_insns, 967 (u_char *)m0, len, 0)) 968 sc->sc_last_sent = time_second; 969 #else 970 /* 971 * Update the time we sent the most recent packet. 972 */ 973 sc->sc_last_sent = time_second; 974 #endif /* PPP_FILTER */ 975 } 976 977 /* 978 * See if bpf wants to look at the packet. 979 */ 980 bpf_mtap(&sc->sc_if, m0); 981 982 /* 983 * Put the packet on the appropriate queue. 984 */ 985 s = splnet(); 986 if (mode == NPMODE_QUEUE) { 987 /* XXX we should limit the number of packets on this queue */ 988 *sc->sc_npqtail = m0; 989 m0->m_nextpkt = NULL; 990 sc->sc_npqtail = &m0->m_nextpkt; 991 } else { 992 ifq = (m0->m_flags & M_HIGHPRI) ? &sc->sc_fastq : NULL; 993 if ((error = ifq_enqueue2(&sc->sc_if, ifq, m0)) != 0) { 994 splx(s); 995 sc->sc_if.if_oerrors++; 996 sc->sc_stats.ppp_oerrors++; 997 return (error); 998 } 999 ppp_restart(sc); 1000 } 1001 ifp->if_opackets++; 1002 ifp->if_obytes += len; 1003 1004 splx(s); 1005 return (0); 1006 1007 bad: 1008 m_freem(m0); 1009 return (error); 1010 } 1011 1012 /* 1013 * After a change in the NPmode for some NP, move packets from the 1014 * npqueue to the send queue or the fast queue as appropriate. 1015 * Should be called at splnet, since we muck with the queues. 1016 */ 1017 static void 1018 ppp_requeue(struct ppp_softc *sc) 1019 { 1020 struct mbuf *m, **mpp; 1021 struct ifqueue *ifq; 1022 enum NPmode mode; 1023 int error; 1024 1025 for (mpp = &sc->sc_npqueue; (m = *mpp) != NULL; ) { 1026 switch (PPP_PROTOCOL(mtod(m, u_char *))) { 1027 case PPP_IP: 1028 mode = sc->sc_npmode[NP_IP]; 1029 break; 1030 case PPP_IPV6: 1031 mode = sc->sc_npmode[NP_IPV6]; 1032 break; 1033 default: 1034 mode = NPMODE_PASS; 1035 } 1036 1037 switch (mode) { 1038 case NPMODE_PASS: 1039 /* 1040 * This packet can now go on one of the queues to 1041 * be sent. 1042 */ 1043 *mpp = m->m_nextpkt; 1044 m->m_nextpkt = NULL; 1045 ifq = (m->m_flags & M_HIGHPRI) ? &sc->sc_fastq : NULL; 1046 if ((error = ifq_enqueue2(&sc->sc_if, ifq, m)) != 0) { 1047 sc->sc_if.if_oerrors++; 1048 sc->sc_stats.ppp_oerrors++; 1049 } 1050 break; 1051 1052 case NPMODE_DROP: 1053 case NPMODE_ERROR: 1054 *mpp = m->m_nextpkt; 1055 m_freem(m); 1056 break; 1057 1058 case NPMODE_QUEUE: 1059 mpp = &m->m_nextpkt; 1060 break; 1061 } 1062 } 1063 sc->sc_npqtail = mpp; 1064 } 1065 1066 /* 1067 * Transmitter has finished outputting some stuff; 1068 * remember to call sc->sc_start later at splsoftnet. 1069 */ 1070 void 1071 ppp_restart(struct ppp_softc *sc) 1072 { 1073 int s = splhigh(); /* XXX IMP ME HARDER */ 1074 1075 sc->sc_flags &= ~SC_TBUSY; 1076 softint_schedule(sc->sc_si); 1077 splx(s); 1078 } 1079 1080 /* 1081 * Get a packet to send. This procedure is intended to be called at 1082 * splsoftnet, since it may involve time-consuming operations such as 1083 * applying VJ compression, packet compression, address/control and/or 1084 * protocol field compression to the packet. 1085 */ 1086 struct mbuf * 1087 ppp_dequeue(struct ppp_softc *sc) 1088 { 1089 struct mbuf *m, *mp; 1090 u_char *cp; 1091 int address, control, protocol; 1092 int s; 1093 1094 /* 1095 * Grab a packet to send: first try the fast queue, then the 1096 * normal queue. 1097 */ 1098 s = splnet(); 1099 if (sc->sc_nfastq < sc->sc_maxfastq) { 1100 IF_DEQUEUE(&sc->sc_fastq, m); 1101 if (m != NULL) 1102 sc->sc_nfastq++; 1103 else 1104 IFQ_DEQUEUE(&sc->sc_if.if_snd, m); 1105 } else { 1106 sc->sc_nfastq = 0; 1107 IFQ_DEQUEUE(&sc->sc_if.if_snd, m); 1108 if (m == NULL) { 1109 IF_DEQUEUE(&sc->sc_fastq, m); 1110 if (m != NULL) 1111 sc->sc_nfastq++; 1112 } 1113 } 1114 splx(s); 1115 1116 if (m == NULL) 1117 return NULL; 1118 1119 ++sc->sc_stats.ppp_opackets; 1120 1121 /* 1122 * Extract the ppp header of the new packet. 1123 * The ppp header will be in one mbuf. 1124 */ 1125 cp = mtod(m, u_char *); 1126 address = PPP_ADDRESS(cp); 1127 control = PPP_CONTROL(cp); 1128 protocol = PPP_PROTOCOL(cp); 1129 1130 switch (protocol) { 1131 case PPP_IP: 1132 #ifdef VJC 1133 /* 1134 * If the packet is a TCP/IP packet, see if we can compress it. 1135 */ 1136 if ((sc->sc_flags & SC_COMP_TCP) && sc->sc_comp != NULL) { 1137 struct ip *ip; 1138 int type; 1139 1140 mp = m; 1141 ip = (struct ip *) (cp + PPP_HDRLEN); 1142 if (mp->m_len <= PPP_HDRLEN) { 1143 mp = mp->m_next; 1144 if (mp == NULL) 1145 break; 1146 ip = mtod(mp, struct ip *); 1147 } 1148 /* 1149 * This code assumes the IP/TCP header is in one 1150 * non-shared mbuf 1151 */ 1152 if (ip->ip_p == IPPROTO_TCP) { 1153 type = sl_compress_tcp(mp, ip, sc->sc_comp, 1154 !(sc->sc_flags & SC_NO_TCP_CCID)); 1155 switch (type) { 1156 case TYPE_UNCOMPRESSED_TCP: 1157 protocol = PPP_VJC_UNCOMP; 1158 break; 1159 case TYPE_COMPRESSED_TCP: 1160 protocol = PPP_VJC_COMP; 1161 cp = mtod(m, u_char *); 1162 cp[0] = address; /* Header has moved */ 1163 cp[1] = control; 1164 cp[2] = 0; 1165 break; 1166 } 1167 /* Update protocol in PPP header */ 1168 cp[3] = protocol; 1169 } 1170 } 1171 #endif /* VJC */ 1172 break; 1173 1174 #ifdef PPP_COMPRESS 1175 case PPP_CCP: 1176 ppp_ccp(sc, m, 0); 1177 break; 1178 #endif /* PPP_COMPRESS */ 1179 } 1180 1181 #ifdef PPP_COMPRESS 1182 if (protocol != PPP_LCP && protocol != PPP_CCP 1183 && sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN)) { 1184 struct mbuf *mcomp = NULL; 1185 int slen; 1186 1187 slen = 0; 1188 for (mp = m; mp != NULL; mp = mp->m_next) 1189 slen += mp->m_len; 1190 (*sc->sc_xcomp->compress) 1191 (sc->sc_xc_state, &mcomp, m, slen, sc->sc_if.if_mtu + PPP_HDRLEN); 1192 if (mcomp != NULL) { 1193 if (sc->sc_flags & SC_CCP_UP) { 1194 /* 1195 * Send the compressed packet instead of the 1196 * original. 1197 */ 1198 m_freem(m); 1199 m = mcomp; 1200 cp = mtod(m, u_char *); 1201 protocol = cp[3]; 1202 } else { 1203 /* 1204 * Can't transmit compressed packets until CCP 1205 * is up. 1206 */ 1207 m_freem(mcomp); 1208 } 1209 } 1210 } 1211 #endif /* PPP_COMPRESS */ 1212 1213 /* 1214 * Compress the address/control and protocol, if possible. 1215 */ 1216 if (sc->sc_flags & SC_COMP_AC && address == PPP_ALLSTATIONS && 1217 control == PPP_UI && protocol != PPP_ALLSTATIONS && 1218 protocol != PPP_LCP) { 1219 /* can compress address/control */ 1220 m->m_data += 2; 1221 m->m_len -= 2; 1222 } 1223 if (sc->sc_flags & SC_COMP_PROT && protocol < 0xFF) { 1224 /* can compress protocol */ 1225 if (mtod(m, u_char *) == cp) { 1226 cp[2] = cp[1]; /* move address/control up */ 1227 cp[1] = cp[0]; 1228 } 1229 ++m->m_data; 1230 --m->m_len; 1231 } 1232 1233 return m; 1234 } 1235 1236 /* 1237 * Software interrupt routine, called at splsoftnet. 1238 */ 1239 static void 1240 pppintr(void *arg) 1241 { 1242 struct ppp_softc *sc = arg; 1243 struct mbuf *m; 1244 int s; 1245 1246 mutex_enter(softnet_lock); 1247 if (!(sc->sc_flags & SC_TBUSY) 1248 && (IFQ_IS_EMPTY(&sc->sc_if.if_snd) == 0 || sc->sc_fastq.ifq_head 1249 || sc->sc_outm)) { 1250 s = splhigh(); /* XXX IMP ME HARDER */ 1251 sc->sc_flags |= SC_TBUSY; 1252 splx(s); 1253 (*sc->sc_start)(sc); 1254 } 1255 for (;;) { 1256 s = splnet(); 1257 IF_DEQUEUE(&sc->sc_rawq, m); 1258 splx(s); 1259 if (m == NULL) 1260 break; 1261 ppp_inproc(sc, m); 1262 } 1263 mutex_exit(softnet_lock); 1264 } 1265 1266 #ifdef PPP_COMPRESS 1267 /* 1268 * Handle a CCP packet. `rcvd' is 1 if the packet was received, 1269 * 0 if it is about to be transmitted. 1270 */ 1271 static void 1272 ppp_ccp(struct ppp_softc *sc, struct mbuf *m, int rcvd) 1273 { 1274 u_char *dp, *ep; 1275 struct mbuf *mp; 1276 int slen, s; 1277 1278 /* 1279 * Get a pointer to the data after the PPP header. 1280 */ 1281 if (m->m_len <= PPP_HDRLEN) { 1282 mp = m->m_next; 1283 if (mp == NULL) 1284 return; 1285 dp = mtod(mp, u_char *); 1286 } else { 1287 mp = m; 1288 dp = mtod(mp, u_char *) + PPP_HDRLEN; 1289 } 1290 1291 ep = mtod(mp, u_char *) + mp->m_len; 1292 if (dp + CCP_HDRLEN > ep) 1293 return; 1294 slen = CCP_LENGTH(dp); 1295 if (dp + slen > ep) { 1296 if (sc->sc_flags & SC_DEBUG) 1297 printf("if_ppp/ccp: not enough data in mbuf (%p+%x > %p+%x)\n", 1298 dp, slen, mtod(mp, u_char *), mp->m_len); 1299 return; 1300 } 1301 1302 switch (CCP_CODE(dp)) { 1303 case CCP_CONFREQ: 1304 case CCP_TERMREQ: 1305 case CCP_TERMACK: 1306 /* CCP must be going down - disable compression */ 1307 if (sc->sc_flags & SC_CCP_UP) { 1308 s = splhigh(); /* XXX IMP ME HARDER */ 1309 sc->sc_flags &= ~(SC_CCP_UP | SC_COMP_RUN | SC_DECOMP_RUN); 1310 splx(s); 1311 } 1312 break; 1313 1314 case CCP_CONFACK: 1315 if (sc->sc_flags & SC_CCP_OPEN && !(sc->sc_flags & SC_CCP_UP) 1316 && slen >= CCP_HDRLEN + CCP_OPT_MINLEN 1317 && slen >= CCP_OPT_LENGTH(dp + CCP_HDRLEN) + CCP_HDRLEN) { 1318 if (!rcvd) { 1319 /* We're agreeing to send compressed packets. */ 1320 if (sc->sc_xc_state != NULL 1321 && (*sc->sc_xcomp->comp_init) 1322 (sc->sc_xc_state, dp + CCP_HDRLEN, 1323 slen - CCP_HDRLEN, sc->sc_unit, 0, 1324 sc->sc_flags & SC_DEBUG)) { 1325 s = splhigh(); /* XXX IMP ME HARDER */ 1326 sc->sc_flags |= SC_COMP_RUN; 1327 splx(s); 1328 } 1329 } else { 1330 /* 1331 * Peer is agreeing to send compressed 1332 * packets. 1333 */ 1334 if (sc->sc_rc_state != NULL 1335 && (*sc->sc_rcomp->decomp_init) 1336 (sc->sc_rc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN, 1337 sc->sc_unit, 0, sc->sc_mru, 1338 sc->sc_flags & SC_DEBUG)) { 1339 s = splhigh(); /* XXX IMP ME HARDER */ 1340 sc->sc_flags |= SC_DECOMP_RUN; 1341 sc->sc_flags &= ~(SC_DC_ERROR | SC_DC_FERROR); 1342 splx(s); 1343 } 1344 } 1345 } 1346 break; 1347 1348 case CCP_RESETACK: 1349 if (sc->sc_flags & SC_CCP_UP) { 1350 if (!rcvd) { 1351 if (sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN)) 1352 (*sc->sc_xcomp->comp_reset)(sc->sc_xc_state); 1353 } else { 1354 if (sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN)) { 1355 (*sc->sc_rcomp->decomp_reset)(sc->sc_rc_state); 1356 s = splhigh(); /* XXX IMP ME HARDER */ 1357 sc->sc_flags &= ~SC_DC_ERROR; 1358 splx(s); 1359 } 1360 } 1361 } 1362 break; 1363 } 1364 } 1365 1366 /* 1367 * CCP is down; free (de)compressor state if necessary. 1368 */ 1369 static void 1370 ppp_ccp_closed(struct ppp_softc *sc) 1371 { 1372 if (sc->sc_xc_state) { 1373 (*sc->sc_xcomp->comp_free)(sc->sc_xc_state); 1374 ppp_compressor_rele(sc->sc_xcomp); 1375 sc->sc_xc_state = NULL; 1376 } 1377 if (sc->sc_rc_state) { 1378 (*sc->sc_rcomp->decomp_free)(sc->sc_rc_state); 1379 ppp_compressor_rele(sc->sc_rcomp); 1380 sc->sc_rc_state = NULL; 1381 } 1382 } 1383 #endif /* PPP_COMPRESS */ 1384 1385 /* 1386 * PPP packet input routine. 1387 * The caller has checked and removed the FCS and has inserted 1388 * the address/control bytes and the protocol high byte if they 1389 * were omitted. 1390 */ 1391 void 1392 ppppktin(struct ppp_softc *sc, struct mbuf *m, int lost) 1393 { 1394 int s = splhigh(); /* XXX IMP ME HARDER */ 1395 1396 if (lost) 1397 m->m_flags |= M_ERRMARK; 1398 IF_ENQUEUE(&sc->sc_rawq, m); 1399 softint_schedule(sc->sc_si); 1400 splx(s); 1401 } 1402 1403 /* 1404 * Process a received PPP packet, doing decompression as necessary. 1405 * Should be called at splsoftnet. 1406 */ 1407 #define COMPTYPE(proto) ((proto) == PPP_VJC_COMP ? TYPE_COMPRESSED_TCP: \ 1408 TYPE_UNCOMPRESSED_TCP) 1409 1410 static void 1411 ppp_inproc(struct ppp_softc *sc, struct mbuf *m) 1412 { 1413 struct ifnet *ifp = &sc->sc_if; 1414 pktqueue_t *pktq = NULL; 1415 struct ifqueue *inq = NULL; 1416 int s, ilen, proto, rv; 1417 u_char *cp, adrs, ctrl; 1418 struct mbuf *mp, *dmp = NULL; 1419 #ifdef VJC 1420 int xlen; 1421 u_char *iphdr; 1422 u_int hlen; 1423 #endif 1424 1425 sc->sc_stats.ppp_ipackets++; 1426 1427 if (sc->sc_flags & SC_LOG_INPKT) { 1428 ilen = 0; 1429 for (mp = m; mp != NULL; mp = mp->m_next) 1430 ilen += mp->m_len; 1431 printf("%s: got %d bytes\n", ifp->if_xname, ilen); 1432 pppdumpm(m); 1433 } 1434 1435 cp = mtod(m, u_char *); 1436 adrs = PPP_ADDRESS(cp); 1437 ctrl = PPP_CONTROL(cp); 1438 proto = PPP_PROTOCOL(cp); 1439 1440 if (m->m_flags & M_ERRMARK) { 1441 m->m_flags &= ~M_ERRMARK; 1442 s = splhigh(); /* XXX IMP ME HARDER */ 1443 sc->sc_flags |= SC_VJ_RESET; 1444 splx(s); 1445 } 1446 1447 #ifdef PPP_COMPRESS 1448 /* 1449 * Decompress this packet if necessary, update the receiver's 1450 * dictionary, or take appropriate action on a CCP packet. 1451 */ 1452 if (proto == PPP_COMP && sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN) 1453 && !(sc->sc_flags & SC_DC_ERROR) && !(sc->sc_flags & SC_DC_FERROR)) { 1454 /* Decompress this packet */ 1455 rv = (*sc->sc_rcomp->decompress)(sc->sc_rc_state, m, &dmp); 1456 if (rv == DECOMP_OK) { 1457 m_freem(m); 1458 if (dmp == NULL) { 1459 /* 1460 * No error, but no decompressed packet 1461 * produced 1462 */ 1463 return; 1464 } 1465 m = dmp; 1466 cp = mtod(m, u_char *); 1467 proto = PPP_PROTOCOL(cp); 1468 1469 } else { 1470 /* 1471 * An error has occurred in decompression. 1472 * Pass the compressed packet up to pppd, which may 1473 * take CCP down or issue a Reset-Req. 1474 */ 1475 if (sc->sc_flags & SC_DEBUG) 1476 printf("%s: decompress failed %d\n", 1477 ifp->if_xname, rv); 1478 s = splhigh(); /* XXX IMP ME HARDER */ 1479 sc->sc_flags |= SC_VJ_RESET; 1480 if (rv == DECOMP_ERROR) 1481 sc->sc_flags |= SC_DC_ERROR; 1482 else 1483 sc->sc_flags |= SC_DC_FERROR; 1484 splx(s); 1485 } 1486 1487 } else { 1488 if (sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN)) 1489 (*sc->sc_rcomp->incomp)(sc->sc_rc_state, m); 1490 if (proto == PPP_CCP) 1491 ppp_ccp(sc, m, 1); 1492 } 1493 #endif 1494 1495 ilen = 0; 1496 for (mp = m; mp != NULL; mp = mp->m_next) 1497 ilen += mp->m_len; 1498 1499 #ifdef VJC 1500 if (sc->sc_flags & SC_VJ_RESET) { 1501 /* 1502 * If we've missed a packet, we must toss subsequent compressed 1503 * packets which don't have an explicit connection ID. 1504 */ 1505 if (sc->sc_comp) 1506 sl_uncompress_tcp(NULL, 0, TYPE_ERROR, sc->sc_comp); 1507 s = splhigh(); /* XXX IMP ME HARDER */ 1508 sc->sc_flags &= ~SC_VJ_RESET; 1509 splx(s); 1510 } 1511 1512 /* 1513 * See if we have a VJ-compressed packet to uncompress. 1514 */ 1515 if (proto == PPP_VJC_COMP) { 1516 if ((sc->sc_flags & SC_REJ_COMP_TCP) || sc->sc_comp == 0) 1517 goto bad; 1518 1519 xlen = sl_uncompress_tcp_core(cp + PPP_HDRLEN, 1520 m->m_len - PPP_HDRLEN, ilen - PPP_HDRLEN, 1521 TYPE_COMPRESSED_TCP, sc->sc_comp, &iphdr, &hlen); 1522 1523 if (xlen <= 0) { 1524 if (sc->sc_flags & SC_DEBUG) 1525 printf("%s: VJ uncompress failed on type comp\n", 1526 ifp->if_xname); 1527 goto bad; 1528 } 1529 1530 /* Copy the PPP and IP headers into a new mbuf. */ 1531 MGETHDR(mp, M_DONTWAIT, MT_DATA); 1532 if (mp == NULL) 1533 goto bad; 1534 mp->m_len = 0; 1535 mp->m_next = NULL; 1536 if (hlen + PPP_HDRLEN > MHLEN) { 1537 MCLGET(mp, M_DONTWAIT); 1538 if (M_TRAILINGSPACE(mp) < hlen + PPP_HDRLEN) { 1539 /* Lose if big headers and no clusters */ 1540 m_freem(mp); 1541 goto bad; 1542 } 1543 } 1544 cp = mtod(mp, u_char *); 1545 cp[0] = adrs; 1546 cp[1] = ctrl; 1547 cp[2] = 0; 1548 cp[3] = PPP_IP; 1549 proto = PPP_IP; 1550 bcopy(iphdr, cp + PPP_HDRLEN, hlen); 1551 mp->m_len = hlen + PPP_HDRLEN; 1552 1553 /* 1554 * Trim the PPP and VJ headers off the old mbuf 1555 * and stick the new and old mbufs together. 1556 */ 1557 m->m_data += PPP_HDRLEN + xlen; 1558 m->m_len -= PPP_HDRLEN + xlen; 1559 if (m->m_len <= M_TRAILINGSPACE(mp)) { 1560 bcopy(mtod(m, u_char *), 1561 mtod(mp, u_char *) + mp->m_len, m->m_len); 1562 mp->m_len += m->m_len; 1563 MFREE(m, mp->m_next); 1564 } else 1565 mp->m_next = m; 1566 m = mp; 1567 ilen += hlen - xlen; 1568 1569 } else if (proto == PPP_VJC_UNCOMP) { 1570 if ((sc->sc_flags & SC_REJ_COMP_TCP) || sc->sc_comp == 0) 1571 goto bad; 1572 1573 xlen = sl_uncompress_tcp_core(cp + PPP_HDRLEN, 1574 m->m_len - PPP_HDRLEN, ilen - PPP_HDRLEN, 1575 TYPE_UNCOMPRESSED_TCP, sc->sc_comp, &iphdr, &hlen); 1576 1577 if (xlen < 0) { 1578 if (sc->sc_flags & SC_DEBUG) 1579 printf("%s: VJ uncompress failed on type uncomp\n", 1580 ifp->if_xname); 1581 goto bad; 1582 } 1583 1584 proto = PPP_IP; 1585 cp[3] = PPP_IP; 1586 } 1587 #endif /* VJC */ 1588 1589 /* 1590 * If the packet will fit in a header mbuf, don't waste a 1591 * whole cluster on it. 1592 */ 1593 if (ilen <= MHLEN && M_IS_CLUSTER(m)) { 1594 MGETHDR(mp, M_DONTWAIT, MT_DATA); 1595 if (mp != NULL) { 1596 m_copydata(m, 0, ilen, mtod(mp, void *)); 1597 m_freem(m); 1598 m = mp; 1599 m->m_len = ilen; 1600 } 1601 } 1602 m->m_pkthdr.len = ilen; 1603 m->m_pkthdr.rcvif = ifp; 1604 1605 if ((proto & 0x8000) == 0) { 1606 #ifdef PPP_FILTER 1607 /* 1608 * See whether we want to pass this packet, and 1609 * if it counts as link activity. 1610 */ 1611 if (sc->sc_pass_filt_in.bf_insns != 0 1612 && bpf_filter(sc->sc_pass_filt_in.bf_insns, 1613 (u_char *)m, ilen, 0) == 0) { 1614 /* drop this packet */ 1615 m_freem(m); 1616 return; 1617 } 1618 if (sc->sc_active_filt_in.bf_insns == 0 1619 || bpf_filter(sc->sc_active_filt_in.bf_insns, 1620 (u_char *)m, ilen, 0)) 1621 sc->sc_last_recv = time_second; 1622 #else 1623 /* 1624 * Record the time that we received this packet. 1625 */ 1626 sc->sc_last_recv = time_second; 1627 #endif /* PPP_FILTER */ 1628 } 1629 1630 /* See if bpf wants to look at the packet. */ 1631 bpf_mtap(&sc->sc_if, m); 1632 1633 switch (proto) { 1634 #ifdef INET 1635 case PPP_IP: 1636 /* 1637 * IP packet - take off the ppp header and pass it up to IP. 1638 */ 1639 if ((ifp->if_flags & IFF_UP) == 0 1640 || sc->sc_npmode[NP_IP] != NPMODE_PASS) { 1641 /* Interface is down - drop the packet. */ 1642 m_freem(m); 1643 return; 1644 } 1645 m->m_pkthdr.len -= PPP_HDRLEN; 1646 m->m_data += PPP_HDRLEN; 1647 m->m_len -= PPP_HDRLEN; 1648 #ifdef GATEWAY 1649 if (ipflow_fastforward(m)) 1650 return; 1651 #endif 1652 pktq = ip_pktq; 1653 break; 1654 #endif 1655 1656 #ifdef INET6 1657 case PPP_IPV6: 1658 /* 1659 * IPv6 packet - take off the ppp header and pass it up to 1660 * IPv6. 1661 */ 1662 if ((ifp->if_flags & IFF_UP) == 0 1663 || sc->sc_npmode[NP_IPV6] != NPMODE_PASS) { 1664 /* interface is down - drop the packet. */ 1665 m_freem(m); 1666 return; 1667 } 1668 m->m_pkthdr.len -= PPP_HDRLEN; 1669 m->m_data += PPP_HDRLEN; 1670 m->m_len -= PPP_HDRLEN; 1671 #ifdef GATEWAY 1672 if (ip6flow_fastforward(&m)) 1673 return; 1674 #endif 1675 pktq = ip6_pktq; 1676 break; 1677 #endif 1678 1679 default: 1680 /* 1681 * Some other protocol - place on input queue for read(). 1682 */ 1683 inq = &sc->sc_inq; 1684 pktq = NULL; 1685 break; 1686 } 1687 1688 /* 1689 * Put the packet on the appropriate input queue. 1690 */ 1691 s = splnet(); 1692 1693 /* pktq: inet or inet6 cases */ 1694 if (__predict_true(pktq)) { 1695 if (__predict_false(!pktq_enqueue(pktq, m, 0))) { 1696 ifp->if_iqdrops++; 1697 goto bad; 1698 } 1699 ifp->if_ipackets++; 1700 ifp->if_ibytes += ilen; 1701 splx(s); 1702 return; 1703 } 1704 1705 /* ifq: other protocol cases */ 1706 if (!inq) { 1707 goto bad; 1708 } 1709 if (IF_QFULL(inq)) { 1710 IF_DROP(inq); 1711 splx(s); 1712 if (sc->sc_flags & SC_DEBUG) 1713 printf("%s: input queue full\n", ifp->if_xname); 1714 ifp->if_iqdrops++; 1715 goto bad; 1716 } 1717 IF_ENQUEUE(inq, m); 1718 splx(s); 1719 ifp->if_ipackets++; 1720 ifp->if_ibytes += ilen; 1721 1722 (*sc->sc_ctlp)(sc); 1723 1724 return; 1725 1726 bad: 1727 m_freem(m); 1728 sc->sc_if.if_ierrors++; 1729 sc->sc_stats.ppp_ierrors++; 1730 } 1731 1732 #define MAX_DUMP_BYTES 128 1733 1734 static void 1735 pppdumpm(struct mbuf *m0) 1736 { 1737 char buf[3*MAX_DUMP_BYTES+4]; 1738 char *bp = buf; 1739 struct mbuf *m; 1740 1741 for (m = m0; m; m = m->m_next) { 1742 int l = m->m_len; 1743 u_char *rptr = (u_char *)m->m_data; 1744 1745 while (l--) { 1746 if (bp > buf + sizeof(buf) - 4) 1747 goto done; 1748 /* Convert byte to ascii hex */ 1749 *bp++ = hexdigits[*rptr >> 4]; 1750 *bp++ = hexdigits[*rptr++ & 0xf]; 1751 } 1752 1753 if (m->m_next) { 1754 if (bp > buf + sizeof(buf) - 3) 1755 goto done; 1756 *bp++ = '|'; 1757 } else 1758 *bp++ = ' '; 1759 } 1760 done: 1761 if (m) 1762 *bp++ = '>'; 1763 *bp = 0; 1764 printf("%s\n", buf); 1765 } 1766 1767 #ifdef ALTQ 1768 /* 1769 * A wrapper to transmit a packet from if_start since ALTQ uses 1770 * if_start to send a packet. 1771 */ 1772 static void 1773 ppp_ifstart(struct ifnet *ifp) 1774 { 1775 struct ppp_softc *sc; 1776 1777 sc = ifp->if_softc; 1778 (*sc->sc_start)(sc); 1779 } 1780 #endif 1781 1782 static const struct ppp_known_compressor { 1783 uint8_t code; 1784 const char *module; 1785 } ppp_known_compressors[] = { 1786 { CI_DEFLATE, "ppp_deflate" }, 1787 { CI_DEFLATE_DRAFT, "ppp_deflate" }, 1788 { CI_BSD_COMPRESS, "ppp_bsdcomp" }, 1789 { CI_MPPE, "ppp_mppe" }, 1790 { 0, NULL } 1791 }; 1792 1793 static int 1794 ppp_compressor_init(void) 1795 { 1796 1797 mutex_init(&ppp_compressors_mtx, MUTEX_DEFAULT, IPL_NONE); 1798 return 0; 1799 } 1800 1801 static void 1802 ppp_compressor_rele(struct compressor *cp) 1803 { 1804 1805 mutex_enter(&ppp_compressors_mtx); 1806 --cp->comp_refcnt; 1807 mutex_exit(&ppp_compressors_mtx); 1808 } 1809 1810 static struct compressor * 1811 ppp_get_compressor_noload(uint8_t ci, bool hold) 1812 { 1813 struct compressor *cp; 1814 1815 KASSERT(mutex_owned(&ppp_compressors_mtx)); 1816 LIST_FOREACH(cp, &ppp_compressors, comp_list) { 1817 if (cp->compress_proto == ci) { 1818 if (hold) 1819 ++cp->comp_refcnt; 1820 return cp; 1821 } 1822 } 1823 1824 return NULL; 1825 } 1826 1827 static struct compressor * 1828 ppp_get_compressor(uint8_t ci) 1829 { 1830 struct compressor *cp = NULL; 1831 const struct ppp_known_compressor *pkc; 1832 1833 mutex_enter(&ppp_compressors_mtx); 1834 cp = ppp_get_compressor_noload(ci, true); 1835 mutex_exit(&ppp_compressors_mtx); 1836 if (cp != NULL) 1837 return cp; 1838 1839 kernconfig_lock(); 1840 mutex_enter(&ppp_compressors_mtx); 1841 cp = ppp_get_compressor_noload(ci, true); 1842 mutex_exit(&ppp_compressors_mtx); 1843 if (cp == NULL) { 1844 /* Not found, so try to autoload a module */ 1845 for (pkc = ppp_known_compressors; pkc->module != NULL; pkc++) { 1846 if (pkc->code == ci) { 1847 if (module_autoload(pkc->module, 1848 MODULE_CLASS_MISC) != 0) 1849 break; 1850 mutex_enter(&ppp_compressors_mtx); 1851 cp = ppp_get_compressor_noload(ci, true); 1852 mutex_exit(&ppp_compressors_mtx); 1853 break; 1854 } 1855 } 1856 } 1857 kernconfig_unlock(); 1858 1859 return cp; 1860 } 1861 1862 int 1863 ppp_register_compressor(struct compressor *pc, size_t ncomp) 1864 { 1865 int error = 0; 1866 size_t i; 1867 1868 RUN_ONCE(&ppp_compressor_mtx_init, ppp_compressor_init); 1869 1870 mutex_enter(&ppp_compressors_mtx); 1871 for (i = 0; i < ncomp; i++) { 1872 if (ppp_get_compressor_noload(pc[i].compress_proto, 1873 false) != NULL) 1874 error = EEXIST; 1875 } 1876 if (!error) { 1877 for (i = 0; i < ncomp; i++) { 1878 pc[i].comp_refcnt = 0; 1879 LIST_INSERT_HEAD(&ppp_compressors, &pc[i], comp_list); 1880 } 1881 } 1882 mutex_exit(&ppp_compressors_mtx); 1883 1884 return error; 1885 } 1886 1887 int 1888 ppp_unregister_compressor(struct compressor *pc, size_t ncomp) 1889 { 1890 int error = 0; 1891 size_t i; 1892 1893 mutex_enter(&ppp_compressors_mtx); 1894 for (i = 0; i < ncomp; i++) { 1895 if (ppp_get_compressor_noload(pc[i].compress_proto, 1896 false) != &pc[i]) 1897 error = ENOENT; 1898 else if (pc[i].comp_refcnt != 0) 1899 error = EBUSY; 1900 } 1901 if (!error) { 1902 for (i = 0; i < ncomp; i++) { 1903 LIST_REMOVE(&pc[i], comp_list); 1904 } 1905 } 1906 mutex_exit(&ppp_compressors_mtx); 1907 1908 return error; 1909 } 1910