xref: /openbsd/sys/net/if_ppp.c (revision 803b30d2)
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