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