2 * if_ppp.c - Point-to-Point Protocol (PPP) Asynchronous driver.
4 * Copyright (c) 1989 Carnegie Mellon University.
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.
20 * Carnegie Mellon University
22 * Pittsburgh, PA 15213
27 * @(#)if_sl.c 7.6.1.2 (Berkeley) 2/15/89
29 * Copyright (c) 1987 Regents of the University of California.
30 * All rights reserved.
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.
44 * Serial Line interface
47 * Center for Seismic Studies
48 * 1300 N 17th Street, Suite 1450
49 * Arlington, Virginia 22209
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.
58 * Converted to 4.3BSD+ 386BSD by Brad Parker (brad@cayman.com)
59 * Added VJ tcp header compression; more unified ioctls
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.
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).
71 * Ultrix port by Per Sundstrom <sundstrom@stkhlm.enet.dec.com>,
72 * Robert Olsson <robert@robur.slu.se> and Paul Mackerras.
75 /* $Id: if_ppp.c,v 1.1 1994/11/21 04:50:03 paulus Exp $ */
76 /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
84 #include "../h/param.h"
85 #include "../h/user.h"
86 #include "../h/proc.h"
87 #include "../h/mbuf.h"
89 #include "../h/socket.h"
90 #include "../h/ioctl.h"
91 #include "../h/file.h"
93 #include "../h/kernel.h"
94 #include "../h/conf.h"
96 #include "../h/systm.h"
98 #include "../net/net/if.h"
99 #include "../net/net/netisr.h"
100 #include "../net/net/route.h"
102 #include "../net/netinet/in.h"
103 #include "../net/netinet/in_systm.h"
104 #include "../net/netinet/in_var.h"
105 #include "../net/netinet/ip.h"
109 #include "slcompress.h"
112 #include "ppp_defs.h"
114 #include "if_pppvar.h"
117 #define PACKET struct mbuf
118 #include "ppp-comp.h"
122 * This is an Ultrix kernel, we've got clists.
124 #define CCOUNT(q) ((q)->c_cc)
127 #define PPP_HIWAT 400 /* Don't start a new packet if HIWAT on que */
129 void pppattach __P((void));
130 int pppopen __P((dev_t dev, struct tty *tp));
131 int pppclose __P((struct tty *tp, int flag));
132 int pppread __P((struct tty *tp, struct uio *uio, int flag));
133 int pppwrite __P((struct tty *tp, struct uio *uio, int flag));
134 int ppptioctl __P((struct tty *tp, int cmd, caddr_t data, int flag,
136 int pppoutput __P((struct ifnet *ifp, struct mbuf *m0,
137 struct sockaddr *dst));
138 int pppinput __P((int c, struct tty *tp));
139 int pppioctl __P((struct ifnet *ifp, int cmd, caddr_t data));
140 int pppstart __P((struct tty *tp));
142 static void ppp_ccp_closed __P((struct ppp_softc *));
143 static int ppp_ccp __P((struct ppp_softc *, struct mbuf *m, int rcvd));
144 static int pppasyncstart __P((struct ppp_softc *));
145 static u_short pppfcs __P((u_short fcs, u_char *cp, int len));
146 static int pppgetm __P((struct ppp_softc *sc));
147 static void pppdumpm __P((struct mbuf *m0, int pktlen));
148 static void pppdumpb __P((u_char *b, int l));
149 static void ppplogchar __P((struct ppp_softc *, int));
152 * Some useful mbuf macros not in mbuf.h.
154 #define M_IS_CLUSTER(m) ((m)->m_off > MMAXOFF)
156 #define M_TRAILINGSPACE(m) \
157 ((M_IS_CLUSTER(m) ? (u_int)(m)->m_clptr + M_CLUSTERSZ : MSIZE) \
158 - ((m)->m_off + (m)->m_len))
160 #define M_OFFSTART(m) \
161 (M_IS_CLUSTER(m) ? (u_int)(m)->m_clptr : MMINOFF)
163 #define M_DATASIZE(m) \
164 (M_IS_CLUSTER(m) ? M_CLUSTERSZ : MLEN)
167 * The following disgusting hack gets around the problem that IP TOS
168 * can't be set yet. We want to put "interactive" traffic on a high
169 * priority queue. To decide if traffic is interactive, we check that
170 * a) it is TCP and b) one of its ports is telnet, rlogin or ftp control.
172 static u_short interactive_ports[8] = {
176 #define INTERACTIVE(p) (interactive_ports[(p) & 7] == (p))
179 * Does c need to be escaped?
181 #define ESCAPE_P(c) (sc->sc_asyncmap[(c) >> 5] & (1 << ((c) & 0x1F)))
185 * List of compressors we know about.
188 extern struct compressor ppp_bsd_compress;
190 struct compressor *ppp_compressors[] = {
194 #endif /* PPP_COMPRESS */
197 * Called from boot code to establish ppp interfaces.
202 register struct ppp_softc *sc;
205 for (sc = ppp_softc; i < NPPP; sc++) {
206 sc->sc_if.if_name = "ppp";
207 sc->sc_if.if_unit = i++;
208 sc->sc_if.if_mtu = PPP_MTU;
209 sc->sc_if.if_flags = IFF_POINTOPOINT;
210 sc->sc_if.if_type = IFT_PPP;
211 sc->sc_if.if_ioctl = pppioctl;
212 sc->sc_if.if_output = pppoutput;
213 sc->sc_if.if_snd.ifq_maxlen = IFQ_MAXLEN;
214 sc->sc_inq.ifq_maxlen = IFQ_MAXLEN;
215 sc->sc_fastq.ifq_maxlen = IFQ_MAXLEN;
216 if_attach(&sc->sc_if);
218 bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_PPP, PPP_HDRLEN);
224 * Allocate a ppp interface unit and initialize it.
231 struct ppp_softc *sc;
233 for (nppp = 0, sc = ppp_softc; nppp < NPPP; nppp++, sc++)
234 if (sc->sc_xfer == pid) {
239 for (nppp = 0, sc = ppp_softc; nppp < NPPP; nppp++, sc++)
240 if (sc->sc_devp == NULL)
246 sc->sc_mru = PPP_MRU;
248 sl_compress_init(&sc->sc_comp);
251 sc->sc_xc_state = NULL;
252 sc->sc_rc_state = NULL;
253 #endif /* PPP_COMPRESS */
254 for (i = 0; i < NUM_NP; ++i)
255 sc->sc_npmode[i] = NPMODE_ERROR;
256 sc->sc_if.if_flags |= IFF_RUNNING;
262 * Deallocate a ppp unit.
265 struct ppp_softc *sc;
270 sc->sc_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
274 IF_DEQUEUE(&sc->sc_inq, m);
280 IF_DEQUEUE(&sc->sc_fastq, m);
287 sc->sc_xc_state = NULL;
288 sc->sc_rc_state = NULL;
289 #endif /* PPP_COMPRESS */
293 * Line specific open routine for async tty devices.
294 * Attach the given tty to the first available ppp unit.
300 register struct tty *tp;
302 register struct ppp_softc *sc;
304 struct proc *p = u.u_procp;
309 if (tp->t_line == PPPDISC) {
310 sc = (struct ppp_softc *) tp->t_sc;
311 if (sc != NULL && sc->sc_devp == (void *) tp)
315 if ((sc = pppalloc(p->p_pid)) == NULL)
318 if (sc->sc_outm != NULL) {
319 m_freem(sc->sc_outm);
326 bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
327 sc->sc_asyncmap[0] = 0xffffffff;
328 sc->sc_asyncmap[3] = 0x60000000;
329 sc->sc_rasyncmap = 0;
330 sc->sc_devp = (void *) tp;
331 sc->sc_start = pppasyncstart;
333 tp->t_sc = (caddr_t) sc;
334 ttyflush(tp, FREAD | FWRITE);
340 * Line specific close routine.
341 * Detach the tty from the ppp unit.
342 * Mimics part of ttyclose().
349 register struct ppp_softc *sc;
354 s = splimp(); /* paranoid; splnet probably ok */
356 sc = (struct ppp_softc *)tp->t_sc;
359 if (tp == (struct tty *) sc->sc_devp) {
360 m_freem(sc->sc_outm);
372 * Line specific (tty) read routine.
375 pppread(tp, uio, flag)
376 register struct tty *tp;
380 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
385 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
386 return 0; /* end of file */
387 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
390 while (sc->sc_inq.ifq_head == NULL && tp->t_line == PPPDISC) {
391 if (tp->t_state & (TS_ASYNC | TS_NBIO)) {
393 return (EWOULDBLOCK);
395 sleep((caddr_t) &tp->t_rawq, TTIPRI);
397 if (tp->t_line != PPPDISC) {
402 /* Pull place-holder byte out of canonical queue */
405 /* Get the packet from the input queue */
406 IF_DEQUEUE(&sc->sc_inq, m0);
409 for (m = m0; m && uio->uio_resid; m = m->m_next)
410 if (error = uiomove(mtod(m, u_char *), m->m_len, UIO_READ, uio))
417 * Line specific (tty) write routine.
420 pppwrite(tp, uio, flag)
421 register struct tty *tp;
425 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
426 struct mbuf *m, *m0, **mp, *p;
430 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
431 return 0; /* wrote 0 bytes */
432 if (tp->t_line != PPPDISC)
434 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
436 if (uio->uio_resid > sc->sc_if.if_mtu + PPP_HDRLEN ||
437 uio->uio_resid < PPP_HDRLEN)
439 for (mp = &m0; uio->uio_resid; mp = &m->m_next) {
440 MGET(m, M_WAIT, MT_DATA);
441 if ((*mp = m) == NULL) {
445 if (uio->uio_resid >= CLBYTES / 2) {
449 len = MIN(m->m_len, uio->uio_resid);
450 if (error = uiomove(mtod(m, u_char *), len, UIO_WRITE, uio)) {
456 dst.sa_family = AF_UNSPEC;
457 bcopy(mtod(m0, u_char *), dst.sa_data, PPP_HDRLEN);
458 m0->m_off += PPP_HDRLEN;
459 m0->m_len -= PPP_HDRLEN;
460 return (pppoutput(&sc->sc_if, m0, &dst));
464 * Line specific (tty) ioctl routine.
465 * Provide a way to get the ppp unit number.
466 * This discipline requires that tty device drivers call
467 * the line specific l_ioctl routine from their ioctl routines.
471 ppptioctl(tp, cmd, data, flag)
476 register struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
477 struct proc *p = u.u_procp;
478 int s, error, flags, mru, nb, npx;
479 struct ppp_option_data *odp;
480 struct compressor **cp;
482 u_char ccp_option[CCP_MAX_OPTION_LENGTH];
484 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
489 *(int *)data = sc->sc_inq.ifq_len;
493 *(int *)data = sc->sc_if.if_unit;
497 *(u_int *)data = sc->sc_flags;
503 flags = *(int *)data & SC_MASK;
505 if (sc->sc_flags & SC_CCP_OPEN && !(flags & SC_CCP_OPEN))
507 sc->sc_flags = (sc->sc_flags & ~SC_MASK) | flags;
511 case PPPIOCSASYNCMAP:
514 sc->sc_asyncmap[0] = *(u_int *)data;
517 case PPPIOCGASYNCMAP:
518 *(u_int *)data = sc->sc_asyncmap[0];
521 case PPPIOCSRASYNCMAP:
524 sc->sc_rasyncmap = *(u_int *)data;
527 case PPPIOCGRASYNCMAP:
528 *(u_int *)data = sc->sc_rasyncmap;
531 case PPPIOCSXASYNCMAP:
534 bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
535 sc->sc_asyncmap[1] = 0; /* mustn't escape 0x20 - 0x3f */
536 sc->sc_asyncmap[2] &= ~0x40000000; /* mustn't escape 0x5e */
537 sc->sc_asyncmap[3] |= 0x60000000; /* must escape 0x7d, 0x7e */
540 case PPPIOCGXASYNCMAP:
541 bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));
548 if (mru >= PPP_MRU && mru <= PPP_MAXMRU) {
555 *(int *)data = sc->sc_mru;
562 sl_compress_setup(&sc->sc_comp, *(int *)data);
569 sc->sc_xfer = p->p_pid;
573 case PPPIOCSCOMPRESS:
576 odp = (struct ppp_option_data *) data;
578 if (nb > sizeof(ccp_option))
579 nb = sizeof(ccp_option);
580 if (error = copyin(odp->ptr, ccp_option, nb))
582 if (ccp_option[1] < 2) /* preliminary check on the length byte */
584 for (cp = ppp_compressors; *cp != NULL; ++cp)
585 if ((*cp)->compress_proto == ccp_option[0]) {
587 * Found a handler for the protocol - try to allocate
588 * a compressor or decompressor.
593 if (sc->sc_xc_state != NULL)
594 (*sc->sc_xcomp->comp_free)(sc->sc_xc_state);
596 sc->sc_xc_state = (*cp)->comp_alloc(ccp_option, nb);
597 if (sc->sc_xc_state == NULL) {
598 if (sc->sc_flags & SC_DEBUG)
599 printf("ppp%d: comp_alloc failed\n",
603 sc->sc_flags &= ~SC_COMP_RUN;
605 if (sc->sc_rc_state != NULL)
606 (*sc->sc_rcomp->decomp_free)(sc->sc_rc_state);
608 sc->sc_rc_state = (*cp)->decomp_alloc(ccp_option, nb);
609 if (sc->sc_rc_state == NULL) {
610 if (sc->sc_flags & SC_DEBUG)
611 printf("ppp%d: decomp_alloc failed\n",
615 sc->sc_flags &= ~SC_DECOMP_RUN;
620 if (sc->sc_flags & SC_DEBUG)
621 printf("ppp%d: no compressor for [%x %x %x], %x\n",
622 sc->sc_if.if_unit, ccp_option[0], ccp_option[1],
624 return (EINVAL); /* no handler found */
625 #endif /* PPP_COMPRESS */
629 npi = (struct npioctl *) data;
630 switch (npi->protocol) {
637 if (cmd == PPPIOCGNPMODE) {
638 npi->mode = sc->sc_npmode[npx];
642 if (npi->mode != sc->sc_npmode[npx]) {
644 sc->sc_npmode[npx] = npi->mode;
645 if (npi->mode != NPMODE_QUEUE)
659 * FCS lookup table as calculated by genfcstab.
661 static u_short fcstab[256] = {
662 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
663 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
664 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
665 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
666 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
667 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
668 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
669 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
670 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
671 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
672 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
673 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
674 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
675 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
676 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
677 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
678 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
679 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
680 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
681 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
682 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
683 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
684 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
685 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
686 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
687 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
688 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
689 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
690 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
691 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
692 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
693 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
697 * Calculate a new FCS given the current FCS and the new data.
701 register u_short fcs;
706 fcs = PPP_FCS(fcs, *cp++);
711 * Queue a packet. Start transmission if not active.
712 * Packet is placed in Information field of PPP frame.
715 pppoutput(ifp, m0, dst)
718 struct sockaddr *dst;
720 register struct ppp_softc *sc = &ppp_softc[ifp->if_unit];
721 struct ppp_header *ph;
722 int protocol, address, control;
729 if (sc->sc_devp == NULL || (ifp->if_flags & IFF_RUNNING) == 0
730 || (ifp->if_flags & IFF_UP) == 0 && dst->sa_family != AF_UNSPEC) {
731 error = ENETDOWN; /* sort of */
736 * Compute PPP header.
739 switch (dst->sa_family) {
742 address = PPP_ALLSTATIONS;
745 mode = sc->sc_npmode[NP_IP];
748 * If this is a TCP packet to or from an "interactive" port,
749 * put the packet on the fastq instead.
751 if ((ip = mtod(m0, struct ip *))->ip_p == IPPROTO_TCP) {
752 register int p = ntohl(((int *)ip)[ip->ip_hl]);
753 if (INTERACTIVE(p & 0xffff) || INTERACTIVE(p >> 16))
759 address = PPP_ADDRESS(dst->sa_data);
760 control = PPP_CONTROL(dst->sa_data);
761 protocol = PPP_PROTOCOL(dst->sa_data);
765 printf("ppp%d: af%d not supported\n", ifp->if_unit, dst->sa_family);
766 error = EAFNOSUPPORT;
771 * Drop this packet, or return an error, if necessary.
773 if (mode == NPMODE_ERROR) {
777 if (mode == NPMODE_DROP) {
783 * Add PPP header. If no space in first mbuf, allocate another.
785 if (M_IS_CLUSTER(m0) || m0->m_off < MMINOFF + PPP_HDRLEN) {
788 MGET(m, M_DONTWAIT, MT_DATA);
797 m0->m_off -= PPP_HDRLEN;
799 cp = mtod(m0, u_char *);
802 *cp++ = protocol >> 8;
803 *cp++ = protocol & 0xff;
804 m0->m_len += PPP_HDRLEN;
806 if (sc->sc_flags & SC_LOG_OUTPKT) {
807 printf("ppp%d output: ", ifp->if_unit);
813 * See if bpf wants to look at the packet.
816 bpf_mtap(sc->sc_bpf, m0);
820 * Put the packet on the appropriate queue.
826 sc->sc_if.if_oerrors++;
833 * Tell the device to send it out.
835 if (mode == NPMODE_PASS)
847 * Grab another packet off a queue and apply VJ compression,
848 * packet compression, address/control and/or protocol compression
853 struct ppp_softc *sc;
856 struct mbuf *m, *mp, **mpp;
858 int address, control, protocol;
865 * Scan through the send queues looking for a packet
866 * which can be sent: first the fast queue, then the normal queue.
870 mpp = &ifq->ifq_head;
872 while ((m = *mpp) != NULL) {
873 switch (PPP_PROTOCOL(mtod(m, u_char *))) {
875 mode = sc->sc_npmode[NP_IP];
880 if (mode == NPMODE_PASS)
897 if (ifq == &sc->sc_if.if_snd)
899 /* Finished the fast queue; do the normal queue. */
900 ifq = &sc->sc_if.if_snd;
908 if ((*mpp = m->m_nextpkt) == NULL)
916 * Extract the ppp header of the new packet.
917 * The ppp header will be in one mbuf.
919 cp = mtod(m, u_char *);
920 address = PPP_ADDRESS(cp);
921 control = PPP_CONTROL(cp);
922 protocol = PPP_PROTOCOL(cp);
928 * If the packet is a TCP/IP packet, see if we can compress it.
930 if (sc->sc_flags & SC_COMP_TCP) {
935 ip = (struct ip *) (cp + PPP_HDRLEN);
936 if (mp->m_len <= PPP_HDRLEN) {
940 ip = mtod(mp, struct ip *);
942 /* this code assumes the IP/TCP header is in one non-shared mbuf */
943 if (ip->ip_p == IPPROTO_TCP) {
944 type = sl_compress_tcp(mp, ip, &sc->sc_comp,
945 !(sc->sc_flags & SC_NO_TCP_CCID));
947 case TYPE_UNCOMPRESSED_TCP:
948 protocol = PPP_VJC_UNCOMP;
950 case TYPE_COMPRESSED_TCP:
951 protocol = PPP_VJC_COMP;
952 cp = mtod(m, u_char *);
953 cp[0] = address; /* header has moved */
958 cp[3] = protocol; /* update protocol in PPP header */
968 #endif /* PPP_COMPRESS */
972 if (protocol != PPP_LCP && protocol != PPP_CCP
973 && sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN)) {
978 for (mp = m; mp != NULL; mp = mp->m_next)
980 clen = (*sc->sc_xcomp->compress)
981 (sc->sc_xc_state, &mcomp, m, slen,
982 (sc->sc_flags & SC_CCP_UP? sc->sc_if.if_mtu: 0));
986 cp = mtod(m, u_char *);
990 #endif /* PPP_COMPRESS */
993 * Compress the address/control and protocol, if possible.
995 if (sc->sc_flags & SC_COMP_AC && address == PPP_ALLSTATIONS &&
996 control == PPP_UI && protocol != PPP_ALLSTATIONS &&
997 protocol != PPP_LCP) {
998 /* can compress address/control */
1002 if (sc->sc_flags & SC_COMP_PROT && protocol < 0xFF) {
1003 /* can compress protocol */
1004 if (mtod(m, u_char *) == cp) {
1005 cp[2] = cp[1]; /* move address/control up */
1017 * Handle a CCP packet. `rcvd' is 1 if the packet was received,
1018 * 0 if it is about to be transmitted.
1021 ppp_ccp(sc, m, rcvd)
1022 struct ppp_softc *sc;
1032 * Get a pointer to the data after the PPP header.
1034 if (m->m_len <= PPP_HDRLEN) {
1038 dp = (mp != NULL)? mtod(mp, u_char *): NULL;
1041 dp = mtod(mp, u_char *) + PPP_HDRLEN;
1044 ep = mtod(mp, u_char *) + mp->m_len;
1045 if (dp + CCP_HDRLEN > ep)
1047 slen = CCP_LENGTH(dp);
1048 if (dp + slen > ep) {
1049 if (sc->sc_flags & SC_DEBUG)
1050 printf("if_ppp/ccp: not enough data in mbuf (%x+%x > %x+%x)\n",
1051 dp, slen, mtod(mp, u_char *), mp->m_len);
1055 switch (CCP_CODE(dp)) {
1059 /* CCP must be going down - disable compression */
1060 if (sc->sc_flags & SC_CCP_UP)
1061 sc->sc_flags &= ~(SC_CCP_UP | SC_COMP_RUN | SC_DECOMP_RUN);
1065 if (sc->sc_flags & SC_CCP_OPEN && !(sc->sc_flags & SC_CCP_UP)
1066 && slen >= CCP_HDRLEN + CCP_OPT_MINLEN
1067 && slen >= CCP_OPT_LENGTH(dp + CCP_HDRLEN) + CCP_HDRLEN) {
1069 /* we're agreeing to send compressed packets. */
1070 if (sc->sc_xc_state != NULL
1071 && (*sc->sc_xcomp->comp_init)
1072 (sc->sc_xc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN,
1073 sc->sc_if.if_unit, sc->sc_flags & SC_DEBUG)) {
1074 sc->sc_flags |= SC_COMP_RUN;
1077 /* peer is agreeing to send compressed packets. */
1078 if (sc->sc_rc_state != NULL
1079 && (*sc->sc_rcomp->decomp_init)
1080 (sc->sc_rc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN,
1081 sc->sc_if.if_unit, sc->sc_mru,
1082 sc->sc_flags & SC_DEBUG)) {
1083 sc->sc_flags |= SC_DECOMP_RUN;
1084 sc->sc_flags &= ~(SC_DC_ERROR | SC_DC_FERROR);
1091 if (sc->sc_flags & SC_CCP_UP) {
1093 if (sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN))
1094 (*sc->sc_xcomp->comp_reset)(sc->sc_xc_state);
1096 if (sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN)) {
1097 (*sc->sc_rcomp->decomp_reset)(sc->sc_rc_state);
1098 sc->sc_flags &= ~SC_DC_ERROR;
1107 * CCP is down; free (de)compressor state if necessary.
1111 struct ppp_softc *sc;
1113 if (sc->sc_xc_state) {
1114 (*sc->sc_xcomp->comp_free)(sc->sc_xc_state);
1115 sc->sc_xc_state = NULL;
1117 if (sc->sc_rc_state) {
1118 (*sc->sc_rcomp->decomp_free)(sc->sc_rc_state);
1119 sc->sc_rc_state = NULL;
1122 #endif /* PPP_COMRPESS */
1125 * This gets called from pppoutput when a new packet is
1130 register struct ppp_softc *sc;
1132 register struct tty *tp = (struct tty *) sc->sc_devp;
1138 * Start output on async tty interface. Get another datagram
1139 * to send from the interface queue and start sending it.
1143 register struct tty *tp;
1145 register struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
1146 register struct mbuf *m;
1148 register u_char *start, *stop, *cp;
1149 int n, s, ndone, done;
1152 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0) {
1153 /* sorry, I can't talk now */
1156 if (sc == NULL || tp != (struct tty *) sc->sc_devp) {
1163 * If there is more in the output queue, just send it now.
1164 * We are being called in lieu of ttstart and must do what
1167 if (CCOUNT(&tp->t_outq) != 0 && tp->t_oproc != NULL) {
1169 if (CCOUNT(&tp->t_outq) > PPP_HIWAT)
1174 * See if we have an existing packet partly sent.
1175 * If not, get a new packet and start sending it.
1180 * Get another packet to be sent.
1182 m = ppp_dequeue(sc);
1187 * The extra PPP_FLAG will start up a new packet, and thus
1188 * will flush any accumulated garbage. We do this whenever
1189 * the line may have been idle for some time.
1191 if (CCOUNT(&tp->t_outq) == 0) {
1193 (void) putc(PPP_FLAG, &tp->t_outq);
1196 /* Calculate the FCS for the first mbuf's worth. */
1197 sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);
1201 start = mtod(m, u_char *);
1206 * Find out how many bytes in the string we can
1207 * handle without doing something special.
1209 for (cp = start; cp < stop; cp++)
1214 ndone = n - b_to_q(start, n, &tp->t_outq);
1217 sc->sc_bytessent += ndone;
1220 break; /* packet doesn't fit */
1223 * If there are characters left in the mbuf,
1224 * the first one must be special..
1225 * Put it out in a different form.
1228 if (putc(PPP_ESCAPE, &tp->t_outq))
1230 if (putc(*start ^ PPP_TRANS, &tp->t_outq)) {
1231 (void) unputc(&tp->t_outq);
1234 sc->sc_bytessent += 2;
1240 * If we didn't empty this mbuf, remember where we're up to.
1241 * If we emptied the last mbuf, try to add the FCS and closing
1242 * flag, and if we can't, leave sc_outm pointing to m, but with
1243 * m->m_len == 0, to remind us to output the FCS and flag later.
1246 if (done && m->m_next == NULL) {
1252 * We may have to escape the bytes in the FCS.
1255 c = ~sc->sc_outfcs & 0xFF;
1258 *p++ = c ^ PPP_TRANS;
1261 c = (~sc->sc_outfcs >> 8) & 0xFF;
1264 *p++ = c ^ PPP_TRANS;
1270 * Try to output the FCS and flag. If the bytes
1271 * don't all fit, back out.
1273 for (q = endseq; q < p; ++q)
1274 if (putc(*q, &tp->t_outq)) {
1276 for (; q > endseq; --q)
1277 unputc(&tp->t_outq);
1283 m->m_off += m->m_len - len;
1286 if (tp->t_oproc != NULL)
1288 return; /* can't do any more at the moment */
1291 /* Finished with this mbuf; free it and move on. */
1297 sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
1300 /* Finished a packet */
1302 sc->sc_bytessent++; /* account for closing flag */
1303 sc->sc_if.if_opackets++;
1308 * Allocate enough mbuf to handle current MRU.
1312 register struct ppp_softc *sc;
1314 struct mbuf *m, **mp, *p;
1320 for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
1321 if ((m = *mp) == NULL) {
1322 MGET(m, M_DONTWAIT, MT_DATA);
1328 len -= M_DATASIZE(m);
1336 * PPP packet input routine.
1337 * The caller has checked and removed the FCS and has inserted
1338 * the address/control bytes and the protocol high byte if they
1339 * were omitted. The return value is 1 if the packet was put on
1340 * sc->sc_inq, 0 otherwise.
1342 #define COMPTYPE(proto) ((proto) == PPP_VJC_COMP? TYPE_COMPRESSED_TCP: \
1343 TYPE_UNCOMPRESSED_TCP)
1347 struct ppp_softc *sc;
1350 struct ifqueue *inq, *lock;
1351 int s, ilen, xlen, proto, rv;
1352 u_char *cp, adrs, ctrl;
1353 struct mbuf *mp, *dmp, *pc;
1357 sc->sc_if.if_ipackets++;
1360 cp = mtod(m, u_char *);
1361 adrs = PPP_ADDRESS(cp);
1362 ctrl = PPP_CONTROL(cp);
1363 proto = PPP_PROTOCOL(cp);
1367 * Decompress this packet if necessary, update the receiver's
1368 * dictionary, or take appropriate action on a CCP packet.
1370 if (proto == PPP_COMP && sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN)
1371 && !(sc->sc_flags & SC_DC_ERROR) && !(sc->sc_flags & SC_DC_FERROR)) {
1372 /* decompress this packet */
1373 rv = (*sc->sc_rcomp->decompress)(sc->sc_rc_state, m, &dmp);
1377 cp = mtod(m, u_char *);
1378 proto = PPP_PROTOCOL(cp);
1381 /* pass the compressed packet up to pppd, which may take
1382 CCP down or issue a Reset-Req. */
1383 if (sc->sc_flags & SC_DEBUG)
1384 printf("ppp%d: decompress failed %d\n", sc->sc_if.if_unit, rv);
1385 sc->sc_flags |= SC_VJ_RESET;
1388 /* no error, but no decompressed packet produced */
1392 sc->sc_flags |= SC_DC_ERROR;
1394 case DECOMP_FATALERROR:
1395 sc->sc_flags |= SC_DC_FERROR;
1401 if (sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN)) {
1402 (*sc->sc_rcomp->incomp)(sc->sc_rc_state, m);
1404 if (proto == PPP_CCP) {
1411 for (mp = m; mp != NULL; mp = mp->m_next)
1416 * If we've missed a packet, we must toss subsequent compressed
1417 * packets which don't have an explicit connection ID.
1419 if (sc->sc_flags & SC_VJ_RESET) {
1420 sl_uncompress_tcp(NULL, 0, TYPE_ERROR, &sc->sc_comp);
1421 sc->sc_flags &= ~SC_VJ_RESET;
1425 * See if we have a VJ-compressed packet to uncompress.
1427 if (proto == PPP_VJC_COMP) {
1428 if (sc->sc_flags & SC_REJ_COMP_TCP)
1431 xlen = sl_uncompress_tcp_core(cp + PPP_HDRLEN, m->m_len - PPP_HDRLEN,
1432 ilen - PPP_HDRLEN, TYPE_COMPRESSED_TCP,
1433 &sc->sc_comp, &iphdr, &hlen);
1436 if (sc->sc_flags & SC_DEBUG)
1437 printf("ppp%d: VJ uncompress failed on type comp\n",
1442 /* Copy the PPP and IP headers into a new mbuf. */
1443 MGET(mp, M_DONTWAIT, MT_DATA);
1448 if (hlen + PPP_HDRLEN > MHLEN) {
1450 if (M_TRAILINGSPACE(mp) < hlen + PPP_HDRLEN) {
1452 goto bad; /* lose if big headers and no clusters */
1455 cp = mtod(mp, u_char *);
1461 bcopy(iphdr, cp + PPP_HDRLEN, hlen);
1462 mp->m_len = hlen + PPP_HDRLEN;
1465 * Trim the PPP and VJ headers off the old mbuf
1466 * and stick the new and old mbufs together.
1468 m->m_off += PPP_HDRLEN + xlen;
1469 m->m_len -= PPP_HDRLEN + xlen;
1470 if (m->m_len <= M_TRAILINGSPACE(mp)) {
1471 bcopy(mtod(m, u_char *), mtod(mp, u_char *) + mp->m_len, m->m_len);
1472 mp->m_len += m->m_len;
1473 MFREE(m, mp->m_next);
1477 ilen += hlen - xlen;
1479 } else if (proto == PPP_VJC_UNCOMP) {
1480 if (sc->sc_flags & SC_REJ_COMP_TCP)
1483 xlen = sl_uncompress_tcp_core(cp + PPP_HDRLEN, m->m_len - PPP_HDRLEN,
1484 ilen - PPP_HDRLEN, TYPE_UNCOMPRESSED_TCP,
1485 &sc->sc_comp, &iphdr, &hlen);
1488 if (sc->sc_flags & SC_DEBUG)
1489 printf("ppp%d: VJ uncompress failed on type uncomp\n",
1500 * If the packet will fit in an ordinary mbuf, don't waste a
1501 * whole cluster on it.
1503 if (ilen <= MLEN && M_IS_CLUSTER(m)) {
1504 MGET(mp, M_DONTWAIT, MT_DATA);
1506 m_copydata(m, 0, ilen, mtod(mp, caddr_t));
1514 /* See if bpf wants to look at the packet. */
1516 bpf_mtap(sc->sc_bpf, m);
1523 * IP packet - take off the ppp header and pass it up to IP.
1525 if ((sc->sc_if.if_flags & IFF_UP) == 0
1526 || sc->sc_npmode[NP_IP] != NPMODE_PASS) {
1527 /* interface is down - drop the packet. */
1531 m->m_off += PPP_HDRLEN;
1532 m->m_len -= PPP_HDRLEN;
1533 schednetisr(NETISR_IP);
1540 * Some other protocol - place on input queue for read().
1548 * Put the packet on the appropriate input queue.
1552 smp_lock(&lock->lk_ifqueue, LK_RETRY);
1553 if (IF_QFULL(inq)) {
1555 /* XXX should we unlock here? */
1556 if (sc->sc_flags & SC_DEBUG)
1557 printf("ppp%d: queue full\n", sc->sc_if.if_unit);
1558 sc->sc_if.if_ierrors++;
1562 IF_ENQUEUEIF(inq, m, &sc->sc_if);
1563 smp_unlock(&lock->lk_ifqueue);
1571 sc->sc_if.if_ierrors++;
1576 * tty interface receiver interrupt.
1578 static unsigned paritytab[8] = {
1579 0x96696996, 0x69969669, 0x69969669, 0x96696996,
1580 0x69969669, 0x96696996, 0x96696996, 0x69969669
1586 register struct tty *tp;
1588 register struct ppp_softc *sc;
1593 sc = (struct ppp_softc *) tp->t_sc;
1594 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
1602 sc->sc_flags |= SC_RCV_B7_1;
1604 sc->sc_flags |= SC_RCV_B7_0;
1605 if (paritytab[c >> 5] & (1 << (c & 0x1F)))
1606 sc->sc_flags |= SC_RCV_ODDP;
1608 sc->sc_flags |= SC_RCV_EVNP;
1610 if (sc->sc_flags & SC_LOG_RAWIN)
1613 if (c == PPP_FLAG) {
1617 if (sc->sc_rawin_count > 0)
1621 * If SC_ESCAPED is set, then we've seen the packet
1622 * abort sequence "}~".
1624 if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
1625 || ilen > 0 && sc->sc_fcs != PPP_GOODFCS) {
1626 sc->sc_flags |= SC_VJ_RESET;
1627 if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
1628 if (sc->sc_flags & SC_DEBUG)
1629 printf("ppp%d: bad fcs %x\n", sc->sc_if.if_unit,
1631 sc->sc_if.if_ierrors++;
1633 sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
1637 if (ilen < PPP_HDRLEN + PPP_FCSLEN) {
1639 if (sc->sc_flags & SC_DEBUG)
1640 printf("ppp%d: too short (%d)\n", sc->sc_if.if_unit, ilen);
1641 sc->sc_if.if_ierrors++;
1647 * Remove FCS trailer. Somewhat painful...
1650 if (--sc->sc_mc->m_len == 0) {
1651 for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next)
1657 /* excise this mbuf chain */
1659 sc->sc_m = sc->sc_mc->m_next;
1660 sc->sc_mc->m_next = NULL;
1662 if (sc->sc_flags & SC_LOG_INPKT) {
1663 printf("ppp%d: got %d bytes\n", sc->sc_if.if_unit, ilen);
1667 if (ppppktin(sc, m)) {
1668 /* Put a placeholder byte in canq for ttselect()/ttnread(). */
1669 putc(0, &tp->t_canq);
1677 if (sc->sc_flags & SC_FLUSH) {
1678 if (sc->sc_flags & SC_LOG_FLUSH)
1683 if (c < 0x20 && (sc->sc_rasyncmap & (1 << c)))
1686 if (sc->sc_flags & SC_ESCAPED) {
1687 sc->sc_flags &= ~SC_ESCAPED;
1689 } else if (c == PPP_ESCAPE) {
1690 sc->sc_flags |= SC_ESCAPED;
1695 * Initialize buffer on first octet received.
1696 * First octet could be address or protocol (when compressing
1698 * Second octet is control.
1699 * Third octet is first or second (when compressing protocol)
1700 * octet of protocol.
1701 * Fourth octet is second octet of protocol.
1703 if (sc->sc_ilen == 0) {
1704 /* reset the first input mbuf */
1705 if (sc->sc_m == NULL) {
1707 if (sc->sc_m == NULL) {
1708 if (sc->sc_flags & SC_DEBUG)
1709 printf("ppp%d: no input mbufs!\n", sc->sc_if.if_unit);
1715 m->m_off = M_OFFSTART(m);
1717 sc->sc_mp = mtod(m, char *);
1718 sc->sc_fcs = PPP_INITFCS;
1719 if (c != PPP_ALLSTATIONS) {
1720 if (sc->sc_flags & SC_REJ_COMP_AC) {
1721 if (sc->sc_flags & SC_DEBUG)
1722 printf("ppp%d: garbage received: 0x%x (need 0xFF)\n",
1723 sc->sc_if.if_unit, c);
1726 *sc->sc_mp++ = PPP_ALLSTATIONS;
1727 *sc->sc_mp++ = PPP_UI;
1732 if (sc->sc_ilen == 1 && c != PPP_UI) {
1733 if (sc->sc_flags & SC_DEBUG)
1734 printf("ppp%d: missing UI (0x3), got 0x%x\n",
1735 sc->sc_if.if_unit, c);
1738 if (sc->sc_ilen == 2 && (c & 1) == 1) {
1739 /* a compressed protocol */
1744 if (sc->sc_ilen == 3 && (c & 1) == 0) {
1745 if (sc->sc_flags & SC_DEBUG)
1746 printf("ppp%d: bad protocol %x\n", sc->sc_if.if_unit,
1747 (sc->sc_mp[-1] << 8) + c);
1751 /* packet beyond configured mru? */
1752 if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) {
1753 if (sc->sc_flags & SC_DEBUG)
1754 printf("ppp%d: packet too big\n", sc->sc_if.if_unit);
1758 /* is this mbuf full? */
1760 if (M_TRAILINGSPACE(m) <= 0) {
1761 if (m->m_next == NULL) {
1763 if (m->m_next == NULL) {
1764 if (sc->sc_flags & SC_DEBUG)
1765 printf("ppp%d: too few input mbufs!\n", sc->sc_if.if_unit);
1769 sc->sc_mc = m = m->m_next;
1771 m->m_off = M_OFFSTART(m);
1772 sc->sc_mp = mtod(m, char *);
1777 sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);
1781 if (!(sc->sc_flags & SC_FLUSH)) {
1782 sc->sc_if.if_ierrors++;
1783 sc->sc_flags |= SC_FLUSH;
1784 if (sc->sc_flags & SC_LOG_FLUSH)
1790 * Process an ioctl request to interface.
1793 pppioctl(ifp, cmd, data)
1794 register struct ifnet *ifp;
1798 struct proc *p = u.u_procp;
1799 register struct ppp_softc *sc = &ppp_softc[ifp->if_unit];
1800 register struct ifaddr *ifa = (struct ifaddr *)data;
1801 register struct ifreq *ifr = (struct ifreq *)data;
1802 struct ppp_stats *psp;
1803 int s = splimp(), error = 0;
1807 if ((ifp->if_flags & IFF_RUNNING) == 0)
1808 ifp->if_flags &= ~IFF_UP;
1812 if (ifa->ifa_addr.sa_family != AF_INET)
1813 error = EAFNOSUPPORT;
1816 case SIOCSIFDSTADDR:
1817 if (ifa->ifa_addr.sa_family != AF_INET)
1818 error = EAFNOSUPPORT;
1824 sc->sc_if.if_mtu = ifr->ifr_mtu;
1828 ifr->ifr_mtu = sc->sc_if.if_mtu;
1832 psp = &((struct ifpppstatsreq *) data)->stats;
1833 bzero(psp, sizeof(*psp));
1834 psp->p.ppp_ibytes = sc->sc_bytesrcvd;
1835 psp->p.ppp_ipackets = ifp->if_ipackets;
1836 psp->p.ppp_ierrors = ifp->if_ierrors;
1837 psp->p.ppp_obytes = sc->sc_bytessent;
1838 psp->p.ppp_opackets = ifp->if_opackets;
1839 psp->p.ppp_oerrors = ifp->if_oerrors;
1841 psp->vj.vjs_packets = sc->sc_comp.sls_packets;
1842 psp->vj.vjs_compressed = sc->sc_comp.sls_compressed;
1843 psp->vj.vjs_searches = sc->sc_comp.sls_searches;
1844 psp->vj.vjs_misses = sc->sc_comp.sls_misses;
1845 psp->vj.vjs_uncompressedin = sc->sc_comp.sls_uncompressedin;
1846 psp->vj.vjs_compressedin = sc->sc_comp.sls_compressedin;
1847 psp->vj.vjs_errorin = sc->sc_comp.sls_errorin;
1848 psp->vj.vjs_tossed = sc->sc_comp.sls_tossed;
1851 if (sc->sc_xc_state != NULL)
1852 (*sc->sc_xcomp->comp_stat)(sc->sc_xc_state, &psp->c);
1853 if (sc->sc_rc_state != NULL)
1854 (*sc->sc_rcomp->decomp_stat)(sc->sc_rc_state, &psp->d);
1855 #endif /* PPP_COMPRESS */
1865 #define MAX_DUMP_BYTES 128
1868 pppdumpm(m0, pktlen)
1872 char buf[3*MAX_DUMP_BYTES+4];
1875 static char digits[] = "0123456789abcdef";
1877 for (m = m0; m && pktlen; m = m->m_next) {
1879 u_char *rptr = mtod(m, u_char *);
1887 if (bp > buf + sizeof(buf) - 4)
1889 *bp++ = digits[*rptr >> 4]; /* convert byte to ascii hex */
1890 *bp++ = digits[*rptr++ & 0xf];
1894 if (bp > buf + sizeof(buf) - 3)
1904 printf("%s\n", buf);
1909 struct ppp_softc *sc;
1913 sc->sc_rawin[sc->sc_rawin_count++] = c;
1914 if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
1915 || c < 0 && sc->sc_rawin_count > 0) {
1916 printf("ppp%d input: ", sc->sc_if.if_unit);
1917 pppdumpb(sc->sc_rawin, sc->sc_rawin_count);
1918 sc->sc_rawin_count = 0;
1927 char buf[3*MAX_DUMP_BYTES+4];
1929 static char digits[] = "0123456789abcdef";
1932 if (bp >= buf + sizeof(buf) - 3) {
1936 *bp++ = digits[*b >> 4]; /* convert byte to ascii hex */
1937 *bp++ = digits[*b++ & 0xf];
1942 printf("%s\n", buf);
1945 #endif /* NPPP > 0 */