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