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