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