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).
73 /* $Id: ppp_tty.c,v 1.4 1995/10/27 03:34:44 paulus Exp $ */
74 /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
82 #include <sys/param.h>
83 #include <sys/systm.h>
86 #include <sys/dkstat.h>
87 #include <sys/socket.h>
88 #include <sys/ioctl.h>
91 #include <sys/kernel.h>
93 #include <sys/vnode.h>
96 #include <net/if_types.h>
99 #include <netinet/in.h>
100 #include <netinet/in_systm.h>
101 #include <netinet/ip.h>
102 #include <net/pppcompress.h>
105 #include <net/ppp_defs.h>
106 #include <net/if_ppp.h>
107 #include <net/if_pppvar.h>
109 void pppasyncattach __P((void));
110 int pppopen __P((dev_t dev, struct tty *tp));
111 int pppclose __P((struct tty *tp, int flag));
112 int pppread __P((struct tty *tp, struct uio *uio, int flag));
113 int pppwrite __P((struct tty *tp, struct uio *uio, int flag));
114 int ppptioctl __P((struct tty *tp, u_long cmd, caddr_t data, int flag,
116 int pppinput __P((int c, struct tty *tp));
117 int pppstart __P((struct tty *tp));
119 static u_short pppfcs __P((u_short fcs, u_char *cp, int len));
120 static void pppasyncstart __P((struct ppp_softc *));
121 static void pppasyncctlp __P((struct ppp_softc *));
122 static void pppasyncrelinq __P((struct ppp_softc *));
123 static void ppp_timeout __P((void *));
124 static void pppgetm __P((struct ppp_softc *sc));
125 static void pppdumpb __P((u_char *b, int l));
126 static void ppplogchar __P((struct ppp_softc *, int));
129 * Some useful mbuf macros not in mbuf.h.
131 #define M_IS_CLUSTER(m) ((m)->m_flags & M_EXT)
133 #define M_DATASTART(m) \
134 (M_IS_CLUSTER(m) ? (m)->m_ext.ext_buf : \
135 (m)->m_flags & M_PKTHDR ? (m)->m_pktdat : (m)->m_dat)
137 #define M_DATASIZE(m) \
138 (M_IS_CLUSTER(m) ? (m)->m_ext.ext_size : \
139 (m)->m_flags & M_PKTHDR ? MHLEN: MLEN)
142 * Does c need to be escaped?
144 #define ESCAPE_P(c) (sc->sc_asyncmap[(c) >> 5] & (1 << ((c) & 0x1F)))
147 * Procedures for using an async tty interface for PPP.
150 /* This is a FreeBSD-2.0 kernel. */
151 #define CCOUNT(q) ((q)->c_cc)
152 #define PPP_HIWAT 400 /* Don't start a new packet if HIWAT on que */
155 * Define the PPP line discipline.
158 static struct linesw pppdisc = {
159 pppopen, pppclose, pppread, pppwrite, ppptioctl,
160 pppinput, pppstart, ttymodem
166 linesw[PPPDISC] = pppdisc;
169 TEXT_SET(pseudo_set, pppasyncattach);
172 * Line specific open routine for async tty devices.
173 * Attach the given tty to the first available ppp unit.
174 * Called from device open routine or ttioctl.
180 register struct tty *tp;
182 struct proc *p = curproc; /* XXX */
183 register struct ppp_softc *sc;
186 if (error = suser(p->p_ucred, &p->p_acflag))
191 if (tp->t_line == PPPDISC) {
192 sc = (struct ppp_softc *) tp->t_sc;
193 if (sc != NULL && sc->sc_devp == (void *) tp) {
199 if ((sc = pppalloc(p->p_pid)) == NULL) {
205 (*sc->sc_relinq)(sc); /* get previous owner to relinquish the unit */
209 bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
210 sc->sc_asyncmap[0] = 0xffffffff;
211 sc->sc_asyncmap[3] = 0x60000000;
212 sc->sc_rasyncmap = 0;
213 sc->sc_devp = (void *) tp;
214 sc->sc_start = pppasyncstart;
215 sc->sc_ctlp = pppasyncctlp;
216 sc->sc_relinq = pppasyncrelinq;
219 sc->sc_if.if_flags |= IFF_RUNNING;
221 tp->t_sc = (caddr_t) sc;
222 ttyflush(tp, FREAD | FWRITE);
229 * Line specific close routine, called from device close routine
231 * Detach the tty from the ppp unit.
232 * Mimics part of ttyclose().
239 register struct ppp_softc *sc;
244 ttyflush(tp, FREAD|FWRITE);
246 sc = (struct ppp_softc *) tp->t_sc;
249 if (tp == (struct tty *) sc->sc_devp) {
259 * Relinquish the interface unit to another device.
263 struct ppp_softc *sc;
269 m_freem(sc->sc_outm);
276 if (sc->sc_flags & SC_TIMEOUT) {
277 untimeout(ppp_timeout, (void *) sc);
278 sc->sc_flags &= ~SC_TIMEOUT;
284 * Line specific (tty) read routine.
287 pppread(tp, uio, flag)
288 register struct tty *tp;
292 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
300 * Loop waiting for input, checking that nothing disasterous
301 * happens in the meantime.
305 if (tp != (struct tty *) sc->sc_devp || tp->t_line != PPPDISC) {
309 if (sc->sc_inq.ifq_head != NULL)
311 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0
312 && (tp->t_state & TS_ISOPEN)) {
314 return 0; /* end of file */
316 if (tp->t_state & TS_ASYNC || flag & IO_NDELAY) {
318 return (EWOULDBLOCK);
320 error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, "ttyin", 0);
327 /* Pull place-holder byte out of canonical queue */
330 /* Get the packet from the input queue */
331 IF_DEQUEUE(&sc->sc_inq, m0);
334 for (m = m0; m && uio->uio_resid; m = m->m_next)
335 if (error = uiomove(mtod(m, u_char *), m->m_len, uio))
342 * Line specific (tty) write routine.
345 pppwrite(tp, uio, flag)
346 register struct tty *tp;
350 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
351 struct mbuf *m, *m0, **mp;
355 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
356 return 0; /* wrote 0 bytes */
357 if (tp->t_line != PPPDISC)
359 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
361 if (uio->uio_resid > sc->sc_if.if_mtu + PPP_HDRLEN ||
362 uio->uio_resid < PPP_HDRLEN)
364 for (mp = &m0; uio->uio_resid; mp = &m->m_next) {
365 MGET(m, M_WAIT, MT_DATA);
366 if ((*mp = m) == NULL) {
371 if (uio->uio_resid >= MCLBYTES / 2)
372 MCLGET(m, M_DONTWAIT);
373 len = M_TRAILINGSPACE(m);
374 if (len > uio->uio_resid)
375 len = uio->uio_resid;
376 if (error = uiomove(mtod(m, u_char *), len, uio)) {
382 dst.sa_family = AF_UNSPEC;
383 bcopy(mtod(m0, u_char *), dst.sa_data, PPP_HDRLEN);
384 m0->m_data += PPP_HDRLEN;
385 m0->m_len -= PPP_HDRLEN;
386 return (pppoutput(&sc->sc_if, m0, &dst, (struct rtentry *)0));
390 * Line specific (tty) ioctl routine.
391 * This discipline requires that tty device drivers call
392 * the line specific l_ioctl routine from their ioctl routines.
396 ppptioctl(tp, cmd, data, flag, p)
403 struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
406 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
411 case PPPIOCSASYNCMAP:
412 if (error = suser(p->p_ucred, &p->p_acflag))
414 sc->sc_asyncmap[0] = *(u_int *)data;
417 case PPPIOCGASYNCMAP:
418 *(u_int *)data = sc->sc_asyncmap[0];
421 case PPPIOCSRASYNCMAP:
422 if (error = suser(p->p_ucred, &p->p_acflag))
424 sc->sc_rasyncmap = *(u_int *)data;
427 case PPPIOCGRASYNCMAP:
428 *(u_int *)data = sc->sc_rasyncmap;
431 case PPPIOCSXASYNCMAP:
432 if (error = suser(p->p_ucred, &p->p_acflag))
435 bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
436 sc->sc_asyncmap[1] = 0; /* mustn't escape 0x20 - 0x3f */
437 sc->sc_asyncmap[2] &= ~0x40000000; /* mustn't escape 0x5e */
438 sc->sc_asyncmap[3] |= 0x60000000; /* must escape 0x7d, 0x7e */
442 case PPPIOCGXASYNCMAP:
443 bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));
447 error = pppioctl(sc, cmd, data, flag, p);
448 if (error == 0 && cmd == PPPIOCSMRU)
456 * FCS lookup table as calculated by genfcstab.
458 static u_short fcstab[256] = {
459 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
460 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
461 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
462 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
463 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
464 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
465 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
466 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
467 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
468 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
469 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
470 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
471 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
472 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
473 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
474 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
475 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
476 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
477 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
478 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
479 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
480 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
481 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
482 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
483 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
484 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
485 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
486 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
487 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
488 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
489 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
490 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
494 * Calculate a new FCS given the current FCS and the new data.
498 register u_short fcs;
503 fcs = PPP_FCS(fcs, *cp++);
508 * This gets called from pppoutput when a new packet is
509 * put on a queue, at splnet.
513 register struct ppp_softc *sc;
515 register struct tty *tp = (struct tty *) sc->sc_devp;
524 * This gets called when a received packet is placed on
525 * the inq, at splnet.
529 struct ppp_softc *sc;
534 /* Put a placeholder byte in canq for ttselect()/ttnread(). */
536 tp = (struct tty *) sc->sc_devp;
537 putc(0, &tp->t_canq);
543 * Start output on async tty interface. Get another datagram
544 * to send from the interface queue and start sending it.
545 * Called at spltty or higher.
549 register struct tty *tp;
551 register struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
552 register struct mbuf *m;
554 register u_char *start, *stop, *cp;
555 int n, s, ndone, done, idle;
558 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0
559 || sc == NULL || tp != (struct tty *) sc->sc_devp) {
560 if (tp->t_oproc != NULL)
566 while (CCOUNT(&tp->t_outq) < PPP_HIWAT) {
568 * See if we have an existing packet partly sent.
569 * If not, get a new packet and start sending it.
574 * Get another packet to be sent.
583 * The extra PPP_FLAG will start up a new packet, and thus
584 * will flush any accumulated garbage. We do this whenever
585 * the line may have been idle for some time.
587 if (CCOUNT(&tp->t_outq) == 0) {
589 (void) putc(PPP_FLAG, &tp->t_outq);
592 /* Calculate the FCS for the first mbuf's worth. */
593 sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);
597 start = mtod(m, u_char *);
602 * Find out how many bytes in the string we can
603 * handle without doing something special.
605 for (cp = start; cp < stop; cp++)
610 /* NetBSD (0.9 or later), 4.3-Reno or similar. */
611 ndone = n - b_to_q(start, n, &tp->t_outq);
614 sc->sc_bytessent += ndone;
617 break; /* packet doesn't fit */
620 * If there are characters left in the mbuf,
621 * the first one must be special..
622 * Put it out in a different form.
625 if (putc(PPP_ESCAPE, &tp->t_outq))
627 if (putc(*start ^ PPP_TRANS, &tp->t_outq)) {
628 (void) unputc(&tp->t_outq);
631 sc->sc_bytessent += 2;
638 * If we didn't empty this mbuf, remember where we're up to.
639 * If we emptied the last mbuf, try to add the FCS and closing
640 * flag, and if we can't, leave sc_outm pointing to m, but with
641 * m->m_len == 0, to remind us to output the FCS and flag later.
644 if (done && m->m_next == NULL) {
650 * We may have to escape the bytes in the FCS.
653 c = ~sc->sc_outfcs & 0xFF;
656 *p++ = c ^ PPP_TRANS;
659 c = (~sc->sc_outfcs >> 8) & 0xFF;
662 *p++ = c ^ PPP_TRANS;
668 * Try to output the FCS and flag. If the bytes
669 * don't all fit, back out.
671 for (q = endseq; q < p; ++q)
672 if (putc(*q, &tp->t_outq)) {
674 for (; q > endseq; --q)
678 sc->sc_bytessent += q - endseq;
682 /* remember where we got to */
688 /* Finished with this mbuf; free it and move on. */
692 /* Finished a packet */
693 sc->sc_if.if_opackets++;
694 sc->sc_if.if_obytes = sc->sc_bytessent;
697 sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
701 * Here we have either finished a packet (m == NULL)
702 * or filled up the output queue (m != NULL).
710 * Send anything that may be in the output queue.
711 * We are being called in lieu of ttstart and must do what it would.
713 if (tp->t_oproc != NULL)
717 * This timeout is needed for operation on a pseudo-tty,
718 * because the pty code doesn't call pppstart after it has
719 * drained the t_outq.
721 if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) {
722 timeout(ppp_timeout, (void *) sc, 1);
723 sc->sc_flags |= SC_TIMEOUT;
730 * Timeout routine - try to start some more output.
736 struct ppp_softc *sc = (struct ppp_softc *) x;
737 struct tty *tp = (struct tty *) sc->sc_devp;
741 sc->sc_flags &= ~SC_TIMEOUT;
747 * Allocate enough mbuf to handle current MRU.
751 register struct ppp_softc *sc;
753 struct mbuf *m, **mp;
759 for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
760 if ((m = *mp) == NULL) {
761 MGETHDR(m, M_DONTWAIT, MT_DATA);
765 MCLGET(m, M_DONTWAIT);
767 len -= M_DATASIZE(m);
774 * tty interface receiver interrupt.
776 static unsigned paritytab[8] = {
777 0x96696996, 0x69969669, 0x69969669, 0x96696996,
778 0x69969669, 0x96696996, 0x96696996, 0x69969669
784 register struct tty *tp;
786 register struct ppp_softc *sc;
790 sc = (struct ppp_softc *) tp->t_sc;
791 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
794 s = spltty(); /* should be unnecessary */
799 /* framing error or overrun on this char - abort packet */
800 if (sc->sc_flags & SC_DEBUG)
801 printf("ppp%d: bad char %x\n", sc->sc_if.if_unit, c);
807 if (sc->sc_flags & SC_XONXOFF) {
809 if ((tp->t_state & TS_TTSTOP) == 0) {
810 tp->t_state |= TS_TTSTOP;
811 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
816 tp->t_state &= ~TS_TTSTOP;
817 if (tp->t_oproc != NULL)
824 sc->sc_flags |= SC_RCV_B7_1;
826 sc->sc_flags |= SC_RCV_B7_0;
827 if (paritytab[c >> 5] & (1 << (c & 0x1F)))
828 sc->sc_flags |= SC_RCV_ODDP;
830 sc->sc_flags |= SC_RCV_EVNP;
832 if (sc->sc_flags & SC_LOG_RAWIN)
838 sc->sc_if.if_ibytes = sc->sc_bytesrcvd;
840 if (sc->sc_rawin_count > 0)
844 * If SC_ESCAPED is set, then we've seen the packet
845 * abort sequence "}~".
847 if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
848 || ilen > 0 && sc->sc_fcs != PPP_GOODFCS) {
849 sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */
850 if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
851 if (sc->sc_flags & SC_DEBUG)
852 printf("ppp%d: bad fcs %x\n", sc->sc_if.if_unit,
854 sc->sc_if.if_ierrors++;
856 sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
861 if (ilen < PPP_HDRLEN + PPP_FCSLEN) {
863 if (sc->sc_flags & SC_DEBUG)
864 printf("ppp%d: too short (%d)\n", sc->sc_if.if_unit, ilen);
865 sc->sc_if.if_ierrors++;
866 sc->sc_flags |= SC_PKTLOST;
873 * Remove FCS trailer. Somewhat painful...
876 if (--sc->sc_mc->m_len == 0) {
877 for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next)
883 /* excise this mbuf chain */
885 sc->sc_m = sc->sc_mc->m_next;
886 sc->sc_mc->m_next = NULL;
888 ppppktin(sc, m, sc->sc_flags & SC_PKTLOST);
889 sc->sc_flags &= ~SC_PKTLOST;
896 if (sc->sc_flags & SC_FLUSH) {
897 if (sc->sc_flags & SC_LOG_FLUSH)
903 if (c < 0x20 && (sc->sc_rasyncmap & (1 << c))) {
908 if (sc->sc_flags & SC_ESCAPED) {
909 sc->sc_flags &= ~SC_ESCAPED;
911 } else if (c == PPP_ESCAPE) {
912 sc->sc_flags |= SC_ESCAPED;
918 * Initialize buffer on first octet received.
919 * First octet could be address or protocol (when compressing
921 * Second octet is control.
922 * Third octet is first or second (when compressing protocol)
924 * Fourth octet is second octet of protocol.
926 if (sc->sc_ilen == 0) {
927 /* reset the first input mbuf */
928 if (sc->sc_m == NULL) {
930 if (sc->sc_m == NULL) {
931 if (sc->sc_flags & SC_DEBUG)
932 printf("ppp%d: no input mbufs!\n", sc->sc_if.if_unit);
938 m->m_data = M_DATASTART(sc->sc_m);
940 sc->sc_mp = mtod(m, char *);
941 sc->sc_fcs = PPP_INITFCS;
942 if (c != PPP_ALLSTATIONS) {
943 if (sc->sc_flags & SC_REJ_COMP_AC) {
944 if (sc->sc_flags & SC_DEBUG)
945 printf("ppp%d: garbage received: 0x%x (need 0xFF)\n",
946 sc->sc_if.if_unit, c);
949 *sc->sc_mp++ = PPP_ALLSTATIONS;
950 *sc->sc_mp++ = PPP_UI;
955 if (sc->sc_ilen == 1 && c != PPP_UI) {
956 if (sc->sc_flags & SC_DEBUG)
957 printf("ppp%d: missing UI (0x3), got 0x%x\n",
958 sc->sc_if.if_unit, c);
961 if (sc->sc_ilen == 2 && (c & 1) == 1) {
962 /* a compressed protocol */
967 if (sc->sc_ilen == 3 && (c & 1) == 0) {
968 if (sc->sc_flags & SC_DEBUG)
969 printf("ppp%d: bad protocol %x\n", sc->sc_if.if_unit,
970 (sc->sc_mp[-1] << 8) + c);
974 /* packet beyond configured mru? */
975 if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) {
976 if (sc->sc_flags & SC_DEBUG)
977 printf("ppp%d: packet too big\n", sc->sc_if.if_unit);
981 /* is this mbuf full? */
983 if (M_TRAILINGSPACE(m) <= 0) {
984 if (m->m_next == NULL) {
986 if (m->m_next == NULL) {
987 if (sc->sc_flags & SC_DEBUG)
988 printf("ppp%d: too few input mbufs!\n", sc->sc_if.if_unit);
992 sc->sc_mc = m = m->m_next;
994 m->m_data = M_DATASTART(m);
995 sc->sc_mp = mtod(m, char *);
1000 sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);
1005 if (!(sc->sc_flags & SC_FLUSH)) {
1006 sc->sc_if.if_ierrors++;
1007 sc->sc_flags |= SC_FLUSH;
1008 if (sc->sc_flags & SC_LOG_FLUSH)
1015 #define MAX_DUMP_BYTES 128
1019 struct ppp_softc *sc;
1023 sc->sc_rawin[sc->sc_rawin_count++] = c;
1024 if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
1025 || c < 0 && sc->sc_rawin_count > 0) {
1026 printf("ppp%d input: ", sc->sc_if.if_unit);
1027 pppdumpb(sc->sc_rawin, sc->sc_rawin_count);
1028 sc->sc_rawin_count = 0;
1037 char buf[3*MAX_DUMP_BYTES+4];
1039 static char digits[] = "0123456789abcdef";
1042 if (bp >= buf + sizeof(buf) - 3) {
1046 *bp++ = digits[*b >> 4]; /* convert byte to ascii hex */
1047 *bp++ = digits[*b++ & 0xf];
1052 printf("%s\n", buf);
1055 #endif /* NPPP > 0 */