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.3 1994/12/08 00:32:59 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 pppgetm __P((struct ppp_softc *sc));
126 static void pppdumpb __P((u_char *b, int l));
127 static void ppplogchar __P((struct ppp_softc *, int));
130 * Some useful mbuf macros not in mbuf.h.
132 #define M_IS_CLUSTER(m) ((m)->m_off > MMAXOFF)
134 #define M_TRAILINGSPACE(m) \
135 ((M_IS_CLUSTER(m) ? (u_int)(m)->m_clptr + M_CLUSTERSZ : MSIZE) \
136 - ((m)->m_off + (m)->m_len))
138 #define M_OFFSTART(m) \
139 (M_IS_CLUSTER(m) ? (u_int)(m)->m_clptr : MMINOFF)
141 #define M_DATASIZE(m) \
142 (M_IS_CLUSTER(m) ? M_CLUSTERSZ : MLEN)
145 * Does c need to be escaped?
147 #define ESCAPE_P(c) (sc->sc_asyncmap[(c) >> 5] & (1 << ((c) & 0x1F)))
150 * Procedures for using an async tty interface for PPP.
154 * This is an Ultrix kernel, we've got clists.
156 #define CCOUNT(q) ((q)->c_cc)
159 #define PPP_HIWAT 400 /* Don't start a new packet if HIWAT on que */
162 * Line specific open routine for async tty devices.
163 * Attach the given tty to the first available ppp unit.
169 register struct tty *tp;
171 register struct ppp_softc *sc;
173 struct proc *p = u.u_procp;
178 if (tp->t_line == PPPDISC) {
179 sc = (struct ppp_softc *) tp->t_sc;
180 if (sc != NULL && sc->sc_devp == (void *) tp)
184 if ((sc = pppalloc(p->p_pid)) == NULL)
188 (*sc->sc_relinq)(sc); /* get previous owner to relinquish the unit */
193 bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
194 sc->sc_asyncmap[0] = 0xffffffff;
195 sc->sc_asyncmap[3] = 0x60000000;
196 sc->sc_rasyncmap = 0;
197 sc->sc_devp = (void *) tp;
198 sc->sc_start = pppasyncstart;
199 sc->sc_ctlp = pppasyncctlp;
200 sc->sc_relinq = pppasyncrelinq;
203 sc->sc_if.if_flags |= IFF_RUNNING;
205 tp->t_sc = (caddr_t) sc;
206 ttyflush(tp, FREAD | FWRITE);
213 * Line specific close routine.
214 * Detach the tty from the ppp unit.
215 * Mimics part of ttyclose().
222 register struct ppp_softc *sc;
227 s = splimp(); /* paranoid; splnet probably ok */
229 sc = (struct ppp_softc *) tp->t_sc;
232 if (tp == (struct tty *) sc->sc_devp) {
242 * Relinquish the interface unit to another device.
246 struct ppp_softc *sc;
252 m_freem(sc->sc_outm);
263 * Line specific (tty) read routine.
266 pppread(tp, uio, flag)
267 register struct tty *tp;
271 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
276 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
277 return 0; /* end of file */
278 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
281 while (sc->sc_inq.ifq_head == NULL && tp->t_line == PPPDISC) {
282 if (tp->t_state & (TS_ASYNC | TS_NBIO)) {
284 return (EWOULDBLOCK);
286 sleep((caddr_t) &tp->t_rawq, TTIPRI);
288 if (tp->t_line != PPPDISC) {
293 /* Pull place-holder byte out of canonical queue */
296 /* Get the packet from the input queue */
297 IF_DEQUEUE(&sc->sc_inq, m0);
300 for (m = m0; m && uio->uio_resid; m = m->m_next)
301 if (error = uiomove(mtod(m, u_char *), m->m_len, UIO_READ, uio))
308 * Line specific (tty) write routine.
311 pppwrite(tp, uio, flag)
312 register struct tty *tp;
316 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
317 struct mbuf *m, *m0, **mp, *p;
321 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
322 return 0; /* wrote 0 bytes */
323 if (tp->t_line != PPPDISC)
325 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
327 if (uio->uio_resid > sc->sc_if.if_mtu + PPP_HDRLEN ||
328 uio->uio_resid < PPP_HDRLEN)
330 for (mp = &m0; uio->uio_resid; mp = &m->m_next) {
331 MGET(m, M_WAIT, MT_DATA);
332 if ((*mp = m) == NULL) {
336 if (uio->uio_resid >= CLBYTES / 2) {
340 len = MIN(m->m_len, uio->uio_resid);
341 if (error = uiomove(mtod(m, u_char *), len, UIO_WRITE, uio)) {
347 dst.sa_family = AF_UNSPEC;
348 bcopy(mtod(m0, caddr_t), dst.sa_data, PPP_HDRLEN);
349 m0->m_off += PPP_HDRLEN;
350 m0->m_len -= PPP_HDRLEN;
351 return (pppoutput(&sc->sc_if, m0, &dst));
355 * Line specific (tty) ioctl routine.
356 * This discipline requires that tty device drivers call
357 * the line specific l_ioctl routine from their ioctl routines.
361 ppptioctl(tp, cmd, data, flag)
366 struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
369 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
374 case PPPIOCSASYNCMAP:
377 sc->sc_asyncmap[0] = *(u_int *)data;
380 case PPPIOCGASYNCMAP:
381 *(u_int *)data = sc->sc_asyncmap[0];
384 case PPPIOCSRASYNCMAP:
387 sc->sc_rasyncmap = *(u_int *)data;
390 case PPPIOCGRASYNCMAP:
391 *(u_int *)data = sc->sc_rasyncmap;
394 case PPPIOCSXASYNCMAP:
398 bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
399 sc->sc_asyncmap[1] = 0; /* mustn't escape 0x20 - 0x3f */
400 sc->sc_asyncmap[2] &= ~0x40000000; /* mustn't escape 0x5e */
401 sc->sc_asyncmap[3] |= 0x60000000; /* must escape 0x7d, 0x7e */
405 case PPPIOCGXASYNCMAP:
406 bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));
410 error = pppioctl(sc, cmd, data, flag);
411 if (error == 0 && cmd == PPPIOCSMRU)
419 * FCS lookup table as calculated by genfcstab.
421 static u_short fcstab[256] = {
422 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
423 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
424 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
425 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
426 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
427 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
428 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
429 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
430 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
431 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
432 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
433 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
434 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
435 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
436 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
437 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
438 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
439 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
440 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
441 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
442 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
443 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
444 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
445 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
446 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
447 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
448 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
449 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
450 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
451 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
452 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
453 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
457 * Calculate a new FCS given the current FCS and the new data.
461 register u_short fcs;
466 fcs = PPP_FCS(fcs, *cp++);
471 * This gets called from pppoutput when a new packet is
476 register struct ppp_softc *sc;
478 register struct tty *tp = (struct tty *) sc->sc_devp;
487 * This gets called when a received packet is placed on
492 struct ppp_softc *sc;
496 /* Put a placeholder byte in canq for ttselect()/ttnread(). */
497 tp = (struct tty *) sc->sc_devp;
498 putc(0, &tp->t_canq);
503 * Start output on async tty interface. Get another datagram
504 * to send from the interface queue and start sending it.
508 register struct tty *tp;
510 register struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
511 register struct mbuf *m;
513 register u_char *start, *stop, *cp;
514 int n, s, ndone, done;
517 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0) {
518 /* sorry, I can't talk now */
521 if (sc == NULL || tp != (struct tty *) sc->sc_devp) {
528 * If there is more in the output queue, just send it now.
529 * We are being called in lieu of ttstart and must do what
532 if (CCOUNT(&tp->t_outq) != 0 && tp->t_oproc != NULL) {
534 if (CCOUNT(&tp->t_outq) > PPP_HIWAT)
539 * See if we have an existing packet partly sent.
540 * If not, get a new packet and start sending it.
545 * Get another packet to be sent.
549 if (tp->t_oproc != NULL)
555 * The extra PPP_FLAG will start up a new packet, and thus
556 * will flush any accumulated garbage. We do this whenever
557 * the line may have been idle for some time.
559 if (CCOUNT(&tp->t_outq) == 0) {
561 (void) putc(PPP_FLAG, &tp->t_outq);
564 /* Calculate the FCS for the first mbuf's worth. */
565 sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);
569 start = mtod(m, u_char *);
574 * Find out how many bytes in the string we can
575 * handle without doing something special.
577 for (cp = start; cp < stop; cp++)
582 ndone = n - b_to_q(start, n, &tp->t_outq);
585 sc->sc_bytessent += ndone;
588 break; /* packet doesn't fit */
591 * If there are characters left in the mbuf,
592 * the first one must be special..
593 * Put it out in a different form.
596 if (putc(PPP_ESCAPE, &tp->t_outq))
598 if (putc(*start ^ PPP_TRANS, &tp->t_outq)) {
599 (void) unputc(&tp->t_outq);
602 sc->sc_bytessent += 2;
608 * If we didn't empty this mbuf, remember where we're up to.
609 * If we emptied the last mbuf, try to add the FCS and closing
610 * flag, and if we can't, leave sc_outm pointing to m, but with
611 * m->m_len == 0, to remind us to output the FCS and flag later.
614 if (done && m->m_next == NULL) {
620 * We may have to escape the bytes in the FCS.
623 c = ~sc->sc_outfcs & 0xFF;
626 *p++ = c ^ PPP_TRANS;
629 c = (~sc->sc_outfcs >> 8) & 0xFF;
632 *p++ = c ^ PPP_TRANS;
638 * Try to output the FCS and flag. If the bytes
639 * don't all fit, back out.
641 for (q = endseq; q < p; ++q)
642 if (putc(*q, &tp->t_outq)) {
644 for (; q > endseq; --q)
651 m->m_off += m->m_len - len;
654 if (tp->t_oproc != NULL)
656 return; /* can't do any more at the moment */
659 /* Finished with this mbuf; free it and move on. */
665 sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
668 /* Finished a packet */
670 sc->sc_bytessent++; /* account for closing flag */
671 sc->sc_if.if_opackets++;
676 * Allocate enough mbuf to handle current MRU.
680 register struct ppp_softc *sc;
682 struct mbuf *m, **mp, *p;
688 for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
689 if ((m = *mp) == NULL) {
690 MGET(m, M_DONTWAIT, MT_DATA);
696 len -= M_DATASIZE(m);
703 * tty interface receiver interrupt.
705 static unsigned paritytab[8] = {
706 0x96696996, 0x69969669, 0x69969669, 0x96696996,
707 0x69969669, 0x96696996, 0x96696996, 0x69969669
713 register struct tty *tp;
715 register struct ppp_softc *sc;
721 sc = (struct ppp_softc *) tp->t_sc;
722 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
731 sc->sc_flags |= SC_RCV_B7_1;
733 sc->sc_flags |= SC_RCV_B7_0;
734 if (paritytab[c >> 5] & (1 << (c & 0x1F)))
735 sc->sc_flags |= SC_RCV_ODDP;
737 sc->sc_flags |= SC_RCV_EVNP;
739 if (sc->sc_flags & SC_LOG_RAWIN)
746 if (sc->sc_rawin_count > 0)
750 * If SC_ESCAPED is set, then we've seen the packet
751 * abort sequence "}~".
753 if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
754 || ilen > 0 && sc->sc_fcs != PPP_GOODFCS) {
755 sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */
756 if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
757 if (sc->sc_flags & SC_DEBUG)
758 printf("ppp%d: bad fcs %x\n", sc->sc_if.if_unit,
760 sc->sc_if.if_ierrors++;
762 sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
767 if (ilen < PPP_HDRLEN + PPP_FCSLEN) {
769 if (sc->sc_flags & SC_DEBUG)
770 printf("ppp%d: too short (%d)\n", sc->sc_if.if_unit, ilen);
771 sc->sc_if.if_ierrors++;
772 sc->sc_flags |= SC_PKTLOST;
779 * Remove FCS trailer. Somewhat painful...
782 if (--sc->sc_mc->m_len == 0) {
783 for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next)
789 /* excise this mbuf chain */
791 sc->sc_m = sc->sc_mc->m_next;
792 sc->sc_mc->m_next = NULL;
794 ppppktin(sc, m, sc->sc_flags & SC_PKTLOST);
795 sc->sc_flags &= ~SC_PKTLOST;
802 if (sc->sc_flags & SC_FLUSH) {
803 if (sc->sc_flags & SC_LOG_FLUSH)
809 if (c < 0x20 && (sc->sc_rasyncmap & (1 << c))) {
814 if (sc->sc_flags & SC_ESCAPED) {
815 sc->sc_flags &= ~SC_ESCAPED;
817 } else if (c == PPP_ESCAPE) {
818 sc->sc_flags |= SC_ESCAPED;
824 * Initialize buffer on first octet received.
825 * First octet could be address or protocol (when compressing
827 * Second octet is control.
828 * Third octet is first or second (when compressing protocol)
830 * Fourth octet is second octet of protocol.
832 if (sc->sc_ilen == 0) {
833 /* reset the first input mbuf */
834 if (sc->sc_m == NULL) {
836 if (sc->sc_m == NULL) {
837 if (sc->sc_flags & SC_DEBUG)
838 printf("ppp%d: no input mbufs!\n", sc->sc_if.if_unit);
844 m->m_off = M_OFFSTART(m);
846 sc->sc_mp = mtod(m, char *);
847 sc->sc_fcs = PPP_INITFCS;
848 if (c != PPP_ALLSTATIONS) {
849 if (sc->sc_flags & SC_REJ_COMP_AC) {
850 if (sc->sc_flags & SC_DEBUG)
851 printf("ppp%d: garbage received: 0x%x (need 0xFF)\n",
852 sc->sc_if.if_unit, c);
855 *sc->sc_mp++ = PPP_ALLSTATIONS;
856 *sc->sc_mp++ = PPP_UI;
861 if (sc->sc_ilen == 1 && c != PPP_UI) {
862 if (sc->sc_flags & SC_DEBUG)
863 printf("ppp%d: missing UI (0x3), got 0x%x\n",
864 sc->sc_if.if_unit, c);
867 if (sc->sc_ilen == 2 && (c & 1) == 1) {
868 /* a compressed protocol */
873 if (sc->sc_ilen == 3 && (c & 1) == 0) {
874 if (sc->sc_flags & SC_DEBUG)
875 printf("ppp%d: bad protocol %x\n", sc->sc_if.if_unit,
876 (sc->sc_mp[-1] << 8) + c);
880 /* packet beyond configured mru? */
881 if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) {
882 if (sc->sc_flags & SC_DEBUG)
883 printf("ppp%d: packet too big\n", sc->sc_if.if_unit);
887 /* is this mbuf full? */
889 if (M_TRAILINGSPACE(m) <= 0) {
890 if (m->m_next == NULL) {
892 if (m->m_next == NULL) {
893 if (sc->sc_flags & SC_DEBUG)
894 printf("ppp%d: too few input mbufs!\n", sc->sc_if.if_unit);
898 sc->sc_mc = m = m->m_next;
900 m->m_off = M_OFFSTART(m);
901 sc->sc_mp = mtod(m, char *);
906 sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);
911 if (!(sc->sc_flags & SC_FLUSH)) {
912 sc->sc_if.if_ierrors++;
913 sc->sc_flags |= SC_FLUSH;
914 if (sc->sc_flags & SC_LOG_FLUSH)
920 #define MAX_DUMP_BYTES 128
924 struct ppp_softc *sc;
928 sc->sc_rawin[sc->sc_rawin_count++] = c;
929 if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
930 || c < 0 && sc->sc_rawin_count > 0) {
931 printf("ppp%d input: ", sc->sc_if.if_unit);
932 pppdumpb(sc->sc_rawin, sc->sc_rawin_count);
933 sc->sc_rawin_count = 0;
942 char buf[3*MAX_DUMP_BYTES+4];
944 static char digits[] = "0123456789abcdef";
947 if (bp >= buf + sizeof(buf) - 3) {
951 *bp++ = digits[*b >> 4]; /* convert byte to ascii hex */
952 *bp++ = digits[*b++ & 0xf];
960 #endif /* NPPP > 0 */