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