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 /* $FreeBSD: src/sys/net/ppp_tty.c,v 1.43.2.1 2002/02/13 00:43:11 dillon Exp $ */
74 /* $DragonFly: src/sys/net/ppp_layer/ppp_tty.c,v 1.10 2004/06/02 14:42:59 eirikn Exp $ */
76 #include "opt_ppp.h" /* XXX for ppp_defs.h */
78 #define VJC /* XXX for ppp_defs.h */
80 #include <sys/param.h>
81 #include <sys/systm.h>
84 #include <sys/dkstat.h>
85 #include <sys/socket.h>
86 #include <sys/fcntl.h>
90 #include <sys/vnode.h>
93 #include <i386/isa/intr_machdep.h>
99 #include <net/ppp/if_ppp.h>
100 #include <net/ppp/if_pppvar.h>
102 static int pppopen (dev_t dev, struct tty *tp);
103 static int pppclose (struct tty *tp, int flag);
104 static int pppread (struct tty *tp, struct uio *uio, int flag);
105 static int pppwrite (struct tty *tp, struct uio *uio, int flag);
106 static int ppptioctl (struct tty *tp, u_long cmd, caddr_t data,
107 int flag, struct thread *);
108 static int pppinput (int c, struct tty *tp);
109 static int pppstart (struct tty *tp);
111 static u_short pppfcs (u_short fcs, u_char *cp, int len);
112 static void pppasyncstart (struct ppp_softc *);
113 static void pppasyncctlp (struct ppp_softc *);
114 static void pppasyncrelinq (struct ppp_softc *);
115 static void pppasyncsetmtu (struct ppp_softc *);
116 static void ppp_timeout (void *);
117 static void pppgetm (struct ppp_softc *sc);
118 static void ppplogchar (struct ppp_softc *, int);
120 /* XXX called from if_ppp.c - layering violation */
121 void pppasyncattach (void *);
124 * Some useful mbuf macros not in mbuf.h.
126 #define M_IS_CLUSTER(m) ((m)->m_flags & M_EXT)
128 #define M_DATASTART(m) \
129 (M_IS_CLUSTER(m) ? (m)->m_ext.ext_buf : \
130 (m)->m_flags & M_PKTHDR ? (m)->m_pktdat : (m)->m_dat)
132 #define M_DATASIZE(m) \
133 (M_IS_CLUSTER(m) ? (m)->m_ext.ext_size : \
134 (m)->m_flags & M_PKTHDR ? MHLEN: MLEN)
137 * Does c need to be escaped?
139 #define ESCAPE_P(c) (sc->sc_asyncmap[(c) >> 5] & (1 << ((c) & 0x1F)))
142 * Procedures for using an async tty interface for PPP.
145 /* This is a FreeBSD-2.X kernel. */
146 #define CCOUNT(q) ((q)->c_cc)
147 #define PPP_LOWAT 100 /* Process more output when < LOWAT on queue */
148 #define PPP_HIWAT 400 /* Don't start a new packet if HIWAT on que */
151 * Define the PPP line discipline.
154 static struct linesw pppdisc = {
155 pppopen, pppclose, pppread, pppwrite,
156 ppptioctl, pppinput, pppstart, ttymodem,
161 pppasyncattach(dummy)
170 * Make sure that the soft net "engine" cannot run while spltty code is
171 * active. The if_ppp.c code can walk down into b_to_q etc, and it is
172 * bad if the tty system was in the middle of another b_to_q...
174 tty_imask |= softnet_imask; /* spltty() block spl[soft]net() */
175 net_imask |= softtty_imask; /* splimp() block splsofttty() */
176 net_imask |= tty_imask; /* splimp() block spltty() */
181 printf("new masks: bio %x, tty %x, net %x\n",
182 bio_imask, tty_imask, net_imask);
185 /* register line discipline */
186 linesw[PPPDISC] = pppdisc;
190 * Line specific open routine for async tty devices.
191 * Attach the given tty to the first available ppp unit.
192 * Called from device open routine or ttioctl() at >= splsofttty()
196 pppopen(dev_t dev, struct tty *tp)
198 struct thread *td = curthread; /* XXX */
199 struct ppp_softc *sc;
202 if ((error = suser(td)) != 0)
207 if (tp->t_line == PPPDISC) {
208 sc = (struct ppp_softc *) tp->t_sc;
209 if (sc != NULL && sc->sc_devp == (void *) tp) {
215 if ((sc = pppalloc(td)) == NULL) {
221 (*sc->sc_relinq)(sc); /* get previous owner to relinquish the unit */
225 bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
226 sc->sc_asyncmap[0] = 0xffffffff;
227 sc->sc_asyncmap[3] = 0x60000000;
228 sc->sc_rasyncmap = 0;
229 sc->sc_devp = (void *) tp;
230 sc->sc_start = pppasyncstart;
231 sc->sc_ctlp = pppasyncctlp;
232 sc->sc_relinq = pppasyncrelinq;
233 sc->sc_setmtu = pppasyncsetmtu;
236 sc->sc_if.if_flags |= IFF_RUNNING;
237 getmicrotime(&sc->sc_if.if_lastchange);
238 sc->sc_if.if_baudrate = tp->t_ospeed;
240 tp->t_sc = (caddr_t) sc;
241 ttyflush(tp, FREAD | FWRITE);
244 * Pre-allocate cblocks to the "just right" amount. The 1 byte t_canq
245 * allocation helps avoid the need for select and/or FIONREAD.
246 * We also pass 1 byte tokens through t_canq...
248 clist_alloc_cblocks(&tp->t_canq, 1, 1);
249 clist_alloc_cblocks(&tp->t_outq, sc->sc_if.if_mtu + PPP_HIWAT,
250 sc->sc_if.if_mtu + PPP_HIWAT);
251 clist_alloc_cblocks(&tp->t_rawq, 0, 0);
259 * Line specific close routine, called from device close routine
260 * and from ttioctl at >= splsofttty().
261 * Detach the tty from the ppp unit.
262 * Mimics part of ttyclose().
269 struct ppp_softc *sc;
273 ttyflush(tp, FREAD | FWRITE);
274 clist_free_cblocks(&tp->t_canq);
275 clist_free_cblocks(&tp->t_outq);
277 sc = (struct ppp_softc *) tp->t_sc;
280 if (tp == (struct tty *) sc->sc_devp) {
290 * Relinquish the interface unit to another device.
294 struct ppp_softc *sc;
300 m_freem(sc->sc_outm);
307 if (sc->sc_flags & SC_TIMEOUT) {
308 untimeout(ppp_timeout, (void *) sc, sc->sc_ch);
309 sc->sc_flags &= ~SC_TIMEOUT;
315 * This gets called from the upper layer to notify a mtu change
319 struct ppp_softc *sc;
321 struct tty *tp = (struct tty *) sc->sc_devp;
326 clist_alloc_cblocks(&tp->t_outq, sc->sc_if.if_mtu + PPP_HIWAT,
327 sc->sc_if.if_mtu + PPP_HIWAT);
332 * Line specific (tty) read routine.
333 * called at zero spl from the device driver in the response to user-level
334 * reads on the tty file descriptor (ie: pppd).
337 pppread(tp, uio, flag)
342 struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
350 * Loop waiting for input, checking that nothing disasterous
351 * happens in the meantime.
355 if (tp != (struct tty *) sc->sc_devp || tp->t_line != PPPDISC) {
359 if (sc->sc_inq.ifq_head != NULL)
361 if ((tp->t_state & TS_CONNECTED) == 0) {
363 return 0; /* end of file */
365 if (tp->t_state & TS_ASYNC || flag & IO_NDELAY) {
367 return (EWOULDBLOCK);
369 error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), PCATCH, "pppin", 0);
376 /* Pull place-holder byte out of canonical queue */
379 /* Get the packet from the input queue */
380 IF_DEQUEUE(&sc->sc_inq, m0);
383 for (m = m0; m && uio->uio_resid; m = m->m_next)
384 if ((error = uiomove(mtod(m, u_char *), m->m_len, uio)) != 0)
391 * Line specific (tty) write routine.
392 * called at zero spl from the device driver in the response to user-level
393 * writes on the tty file descriptor (ie: pppd).
396 pppwrite(tp, uio, flag)
401 struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
402 struct mbuf *m, *m0, **mp;
406 if ((tp->t_state & TS_CONNECTED) == 0)
407 return 0; /* wrote 0 bytes */
408 if (tp->t_line != PPPDISC)
410 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
412 if (uio->uio_resid > sc->sc_if.if_mtu + PPP_HDRLEN ||
413 uio->uio_resid < PPP_HDRLEN)
417 for (mp = &m0; uio->uio_resid; mp = &m->m_next) {
418 MGET(m, MB_WAIT, MT_DATA);
419 if ((*mp = m) == NULL) {
425 if (uio->uio_resid >= MCLBYTES / 2)
426 MCLGET(m, MB_DONTWAIT);
427 len = M_TRAILINGSPACE(m);
428 if (len > uio->uio_resid)
429 len = uio->uio_resid;
430 if ((error = uiomove(mtod(m, u_char *), len, uio)) != 0) {
437 dst.sa_family = AF_UNSPEC;
438 bcopy(mtod(m0, u_char *), dst.sa_data, PPP_HDRLEN);
439 m0->m_data += PPP_HDRLEN;
440 m0->m_len -= PPP_HDRLEN;
442 /* call the upper layer to "transmit" it... */
443 error = pppoutput(&sc->sc_if, m0, &dst, (struct rtentry *)0);
449 * Line specific (tty) ioctl routine.
450 * This discipline requires that tty device drivers call
451 * the line specific l_ioctl routine from their ioctl routines.
455 ppptioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct thread *td)
457 struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
460 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
465 case PPPIOCSASYNCMAP:
466 if ((error = suser(td)) != 0)
468 sc->sc_asyncmap[0] = *(u_int *)data;
471 case PPPIOCGASYNCMAP:
472 *(u_int *)data = sc->sc_asyncmap[0];
475 case PPPIOCSRASYNCMAP:
476 if ((error = suser(td)) != 0)
478 sc->sc_rasyncmap = *(u_int *)data;
481 case PPPIOCGRASYNCMAP:
482 *(u_int *)data = sc->sc_rasyncmap;
485 case PPPIOCSXASYNCMAP:
486 if ((error = suser(td)) != 0)
489 bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
490 sc->sc_asyncmap[1] = 0; /* mustn't escape 0x20 - 0x3f */
491 sc->sc_asyncmap[2] &= ~0x40000000; /* mustn't escape 0x5e */
492 sc->sc_asyncmap[3] |= 0x60000000; /* must escape 0x7d, 0x7e */
496 case PPPIOCGXASYNCMAP:
497 bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));
501 error = pppioctl(sc, cmd, data, flag, td);
502 if (error == 0 && cmd == PPPIOCSMRU)
510 * FCS lookup table as calculated by genfcstab.
512 static u_short fcstab[256] = {
513 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
514 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
515 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
516 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
517 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
518 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
519 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
520 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
521 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
522 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
523 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
524 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
525 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
526 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
527 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
528 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
529 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
530 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
531 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
532 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
533 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
534 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
535 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
536 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
537 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
538 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
539 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
540 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
541 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
542 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
543 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
544 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
548 * Calculate a new FCS given the current FCS and the new data.
551 pppfcs(u_short fcs, u_char *cp, int len)
554 fcs = PPP_FCS(fcs, *cp++);
559 * This gets called at splsoftnet from if_ppp.c at various times
560 * when there is data ready to be sent.
564 struct ppp_softc *sc;
566 struct tty *tp = (struct tty *) sc->sc_devp;
569 u_char *start, *stop, *cp;
570 int n, ndone, done, idle;
574 /* XXX assumes atomic access to *tp although we're not at spltty(). */
575 while (CCOUNT(&tp->t_outq) < PPP_HIWAT) {
577 * See if we have an existing packet partly sent.
578 * If not, get a new packet and start sending it.
583 * Get another packet to be sent.
592 * The extra PPP_FLAG will start up a new packet, and thus
593 * will flush any accumulated garbage. We do this whenever
594 * the line may have been idle for some time.
597 if (CCOUNT(&tp->t_outq) == 0) {
598 ++sc->sc_stats.ppp_obytes;
599 (void) putc(PPP_FLAG, &tp->t_outq);
602 /* Calculate the FCS for the first mbuf's worth. */
603 sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);
604 getmicrotime(&sc->sc_if.if_lastchange);
608 start = mtod(m, u_char *);
613 * Find out how many bytes in the string we can
614 * handle without doing something special.
616 for (cp = start; cp < stop; cp++)
621 /* NetBSD (0.9 or later), 4.3-Reno or similar. */
622 ndone = n - b_to_q(start, n, &tp->t_outq);
625 sc->sc_stats.ppp_obytes += ndone;
628 break; /* packet doesn't fit */
631 * If there are characters left in the mbuf,
632 * the first one must be special.
633 * Put it out in a different form.
637 if (putc(PPP_ESCAPE, &tp->t_outq)) {
641 if (putc(*start ^ PPP_TRANS, &tp->t_outq)) {
642 (void) unputc(&tp->t_outq);
647 sc->sc_stats.ppp_obytes += 2;
654 * If we didn't empty this mbuf, remember where we're up to.
655 * If we emptied the last mbuf, try to add the FCS and closing
656 * flag, and if we can't, leave sc_outm pointing to m, but with
657 * m->m_len == 0, to remind us to output the FCS and flag later.
660 if (done && m->m_next == NULL) {
666 * We may have to escape the bytes in the FCS.
669 c = ~sc->sc_outfcs & 0xFF;
672 *p++ = c ^ PPP_TRANS;
675 c = (~sc->sc_outfcs >> 8) & 0xFF;
678 *p++ = c ^ PPP_TRANS;
684 * Try to output the FCS and flag. If the bytes
685 * don't all fit, back out.
688 for (q = endseq; q < p; ++q)
689 if (putc(*q, &tp->t_outq)) {
691 for (; q > endseq; --q)
697 sc->sc_stats.ppp_obytes += q - endseq;
701 /* remember where we got to */
707 /* Finished with this mbuf; free it and move on. */
710 /* Finished a packet */
713 sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
717 * If m == NULL, we have finished a packet.
718 * If m != NULL, we've either done as much work this time
719 * as we need to, or else we've filled up the output queue.
726 /* Call pppstart to start output again if necessary. */
731 * This timeout is needed for operation on a pseudo-tty,
732 * because the pty code doesn't call pppstart after it has
733 * drained the t_outq.
735 if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) {
736 sc->sc_ch = timeout(ppp_timeout, (void *) sc, 1);
737 sc->sc_flags |= SC_TIMEOUT;
744 * This gets called when a received packet is placed on
745 * the inq, at splsoftnet. The pppd daemon is to be woken up to do a read().
749 struct ppp_softc *sc;
754 /* Put a placeholder byte in canq for ttselect()/ttnread(). */
756 tp = (struct tty *) sc->sc_devp;
757 putc(0, &tp->t_canq);
763 * Start output on async tty interface. If the transmit queue
764 * has drained sufficiently, arrange for pppasyncstart to be
765 * called later at splsoftnet.
766 * Called at spltty or higher.
772 struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
775 * Call output process whether or not there is any output.
776 * We are being called in lieu of ttstart and must do what it would.
778 if (tp->t_oproc != NULL)
782 * If the transmit queue has drained and the tty has not hung up
783 * or been disconnected from the ppp unit, then tell if_ppp.c that
784 * we need more output.
786 if (CCOUNT(&tp->t_outq) < PPP_LOWAT
787 && !((tp->t_state & TS_CONNECTED) == 0)
788 && sc != NULL && tp == (struct tty *) sc->sc_devp) {
796 * Timeout routine - try to start some more output.
802 struct ppp_softc *sc = (struct ppp_softc *) x;
803 struct tty *tp = (struct tty *) sc->sc_devp;
807 sc->sc_flags &= ~SC_TIMEOUT;
813 * Allocate enough mbuf to handle current MRU.
817 struct ppp_softc *sc;
819 struct mbuf *m, **mp;
823 for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
824 if ((m = *mp) == NULL) {
825 MGETHDR(m, MB_DONTWAIT, MT_DATA);
829 MCLGET(m, MB_DONTWAIT);
831 len -= M_DATASIZE(m);
837 * tty interface receiver interrupt.
839 static unsigned paritytab[8] = {
840 0x96696996, 0x69969669, 0x69969669, 0x96696996,
841 0x69969669, 0x96696996, 0x96696996, 0x69969669
845 * Called when character is available from device driver.
846 * Only guaranteed to be at splsofttty() or spltty()
847 * This is safe to be called while the upper half's netisr is preempted.
854 struct ppp_softc *sc;
858 sc = (struct ppp_softc *) tp->t_sc;
859 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
863 ++sc->sc_stats.ppp_ibytes;
865 if ((tp->t_state & TS_CONNECTED) == 0) {
866 if (sc->sc_flags & SC_DEBUG)
867 printf("%s: no carrier\n", sc->sc_if.if_xname);
871 if (c & TTY_ERRORMASK) {
872 /* framing error or overrun on this char - abort packet */
873 if (sc->sc_flags & SC_DEBUG)
874 printf("%s: line error %x\n", sc->sc_if.if_xname,
882 * Handle software flow control of output.
884 if (tp->t_iflag & IXON) {
885 if (c == tp->t_cc[VSTOP] && tp->t_cc[VSTOP] != _POSIX_VDISABLE) {
886 if ((tp->t_state & TS_TTSTOP) == 0) {
887 tp->t_state |= TS_TTSTOP;
892 if (c == tp->t_cc[VSTART] && tp->t_cc[VSTART] != _POSIX_VDISABLE) {
893 tp->t_state &= ~TS_TTSTOP;
894 if (tp->t_oproc != NULL)
902 sc->sc_flags |= SC_RCV_B7_1;
904 sc->sc_flags |= SC_RCV_B7_0;
905 if (paritytab[c >> 5] & (1 << (c & 0x1F)))
906 sc->sc_flags |= SC_RCV_ODDP;
908 sc->sc_flags |= SC_RCV_EVNP;
911 if (sc->sc_flags & SC_LOG_RAWIN)
918 if (sc->sc_rawin_count > 0)
922 * If SC_ESCAPED is set, then we've seen the packet
923 * abort sequence "}~".
925 if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
926 || (ilen > 0 && sc->sc_fcs != PPP_GOODFCS)) {
928 sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */
929 if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
930 if (sc->sc_flags & SC_DEBUG)
931 printf("%s: bad fcs %x, pkt len %d\n",
932 sc->sc_if.if_xname, sc->sc_fcs, ilen);
933 sc->sc_if.if_ierrors++;
934 sc->sc_stats.ppp_ierrors++;
936 sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
941 if (ilen < PPP_HDRLEN + PPP_FCSLEN) {
943 if (sc->sc_flags & SC_DEBUG)
944 printf("%s: too short (%d)\n", sc->sc_if.if_xname, ilen);
946 sc->sc_if.if_ierrors++;
947 sc->sc_stats.ppp_ierrors++;
948 sc->sc_flags |= SC_PKTLOST;
955 * Remove FCS trailer. Somewhat painful...
958 if (--sc->sc_mc->m_len == 0) {
959 for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next)
965 /* excise this mbuf chain */
967 sc->sc_m = sc->sc_mc->m_next;
968 sc->sc_mc->m_next = NULL;
970 ppppktin(sc, m, sc->sc_flags & SC_PKTLOST);
971 if (sc->sc_flags & SC_PKTLOST) {
973 sc->sc_flags &= ~SC_PKTLOST;
981 if (sc->sc_flags & SC_FLUSH) {
982 if (sc->sc_flags & SC_LOG_FLUSH)
987 if (c < 0x20 && (sc->sc_rasyncmap & (1 << c)))
991 if (sc->sc_flags & SC_ESCAPED) {
992 sc->sc_flags &= ~SC_ESCAPED;
994 } else if (c == PPP_ESCAPE) {
995 sc->sc_flags |= SC_ESCAPED;
1002 * Initialize buffer on first octet received.
1003 * First octet could be address or protocol (when compressing
1005 * Second octet is control.
1006 * Third octet is first or second (when compressing protocol)
1007 * octet of protocol.
1008 * Fourth octet is second octet of protocol.
1010 if (sc->sc_ilen == 0) {
1011 /* reset the first input mbuf */
1012 if (sc->sc_m == NULL) {
1014 if (sc->sc_m == NULL) {
1015 if (sc->sc_flags & SC_DEBUG)
1016 printf("%s: no input mbufs!\n", sc->sc_if.if_xname);
1022 m->m_data = M_DATASTART(sc->sc_m);
1024 sc->sc_mp = mtod(m, char *);
1025 sc->sc_fcs = PPP_INITFCS;
1026 if (c != PPP_ALLSTATIONS) {
1027 if (sc->sc_flags & SC_REJ_COMP_AC) {
1028 if (sc->sc_flags & SC_DEBUG)
1029 printf("%s: garbage received: 0x%x (need 0xFF)\n",
1030 sc->sc_if.if_xname, c);
1033 *sc->sc_mp++ = PPP_ALLSTATIONS;
1034 *sc->sc_mp++ = PPP_UI;
1039 if (sc->sc_ilen == 1 && c != PPP_UI) {
1040 if (sc->sc_flags & SC_DEBUG)
1041 printf("%s: missing UI (0x3), got 0x%x\n",
1042 sc->sc_if.if_xname, c);
1045 if (sc->sc_ilen == 2 && (c & 1) == 1) {
1046 /* a compressed protocol */
1051 if (sc->sc_ilen == 3 && (c & 1) == 0) {
1052 if (sc->sc_flags & SC_DEBUG)
1053 printf("%s: bad protocol %x\n", sc->sc_if.if_xname,
1054 (sc->sc_mp[-1] << 8) + c);
1058 /* packet beyond configured mru? */
1059 if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) {
1060 if (sc->sc_flags & SC_DEBUG)
1061 printf("%s: packet too big\n", sc->sc_if.if_xname);
1065 /* is this mbuf full? */
1067 if (M_TRAILINGSPACE(m) <= 0) {
1068 if (m->m_next == NULL) {
1070 if (m->m_next == NULL) {
1071 if (sc->sc_flags & SC_DEBUG)
1072 printf("%s: too few input mbufs!\n", sc->sc_if.if_xname);
1076 sc->sc_mc = m = m->m_next;
1078 m->m_data = M_DATASTART(m);
1079 sc->sc_mp = mtod(m, char *);
1084 sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);
1088 if (!(sc->sc_flags & SC_FLUSH)) {
1090 sc->sc_if.if_ierrors++;
1091 sc->sc_stats.ppp_ierrors++;
1092 sc->sc_flags |= SC_FLUSH;
1094 if (sc->sc_flags & SC_LOG_FLUSH)
1100 #define MAX_DUMP_BYTES 128
1104 struct ppp_softc *sc;
1108 sc->sc_rawin[sc->sc_rawin_count++] = c;
1109 if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
1110 || (c < 0 && sc->sc_rawin_count > 0)) {
1111 printf("%s input: %*D", sc->sc_if.if_xname,
1112 sc->sc_rawin_count, sc->sc_rawin, " ");
1113 sc->sc_rawin_count = 0;