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