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