1 /* $NetBSD: if_ppp.c,v 1.58 2000/03/30 09:45:36 augustss 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) 1989 Carnegie Mellon University. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms are permitted 11 * provided that the above copyright notice and this paragraph are 12 * duplicated in all such forms and that any documentation, 13 * advertising materials, and other materials related to such 14 * distribution and use acknowledge that the software was developed 15 * by Carnegie Mellon University. The name of the 16 * University may not be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 20 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 21 * 22 * Drew D. Perkins 23 * Carnegie Mellon University 24 * 4910 Forbes Ave. 25 * Pittsburgh, PA 15213 26 * (412) 268-8576 27 * ddp@andrew.cmu.edu 28 * 29 * Based on: 30 * @(#)if_sl.c 7.6.1.2 (Berkeley) 2/15/89 31 * 32 * Copyright (c) 1987 Regents of the University of California. 33 * All rights reserved. 34 * 35 * Redistribution and use in source and binary forms are permitted 36 * provided that the above copyright notice and this paragraph are 37 * duplicated in all such forms and that any documentation, 38 * advertising materials, and other materials related to such 39 * distribution and use acknowledge that the software was developed 40 * by the University of California, Berkeley. The name of the 41 * University may not be used to endorse or promote products derived 42 * from this software without specific prior written permission. 43 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 44 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 45 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 46 * 47 * Serial Line interface 48 * 49 * Rick Adams 50 * Center for Seismic Studies 51 * 1300 N 17th Street, Suite 1450 52 * Arlington, Virginia 22209 53 * (703)276-7900 54 * rick@seismo.ARPA 55 * seismo!rick 56 * 57 * Pounded on heavily by Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris). 58 * Converted to 4.3BSD Beta by Chris Torek. 59 * Other changes made at Berkeley, based in part on code by Kirk Smith. 60 * 61 * Converted to 4.3BSD+ 386BSD by Brad Parker (brad@cayman.com) 62 * Added VJ tcp header compression; more unified ioctls 63 * 64 * Extensively modified by Paul Mackerras (paulus@cs.anu.edu.au). 65 * Cleaned up a lot of the mbuf-related code to fix bugs that 66 * caused system crashes and packet corruption. Changed pppstart 67 * so that it doesn't just give up with a collision if the whole 68 * packet doesn't fit in the output ring buffer. 69 * 70 * Added priority queueing for interactive IP packets, following 71 * the model of if_sl.c, plus hooks for bpf. 72 * Paul Mackerras (paulus@cs.anu.edu.au). 73 */ 74 75 /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */ 76 /* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */ 77 78 #include "ppp.h" 79 #if NPPP > 0 80 81 #define VJC 82 #define PPP_COMPRESS 83 84 #include "opt_inet.h" 85 #include "opt_gateway.h" 86 #include "opt_ppp.h" 87 88 #include <sys/param.h> 89 #include <sys/proc.h> 90 #include <sys/mbuf.h> 91 #include <sys/socket.h> 92 #include <sys/ioctl.h> 93 #include <sys/kernel.h> 94 #include <sys/systm.h> 95 #include <sys/time.h> 96 #include <sys/malloc.h> 97 98 #include <net/if.h> 99 #include <net/if_types.h> 100 #include <net/netisr.h> 101 #include <net/route.h> 102 #ifdef PPP_FILTER 103 #include <net/bpf.h> 104 #endif 105 106 #ifdef INET 107 #include <netinet/in.h> 108 #include <netinet/in_systm.h> 109 #include <netinet/in_var.h> 110 #include <netinet/ip.h> 111 #else 112 #ifdef _KERNEL 113 #ifdef VJC 114 #error ppp device with VJC assumes INET 115 #endif 116 #endif 117 #endif 118 119 #include "bpfilter.h" 120 #if NBPFILTER > 0 121 #include <sys/time.h> 122 #include <net/bpf.h> 123 #endif 124 125 #if defined(PPP_FILTER) || NBPFILTER > 0 126 #include <net/slip.h> 127 #endif 128 129 #ifdef VJC 130 #include <net/slcompress.h> 131 #endif 132 133 #include <net/ppp_defs.h> 134 #include <net/if_ppp.h> 135 #include <net/if_pppvar.h> 136 #include <machine/cpu.h> 137 138 #ifdef PPP_COMPRESS 139 #define PACKETPTR struct mbuf * 140 #include <net/ppp-comp.h> 141 #endif 142 143 static int pppsioctl __P((struct ifnet *, u_long, caddr_t)); 144 static void ppp_requeue __P((struct ppp_softc *)); 145 static void ppp_ccp __P((struct ppp_softc *, struct mbuf *m, int rcvd)); 146 static void ppp_ccp_closed __P((struct ppp_softc *)); 147 static void ppp_inproc __P((struct ppp_softc *, struct mbuf *)); 148 static void pppdumpm __P((struct mbuf *m0)); 149 150 /* 151 * Some useful mbuf macros not in mbuf.h. 152 */ 153 #define M_IS_CLUSTER(m) ((m)->m_flags & M_EXT) 154 155 #define M_DATASTART(m) \ 156 (M_IS_CLUSTER(m) ? (m)->m_ext.ext_buf : \ 157 (m)->m_flags & M_PKTHDR ? (m)->m_pktdat : (m)->m_dat) 158 159 #define M_DATASIZE(m) \ 160 (M_IS_CLUSTER(m) ? (m)->m_ext.ext_size : \ 161 (m)->m_flags & M_PKTHDR ? MHLEN: MLEN) 162 163 /* 164 * We define two link layer specific mbuf flags, to mark high-priority 165 * packets for output, and received packets following lost/corrupted 166 * packets. 167 */ 168 #define M_HIGHPRI M_LINK0 /* output packet for sc_fastq */ 169 #define M_ERRMARK M_LINK1 /* rx packet following lost/corrupted pkt */ 170 171 #ifdef PPP_COMPRESS 172 /* 173 * List of compressors we know about. 174 * We leave some space so maybe we can modload compressors. 175 */ 176 177 extern struct compressor ppp_bsd_compress; 178 extern struct compressor ppp_deflate, ppp_deflate_draft; 179 180 struct compressor *ppp_compressors[8] = { 181 #if DO_BSD_COMPRESS && defined(PPP_BSDCOMP) 182 &ppp_bsd_compress, 183 #endif 184 #if DO_DEFLATE && defined(PPP_DEFLATE) 185 &ppp_deflate, 186 &ppp_deflate_draft, 187 #endif 188 NULL 189 }; 190 #endif /* PPP_COMPRESS */ 191 192 193 /* 194 * Called from boot code to establish ppp interfaces. 195 */ 196 void 197 pppattach() 198 { 199 struct ppp_softc *sc; 200 int i = 0; 201 202 for (sc = ppp_softc; i < NPPP; sc++) { 203 sc->sc_unit = i; /* XXX */ 204 sprintf(sc->sc_if.if_xname, "ppp%d", i++); 205 callout_init(&sc->sc_timo_ch); 206 sc->sc_if.if_softc = sc; 207 sc->sc_if.if_mtu = PPP_MTU; 208 sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST; 209 sc->sc_if.if_type = IFT_PPP; 210 sc->sc_if.if_hdrlen = PPP_HDRLEN; 211 sc->sc_if.if_ioctl = pppsioctl; 212 sc->sc_if.if_output = pppoutput; 213 sc->sc_if.if_snd.ifq_maxlen = IFQ_MAXLEN; 214 sc->sc_inq.ifq_maxlen = IFQ_MAXLEN; 215 sc->sc_fastq.ifq_maxlen = IFQ_MAXLEN; 216 sc->sc_rawq.ifq_maxlen = IFQ_MAXLEN; 217 if_attach(&sc->sc_if); 218 #if NBPFILTER > 0 219 bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_NULL, 0); 220 #endif 221 } 222 } 223 224 /* 225 * Allocate a ppp interface unit and initialize it. 226 */ 227 struct ppp_softc * 228 pppalloc(pid) 229 pid_t pid; 230 { 231 int nppp, i; 232 struct ppp_softc *sc; 233 234 for (nppp = 0, sc = ppp_softc; nppp < NPPP; nppp++, sc++) 235 if (sc->sc_xfer == pid) { 236 sc->sc_xfer = 0; 237 return sc; 238 } 239 for (nppp = 0, sc = ppp_softc; nppp < NPPP; nppp++, sc++) 240 if (sc->sc_devp == NULL) 241 break; 242 if (nppp >= NPPP) 243 return NULL; 244 245 sc->sc_flags = 0; 246 sc->sc_mru = PPP_MRU; 247 sc->sc_relinq = NULL; 248 bzero((char *)&sc->sc_stats, sizeof(sc->sc_stats)); 249 #ifdef VJC 250 MALLOC(sc->sc_comp, struct slcompress *, sizeof(struct slcompress), 251 M_DEVBUF, M_NOWAIT); 252 if (sc->sc_comp) 253 sl_compress_init(sc->sc_comp); 254 #endif 255 #ifdef PPP_COMPRESS 256 sc->sc_xc_state = NULL; 257 sc->sc_rc_state = NULL; 258 #endif /* PPP_COMPRESS */ 259 for (i = 0; i < NUM_NP; ++i) 260 sc->sc_npmode[i] = NPMODE_ERROR; 261 sc->sc_npqueue = NULL; 262 sc->sc_npqtail = &sc->sc_npqueue; 263 sc->sc_last_sent = sc->sc_last_recv = time.tv_sec; 264 265 return sc; 266 } 267 268 /* 269 * Deallocate a ppp unit. Must be called at splsoftnet or higher. 270 */ 271 void 272 pppdealloc(sc) 273 struct ppp_softc *sc; 274 { 275 struct mbuf *m; 276 277 if_down(&sc->sc_if); 278 sc->sc_if.if_flags &= ~(IFF_UP|IFF_RUNNING); 279 sc->sc_devp = NULL; 280 sc->sc_xfer = 0; 281 for (;;) { 282 IF_DEQUEUE(&sc->sc_rawq, m); 283 if (m == NULL) 284 break; 285 m_freem(m); 286 } 287 for (;;) { 288 IF_DEQUEUE(&sc->sc_inq, m); 289 if (m == NULL) 290 break; 291 m_freem(m); 292 } 293 for (;;) { 294 IF_DEQUEUE(&sc->sc_fastq, m); 295 if (m == NULL) 296 break; 297 m_freem(m); 298 } 299 while ((m = sc->sc_npqueue) != NULL) { 300 sc->sc_npqueue = m->m_nextpkt; 301 m_freem(m); 302 } 303 if (sc->sc_togo != NULL) { 304 m_freem(sc->sc_togo); 305 sc->sc_togo = NULL; 306 } 307 #ifdef PPP_COMPRESS 308 ppp_ccp_closed(sc); 309 sc->sc_xc_state = NULL; 310 sc->sc_rc_state = NULL; 311 #endif /* PPP_COMPRESS */ 312 #ifdef PPP_FILTER 313 if (sc->sc_pass_filt_in.bf_insns != 0) { 314 FREE(sc->sc_pass_filt_in.bf_insns, M_DEVBUF); 315 sc->sc_pass_filt_in.bf_insns = 0; 316 sc->sc_pass_filt_in.bf_len = 0; 317 } 318 if (sc->sc_pass_filt_out.bf_insns != 0) { 319 FREE(sc->sc_pass_filt_out.bf_insns, M_DEVBUF); 320 sc->sc_pass_filt_out.bf_insns = 0; 321 sc->sc_pass_filt_out.bf_len = 0; 322 } 323 if (sc->sc_active_filt_in.bf_insns != 0) { 324 FREE(sc->sc_active_filt_in.bf_insns, M_DEVBUF); 325 sc->sc_active_filt_in.bf_insns = 0; 326 sc->sc_active_filt_in.bf_len = 0; 327 } 328 if (sc->sc_active_filt_out.bf_insns != 0) { 329 FREE(sc->sc_active_filt_out.bf_insns, M_DEVBUF); 330 sc->sc_active_filt_out.bf_insns = 0; 331 sc->sc_active_filt_out.bf_len = 0; 332 } 333 #endif /* PPP_FILTER */ 334 #ifdef VJC 335 if (sc->sc_comp != 0) { 336 FREE(sc->sc_comp, M_DEVBUF); 337 sc->sc_comp = 0; 338 } 339 #endif 340 } 341 342 /* 343 * Ioctl routine for generic ppp devices. 344 */ 345 int 346 pppioctl(sc, cmd, data, flag, p) 347 struct ppp_softc *sc; 348 u_long cmd; 349 caddr_t data; 350 int flag; 351 struct proc *p; 352 { 353 int s, error, flags, mru, nb, npx; 354 struct ppp_option_data *odp; 355 struct compressor **cp; 356 struct npioctl *npi; 357 time_t t; 358 #ifdef PPP_FILTER 359 struct bpf_program *bp, *nbp; 360 struct bpf_insn *newcode, *oldcode; 361 int newcodelen; 362 #endif /* PPP_FILTER */ 363 #ifdef PPP_COMPRESS 364 u_char ccp_option[CCP_MAX_OPTION_LENGTH]; 365 #endif 366 367 switch (cmd) { 368 case FIONREAD: 369 *(int *)data = sc->sc_inq.ifq_len; 370 break; 371 372 case PPPIOCGUNIT: 373 *(int *)data = sc->sc_unit; /* XXX */ 374 break; 375 376 case PPPIOCGFLAGS: 377 *(u_int *)data = sc->sc_flags; 378 break; 379 380 case PPPIOCSFLAGS: 381 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 382 return (error); 383 flags = *(int *)data & SC_MASK; 384 s = splsoftnet(); 385 #ifdef PPP_COMPRESS 386 if (sc->sc_flags & SC_CCP_OPEN && !(flags & SC_CCP_OPEN)) 387 ppp_ccp_closed(sc); 388 #endif 389 splimp(); 390 sc->sc_flags = (sc->sc_flags & ~SC_MASK) | flags; 391 splx(s); 392 break; 393 394 case PPPIOCSMRU: 395 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 396 return (error); 397 mru = *(int *)data; 398 if (mru >= PPP_MRU && mru <= PPP_MAXMRU) 399 sc->sc_mru = mru; 400 break; 401 402 case PPPIOCGMRU: 403 *(int *)data = sc->sc_mru; 404 break; 405 406 #ifdef VJC 407 case PPPIOCSMAXCID: 408 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 409 return (error); 410 if (sc->sc_comp) { 411 s = splsoftnet(); 412 sl_compress_setup(sc->sc_comp, *(int *)data); 413 splx(s); 414 } 415 break; 416 #endif 417 418 case PPPIOCXFERUNIT: 419 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 420 return (error); 421 sc->sc_xfer = p->p_pid; 422 break; 423 424 #ifdef PPP_COMPRESS 425 case PPPIOCSCOMPRESS: 426 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 427 return (error); 428 odp = (struct ppp_option_data *) data; 429 nb = odp->length; 430 if (nb > sizeof(ccp_option)) 431 nb = sizeof(ccp_option); 432 if ((error = copyin(odp->ptr, ccp_option, nb)) != 0) 433 return (error); 434 if (ccp_option[1] < 2) /* preliminary check on the length byte */ 435 return (EINVAL); 436 for (cp = ppp_compressors; *cp != NULL; ++cp) 437 if ((*cp)->compress_proto == ccp_option[0]) { 438 /* 439 * Found a handler for the protocol - try to allocate 440 * a compressor or decompressor. 441 */ 442 error = 0; 443 if (odp->transmit) { 444 s = splsoftnet(); 445 if (sc->sc_xc_state != NULL) 446 (*sc->sc_xcomp->comp_free)(sc->sc_xc_state); 447 sc->sc_xcomp = *cp; 448 sc->sc_xc_state = (*cp)->comp_alloc(ccp_option, nb); 449 if (sc->sc_xc_state == NULL) { 450 if (sc->sc_flags & SC_DEBUG) 451 printf("%s: comp_alloc failed\n", 452 sc->sc_if.if_xname); 453 error = ENOBUFS; 454 } 455 splimp(); 456 sc->sc_flags &= ~SC_COMP_RUN; 457 splx(s); 458 } else { 459 s = splsoftnet(); 460 if (sc->sc_rc_state != NULL) 461 (*sc->sc_rcomp->decomp_free)(sc->sc_rc_state); 462 sc->sc_rcomp = *cp; 463 sc->sc_rc_state = (*cp)->decomp_alloc(ccp_option, nb); 464 if (sc->sc_rc_state == NULL) { 465 if (sc->sc_flags & SC_DEBUG) 466 printf("%s: decomp_alloc failed\n", 467 sc->sc_if.if_xname); 468 error = ENOBUFS; 469 } 470 splimp(); 471 sc->sc_flags &= ~SC_DECOMP_RUN; 472 splx(s); 473 } 474 return (error); 475 } 476 if (sc->sc_flags & SC_DEBUG) 477 printf("%s: no compressor for [%x %x %x], %x\n", 478 sc->sc_if.if_xname, ccp_option[0], ccp_option[1], 479 ccp_option[2], nb); 480 return (EINVAL); /* no handler found */ 481 #endif /* PPP_COMPRESS */ 482 483 case PPPIOCGNPMODE: 484 case PPPIOCSNPMODE: 485 npi = (struct npioctl *) data; 486 switch (npi->protocol) { 487 case PPP_IP: 488 npx = NP_IP; 489 break; 490 case PPP_IPV6: 491 npx = NP_IPV6; 492 break; 493 default: 494 return EINVAL; 495 } 496 if (cmd == PPPIOCGNPMODE) { 497 npi->mode = sc->sc_npmode[npx]; 498 } else { 499 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 500 return (error); 501 if (npi->mode != sc->sc_npmode[npx]) { 502 s = splimp(); 503 sc->sc_npmode[npx] = npi->mode; 504 if (npi->mode != NPMODE_QUEUE) { 505 ppp_requeue(sc); 506 ppp_restart(sc); 507 } 508 splx(s); 509 } 510 } 511 break; 512 513 case PPPIOCGIDLE: 514 s = splsoftnet(); 515 t = time.tv_sec; 516 ((struct ppp_idle *)data)->xmit_idle = t - sc->sc_last_sent; 517 ((struct ppp_idle *)data)->recv_idle = t - sc->sc_last_recv; 518 splx(s); 519 break; 520 521 #ifdef PPP_FILTER 522 case PPPIOCSPASS: 523 case PPPIOCSACTIVE: 524 /* These are no longer supported. */ 525 return EOPNOTSUPP; 526 527 case PPPIOCSIPASS: 528 case PPPIOCSOPASS: 529 case PPPIOCSIACTIVE: 530 case PPPIOCSOACTIVE: 531 nbp = (struct bpf_program *) data; 532 if ((unsigned) nbp->bf_len > BPF_MAXINSNS) 533 return EINVAL; 534 newcodelen = nbp->bf_len * sizeof(struct bpf_insn); 535 if (newcodelen != 0) { 536 newcode = malloc(newcodelen, M_DEVBUF, M_WAITOK); 537 /* WAITOK -- malloc() never fails. */ 538 if ((error = copyin((caddr_t)nbp->bf_insns, (caddr_t)newcode, 539 newcodelen)) != 0) { 540 free(newcode, M_DEVBUF); 541 return error; 542 } 543 if (!bpf_validate(newcode, nbp->bf_len)) { 544 free(newcode, M_DEVBUF); 545 return EINVAL; 546 } 547 } else 548 newcode = 0; 549 switch (cmd) { 550 case PPPIOCSIPASS: 551 bp = &sc->sc_pass_filt_in; 552 break; 553 554 case PPPIOCSOPASS: 555 bp = &sc->sc_pass_filt_out; 556 break; 557 558 case PPPIOCSIACTIVE: 559 bp = &sc->sc_active_filt_in; 560 break; 561 562 case PPPIOCSOACTIVE: 563 bp = &sc->sc_active_filt_out; 564 break; 565 } 566 oldcode = bp->bf_insns; 567 s = splimp(); 568 bp->bf_len = nbp->bf_len; 569 bp->bf_insns = newcode; 570 splx(s); 571 if (oldcode != 0) 572 free(oldcode, M_DEVBUF); 573 break; 574 #endif /* PPP_FILTER */ 575 576 default: 577 return (-1); 578 } 579 return (0); 580 } 581 582 /* 583 * Process an ioctl request to the ppp network interface. 584 */ 585 static int 586 pppsioctl(ifp, cmd, data) 587 struct ifnet *ifp; 588 u_long cmd; 589 caddr_t data; 590 { 591 struct proc *p = curproc; /* XXX */ 592 struct ppp_softc *sc = ifp->if_softc; 593 struct ifaddr *ifa = (struct ifaddr *)data; 594 struct ifreq *ifr = (struct ifreq *)data; 595 struct ppp_stats *psp; 596 #ifdef PPP_COMPRESS 597 struct ppp_comp_stats *pcp; 598 #endif 599 int s = splimp(), error = 0; 600 601 switch (cmd) { 602 case SIOCSIFFLAGS: 603 if ((ifp->if_flags & IFF_RUNNING) == 0) 604 ifp->if_flags &= ~IFF_UP; 605 break; 606 607 case SIOCSIFADDR: 608 switch (ifa->ifa_addr->sa_family) { 609 #ifdef INET 610 case AF_INET: 611 break; 612 #endif 613 #ifdef INET6 614 case AF_INET6: 615 break; 616 #endif 617 default: 618 error = EAFNOSUPPORT; 619 break; 620 } 621 break; 622 623 case SIOCSIFDSTADDR: 624 switch (ifa->ifa_addr->sa_family) { 625 #ifdef INET 626 case AF_INET: 627 break; 628 #endif 629 #ifdef INET6 630 case AF_INET6: 631 break; 632 #endif 633 default: 634 error = EAFNOSUPPORT; 635 break; 636 } 637 break; 638 639 case SIOCSIFMTU: 640 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 641 break; 642 sc->sc_if.if_mtu = ifr->ifr_mtu; 643 break; 644 645 case SIOCGIFMTU: 646 ifr->ifr_mtu = sc->sc_if.if_mtu; 647 break; 648 649 case SIOCADDMULTI: 650 case SIOCDELMULTI: 651 if (ifr == 0) { 652 error = EAFNOSUPPORT; 653 break; 654 } 655 switch(ifr->ifr_addr.sa_family) { 656 #ifdef INET 657 case AF_INET: 658 break; 659 #endif 660 #ifdef INET6 661 case AF_INET6: 662 break; 663 #endif 664 default: 665 error = EAFNOSUPPORT; 666 break; 667 } 668 break; 669 670 case SIOCGPPPSTATS: 671 psp = &((struct ifpppstatsreq *) data)->stats; 672 bzero(psp, sizeof(*psp)); 673 psp->p = sc->sc_stats; 674 #if defined(VJC) && !defined(SL_NO_STATS) 675 if (sc->sc_comp) { 676 psp->vj.vjs_packets = sc->sc_comp->sls_packets; 677 psp->vj.vjs_compressed = sc->sc_comp->sls_compressed; 678 psp->vj.vjs_searches = sc->sc_comp->sls_searches; 679 psp->vj.vjs_misses = sc->sc_comp->sls_misses; 680 psp->vj.vjs_uncompressedin = sc->sc_comp->sls_uncompressedin; 681 psp->vj.vjs_compressedin = sc->sc_comp->sls_compressedin; 682 psp->vj.vjs_errorin = sc->sc_comp->sls_errorin; 683 psp->vj.vjs_tossed = sc->sc_comp->sls_tossed; 684 } 685 #endif /* VJC */ 686 break; 687 688 #ifdef PPP_COMPRESS 689 case SIOCGPPPCSTATS: 690 pcp = &((struct ifpppcstatsreq *) data)->stats; 691 bzero(pcp, sizeof(*pcp)); 692 if (sc->sc_xc_state != NULL) 693 (*sc->sc_xcomp->comp_stat)(sc->sc_xc_state, &pcp->c); 694 if (sc->sc_rc_state != NULL) 695 (*sc->sc_rcomp->decomp_stat)(sc->sc_rc_state, &pcp->d); 696 break; 697 #endif /* PPP_COMPRESS */ 698 699 default: 700 error = EINVAL; 701 } 702 splx(s); 703 return (error); 704 } 705 706 /* 707 * Queue a packet. Start transmission if not active. 708 * Packet is placed in Information field of PPP frame. 709 */ 710 int 711 pppoutput(ifp, m0, dst, rtp) 712 struct ifnet *ifp; 713 struct mbuf *m0; 714 struct sockaddr *dst; 715 struct rtentry *rtp; 716 { 717 struct ppp_softc *sc = ifp->if_softc; 718 int protocol, address, control; 719 u_char *cp; 720 int s, error; 721 struct ip *ip; 722 struct ifqueue *ifq; 723 enum NPmode mode; 724 int len; 725 struct mbuf *m; 726 727 if (sc->sc_devp == NULL || (ifp->if_flags & IFF_RUNNING) == 0 728 || ((ifp->if_flags & IFF_UP) == 0 && dst->sa_family != AF_UNSPEC)) { 729 error = ENETDOWN; /* sort of */ 730 goto bad; 731 } 732 733 /* 734 * Compute PPP header. 735 */ 736 m0->m_flags &= ~M_HIGHPRI; 737 switch (dst->sa_family) { 738 #ifdef INET 739 case AF_INET: 740 address = PPP_ALLSTATIONS; 741 control = PPP_UI; 742 protocol = PPP_IP; 743 mode = sc->sc_npmode[NP_IP]; 744 745 /* 746 * If this packet has the "low delay" bit set in the IP header, 747 * put it on the fastq instead. 748 */ 749 ip = mtod(m0, struct ip *); 750 if (ip->ip_tos & IPTOS_LOWDELAY) 751 m0->m_flags |= M_HIGHPRI; 752 break; 753 #endif 754 #ifdef INET6 755 case AF_INET6: 756 address = PPP_ALLSTATIONS; /*XXX*/ 757 control = PPP_UI; /*XXX*/ 758 protocol = PPP_IPV6; 759 mode = sc->sc_npmode[NP_IPV6]; 760 761 #if 0 /* XXX flowinfo/traffic class, maybe? */ 762 /* 763 * If this packet has the "low delay" bit set in the IP header, 764 * put it on the fastq instead. 765 */ 766 ip = mtod(m0, struct ip *); 767 if (ip->ip_tos & IPTOS_LOWDELAY) 768 m0->m_flags |= M_HIGHPRI; 769 #endif 770 break; 771 #endif 772 case AF_UNSPEC: 773 address = PPP_ADDRESS(dst->sa_data); 774 control = PPP_CONTROL(dst->sa_data); 775 protocol = PPP_PROTOCOL(dst->sa_data); 776 mode = NPMODE_PASS; 777 break; 778 default: 779 printf("%s: af%d not supported\n", ifp->if_xname, dst->sa_family); 780 error = EAFNOSUPPORT; 781 goto bad; 782 } 783 784 /* 785 * Drop this packet, or return an error, if necessary. 786 */ 787 if (mode == NPMODE_ERROR) { 788 error = ENETDOWN; 789 goto bad; 790 } 791 if (mode == NPMODE_DROP) { 792 error = 0; 793 goto bad; 794 } 795 796 /* 797 * Add PPP header. If no space in first mbuf, allocate another. 798 * (This assumes M_LEADINGSPACE is always 0 for a cluster mbuf.) 799 */ 800 if (M_LEADINGSPACE(m0) < PPP_HDRLEN) { 801 m0 = m_prepend(m0, PPP_HDRLEN, M_DONTWAIT); 802 if (m0 == 0) { 803 error = ENOBUFS; 804 goto bad; 805 } 806 m0->m_len = 0; 807 } else 808 m0->m_data -= PPP_HDRLEN; 809 810 cp = mtod(m0, u_char *); 811 *cp++ = address; 812 *cp++ = control; 813 *cp++ = protocol >> 8; 814 *cp++ = protocol & 0xff; 815 m0->m_len += PPP_HDRLEN; 816 817 len = 0; 818 for (m = m0; m != 0; m = m->m_next) 819 len += m->m_len; 820 821 if (sc->sc_flags & SC_LOG_OUTPKT) { 822 printf("%s output: ", ifp->if_xname); 823 pppdumpm(m0); 824 } 825 826 if ((protocol & 0x8000) == 0) { 827 #ifdef PPP_FILTER 828 /* 829 * Apply the pass and active filters to the packet, 830 * but only if it is a data packet. 831 */ 832 if (sc->sc_pass_filt_out.bf_insns != 0 833 && bpf_filter(sc->sc_pass_filt_out.bf_insns, (u_char *) m0, 834 len, 0) == 0) { 835 error = 0; /* drop this packet */ 836 goto bad; 837 } 838 839 /* 840 * Update the time we sent the most recent packet. 841 */ 842 if (sc->sc_active_filt_out.bf_insns == 0 843 || bpf_filter(sc->sc_active_filt_out.bf_insns, (u_char *) m0, 844 len, 0)) 845 sc->sc_last_sent = time.tv_sec; 846 #else 847 /* 848 * Update the time we sent the most recent packet. 849 */ 850 sc->sc_last_sent = time.tv_sec; 851 #endif /* PPP_FILTER */ 852 } 853 854 #if NBPFILTER > 0 855 /* 856 * See if bpf wants to look at the packet. 857 */ 858 if (sc->sc_bpf) 859 bpf_mtap(sc->sc_bpf, m0); 860 #endif 861 862 /* 863 * Put the packet on the appropriate queue. 864 */ 865 s = splimp(); 866 if (mode == NPMODE_QUEUE) { 867 /* XXX we should limit the number of packets on this queue */ 868 *sc->sc_npqtail = m0; 869 m0->m_nextpkt = NULL; 870 sc->sc_npqtail = &m0->m_nextpkt; 871 } else { 872 ifq = (m0->m_flags & M_HIGHPRI)? &sc->sc_fastq: &ifp->if_snd; 873 if (IF_QFULL(ifq) && dst->sa_family != AF_UNSPEC) { 874 IF_DROP(ifq); 875 splx(s); 876 sc->sc_if.if_oerrors++; 877 sc->sc_stats.ppp_oerrors++; 878 error = ENOBUFS; 879 goto bad; 880 } 881 IF_ENQUEUE(ifq, m0); 882 ppp_restart(sc); 883 } 884 ifp->if_lastchange = time; 885 ifp->if_opackets++; 886 ifp->if_obytes += len; 887 888 splx(s); 889 return (0); 890 891 bad: 892 m_freem(m0); 893 return (error); 894 } 895 896 /* 897 * After a change in the NPmode for some NP, move packets from the 898 * npqueue to the send queue or the fast queue as appropriate. 899 * Should be called at splimp, since we muck with the queues. 900 */ 901 static void 902 ppp_requeue(sc) 903 struct ppp_softc *sc; 904 { 905 struct mbuf *m, **mpp; 906 struct ifqueue *ifq; 907 enum NPmode mode; 908 909 for (mpp = &sc->sc_npqueue; (m = *mpp) != NULL; ) { 910 switch (PPP_PROTOCOL(mtod(m, u_char *))) { 911 case PPP_IP: 912 mode = sc->sc_npmode[NP_IP]; 913 break; 914 case PPP_IPV6: 915 mode = sc->sc_npmode[NP_IPV6]; 916 break; 917 default: 918 mode = NPMODE_PASS; 919 } 920 921 switch (mode) { 922 case NPMODE_PASS: 923 /* 924 * This packet can now go on one of the queues to be sent. 925 */ 926 *mpp = m->m_nextpkt; 927 m->m_nextpkt = NULL; 928 ifq = (m->m_flags & M_HIGHPRI)? &sc->sc_fastq: &sc->sc_if.if_snd; 929 if (IF_QFULL(ifq)) { 930 IF_DROP(ifq); 931 sc->sc_if.if_oerrors++; 932 sc->sc_stats.ppp_oerrors++; 933 } else 934 IF_ENQUEUE(ifq, m); 935 break; 936 937 case NPMODE_DROP: 938 case NPMODE_ERROR: 939 *mpp = m->m_nextpkt; 940 m_freem(m); 941 break; 942 943 case NPMODE_QUEUE: 944 mpp = &m->m_nextpkt; 945 break; 946 } 947 } 948 sc->sc_npqtail = mpp; 949 } 950 951 /* 952 * Transmitter has finished outputting some stuff; 953 * remember to call sc->sc_start later at splsoftnet. 954 */ 955 void 956 ppp_restart(sc) 957 struct ppp_softc *sc; 958 { 959 int s = splimp(); 960 961 sc->sc_flags &= ~SC_TBUSY; 962 schednetisr(NETISR_PPP); 963 splx(s); 964 } 965 966 /* 967 * Get a packet to send. This procedure is intended to be called at 968 * splsoftnet, since it may involve time-consuming operations such as 969 * applying VJ compression, packet compression, address/control and/or 970 * protocol field compression to the packet. 971 */ 972 struct mbuf * 973 ppp_dequeue(sc) 974 struct ppp_softc *sc; 975 { 976 struct mbuf *m, *mp; 977 u_char *cp; 978 int address, control, protocol; 979 int s; 980 981 /* 982 * Grab a packet to send: first try the fast queue, then the 983 * normal queue. 984 */ 985 s = splimp(); 986 IF_DEQUEUE(&sc->sc_fastq, m); 987 if (m == NULL) 988 IF_DEQUEUE(&sc->sc_if.if_snd, m); 989 splx(s); 990 991 if (m == NULL) 992 return NULL; 993 994 ++sc->sc_stats.ppp_opackets; 995 996 /* 997 * Extract the ppp header of the new packet. 998 * The ppp header will be in one mbuf. 999 */ 1000 cp = mtod(m, u_char *); 1001 address = PPP_ADDRESS(cp); 1002 control = PPP_CONTROL(cp); 1003 protocol = PPP_PROTOCOL(cp); 1004 1005 switch (protocol) { 1006 case PPP_IP: 1007 #ifdef VJC 1008 /* 1009 * If the packet is a TCP/IP packet, see if we can compress it. 1010 */ 1011 if ((sc->sc_flags & SC_COMP_TCP) && sc->sc_comp != NULL) { 1012 struct ip *ip; 1013 int type; 1014 1015 mp = m; 1016 ip = (struct ip *) (cp + PPP_HDRLEN); 1017 if (mp->m_len <= PPP_HDRLEN) { 1018 mp = mp->m_next; 1019 if (mp == NULL) 1020 break; 1021 ip = mtod(mp, struct ip *); 1022 } 1023 /* this code assumes the IP/TCP header is in one non-shared mbuf */ 1024 if (ip->ip_p == IPPROTO_TCP) { 1025 type = sl_compress_tcp(mp, ip, sc->sc_comp, 1026 !(sc->sc_flags & SC_NO_TCP_CCID)); 1027 switch (type) { 1028 case TYPE_UNCOMPRESSED_TCP: 1029 protocol = PPP_VJC_UNCOMP; 1030 break; 1031 case TYPE_COMPRESSED_TCP: 1032 protocol = PPP_VJC_COMP; 1033 cp = mtod(m, u_char *); 1034 cp[0] = address; /* header has moved */ 1035 cp[1] = control; 1036 cp[2] = 0; 1037 break; 1038 } 1039 cp[3] = protocol; /* update protocol in PPP header */ 1040 } 1041 } 1042 #endif /* VJC */ 1043 break; 1044 1045 #ifdef PPP_COMPRESS 1046 case PPP_CCP: 1047 ppp_ccp(sc, m, 0); 1048 break; 1049 #endif /* PPP_COMPRESS */ 1050 } 1051 1052 #ifdef PPP_COMPRESS 1053 if (protocol != PPP_LCP && protocol != PPP_CCP 1054 && sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN)) { 1055 struct mbuf *mcomp = NULL; 1056 int slen, clen; 1057 1058 slen = 0; 1059 for (mp = m; mp != NULL; mp = mp->m_next) 1060 slen += mp->m_len; 1061 clen = (*sc->sc_xcomp->compress) 1062 (sc->sc_xc_state, &mcomp, m, slen, sc->sc_if.if_mtu + PPP_HDRLEN); 1063 if (mcomp != NULL) { 1064 if (sc->sc_flags & SC_CCP_UP) { 1065 /* Send the compressed packet instead of the original. */ 1066 m_freem(m); 1067 m = mcomp; 1068 cp = mtod(m, u_char *); 1069 protocol = cp[3]; 1070 } else { 1071 /* Can't transmit compressed packets until CCP is up. */ 1072 m_freem(mcomp); 1073 } 1074 } 1075 } 1076 #endif /* PPP_COMPRESS */ 1077 1078 /* 1079 * Compress the address/control and protocol, if possible. 1080 */ 1081 if (sc->sc_flags & SC_COMP_AC && address == PPP_ALLSTATIONS && 1082 control == PPP_UI && protocol != PPP_ALLSTATIONS && 1083 protocol != PPP_LCP) { 1084 /* can compress address/control */ 1085 m->m_data += 2; 1086 m->m_len -= 2; 1087 } 1088 if (sc->sc_flags & SC_COMP_PROT && protocol < 0xFF) { 1089 /* can compress protocol */ 1090 if (mtod(m, u_char *) == cp) { 1091 cp[2] = cp[1]; /* move address/control up */ 1092 cp[1] = cp[0]; 1093 } 1094 ++m->m_data; 1095 --m->m_len; 1096 } 1097 1098 return m; 1099 } 1100 1101 /* 1102 * Software interrupt routine, called at splsoftnet. 1103 */ 1104 void 1105 pppintr() 1106 { 1107 struct ppp_softc *sc; 1108 int i, s, s2; 1109 struct mbuf *m; 1110 1111 sc = ppp_softc; 1112 s = splsoftnet(); 1113 for (i = 0; i < NPPP; ++i, ++sc) { 1114 if (!(sc->sc_flags & SC_TBUSY) 1115 && (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head 1116 || sc->sc_outm)) { 1117 s2 = splimp(); 1118 sc->sc_flags |= SC_TBUSY; 1119 splx(s2); 1120 (*sc->sc_start)(sc); 1121 } 1122 for (;;) { 1123 s2 = splimp(); 1124 IF_DEQUEUE(&sc->sc_rawq, m); 1125 splx(s2); 1126 if (m == NULL) 1127 break; 1128 ppp_inproc(sc, m); 1129 } 1130 } 1131 splx(s); 1132 } 1133 1134 #ifdef PPP_COMPRESS 1135 /* 1136 * Handle a CCP packet. `rcvd' is 1 if the packet was received, 1137 * 0 if it is about to be transmitted. 1138 */ 1139 static void 1140 ppp_ccp(sc, m, rcvd) 1141 struct ppp_softc *sc; 1142 struct mbuf *m; 1143 int rcvd; 1144 { 1145 u_char *dp, *ep; 1146 struct mbuf *mp; 1147 int slen, s; 1148 1149 /* 1150 * Get a pointer to the data after the PPP header. 1151 */ 1152 if (m->m_len <= PPP_HDRLEN) { 1153 mp = m->m_next; 1154 if (mp == NULL) 1155 return; 1156 dp = (mp != NULL)? mtod(mp, u_char *): NULL; 1157 } else { 1158 mp = m; 1159 dp = mtod(mp, u_char *) + PPP_HDRLEN; 1160 } 1161 1162 ep = mtod(mp, u_char *) + mp->m_len; 1163 if (dp + CCP_HDRLEN > ep) 1164 return; 1165 slen = CCP_LENGTH(dp); 1166 if (dp + slen > ep) { 1167 if (sc->sc_flags & SC_DEBUG) 1168 printf("if_ppp/ccp: not enough data in mbuf (%p+%x > %p+%x)\n", 1169 dp, slen, mtod(mp, u_char *), mp->m_len); 1170 return; 1171 } 1172 1173 switch (CCP_CODE(dp)) { 1174 case CCP_CONFREQ: 1175 case CCP_TERMREQ: 1176 case CCP_TERMACK: 1177 /* CCP must be going down - disable compression */ 1178 if (sc->sc_flags & SC_CCP_UP) { 1179 s = splimp(); 1180 sc->sc_flags &= ~(SC_CCP_UP | SC_COMP_RUN | SC_DECOMP_RUN); 1181 splx(s); 1182 } 1183 break; 1184 1185 case CCP_CONFACK: 1186 if (sc->sc_flags & SC_CCP_OPEN && !(sc->sc_flags & SC_CCP_UP) 1187 && slen >= CCP_HDRLEN + CCP_OPT_MINLEN 1188 && slen >= CCP_OPT_LENGTH(dp + CCP_HDRLEN) + CCP_HDRLEN) { 1189 if (!rcvd) { 1190 /* we're agreeing to send compressed packets. */ 1191 if (sc->sc_xc_state != NULL 1192 && (*sc->sc_xcomp->comp_init) 1193 (sc->sc_xc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN, 1194 sc->sc_unit, 0, sc->sc_flags & SC_DEBUG)) { 1195 s = splimp(); 1196 sc->sc_flags |= SC_COMP_RUN; 1197 splx(s); 1198 } 1199 } else { 1200 /* peer is agreeing to send compressed packets. */ 1201 if (sc->sc_rc_state != NULL 1202 && (*sc->sc_rcomp->decomp_init) 1203 (sc->sc_rc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN, 1204 sc->sc_unit, 0, sc->sc_mru, 1205 sc->sc_flags & SC_DEBUG)) { 1206 s = splimp(); 1207 sc->sc_flags |= SC_DECOMP_RUN; 1208 sc->sc_flags &= ~(SC_DC_ERROR | SC_DC_FERROR); 1209 splx(s); 1210 } 1211 } 1212 } 1213 break; 1214 1215 case CCP_RESETACK: 1216 if (sc->sc_flags & SC_CCP_UP) { 1217 if (!rcvd) { 1218 if (sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN)) 1219 (*sc->sc_xcomp->comp_reset)(sc->sc_xc_state); 1220 } else { 1221 if (sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN)) { 1222 (*sc->sc_rcomp->decomp_reset)(sc->sc_rc_state); 1223 s = splimp(); 1224 sc->sc_flags &= ~SC_DC_ERROR; 1225 splx(s); 1226 } 1227 } 1228 } 1229 break; 1230 } 1231 } 1232 1233 /* 1234 * CCP is down; free (de)compressor state if necessary. 1235 */ 1236 static void 1237 ppp_ccp_closed(sc) 1238 struct ppp_softc *sc; 1239 { 1240 if (sc->sc_xc_state) { 1241 (*sc->sc_xcomp->comp_free)(sc->sc_xc_state); 1242 sc->sc_xc_state = NULL; 1243 } 1244 if (sc->sc_rc_state) { 1245 (*sc->sc_rcomp->decomp_free)(sc->sc_rc_state); 1246 sc->sc_rc_state = NULL; 1247 } 1248 } 1249 #endif /* PPP_COMPRESS */ 1250 1251 /* 1252 * PPP packet input routine. 1253 * The caller has checked and removed the FCS and has inserted 1254 * the address/control bytes and the protocol high byte if they 1255 * were omitted. 1256 */ 1257 void 1258 ppppktin(sc, m, lost) 1259 struct ppp_softc *sc; 1260 struct mbuf *m; 1261 int lost; 1262 { 1263 int s = splimp(); 1264 1265 if (lost) 1266 m->m_flags |= M_ERRMARK; 1267 IF_ENQUEUE(&sc->sc_rawq, m); 1268 schednetisr(NETISR_PPP); 1269 splx(s); 1270 } 1271 1272 /* 1273 * Process a received PPP packet, doing decompression as necessary. 1274 * Should be called at splsoftnet. 1275 */ 1276 #define COMPTYPE(proto) ((proto) == PPP_VJC_COMP? TYPE_COMPRESSED_TCP: \ 1277 TYPE_UNCOMPRESSED_TCP) 1278 1279 static void 1280 ppp_inproc(sc, m) 1281 struct ppp_softc *sc; 1282 struct mbuf *m; 1283 { 1284 struct ifnet *ifp = &sc->sc_if; 1285 struct ifqueue *inq; 1286 int s, ilen, xlen, proto, rv; 1287 u_char *cp, adrs, ctrl; 1288 struct mbuf *mp, *dmp = NULL; 1289 u_char *iphdr; 1290 u_int hlen; 1291 1292 sc->sc_stats.ppp_ipackets++; 1293 1294 if (sc->sc_flags & SC_LOG_INPKT) { 1295 ilen = 0; 1296 for (mp = m; mp != NULL; mp = mp->m_next) 1297 ilen += mp->m_len; 1298 printf("%s: got %d bytes\n", ifp->if_xname, ilen); 1299 pppdumpm(m); 1300 } 1301 1302 cp = mtod(m, u_char *); 1303 adrs = PPP_ADDRESS(cp); 1304 ctrl = PPP_CONTROL(cp); 1305 proto = PPP_PROTOCOL(cp); 1306 1307 if (m->m_flags & M_ERRMARK) { 1308 m->m_flags &= ~M_ERRMARK; 1309 s = splimp(); 1310 sc->sc_flags |= SC_VJ_RESET; 1311 splx(s); 1312 } 1313 1314 #ifdef PPP_COMPRESS 1315 /* 1316 * Decompress this packet if necessary, update the receiver's 1317 * dictionary, or take appropriate action on a CCP packet. 1318 */ 1319 if (proto == PPP_COMP && sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN) 1320 && !(sc->sc_flags & SC_DC_ERROR) && !(sc->sc_flags & SC_DC_FERROR)) { 1321 /* decompress this packet */ 1322 rv = (*sc->sc_rcomp->decompress)(sc->sc_rc_state, m, &dmp); 1323 if (rv == DECOMP_OK) { 1324 m_freem(m); 1325 if (dmp == NULL) { 1326 /* no error, but no decompressed packet produced */ 1327 return; 1328 } 1329 m = dmp; 1330 cp = mtod(m, u_char *); 1331 proto = PPP_PROTOCOL(cp); 1332 1333 } else { 1334 /* 1335 * An error has occurred in decompression. 1336 * Pass the compressed packet up to pppd, which may take 1337 * CCP down or issue a Reset-Req. 1338 */ 1339 if (sc->sc_flags & SC_DEBUG) 1340 printf("%s: decompress failed %d\n", ifp->if_xname, rv); 1341 s = splimp(); 1342 sc->sc_flags |= SC_VJ_RESET; 1343 if (rv == DECOMP_ERROR) 1344 sc->sc_flags |= SC_DC_ERROR; 1345 else 1346 sc->sc_flags |= SC_DC_FERROR; 1347 splx(s); 1348 } 1349 1350 } else { 1351 if (sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN)) { 1352 (*sc->sc_rcomp->incomp)(sc->sc_rc_state, m); 1353 } 1354 if (proto == PPP_CCP) { 1355 ppp_ccp(sc, m, 1); 1356 } 1357 } 1358 #endif 1359 1360 ilen = 0; 1361 for (mp = m; mp != NULL; mp = mp->m_next) 1362 ilen += mp->m_len; 1363 1364 #ifdef VJC 1365 if (sc->sc_flags & SC_VJ_RESET) { 1366 /* 1367 * If we've missed a packet, we must toss subsequent compressed 1368 * packets which don't have an explicit connection ID. 1369 */ 1370 if (sc->sc_comp) 1371 sl_uncompress_tcp(NULL, 0, TYPE_ERROR, sc->sc_comp); 1372 s = splimp(); 1373 sc->sc_flags &= ~SC_VJ_RESET; 1374 splx(s); 1375 } 1376 1377 /* 1378 * See if we have a VJ-compressed packet to uncompress. 1379 */ 1380 if (proto == PPP_VJC_COMP) { 1381 if ((sc->sc_flags & SC_REJ_COMP_TCP) || sc->sc_comp == 0) 1382 goto bad; 1383 1384 xlen = sl_uncompress_tcp_core(cp + PPP_HDRLEN, m->m_len - PPP_HDRLEN, 1385 ilen - PPP_HDRLEN, TYPE_COMPRESSED_TCP, 1386 sc->sc_comp, &iphdr, &hlen); 1387 1388 if (xlen <= 0) { 1389 if (sc->sc_flags & SC_DEBUG) 1390 printf("%s: VJ uncompress failed on type comp\n", 1391 ifp->if_xname); 1392 goto bad; 1393 } 1394 1395 /* Copy the PPP and IP headers into a new mbuf. */ 1396 MGETHDR(mp, M_DONTWAIT, MT_DATA); 1397 if (mp == NULL) 1398 goto bad; 1399 mp->m_len = 0; 1400 mp->m_next = NULL; 1401 if (hlen + PPP_HDRLEN > MHLEN) { 1402 MCLGET(mp, M_DONTWAIT); 1403 if (M_TRAILINGSPACE(mp) < hlen + PPP_HDRLEN) { 1404 m_freem(mp); 1405 goto bad; /* lose if big headers and no clusters */ 1406 } 1407 } 1408 cp = mtod(mp, u_char *); 1409 cp[0] = adrs; 1410 cp[1] = ctrl; 1411 cp[2] = 0; 1412 cp[3] = PPP_IP; 1413 proto = PPP_IP; 1414 bcopy(iphdr, cp + PPP_HDRLEN, hlen); 1415 mp->m_len = hlen + PPP_HDRLEN; 1416 1417 /* 1418 * Trim the PPP and VJ headers off the old mbuf 1419 * and stick the new and old mbufs together. 1420 */ 1421 m->m_data += PPP_HDRLEN + xlen; 1422 m->m_len -= PPP_HDRLEN + xlen; 1423 if (m->m_len <= M_TRAILINGSPACE(mp)) { 1424 bcopy(mtod(m, u_char *), mtod(mp, u_char *) + mp->m_len, m->m_len); 1425 mp->m_len += m->m_len; 1426 MFREE(m, mp->m_next); 1427 } else 1428 mp->m_next = m; 1429 m = mp; 1430 ilen += hlen - xlen; 1431 1432 } else if (proto == PPP_VJC_UNCOMP) { 1433 if ((sc->sc_flags & SC_REJ_COMP_TCP) || sc->sc_comp == 0) 1434 goto bad; 1435 1436 xlen = sl_uncompress_tcp_core(cp + PPP_HDRLEN, m->m_len - PPP_HDRLEN, 1437 ilen - PPP_HDRLEN, TYPE_UNCOMPRESSED_TCP, 1438 sc->sc_comp, &iphdr, &hlen); 1439 1440 if (xlen < 0) { 1441 if (sc->sc_flags & SC_DEBUG) 1442 printf("%s: VJ uncompress failed on type uncomp\n", 1443 ifp->if_xname); 1444 goto bad; 1445 } 1446 1447 proto = PPP_IP; 1448 cp[3] = PPP_IP; 1449 } 1450 #endif /* VJC */ 1451 1452 /* 1453 * If the packet will fit in a header mbuf, don't waste a 1454 * whole cluster on it. 1455 */ 1456 if (ilen <= MHLEN && M_IS_CLUSTER(m)) { 1457 MGETHDR(mp, M_DONTWAIT, MT_DATA); 1458 if (mp != NULL) { 1459 m_copydata(m, 0, ilen, mtod(mp, caddr_t)); 1460 m_freem(m); 1461 m = mp; 1462 m->m_len = ilen; 1463 } 1464 } 1465 m->m_pkthdr.len = ilen; 1466 m->m_pkthdr.rcvif = ifp; 1467 1468 if ((proto & 0x8000) == 0) { 1469 #ifdef PPP_FILTER 1470 /* 1471 * See whether we want to pass this packet, and 1472 * if it counts as link activity. 1473 */ 1474 if (sc->sc_pass_filt_in.bf_insns != 0 1475 && bpf_filter(sc->sc_pass_filt_in.bf_insns, (u_char *) m, 1476 ilen, 0) == 0) { 1477 /* drop this packet */ 1478 m_freem(m); 1479 return; 1480 } 1481 if (sc->sc_active_filt_in.bf_insns == 0 1482 || bpf_filter(sc->sc_active_filt_in.bf_insns, (u_char *) m, 1483 ilen, 0)) 1484 sc->sc_last_recv = time.tv_sec; 1485 #else 1486 /* 1487 * Record the time that we received this packet. 1488 */ 1489 sc->sc_last_recv = time.tv_sec; 1490 #endif /* PPP_FILTER */ 1491 } 1492 1493 #if NBPFILTER > 0 1494 /* See if bpf wants to look at the packet. */ 1495 if (sc->sc_bpf) 1496 bpf_mtap(sc->sc_bpf, m); 1497 #endif 1498 1499 rv = 0; 1500 switch (proto) { 1501 #ifdef INET 1502 case PPP_IP: 1503 /* 1504 * IP packet - take off the ppp header and pass it up to IP. 1505 */ 1506 if ((ifp->if_flags & IFF_UP) == 0 1507 || sc->sc_npmode[NP_IP] != NPMODE_PASS) { 1508 /* interface is down - drop the packet. */ 1509 m_freem(m); 1510 return; 1511 } 1512 m->m_pkthdr.len -= PPP_HDRLEN; 1513 m->m_data += PPP_HDRLEN; 1514 m->m_len -= PPP_HDRLEN; 1515 #ifdef GATEWAY 1516 if (ipflow_fastforward(m)) 1517 return; 1518 #endif 1519 schednetisr(NETISR_IP); 1520 inq = &ipintrq; 1521 break; 1522 #endif 1523 1524 #ifdef INET6 1525 case PPP_IPV6: 1526 /* 1527 * IPv6 packet - take off the ppp header and pass it up to IPv6. 1528 */ 1529 if ((ifp->if_flags & IFF_UP) == 0 1530 || sc->sc_npmode[NP_IPV6] != NPMODE_PASS) { 1531 /* interface is down - drop the packet. */ 1532 m_freem(m); 1533 return; 1534 } 1535 m->m_pkthdr.len -= PPP_HDRLEN; 1536 m->m_data += PPP_HDRLEN; 1537 m->m_len -= PPP_HDRLEN; 1538 schednetisr(NETISR_IPV6); 1539 inq = &ip6intrq; 1540 break; 1541 #endif 1542 1543 default: 1544 /* 1545 * Some other protocol - place on input queue for read(). 1546 */ 1547 inq = &sc->sc_inq; 1548 rv = 1; 1549 break; 1550 } 1551 1552 /* 1553 * Put the packet on the appropriate input queue. 1554 */ 1555 s = splimp(); 1556 if (IF_QFULL(inq)) { 1557 IF_DROP(inq); 1558 splx(s); 1559 if (sc->sc_flags & SC_DEBUG) 1560 printf("%s: input queue full\n", ifp->if_xname); 1561 ifp->if_iqdrops++; 1562 goto bad; 1563 } 1564 IF_ENQUEUE(inq, m); 1565 splx(s); 1566 ifp->if_ipackets++; 1567 ifp->if_ibytes += ilen; 1568 ifp->if_lastchange = time; 1569 1570 if (rv) 1571 (*sc->sc_ctlp)(sc); 1572 1573 return; 1574 1575 bad: 1576 m_freem(m); 1577 sc->sc_if.if_ierrors++; 1578 sc->sc_stats.ppp_ierrors++; 1579 } 1580 1581 #define MAX_DUMP_BYTES 128 1582 1583 static void 1584 pppdumpm(m0) 1585 struct mbuf *m0; 1586 { 1587 char buf[3*MAX_DUMP_BYTES+4]; 1588 char *bp = buf; 1589 struct mbuf *m; 1590 static char digits[] = "0123456789abcdef"; 1591 1592 for (m = m0; m; m = m->m_next) { 1593 int l = m->m_len; 1594 u_char *rptr = (u_char *)m->m_data; 1595 1596 while (l--) { 1597 if (bp > buf + sizeof(buf) - 4) 1598 goto done; 1599 *bp++ = digits[*rptr >> 4]; /* convert byte to ascii hex */ 1600 *bp++ = digits[*rptr++ & 0xf]; 1601 } 1602 1603 if (m->m_next) { 1604 if (bp > buf + sizeof(buf) - 3) 1605 goto done; 1606 *bp++ = '|'; 1607 } else 1608 *bp++ = ' '; 1609 } 1610 done: 1611 if (m) 1612 *bp++ = '>'; 1613 *bp = 0; 1614 printf("%s\n", buf); 1615 } 1616 1617 #endif /* NPPP > 0 */ 1618