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