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.6 1995/10/27 04:00:10 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));
117 int pppinput __P((int c, struct tty *tp));
118 int pppstart __P((struct tty *tp));
120 static u_short pppfcs __P((u_short fcs, u_char *cp, int len));
121 static void pppasyncstart __P((struct ppp_softc *));
122 static void pppasyncctlp __P((struct ppp_softc *));
123 static void pppasyncrelinq __P((struct ppp_softc *));
124 static void ppp_timeout __P((void *));
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.
164 * Called from device open routine or ttioctl.
170 register struct tty *tp;
172 register struct ppp_softc *sc;
174 struct proc *p = u.u_procp;
181 if (tp->t_line == PPPDISC) {
182 sc = (struct ppp_softc *) tp->t_sc;
183 if (sc != NULL && sc->sc_devp == (void *) tp) {
189 if ((sc = pppalloc(p->p_pid)) == NULL) {
195 (*sc->sc_relinq)(sc); /* get previous owner to relinquish the unit */
199 bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
200 sc->sc_asyncmap[0] = 0xffffffff;
201 sc->sc_asyncmap[3] = 0x60000000;
202 sc->sc_rasyncmap = 0;
203 sc->sc_devp = (void *) tp;
204 sc->sc_start = pppasyncstart;
205 sc->sc_ctlp = pppasyncctlp;
206 sc->sc_relinq = pppasyncrelinq;
209 sc->sc_if.if_flags |= IFF_RUNNING;
211 tp->t_sc = (caddr_t) sc;
212 ttyflush(tp, FREAD | FWRITE);
219 * Line specific close routine, called from device close routine
221 * Detach the tty from the ppp unit.
222 * Mimics part of ttyclose().
229 register struct ppp_softc *sc;
234 ttyflush(tp, FREAD|FWRITE);
236 sc = (struct ppp_softc *) tp->t_sc;
239 if (tp == (struct tty *) sc->sc_devp) {
249 * Relinquish the interface unit to another device.
253 struct ppp_softc *sc;
259 m_freem(sc->sc_outm);
266 if (sc->sc_flags & SC_TIMEOUT) {
267 untimeout(ppp_timeout, (void *) sc);
268 sc->sc_flags &= ~SC_TIMEOUT;
274 * Line specific (tty) read routine.
277 pppread(tp, uio, flag)
278 register struct tty *tp;
282 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
290 * Loop waiting for input, checking that nothing disasterous
291 * happens in the meantime.
295 if (tp != (struct tty *) sc->sc_devp || tp->t_line != PPPDISC) {
299 if (sc->sc_inq.ifq_head != NULL)
301 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0
302 && (tp->t_state & TS_ISOPEN)) {
304 return 0; /* end of file */
306 if (tp->t_state & (TS_ASYNC | TS_NBIO)) {
308 return (EWOULDBLOCK);
310 sleep((caddr_t) &tp->t_rawq, TTIPRI);
313 /* Pull place-holder byte out of canonical queue */
316 /* Get the packet from the input queue */
317 IF_DEQUEUE(&sc->sc_inq, m0);
320 for (m = m0; m && uio->uio_resid; m = m->m_next)
321 if (error = uiomove(mtod(m, u_char *), m->m_len, UIO_READ, uio))
328 * Line specific (tty) write routine.
331 pppwrite(tp, uio, flag)
332 register struct tty *tp;
336 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
337 struct mbuf *m, *m0, **mp, *p;
341 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
342 return 0; /* wrote 0 bytes */
343 if (tp->t_line != PPPDISC)
345 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
347 if (uio->uio_resid > sc->sc_if.if_mtu + PPP_HDRLEN ||
348 uio->uio_resid < PPP_HDRLEN)
350 for (mp = &m0; uio->uio_resid; mp = &m->m_next) {
351 MGET(m, M_WAIT, MT_DATA);
352 if ((*mp = m) == NULL) {
356 if (uio->uio_resid >= CLBYTES / 2) {
360 len = MIN(m->m_len, uio->uio_resid);
361 if (error = uiomove(mtod(m, u_char *), len, UIO_WRITE, uio)) {
367 dst.sa_family = AF_UNSPEC;
368 bcopy(mtod(m0, caddr_t), dst.sa_data, PPP_HDRLEN);
369 m0->m_off += PPP_HDRLEN;
370 m0->m_len -= PPP_HDRLEN;
371 return (pppoutput(&sc->sc_if, m0, &dst));
375 * Line specific (tty) ioctl routine.
376 * This discipline requires that tty device drivers call
377 * the line specific l_ioctl routine from their ioctl routines.
381 ppptioctl(tp, cmd, data, flag)
386 struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
389 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
394 case PPPIOCSASYNCMAP:
397 sc->sc_asyncmap[0] = *(u_int *)data;
400 case PPPIOCGASYNCMAP:
401 *(u_int *)data = sc->sc_asyncmap[0];
404 case PPPIOCSRASYNCMAP:
407 sc->sc_rasyncmap = *(u_int *)data;
410 case PPPIOCGRASYNCMAP:
411 *(u_int *)data = sc->sc_rasyncmap;
414 case PPPIOCSXASYNCMAP:
418 bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
419 sc->sc_asyncmap[1] = 0; /* mustn't escape 0x20 - 0x3f */
420 sc->sc_asyncmap[2] &= ~0x40000000; /* mustn't escape 0x5e */
421 sc->sc_asyncmap[3] |= 0x60000000; /* must escape 0x7d, 0x7e */
425 case PPPIOCGXASYNCMAP:
426 bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));
430 error = pppioctl(sc, cmd, data, flag);
431 if (error == 0 && cmd == PPPIOCSMRU)
439 * FCS lookup table as calculated by genfcstab.
441 static u_short fcstab[256] = {
442 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
443 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
444 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
445 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
446 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
447 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
448 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
449 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
450 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
451 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
452 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
453 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
454 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
455 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
456 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
457 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
458 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
459 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
460 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
461 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
462 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
463 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
464 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
465 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
466 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
467 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
468 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
469 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
470 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
471 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
472 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
473 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
477 * Calculate a new FCS given the current FCS and the new data.
481 register u_short fcs;
486 fcs = PPP_FCS(fcs, *cp++);
491 * This gets called from pppoutput when a new packet is
492 * put on a queue, at splnet.
496 register struct ppp_softc *sc;
498 register struct tty *tp = (struct tty *) sc->sc_devp;
507 * This gets called when a received packet is placed on
508 * the inq, at splnet.
512 struct ppp_softc *sc;
517 /* Put a placeholder byte in canq for ttselect()/ttnread(). */
519 tp = (struct tty *) sc->sc_devp;
520 putc(0, &tp->t_canq);
526 * Start output on async tty interface. Get another datagram
527 * to send from the interface queue and start sending it.
528 * Called at spltty or higher.
532 register struct tty *tp;
534 register struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
535 register struct mbuf *m;
537 register u_char *start, *stop, *cp;
538 int n, s, ndone, done, idle;
541 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0
542 || sc == NULL || tp != (struct tty *) sc->sc_devp) {
543 if (tp->t_oproc != NULL)
549 while (CCOUNT(&tp->t_outq) < PPP_HIWAT) {
551 * See if we have an existing packet partly sent.
552 * If not, get a new packet and start sending it.
557 * Get another packet to be sent.
566 * The extra PPP_FLAG will start up a new packet, and thus
567 * will flush any accumulated garbage. We do this whenever
568 * the line may have been idle for some time.
570 if (CCOUNT(&tp->t_outq) == 0) {
572 (void) putc(PPP_FLAG, &tp->t_outq);
575 /* Calculate the FCS for the first mbuf's worth. */
576 sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);
580 start = mtod(m, u_char *);
585 * Find out how many bytes in the string we can
586 * handle without doing something special.
588 for (cp = start; cp < stop; cp++)
593 ndone = n - b_to_q(start, n, &tp->t_outq);
596 sc->sc_bytessent += ndone;
599 break; /* packet doesn't fit */
602 * If there are characters left in the mbuf,
603 * the first one must be special..
604 * Put it out in a different form.
607 if (putc(PPP_ESCAPE, &tp->t_outq))
609 if (putc(*start ^ PPP_TRANS, &tp->t_outq)) {
610 (void) unputc(&tp->t_outq);
613 sc->sc_bytessent += 2;
620 * If we didn't empty this mbuf, remember where we're up to.
621 * If we emptied the last mbuf, try to add the FCS and closing
622 * flag, and if we can't, leave sc_outm pointing to m, but with
623 * m->m_len == 0, to remind us to output the FCS and flag later.
626 if (done && m->m_next == NULL) {
632 * We may have to escape the bytes in the FCS.
635 c = ~sc->sc_outfcs & 0xFF;
638 *p++ = c ^ PPP_TRANS;
641 c = (~sc->sc_outfcs >> 8) & 0xFF;
644 *p++ = c ^ PPP_TRANS;
650 * Try to output the FCS and flag. If the bytes
651 * don't all fit, back out.
653 for (q = endseq; q < p; ++q)
654 if (putc(*q, &tp->t_outq)) {
656 for (; q > endseq; --q)
660 sc->sc_bytessent += q - endseq;
664 m->m_off += m->m_len - len;
669 /* Finished with this mbuf; free it and move on. */
673 /* Finished a packet */
674 sc->sc_if.if_opackets++;
677 sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
681 * Here we have either finished a packet (m == NULL)
682 * or filled up the output queue (m != NULL).
690 * If there is stuff in the output queue, send it now.
691 * We are being called in lieu of ttstart and must do what it would.
693 if (tp->t_oproc != NULL)
697 * This timeout is needed for operation on a pseudo-tty,
698 * because the pty code doesn't call pppstart after it has
699 * drained the t_outq.
701 if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) {
702 timeout(ppp_timeout, (void *) sc, 1);
703 sc->sc_flags |= SC_TIMEOUT;
710 * Timeout routine - try to start some more output.
716 struct ppp_softc *sc = (struct ppp_softc *) x;
717 struct tty *tp = (struct tty *) sc->sc_devp;
721 sc->sc_flags &= ~SC_TIMEOUT;
727 * Allocate enough mbuf to handle current MRU.
731 register struct ppp_softc *sc;
733 struct mbuf *m, **mp, *p;
739 for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
740 if ((m = *mp) == NULL) {
741 MGET(m, M_DONTWAIT, MT_DATA);
747 len -= M_DATASIZE(m);
754 * tty interface receiver interrupt.
756 static unsigned paritytab[8] = {
757 0x96696996, 0x69969669, 0x69969669, 0x96696996,
758 0x69969669, 0x96696996, 0x96696996, 0x69969669
764 register struct tty *tp;
766 register struct ppp_softc *sc;
771 sc = (struct ppp_softc *) tp->t_sc;
772 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
775 s = spltty(); /* should be unnecessary */
781 if (sc->sc_flags & SC_XONXOFF) {
783 if ((tp->t_state & TS_TTSTOP) == 0) {
784 tp->t_state |= TS_TTSTOP;
785 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
790 tp->t_state &= ~TS_TTSTOP;
791 if (tp->t_oproc != NULL)
798 sc->sc_flags |= SC_RCV_B7_1;
800 sc->sc_flags |= SC_RCV_B7_0;
801 if (paritytab[c >> 5] & (1 << (c & 0x1F)))
802 sc->sc_flags |= SC_RCV_ODDP;
804 sc->sc_flags |= SC_RCV_EVNP;
806 if (sc->sc_flags & SC_LOG_RAWIN)
813 if (sc->sc_rawin_count > 0)
817 * If SC_ESCAPED is set, then we've seen the packet
818 * abort sequence "}~".
820 if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
821 || ilen > 0 && sc->sc_fcs != PPP_GOODFCS) {
822 sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */
823 if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
824 if (sc->sc_flags & SC_DEBUG)
825 printf("ppp%d: bad fcs %x\n", sc->sc_if.if_unit,
827 sc->sc_if.if_ierrors++;
829 sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
834 if (ilen < PPP_HDRLEN + PPP_FCSLEN) {
836 if (sc->sc_flags & SC_DEBUG)
837 printf("ppp%d: too short (%d)\n", sc->sc_if.if_unit, ilen);
838 sc->sc_if.if_ierrors++;
839 sc->sc_flags |= SC_PKTLOST;
846 * Remove FCS trailer. Somewhat painful...
849 if (--sc->sc_mc->m_len == 0) {
850 for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next)
856 /* excise this mbuf chain */
858 sc->sc_m = sc->sc_mc->m_next;
859 sc->sc_mc->m_next = NULL;
861 ppppktin(sc, m, sc->sc_flags & SC_PKTLOST);
862 sc->sc_flags &= ~SC_PKTLOST;
869 if (sc->sc_flags & SC_FLUSH) {
870 if (sc->sc_flags & SC_LOG_FLUSH)
876 if (c < 0x20 && (sc->sc_rasyncmap & (1 << c))) {
881 if (sc->sc_flags & SC_ESCAPED) {
882 sc->sc_flags &= ~SC_ESCAPED;
884 } else if (c == PPP_ESCAPE) {
885 sc->sc_flags |= SC_ESCAPED;
891 * Initialize buffer on first octet received.
892 * First octet could be address or protocol (when compressing
894 * Second octet is control.
895 * Third octet is first or second (when compressing protocol)
897 * Fourth octet is second octet of protocol.
899 if (sc->sc_ilen == 0) {
900 /* reset the first input mbuf */
901 if (sc->sc_m == NULL) {
903 if (sc->sc_m == NULL) {
904 if (sc->sc_flags & SC_DEBUG)
905 printf("ppp%d: no input mbufs!\n", sc->sc_if.if_unit);
911 m->m_off = M_OFFSTART(m);
913 sc->sc_mp = mtod(m, char *);
914 sc->sc_fcs = PPP_INITFCS;
915 if (c != PPP_ALLSTATIONS) {
916 if (sc->sc_flags & SC_REJ_COMP_AC) {
917 if (sc->sc_flags & SC_DEBUG)
918 printf("ppp%d: garbage received: 0x%x (need 0xFF)\n",
919 sc->sc_if.if_unit, c);
922 *sc->sc_mp++ = PPP_ALLSTATIONS;
923 *sc->sc_mp++ = PPP_UI;
928 if (sc->sc_ilen == 1 && c != PPP_UI) {
929 if (sc->sc_flags & SC_DEBUG)
930 printf("ppp%d: missing UI (0x3), got 0x%x\n",
931 sc->sc_if.if_unit, c);
934 if (sc->sc_ilen == 2 && (c & 1) == 1) {
935 /* a compressed protocol */
940 if (sc->sc_ilen == 3 && (c & 1) == 0) {
941 if (sc->sc_flags & SC_DEBUG)
942 printf("ppp%d: bad protocol %x\n", sc->sc_if.if_unit,
943 (sc->sc_mp[-1] << 8) + c);
947 /* packet beyond configured mru? */
948 if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) {
949 if (sc->sc_flags & SC_DEBUG)
950 printf("ppp%d: packet too big\n", sc->sc_if.if_unit);
954 /* is this mbuf full? */
956 if (M_TRAILINGSPACE(m) <= 0) {
957 if (m->m_next == NULL) {
959 if (m->m_next == NULL) {
960 if (sc->sc_flags & SC_DEBUG)
961 printf("ppp%d: too few input mbufs!\n", sc->sc_if.if_unit);
965 sc->sc_mc = m = m->m_next;
967 m->m_off = M_OFFSTART(m);
968 sc->sc_mp = mtod(m, char *);
973 sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);
978 if (!(sc->sc_flags & SC_FLUSH)) {
979 sc->sc_if.if_ierrors++;
980 sc->sc_flags |= SC_FLUSH;
981 if (sc->sc_flags & SC_LOG_FLUSH)
988 #define MAX_DUMP_BYTES 128
992 struct ppp_softc *sc;
996 sc->sc_rawin[sc->sc_rawin_count++] = c;
997 if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
998 || c < 0 && sc->sc_rawin_count > 0) {
999 printf("ppp%d input: ", sc->sc_if.if_unit);
1000 pppdumpb(sc->sc_rawin, sc->sc_rawin_count);
1001 sc->sc_rawin_count = 0;
1010 char buf[3*MAX_DUMP_BYTES+4];
1012 static char digits[] = "0123456789abcdef";
1015 if (bp >= buf + sizeof(buf) - 3) {
1019 *bp++ = digits[*b >> 4]; /* convert byte to ascii hex */
1020 *bp++ = digits[*b++ & 0xf];
1025 printf("%s\n", buf);
1028 #endif /* NPPP > 0 */