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