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.4 1994/12/13 03:30:21 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;
281 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
282 return 0; /* end of file */
283 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
286 while (sc->sc_inq.ifq_head == NULL && tp->t_line == PPPDISC) {
287 if (tp->t_state & (TS_ASYNC | TS_NBIO)) {
289 return (EWOULDBLOCK);
291 sleep((caddr_t) &tp->t_rawq, TTIPRI);
293 if (tp->t_line != PPPDISC) {
298 /* Pull place-holder byte out of canonical queue */
301 /* Get the packet from the input queue */
302 IF_DEQUEUE(&sc->sc_inq, m0);
305 for (m = m0; m && uio->uio_resid; m = m->m_next)
306 if (error = uiomove(mtod(m, u_char *), m->m_len, UIO_READ, uio))
313 * Line specific (tty) write routine.
316 pppwrite(tp, uio, flag)
317 register struct tty *tp;
321 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
322 struct mbuf *m, *m0, **mp, *p;
326 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
327 return 0; /* wrote 0 bytes */
328 if (tp->t_line != PPPDISC)
330 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
332 if (uio->uio_resid > sc->sc_if.if_mtu + PPP_HDRLEN ||
333 uio->uio_resid < PPP_HDRLEN)
335 for (mp = &m0; uio->uio_resid; mp = &m->m_next) {
336 MGET(m, M_WAIT, MT_DATA);
337 if ((*mp = m) == NULL) {
341 if (uio->uio_resid >= CLBYTES / 2) {
345 len = MIN(m->m_len, uio->uio_resid);
346 if (error = uiomove(mtod(m, u_char *), len, UIO_WRITE, uio)) {
352 dst.sa_family = AF_UNSPEC;
353 bcopy(mtod(m0, caddr_t), dst.sa_data, PPP_HDRLEN);
354 m0->m_off += PPP_HDRLEN;
355 m0->m_len -= PPP_HDRLEN;
356 return (pppoutput(&sc->sc_if, m0, &dst));
360 * Line specific (tty) ioctl routine.
361 * This discipline requires that tty device drivers call
362 * the line specific l_ioctl routine from their ioctl routines.
366 ppptioctl(tp, cmd, data, flag)
371 struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
374 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
379 case PPPIOCSASYNCMAP:
382 sc->sc_asyncmap[0] = *(u_int *)data;
385 case PPPIOCGASYNCMAP:
386 *(u_int *)data = sc->sc_asyncmap[0];
389 case PPPIOCSRASYNCMAP:
392 sc->sc_rasyncmap = *(u_int *)data;
395 case PPPIOCGRASYNCMAP:
396 *(u_int *)data = sc->sc_rasyncmap;
399 case PPPIOCSXASYNCMAP:
403 bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
404 sc->sc_asyncmap[1] = 0; /* mustn't escape 0x20 - 0x3f */
405 sc->sc_asyncmap[2] &= ~0x40000000; /* mustn't escape 0x5e */
406 sc->sc_asyncmap[3] |= 0x60000000; /* must escape 0x7d, 0x7e */
410 case PPPIOCGXASYNCMAP:
411 bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));
415 error = pppioctl(sc, cmd, data, flag);
416 if (error == 0 && cmd == PPPIOCSMRU)
424 * FCS lookup table as calculated by genfcstab.
426 static u_short fcstab[256] = {
427 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
428 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
429 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
430 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
431 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
432 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
433 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
434 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
435 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
436 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
437 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
438 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
439 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
440 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
441 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
442 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
443 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
444 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
445 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
446 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
447 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
448 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
449 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
450 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
451 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
452 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
453 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
454 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
455 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
456 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
457 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
458 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
462 * Calculate a new FCS given the current FCS and the new data.
466 register u_short fcs;
471 fcs = PPP_FCS(fcs, *cp++);
476 * This gets called from pppoutput when a new packet is
481 register struct ppp_softc *sc;
483 register struct tty *tp = (struct tty *) sc->sc_devp;
492 * This gets called when a received packet is placed on
497 struct ppp_softc *sc;
501 /* Put a placeholder byte in canq for ttselect()/ttnread(). */
502 tp = (struct tty *) sc->sc_devp;
503 putc(0, &tp->t_canq);
508 * Start output on async tty interface. Get another datagram
509 * to send from the interface queue and start sending it.
513 register struct tty *tp;
515 register struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
516 register struct mbuf *m;
518 register u_char *start, *stop, *cp;
519 int n, s, ndone, done, idle;
522 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0
523 || sc == NULL || tp != (struct tty *) sc->sc_devp) {
524 if (tp->t_oproc != NULL)
530 while (CCOUNT(&tp->t_outq) < PPP_HIWAT) {
532 * See if we have an existing packet partly sent.
533 * If not, get a new packet and start sending it.
538 * Get another packet to be sent.
547 * The extra PPP_FLAG will start up a new packet, and thus
548 * will flush any accumulated garbage. We do this whenever
549 * the line may have been idle for some time.
551 if (CCOUNT(&tp->t_outq) == 0) {
553 (void) putc(PPP_FLAG, &tp->t_outq);
556 /* Calculate the FCS for the first mbuf's worth. */
557 sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);
561 start = mtod(m, u_char *);
566 * Find out how many bytes in the string we can
567 * handle without doing something special.
569 for (cp = start; cp < stop; cp++)
574 ndone = n - b_to_q(start, n, &tp->t_outq);
577 sc->sc_bytessent += ndone;
580 break; /* packet doesn't fit */
583 * If there are characters left in the mbuf,
584 * the first one must be special..
585 * Put it out in a different form.
588 if (putc(PPP_ESCAPE, &tp->t_outq))
590 if (putc(*start ^ PPP_TRANS, &tp->t_outq)) {
591 (void) unputc(&tp->t_outq);
594 sc->sc_bytessent += 2;
601 * If we didn't empty this mbuf, remember where we're up to.
602 * If we emptied the last mbuf, try to add the FCS and closing
603 * flag, and if we can't, leave sc_outm pointing to m, but with
604 * m->m_len == 0, to remind us to output the FCS and flag later.
607 if (done && m->m_next == NULL) {
613 * We may have to escape the bytes in the FCS.
616 c = ~sc->sc_outfcs & 0xFF;
619 *p++ = c ^ PPP_TRANS;
622 c = (~sc->sc_outfcs >> 8) & 0xFF;
625 *p++ = c ^ PPP_TRANS;
631 * Try to output the FCS and flag. If the bytes
632 * don't all fit, back out.
634 for (q = endseq; q < p; ++q)
635 if (putc(*q, &tp->t_outq)) {
637 for (; q > endseq; --q)
641 sc->sc_bytessent += q - endseq;
645 m->m_off += m->m_len - len;
650 /* Finished with this mbuf; free it and move on. */
654 /* Finished a packet */
655 sc->sc_if.if_opackets++;
658 sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
662 * Here we have either finished a packet (m == NULL)
663 * or filled up the output queue (m != NULL).
671 * If there is stuff in the output queue, send it now.
672 * We are being called in lieu of ttstart and must do what it would.
674 if (tp->t_oproc != NULL)
678 * This timeout is needed for operation on a pseudo-tty,
679 * because the pty code doesn't call pppstart after it has
680 * drained the t_outq.
682 if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) {
683 timeout(ppp_timeout, (void *) sc, 1);
684 sc->sc_flags |= SC_TIMEOUT;
689 * Timeout routine - try to start some more output.
695 struct ppp_softc *sc = (struct ppp_softc *) x;
696 struct tty *tp = (struct tty *) sc->sc_devp;
700 sc->sc_flags &= ~SC_TIMEOUT;
706 * Allocate enough mbuf to handle current MRU.
710 register struct ppp_softc *sc;
712 struct mbuf *m, **mp, *p;
718 for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
719 if ((m = *mp) == NULL) {
720 MGET(m, M_DONTWAIT, MT_DATA);
726 len -= M_DATASIZE(m);
733 * tty interface receiver interrupt.
735 static unsigned paritytab[8] = {
736 0x96696996, 0x69969669, 0x69969669, 0x96696996,
737 0x69969669, 0x96696996, 0x96696996, 0x69969669
743 register struct tty *tp;
745 register struct ppp_softc *sc;
750 sc = (struct ppp_softc *) tp->t_sc;
751 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
761 sc->sc_flags |= SC_RCV_B7_1;
763 sc->sc_flags |= SC_RCV_B7_0;
764 if (paritytab[c >> 5] & (1 << (c & 0x1F)))
765 sc->sc_flags |= SC_RCV_ODDP;
767 sc->sc_flags |= SC_RCV_EVNP;
769 if (sc->sc_flags & SC_LOG_RAWIN)
776 if (sc->sc_rawin_count > 0)
780 * If SC_ESCAPED is set, then we've seen the packet
781 * abort sequence "}~".
783 if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
784 || ilen > 0 && sc->sc_fcs != PPP_GOODFCS) {
785 sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */
786 if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
787 if (sc->sc_flags & SC_DEBUG)
788 printf("ppp%d: bad fcs %x\n", sc->sc_if.if_unit,
790 sc->sc_if.if_ierrors++;
792 sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
797 if (ilen < PPP_HDRLEN + PPP_FCSLEN) {
799 if (sc->sc_flags & SC_DEBUG)
800 printf("ppp%d: too short (%d)\n", sc->sc_if.if_unit, ilen);
801 sc->sc_if.if_ierrors++;
802 sc->sc_flags |= SC_PKTLOST;
809 * Remove FCS trailer. Somewhat painful...
812 if (--sc->sc_mc->m_len == 0) {
813 for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next)
819 /* excise this mbuf chain */
821 sc->sc_m = sc->sc_mc->m_next;
822 sc->sc_mc->m_next = NULL;
824 ppppktin(sc, m, sc->sc_flags & SC_PKTLOST);
825 sc->sc_flags &= ~SC_PKTLOST;
832 if (sc->sc_flags & SC_FLUSH) {
833 if (sc->sc_flags & SC_LOG_FLUSH)
839 if (c < 0x20 && (sc->sc_rasyncmap & (1 << c))) {
844 if (sc->sc_flags & SC_ESCAPED) {
845 sc->sc_flags &= ~SC_ESCAPED;
847 } else if (c == PPP_ESCAPE) {
848 sc->sc_flags |= SC_ESCAPED;
854 * Initialize buffer on first octet received.
855 * First octet could be address or protocol (when compressing
857 * Second octet is control.
858 * Third octet is first or second (when compressing protocol)
860 * Fourth octet is second octet of protocol.
862 if (sc->sc_ilen == 0) {
863 /* reset the first input mbuf */
864 if (sc->sc_m == NULL) {
866 if (sc->sc_m == NULL) {
867 if (sc->sc_flags & SC_DEBUG)
868 printf("ppp%d: no input mbufs!\n", sc->sc_if.if_unit);
874 m->m_off = M_OFFSTART(m);
876 sc->sc_mp = mtod(m, char *);
877 sc->sc_fcs = PPP_INITFCS;
878 if (c != PPP_ALLSTATIONS) {
879 if (sc->sc_flags & SC_REJ_COMP_AC) {
880 if (sc->sc_flags & SC_DEBUG)
881 printf("ppp%d: garbage received: 0x%x (need 0xFF)\n",
882 sc->sc_if.if_unit, c);
885 *sc->sc_mp++ = PPP_ALLSTATIONS;
886 *sc->sc_mp++ = PPP_UI;
891 if (sc->sc_ilen == 1 && c != PPP_UI) {
892 if (sc->sc_flags & SC_DEBUG)
893 printf("ppp%d: missing UI (0x3), got 0x%x\n",
894 sc->sc_if.if_unit, c);
897 if (sc->sc_ilen == 2 && (c & 1) == 1) {
898 /* a compressed protocol */
903 if (sc->sc_ilen == 3 && (c & 1) == 0) {
904 if (sc->sc_flags & SC_DEBUG)
905 printf("ppp%d: bad protocol %x\n", sc->sc_if.if_unit,
906 (sc->sc_mp[-1] << 8) + c);
910 /* packet beyond configured mru? */
911 if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) {
912 if (sc->sc_flags & SC_DEBUG)
913 printf("ppp%d: packet too big\n", sc->sc_if.if_unit);
917 /* is this mbuf full? */
919 if (M_TRAILINGSPACE(m) <= 0) {
920 if (m->m_next == NULL) {
922 if (m->m_next == NULL) {
923 if (sc->sc_flags & SC_DEBUG)
924 printf("ppp%d: too few input mbufs!\n", sc->sc_if.if_unit);
928 sc->sc_mc = m = m->m_next;
930 m->m_off = M_OFFSTART(m);
931 sc->sc_mp = mtod(m, char *);
936 sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);
941 if (!(sc->sc_flags & SC_FLUSH)) {
942 sc->sc_if.if_ierrors++;
943 sc->sc_flags |= SC_FLUSH;
944 if (sc->sc_flags & SC_LOG_FLUSH)
950 #define MAX_DUMP_BYTES 128
954 struct ppp_softc *sc;
958 sc->sc_rawin[sc->sc_rawin_count++] = c;
959 if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
960 || c < 0 && sc->sc_rawin_count > 0) {
961 printf("ppp%d input: ", sc->sc_if.if_unit);
962 pppdumpb(sc->sc_rawin, sc->sc_rawin_count);
963 sc->sc_rawin_count = 0;
972 char buf[3*MAX_DUMP_BYTES+4];
974 static char digits[] = "0123456789abcdef";
977 if (bp >= buf + sizeof(buf) - 3) {
981 *bp++ = digits[*b >> 4]; /* convert byte to ascii hex */
982 *bp++ = digits[*b++ & 0xf];
990 #endif /* NPPP > 0 */