2 * ppp_tty.c - Point-to-Point Protocol (PPP) driver for asynchronous
5 * Copyright (c) 1989 Carnegie Mellon University.
8 * Redistribution and use in source and binary forms are permitted
9 * provided that the above copyright notice and this paragraph are
10 * duplicated in all such forms and that any documentation,
11 * advertising materials, and other materials related to such
12 * distribution and use acknowledge that the software was developed
13 * by Carnegie Mellon University. The name of the
14 * University may not be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 * Carnegie Mellon University
23 * Pittsburgh, PA 15213
28 * @(#)if_sl.c 7.6.1.2 (Berkeley) 2/15/89
30 * Copyright (c) 1987 Regents of the University of California.
31 * All rights reserved.
33 * Redistribution and use in source and binary forms are permitted
34 * provided that the above copyright notice and this paragraph are
35 * duplicated in all such forms and that any documentation,
36 * advertising materials, and other materials related to such
37 * distribution and use acknowledge that the software was developed
38 * by the University of California, Berkeley. The name of the
39 * University may not be used to endorse or promote products derived
40 * from this software without specific prior written permission.
41 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
42 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
43 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
45 * Serial Line interface
48 * Center for Seismic Studies
49 * 1300 N 17th Street, Suite 1450
50 * Arlington, Virginia 22209
55 * Pounded on heavily by Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris).
56 * Converted to 4.3BSD Beta by Chris Torek.
57 * Other changes made at Berkeley, based in part on code by Kirk Smith.
59 * Converted to 4.3BSD+ 386BSD by Brad Parker (brad@cayman.com)
60 * Added VJ tcp header compression; more unified ioctls
62 * Extensively modified by Paul Mackerras (paulus@cs.anu.edu.au).
63 * Cleaned up a lot of the mbuf-related code to fix bugs that
64 * caused system crashes and packet corruption. Changed pppstart
65 * so that it doesn't just give up with a collision if the whole
66 * packet doesn't fit in the output ring buffer.
68 * Added priority queueing for interactive IP packets, following
69 * the model of if_sl.c, plus hooks for bpf.
70 * Paul Mackerras (paulus@cs.anu.edu.au).
72 * Ultrix port by Per Sundstrom <sundstrom@stkhlm.enet.dec.com>,
73 * Robert Olsson <robert@robur.slu.se> and Paul Mackerras.
76 /* $Id: ppp_tty.c,v 1.5 1995/05/02 02:48:32 paulus Exp $ */
77 /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
85 #include "../h/param.h"
86 #include "../h/user.h"
87 #include "../h/proc.h"
88 #include "../h/mbuf.h"
90 #include "../h/socket.h"
91 #include "../h/ioctl.h"
92 #include "../h/file.h"
94 #include "../h/kernel.h"
95 #include "../h/conf.h"
97 #include "../h/systm.h"
99 #include "../net/net/if.h"
100 #include "ppp_defs.h"
103 #include "../net/netinet/in.h"
104 #include "../net/netinet/in_systm.h"
105 #include "../net/netinet/ip.h"
106 #include "slcompress.h"
110 #include "if_pppvar.h"
112 int pppopen __P((dev_t dev, struct tty *tp));
113 int pppclose __P((struct tty *tp, int flag));
114 int pppread __P((struct tty *tp, struct uio *uio, int flag));
115 int pppwrite __P((struct tty *tp, struct uio *uio, int flag));
116 int ppptioctl __P((struct tty *tp, int cmd, caddr_t data, int flag,
118 int pppinput __P((int c, struct tty *tp));
119 int pppstart __P((struct tty *tp));
121 static u_short pppfcs __P((u_short fcs, u_char *cp, int len));
122 static void pppasyncstart __P((struct ppp_softc *));
123 static void pppasyncctlp __P((struct ppp_softc *));
124 static void pppasyncrelinq __P((struct ppp_softc *));
125 static void ppp_timeout __P((void *));
126 static void pppgetm __P((struct ppp_softc *sc));
127 static void pppdumpb __P((u_char *b, int l));
128 static void ppplogchar __P((struct ppp_softc *, int));
131 * Some useful mbuf macros not in mbuf.h.
133 #define M_IS_CLUSTER(m) ((m)->m_off > MMAXOFF)
135 #define M_TRAILINGSPACE(m) \
136 ((M_IS_CLUSTER(m) ? (u_int)(m)->m_clptr + M_CLUSTERSZ : MSIZE) \
137 - ((m)->m_off + (m)->m_len))
139 #define M_OFFSTART(m) \
140 (M_IS_CLUSTER(m) ? (u_int)(m)->m_clptr : MMINOFF)
142 #define M_DATASIZE(m) \
143 (M_IS_CLUSTER(m) ? M_CLUSTERSZ : MLEN)
146 * Does c need to be escaped?
148 #define ESCAPE_P(c) (sc->sc_asyncmap[(c) >> 5] & (1 << ((c) & 0x1F)))
151 * Procedures for using an async tty interface for PPP.
155 * This is an Ultrix kernel, we've got clists.
157 #define CCOUNT(q) ((q)->c_cc)
160 #define PPP_HIWAT 400 /* Don't start a new packet if HIWAT on que */
163 * Line specific open routine for async tty devices.
164 * Attach the given tty to the first available ppp unit.
170 register struct tty *tp;
172 register struct ppp_softc *sc;
174 struct proc *p = u.u_procp;
179 if (tp->t_line == PPPDISC) {
180 sc = (struct ppp_softc *) tp->t_sc;
181 if (sc != NULL && sc->sc_devp == (void *) tp)
185 if ((sc = pppalloc(p->p_pid)) == NULL)
189 (*sc->sc_relinq)(sc); /* get previous owner to relinquish the unit */
194 bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
195 sc->sc_asyncmap[0] = 0xffffffff;
196 sc->sc_asyncmap[3] = 0x60000000;
197 sc->sc_rasyncmap = 0;
198 sc->sc_devp = (void *) tp;
199 sc->sc_start = pppasyncstart;
200 sc->sc_ctlp = pppasyncctlp;
201 sc->sc_relinq = pppasyncrelinq;
204 sc->sc_if.if_flags |= IFF_RUNNING;
206 tp->t_sc = (caddr_t) sc;
207 ttyflush(tp, FREAD | FWRITE);
214 * Line specific close routine.
215 * Detach the tty from the ppp unit.
216 * Mimics part of ttyclose().
223 register struct ppp_softc *sc;
228 s = splimp(); /* paranoid; splnet probably ok */
230 sc = (struct ppp_softc *) tp->t_sc;
233 if (tp == (struct tty *) sc->sc_devp) {
243 * Relinquish the interface unit to another device.
247 struct ppp_softc *sc;
253 m_freem(sc->sc_outm);
260 if (sc->sc_flags & SC_TIMEOUT) {
261 untimeout(ppp_timeout, (void *) sc);
262 sc->sc_flags &= ~SC_TIMEOUT;
268 * Line specific (tty) read routine.
271 pppread(tp, uio, flag)
272 register struct tty *tp;
276 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
284 * Loop waiting for input, checking that nothing disasterous
285 * happens in the meantime.
289 if (tp != (struct tty *) sc->sc_devp || tp->t_line != PPPDISC) {
293 if (sc->sc_inq.ifq_head != NULL)
295 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0
296 && (tp->t_state & TS_ISOPEN)) {
298 return 0; /* end of file */
300 if (tp->t_state & (TS_ASYNC | TS_NBIO)) {
302 return (EWOULDBLOCK);
304 sleep((caddr_t) &tp->t_rawq, TTIPRI);
307 /* Pull place-holder byte out of canonical queue */
310 /* Get the packet from the input queue */
311 IF_DEQUEUE(&sc->sc_inq, m0);
314 for (m = m0; m && uio->uio_resid; m = m->m_next)
315 if (error = uiomove(mtod(m, u_char *), m->m_len, UIO_READ, uio))
322 * Line specific (tty) write routine.
325 pppwrite(tp, uio, flag)
326 register struct tty *tp;
330 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
331 struct mbuf *m, *m0, **mp, *p;
335 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
336 return 0; /* wrote 0 bytes */
337 if (tp->t_line != PPPDISC)
339 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
341 if (uio->uio_resid > sc->sc_if.if_mtu + PPP_HDRLEN ||
342 uio->uio_resid < PPP_HDRLEN)
344 for (mp = &m0; uio->uio_resid; mp = &m->m_next) {
345 MGET(m, M_WAIT, MT_DATA);
346 if ((*mp = m) == NULL) {
350 if (uio->uio_resid >= CLBYTES / 2) {
354 len = MIN(m->m_len, uio->uio_resid);
355 if (error = uiomove(mtod(m, u_char *), len, UIO_WRITE, uio)) {
361 dst.sa_family = AF_UNSPEC;
362 bcopy(mtod(m0, caddr_t), dst.sa_data, PPP_HDRLEN);
363 m0->m_off += PPP_HDRLEN;
364 m0->m_len -= PPP_HDRLEN;
365 return (pppoutput(&sc->sc_if, m0, &dst));
369 * Line specific (tty) ioctl routine.
370 * This discipline requires that tty device drivers call
371 * the line specific l_ioctl routine from their ioctl routines.
375 ppptioctl(tp, cmd, data, flag)
380 struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
383 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
388 case PPPIOCSASYNCMAP:
391 sc->sc_asyncmap[0] = *(u_int *)data;
394 case PPPIOCGASYNCMAP:
395 *(u_int *)data = sc->sc_asyncmap[0];
398 case PPPIOCSRASYNCMAP:
401 sc->sc_rasyncmap = *(u_int *)data;
404 case PPPIOCGRASYNCMAP:
405 *(u_int *)data = sc->sc_rasyncmap;
408 case PPPIOCSXASYNCMAP:
412 bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
413 sc->sc_asyncmap[1] = 0; /* mustn't escape 0x20 - 0x3f */
414 sc->sc_asyncmap[2] &= ~0x40000000; /* mustn't escape 0x5e */
415 sc->sc_asyncmap[3] |= 0x60000000; /* must escape 0x7d, 0x7e */
419 case PPPIOCGXASYNCMAP:
420 bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));
424 error = pppioctl(sc, cmd, data, flag);
425 if (error == 0 && cmd == PPPIOCSMRU)
433 * FCS lookup table as calculated by genfcstab.
435 static u_short fcstab[256] = {
436 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
437 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
438 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
439 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
440 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
441 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
442 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
443 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
444 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
445 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
446 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
447 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
448 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
449 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
450 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
451 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
452 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
453 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
454 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
455 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
456 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
457 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
458 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
459 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
460 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
461 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
462 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
463 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
464 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
465 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
466 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
467 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
471 * Calculate a new FCS given the current FCS and the new data.
475 register u_short fcs;
480 fcs = PPP_FCS(fcs, *cp++);
485 * This gets called from pppoutput when a new packet is
490 register struct ppp_softc *sc;
492 register struct tty *tp = (struct tty *) sc->sc_devp;
501 * This gets called when a received packet is placed on
506 struct ppp_softc *sc;
510 /* Put a placeholder byte in canq for ttselect()/ttnread(). */
511 tp = (struct tty *) sc->sc_devp;
512 putc(0, &tp->t_canq);
517 * Start output on async tty interface. Get another datagram
518 * to send from the interface queue and start sending it.
522 register struct tty *tp;
524 register struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
525 register struct mbuf *m;
527 register u_char *start, *stop, *cp;
528 int n, s, ndone, done, idle;
531 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0
532 || sc == NULL || tp != (struct tty *) sc->sc_devp) {
533 if (tp->t_oproc != NULL)
539 while (CCOUNT(&tp->t_outq) < PPP_HIWAT) {
541 * See if we have an existing packet partly sent.
542 * If not, get a new packet and start sending it.
547 * Get another packet to be sent.
556 * The extra PPP_FLAG will start up a new packet, and thus
557 * will flush any accumulated garbage. We do this whenever
558 * the line may have been idle for some time.
560 if (CCOUNT(&tp->t_outq) == 0) {
562 (void) putc(PPP_FLAG, &tp->t_outq);
565 /* Calculate the FCS for the first mbuf's worth. */
566 sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);
570 start = mtod(m, u_char *);
575 * Find out how many bytes in the string we can
576 * handle without doing something special.
578 for (cp = start; cp < stop; cp++)
583 ndone = n - b_to_q(start, n, &tp->t_outq);
586 sc->sc_bytessent += ndone;
589 break; /* packet doesn't fit */
592 * If there are characters left in the mbuf,
593 * the first one must be special..
594 * Put it out in a different form.
597 if (putc(PPP_ESCAPE, &tp->t_outq))
599 if (putc(*start ^ PPP_TRANS, &tp->t_outq)) {
600 (void) unputc(&tp->t_outq);
603 sc->sc_bytessent += 2;
610 * If we didn't empty this mbuf, remember where we're up to.
611 * If we emptied the last mbuf, try to add the FCS and closing
612 * flag, and if we can't, leave sc_outm pointing to m, but with
613 * m->m_len == 0, to remind us to output the FCS and flag later.
616 if (done && m->m_next == NULL) {
622 * We may have to escape the bytes in the FCS.
625 c = ~sc->sc_outfcs & 0xFF;
628 *p++ = c ^ PPP_TRANS;
631 c = (~sc->sc_outfcs >> 8) & 0xFF;
634 *p++ = c ^ PPP_TRANS;
640 * Try to output the FCS and flag. If the bytes
641 * don't all fit, back out.
643 for (q = endseq; q < p; ++q)
644 if (putc(*q, &tp->t_outq)) {
646 for (; q > endseq; --q)
650 sc->sc_bytessent += q - endseq;
654 m->m_off += m->m_len - len;
659 /* Finished with this mbuf; free it and move on. */
663 /* Finished a packet */
664 sc->sc_if.if_opackets++;
667 sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
671 * Here we have either finished a packet (m == NULL)
672 * or filled up the output queue (m != NULL).
680 * If there is stuff in the output queue, send it now.
681 * We are being called in lieu of ttstart and must do what it would.
683 if (tp->t_oproc != NULL)
687 * This timeout is needed for operation on a pseudo-tty,
688 * because the pty code doesn't call pppstart after it has
689 * drained the t_outq.
691 if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) {
692 timeout(ppp_timeout, (void *) sc, 1);
693 sc->sc_flags |= SC_TIMEOUT;
700 * Timeout routine - try to start some more output.
706 struct ppp_softc *sc = (struct ppp_softc *) x;
707 struct tty *tp = (struct tty *) sc->sc_devp;
711 sc->sc_flags &= ~SC_TIMEOUT;
717 * Allocate enough mbuf to handle current MRU.
721 register struct ppp_softc *sc;
723 struct mbuf *m, **mp, *p;
729 for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
730 if ((m = *mp) == NULL) {
731 MGET(m, M_DONTWAIT, MT_DATA);
737 len -= M_DATASIZE(m);
744 * tty interface receiver interrupt.
746 static unsigned paritytab[8] = {
747 0x96696996, 0x69969669, 0x69969669, 0x96696996,
748 0x69969669, 0x96696996, 0x96696996, 0x69969669
754 register struct tty *tp;
756 register struct ppp_softc *sc;
761 sc = (struct ppp_softc *) tp->t_sc;
762 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
772 sc->sc_flags |= SC_RCV_B7_1;
774 sc->sc_flags |= SC_RCV_B7_0;
775 if (paritytab[c >> 5] & (1 << (c & 0x1F)))
776 sc->sc_flags |= SC_RCV_ODDP;
778 sc->sc_flags |= SC_RCV_EVNP;
780 if (sc->sc_flags & SC_LOG_RAWIN)
787 if (sc->sc_rawin_count > 0)
791 * If SC_ESCAPED is set, then we've seen the packet
792 * abort sequence "}~".
794 if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
795 || ilen > 0 && sc->sc_fcs != PPP_GOODFCS) {
796 sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */
797 if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
798 if (sc->sc_flags & SC_DEBUG)
799 printf("ppp%d: bad fcs %x\n", sc->sc_if.if_unit,
801 sc->sc_if.if_ierrors++;
803 sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
808 if (ilen < PPP_HDRLEN + PPP_FCSLEN) {
810 if (sc->sc_flags & SC_DEBUG)
811 printf("ppp%d: too short (%d)\n", sc->sc_if.if_unit, ilen);
812 sc->sc_if.if_ierrors++;
813 sc->sc_flags |= SC_PKTLOST;
820 * Remove FCS trailer. Somewhat painful...
823 if (--sc->sc_mc->m_len == 0) {
824 for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next)
830 /* excise this mbuf chain */
832 sc->sc_m = sc->sc_mc->m_next;
833 sc->sc_mc->m_next = NULL;
835 ppppktin(sc, m, sc->sc_flags & SC_PKTLOST);
836 sc->sc_flags &= ~SC_PKTLOST;
843 if (sc->sc_flags & SC_FLUSH) {
844 if (sc->sc_flags & SC_LOG_FLUSH)
850 if (c < 0x20 && (sc->sc_rasyncmap & (1 << c))) {
855 if (sc->sc_flags & SC_ESCAPED) {
856 sc->sc_flags &= ~SC_ESCAPED;
858 } else if (c == PPP_ESCAPE) {
859 sc->sc_flags |= SC_ESCAPED;
865 * Initialize buffer on first octet received.
866 * First octet could be address or protocol (when compressing
868 * Second octet is control.
869 * Third octet is first or second (when compressing protocol)
871 * Fourth octet is second octet of protocol.
873 if (sc->sc_ilen == 0) {
874 /* reset the first input mbuf */
875 if (sc->sc_m == NULL) {
877 if (sc->sc_m == NULL) {
878 if (sc->sc_flags & SC_DEBUG)
879 printf("ppp%d: no input mbufs!\n", sc->sc_if.if_unit);
885 m->m_off = M_OFFSTART(m);
887 sc->sc_mp = mtod(m, char *);
888 sc->sc_fcs = PPP_INITFCS;
889 if (c != PPP_ALLSTATIONS) {
890 if (sc->sc_flags & SC_REJ_COMP_AC) {
891 if (sc->sc_flags & SC_DEBUG)
892 printf("ppp%d: garbage received: 0x%x (need 0xFF)\n",
893 sc->sc_if.if_unit, c);
896 *sc->sc_mp++ = PPP_ALLSTATIONS;
897 *sc->sc_mp++ = PPP_UI;
902 if (sc->sc_ilen == 1 && c != PPP_UI) {
903 if (sc->sc_flags & SC_DEBUG)
904 printf("ppp%d: missing UI (0x3), got 0x%x\n",
905 sc->sc_if.if_unit, c);
908 if (sc->sc_ilen == 2 && (c & 1) == 1) {
909 /* a compressed protocol */
914 if (sc->sc_ilen == 3 && (c & 1) == 0) {
915 if (sc->sc_flags & SC_DEBUG)
916 printf("ppp%d: bad protocol %x\n", sc->sc_if.if_unit,
917 (sc->sc_mp[-1] << 8) + c);
921 /* packet beyond configured mru? */
922 if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) {
923 if (sc->sc_flags & SC_DEBUG)
924 printf("ppp%d: packet too big\n", sc->sc_if.if_unit);
928 /* is this mbuf full? */
930 if (M_TRAILINGSPACE(m) <= 0) {
931 if (m->m_next == NULL) {
933 if (m->m_next == NULL) {
934 if (sc->sc_flags & SC_DEBUG)
935 printf("ppp%d: too few input mbufs!\n", sc->sc_if.if_unit);
939 sc->sc_mc = m = m->m_next;
941 m->m_off = M_OFFSTART(m);
942 sc->sc_mp = mtod(m, char *);
947 sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);
952 if (!(sc->sc_flags & SC_FLUSH)) {
953 sc->sc_if.if_ierrors++;
954 sc->sc_flags |= SC_FLUSH;
955 if (sc->sc_flags & SC_LOG_FLUSH)
962 #define MAX_DUMP_BYTES 128
966 struct ppp_softc *sc;
970 sc->sc_rawin[sc->sc_rawin_count++] = c;
971 if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
972 || c < 0 && sc->sc_rawin_count > 0) {
973 printf("ppp%d input: ", sc->sc_if.if_unit);
974 pppdumpb(sc->sc_rawin, sc->sc_rawin_count);
975 sc->sc_rawin_count = 0;
984 char buf[3*MAX_DUMP_BYTES+4];
986 static char digits[] = "0123456789abcdef";
989 if (bp >= buf + sizeof(buf) - 3) {
993 *bp++ = digits[*b >> 4]; /* convert byte to ascii hex */
994 *bp++ = digits[*b++ & 0xf];
1002 #endif /* NPPP > 0 */