2 * ppp_tty.c - Point-to-Point Protocol (PPP) driver for asynchronous
6 * Copyright (c) 1989 Carnegie Mellon University.
9 * Redistribution and use in source and binary forms are permitted
10 * provided that the above copyright notice and this paragraph are
11 * duplicated in all such forms and that any documentation,
12 * advertising materials, and other materials related to such
13 * distribution and use acknowledge that the software was developed
14 * by Carnegie Mellon University. The name of the
15 * University may not be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
19 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 * Carnegie Mellon University
24 * Pittsburgh, PA 15213
29 * @(#)if_sl.c 7.6.1.2 (Berkeley) 2/15/89
31 * Copyright (c) 1987 Regents of the University of California.
32 * All rights reserved.
34 * Redistribution and use in source and binary forms are permitted
35 * provided that the above copyright notice and this paragraph are
36 * duplicated in all such forms and that any documentation,
37 * advertising materials, and other materials related to such
38 * distribution and use acknowledge that the software was developed
39 * by the University of California, Berkeley. The name of the
40 * University may not be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
43 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
44 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
46 * Serial Line interface
49 * Center for Seismic Studies
50 * 1300 N 17th Street, Suite 1450
51 * Arlington, Virginia 22209
56 * Pounded on heavily by Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris).
57 * Converted to 4.3BSD Beta by Chris Torek.
58 * Other changes made at Berkeley, based in part on code by Kirk Smith.
60 * Converted to 4.3BSD+ 386BSD by Brad Parker (brad@cayman.com)
61 * Added VJ tcp header compression; more unified ioctls
63 * Extensively modified by Paul Mackerras (paulus@cs.anu.edu.au).
64 * Cleaned up a lot of the mbuf-related code to fix bugs that
65 * caused system crashes and packet corruption. Changed pppstart
66 * so that it doesn't just give up with a "collision" if the whole
67 * packet doesn't fit in the output ring buffer.
69 * Added priority queueing for interactive IP packets, following
70 * the model of if_sl.c, plus hooks for bpf.
71 * Paul Mackerras (paulus@cs.anu.edu.au).
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>
85 #include <sys/socket.h>
86 #include <sys/fcntl.h>
94 #include <net/if_ppp.h>
95 #include <net/if_pppvar.h>
97 static int pppopen(struct cdev *dev, struct tty *tp);
98 static int pppclose(struct tty *tp, int flag);
99 static int pppread(struct tty *tp, struct uio *uio, int flag);
100 static int pppwrite(struct tty *tp, struct uio *uio, int flag);
101 static int ppptioctl(struct tty *tp, u_long cmd, caddr_t data,
102 int flag, struct thread *td);
103 static int pppinput(int c, struct tty *tp);
104 static int pppstart(struct tty *tp);
106 static u_short pppfcs(u_short fcs, u_char *cp, int len);
107 static void pppasyncstart(struct ppp_softc *);
108 static void pppasyncctlp(struct ppp_softc *);
109 static void pppasyncrelinq(struct ppp_softc *);
110 static void pppasyncsetmtu(struct ppp_softc *);
111 static void ppp_timeout(void *);
112 static void pppgetm(struct ppp_softc *sc);
113 static void ppplogchar(struct ppp_softc *, int);
115 /* XXX called from if_ppp.c - layering violation */
116 void pppasyncattach(void *);
117 void pppasyncdetach(void);
120 * Some useful mbuf macros not in mbuf.h.
122 #define M_IS_CLUSTER(m) ((m)->m_flags & M_EXT)
124 #define M_DATASTART(m) \
125 (M_IS_CLUSTER(m) ? (m)->m_ext.ext_buf : \
126 (m)->m_flags & M_PKTHDR ? (m)->m_pktdat : (m)->m_dat)
128 #define M_DATASIZE(m) \
129 (M_IS_CLUSTER(m) ? (m)->m_ext.ext_size : \
130 (m)->m_flags & M_PKTHDR ? MHLEN: MLEN)
133 * Does c need to be escaped?
135 #define ESCAPE_P(c) (sc->sc_asyncmap[(c) >> 5] & (1 << ((c) & 0x1F)))
138 * Procedures for using an async tty interface for PPP.
141 /* This is a FreeBSD-2.X kernel. */
142 #define CCOUNT(q) ((q)->c_cc)
143 #define PPP_LOWAT 100 /* Process more output when < LOWAT on queue */
144 #define PPP_HIWAT 400 /* Don't start a new packet if HIWAT on que */
147 * Define the PPP line discipline.
150 static struct linesw pppdisc = {
151 pppopen, pppclose, pppread, pppwrite,
152 ppptioctl, pppinput, pppstart, ttymodem
156 pppasyncattach(dummy)
159 ldisc_register(PPPDISC, &pppdisc);
165 ldisc_deregister(PPPDISC);
169 * Line specific open routine for async tty devices.
170 * Attach the given tty to the first available ppp unit.
171 * Called from device open routine or ttioctl() at >= splsofttty()
177 register struct tty *tp;
179 struct thread *td = curthread; /* XXX */
180 register struct ppp_softc *sc;
183 error = priv_check(td, PRIV_NET_PPP);
189 tp->t_hotchar = PPP_FLAG;
191 if ((sc = pppalloc(td->td_proc->p_pid)) == NULL) {
197 (*sc->sc_relinq)(sc); /* get previous owner to relinquish the unit */
201 bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
202 sc->sc_asyncmap[0] = 0xffffffff;
203 sc->sc_asyncmap[3] = 0x60000000;
204 sc->sc_rasyncmap = 0;
205 sc->sc_devp = (void *) tp;
206 sc->sc_start = pppasyncstart;
207 sc->sc_ctlp = pppasyncctlp;
208 sc->sc_relinq = pppasyncrelinq;
209 sc->sc_setmtu = pppasyncsetmtu;
212 PPP2IFP(sc)->if_drv_flags |= IFF_DRV_RUNNING;
213 getmicrotime(&PPP2IFP(sc)->if_lastchange);
214 PPP2IFP(sc)->if_baudrate = tp->t_ospeed;
216 tp->t_hotchar = PPP_FLAG;
218 ttyflush(tp, FREAD | FWRITE);
221 * Pre-allocate cblocks to the "just right" amount. The 1 byte t_canq
222 * allocation helps avoid the need for select and/or FIONREAD.
223 * We also pass 1 byte tokens through t_canq...
225 clist_alloc_cblocks(&tp->t_canq, 1, 1);
226 clist_alloc_cblocks(&tp->t_outq, PPP2IFP(sc)->if_mtu + PPP_HIWAT,
227 PPP2IFP(sc)->if_mtu + PPP_HIWAT);
228 clist_alloc_cblocks(&tp->t_rawq, 0, 0);
236 * Line specific close routine, called from device close routine
237 * and from ttioctl at >= splsofttty().
238 * Detach the tty from the ppp unit.
239 * Mimics part of tty_close().
246 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_lsc;
250 ttyflush(tp, FREAD | FWRITE);
251 clist_free_cblocks(&tp->t_canq);
252 clist_free_cblocks(&tp->t_outq);
262 * Relinquish the interface unit to another device.
266 struct ppp_softc *sc;
272 m_freem(sc->sc_outm);
279 if (sc->sc_flags & SC_TIMEOUT) {
280 callout_stop(&sc->sc_timo_ch);
281 sc->sc_flags &= ~SC_TIMEOUT;
287 * This gets called from the upper layer to notify a mtu change
291 register struct ppp_softc *sc;
293 register struct tty *tp = (struct tty *) sc->sc_devp;
298 clist_alloc_cblocks(&tp->t_outq, PPP2IFP(sc)->if_mtu + PPP_HIWAT,
299 PPP2IFP(sc)->if_mtu + PPP_HIWAT);
304 * Line specific (tty) read routine.
305 * called at zero spl from the device driver in the response to user-level
306 * reads on the tty file descriptor (ie: pppd).
309 pppread(tp, uio, flag)
310 register struct tty *tp;
314 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_lsc;
322 * Loop waiting for input, checking that nothing disasterous
323 * happens in the meantime.
327 if (tp != (struct tty *) sc->sc_devp || tp->t_line != PPPDISC) {
331 if (sc->sc_inq.ifq_head != NULL)
333 if ((tp->t_state & TS_CONNECTED) == 0) {
335 return 0; /* end of file */
337 if (tp->t_state & TS_ASYNC || flag & O_NONBLOCK) {
339 return (EWOULDBLOCK);
341 error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH, "pppin", 0);
348 /* Pull place-holder byte out of canonical queue */
351 /* Get the packet from the input queue */
352 IF_DEQUEUE(&sc->sc_inq, m0);
355 for (m = m0; m && uio->uio_resid; m = m->m_next)
356 if ((error = uiomove(mtod(m, u_char *), m->m_len, uio)) != 0)
363 * Line specific (tty) write routine.
364 * called at zero spl from the device driver in the response to user-level
365 * writes on the tty file descriptor (ie: pppd).
368 pppwrite(tp, uio, flag)
369 register struct tty *tp;
373 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_lsc;
378 if ((tp->t_state & TS_CONNECTED) == 0)
379 return 0; /* wrote 0 bytes */
380 if (tp->t_line != PPPDISC)
384 if (uio->uio_resid > PPP2IFP(sc)->if_mtu + PPP_HDRLEN ||
385 uio->uio_resid < PPP_HDRLEN)
389 if ((m = m_uiotombuf(uio, M_DONTWAIT, 0, 0, M_PKTHDR)) == NULL) {
394 dst.sa_family = AF_UNSPEC;
395 bcopy(mtod(m, u_char *), dst.sa_data, PPP_HDRLEN);
396 m->m_data += PPP_HDRLEN;
397 m->m_len -= PPP_HDRLEN;
399 /* call the upper layer to "transmit" it... */
400 error = pppoutput(PPP2IFP(sc), m, &dst, NULL);
406 * Line specific (tty) ioctl routine.
407 * This discipline requires that tty device drivers call
408 * the line specific l_ioctl routine from their ioctl routines.
412 ppptioctl(tp, cmd, data, flag, td)
419 struct ppp_softc *sc = (struct ppp_softc *)tp->t_lsc;
422 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
427 case PPPIOCSASYNCMAP:
428 error = priv_check(td, PRIV_NET_PPP);
431 sc->sc_asyncmap[0] = *(u_int *)data;
434 case PPPIOCGASYNCMAP:
435 *(u_int *)data = sc->sc_asyncmap[0];
438 case PPPIOCSRASYNCMAP:
439 error = priv_check(td, PRIV_NET_PPP);
442 sc->sc_rasyncmap = *(u_int *)data;
445 case PPPIOCGRASYNCMAP:
446 *(u_int *)data = sc->sc_rasyncmap;
449 case PPPIOCSXASYNCMAP:
450 error = priv_check(td, PRIV_NET_PPP);
454 bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
455 sc->sc_asyncmap[1] = 0; /* mustn't escape 0x20 - 0x3f */
456 sc->sc_asyncmap[2] &= ~0x40000000; /* mustn't escape 0x5e */
457 sc->sc_asyncmap[3] |= 0x60000000; /* must escape 0x7d, 0x7e */
461 case PPPIOCGXASYNCMAP:
462 bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));
466 error = pppioctl(sc, cmd, data, flag, td);
467 if (error == 0 && cmd == PPPIOCSMRU)
475 * FCS lookup table as calculated by genfcstab.
477 static u_short fcstab[256] = {
478 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
479 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
480 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
481 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
482 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
483 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
484 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
485 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
486 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
487 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
488 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
489 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
490 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
491 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
492 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
493 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
494 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
495 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
496 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
497 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
498 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
499 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
500 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
501 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
502 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
503 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
504 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
505 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
506 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
507 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
508 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
509 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
513 * Calculate a new FCS given the current FCS and the new data.
516 pppfcs(u_short fcs, u_char *cp, int len)
519 fcs = PPP_FCS(fcs, *cp++);
524 * This gets called at splsoftnet from if_ppp.c at various times
525 * when there is data ready to be sent.
529 register struct ppp_softc *sc;
531 register struct tty *tp = (struct tty *) sc->sc_devp;
532 register struct mbuf *m;
534 register u_char *start, *stop, *cp;
535 int n, ndone, done, idle;
539 /* XXX assumes atomic access to *tp although we're not at spltty(). */
540 while (CCOUNT(&tp->t_outq) < PPP_HIWAT) {
542 * See if we have an existing packet partly sent.
543 * If not, get a new packet and start sending it.
548 * Get another packet to be sent.
557 * The extra PPP_FLAG will start up a new packet, and thus
558 * will flush any accumulated garbage. We do this whenever
559 * the line may have been idle for some time.
562 if (CCOUNT(&tp->t_outq) == 0) {
563 ++sc->sc_stats.ppp_obytes;
564 (void) putc(PPP_FLAG, &tp->t_outq);
567 /* Calculate the FCS for the first mbuf's worth. */
568 sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);
569 getmicrotime(&PPP2IFP(sc)->if_lastchange);
573 start = mtod(m, u_char *);
578 * Find out how many bytes in the string we can
579 * handle without doing something special.
581 for (cp = start; cp < stop; cp++)
586 /* NetBSD (0.9 or later), 4.3-Reno or similar. */
587 ndone = n - b_to_q(start, n, &tp->t_outq);
590 sc->sc_stats.ppp_obytes += ndone;
593 break; /* packet doesn't fit */
596 * If there are characters left in the mbuf,
597 * the first one must be special.
598 * Put it out in a different form.
602 if (putc(PPP_ESCAPE, &tp->t_outq)) {
606 if (putc(*start ^ PPP_TRANS, &tp->t_outq)) {
607 (void) unputc(&tp->t_outq);
612 sc->sc_stats.ppp_obytes += 2;
619 * If we didn't empty this mbuf, remember where we're up to.
620 * If we emptied the last mbuf, try to add the FCS and closing
621 * flag, and if we can't, leave sc_outm pointing to m, but with
622 * m->m_len == 0, to remind us to output the FCS and flag later.
625 if (done && m->m_next == NULL) {
631 * We may have to escape the bytes in the FCS.
634 c = ~sc->sc_outfcs & 0xFF;
637 *p++ = c ^ PPP_TRANS;
640 c = (~sc->sc_outfcs >> 8) & 0xFF;
643 *p++ = c ^ PPP_TRANS;
649 * Try to output the FCS and flag. If the bytes
650 * 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)
662 sc->sc_stats.ppp_obytes += q - endseq;
666 /* remember where we got to */
672 /* Finished with this mbuf; free it and move on. */
675 /* Finished a packet */
678 sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
682 * If m == NULL, we have finished a packet.
683 * If m != NULL, we've either done as much work this time
684 * as we need to, or else we've filled up the output queue.
691 /* Call pppstart to start output again if necessary. */
696 * This timeout is needed for operation on a pseudo-tty,
697 * because the pty code doesn't call pppstart after it has
698 * drained the t_outq.
700 if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) {
701 callout_reset(&sc->sc_timo_ch, 1, ppp_timeout, sc);
702 sc->sc_flags |= SC_TIMEOUT;
709 * This gets called when a received packet is placed on
710 * the inq, at splsoftnet. The pppd daemon is to be woken up to do a read().
714 struct ppp_softc *sc;
719 /* Put a placeholder byte in canq for ttselect()/ttnread(). */
721 tp = (struct tty *) sc->sc_devp;
722 putc(0, &tp->t_canq);
728 * Start output on async tty interface. If the transmit queue
729 * has drained sufficiently, arrange for pppasyncstart to be
730 * called later at splsoftnet.
731 * Called at spltty or higher.
735 register struct tty *tp;
737 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_lsc;
740 * Call output process whether or not there is any output.
741 * We are being called in lieu of ttstart and must do what it would.
746 * If the transmit queue has drained and the tty has not hung up
747 * or been disconnected from the ppp unit, then tell if_ppp.c that
748 * we need more output.
750 if (CCOUNT(&tp->t_outq) < PPP_LOWAT
751 && !((tp->t_state & TS_CONNECTED) == 0)
760 * Timeout routine - try to start some more output.
766 struct ppp_softc *sc = (struct ppp_softc *) x;
767 struct tty *tp = (struct tty *) sc->sc_devp;
771 sc->sc_flags &= ~SC_TIMEOUT;
777 * Allocate enough mbuf to handle current MRU.
781 register struct ppp_softc *sc;
783 struct mbuf *m, **mp;
787 for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
788 if ((m = *mp) == NULL) {
789 MGETHDR(m, M_DONTWAIT, MT_DATA);
793 MCLGET(m, M_DONTWAIT);
795 len -= M_DATASIZE(m);
801 * tty interface receiver interrupt.
803 static unsigned paritytab[8] = {
804 0x96696996, 0x69969669, 0x69969669, 0x96696996,
805 0x69969669, 0x96696996, 0x96696996, 0x69969669
809 * Called when character is available from device driver.
810 * Only guaranteed to be at splsofttty() or spltty()
811 * This is safe to be called while the upper half's netisr is preempted.
816 register struct tty *tp;
818 register struct ppp_softc *sc;
822 sc = (struct ppp_softc *)tp->t_lsc;
827 ++sc->sc_stats.ppp_ibytes;
829 if ((tp->t_state & TS_CONNECTED) == 0) {
830 if (sc->sc_flags & SC_DEBUG)
831 if_printf(PPP2IFP(sc), "no carrier\n");
835 if (c & TTY_ERRORMASK) {
836 /* framing error or overrun on this char - abort packet */
837 if (sc->sc_flags & SC_DEBUG)
838 if_printf(PPP2IFP(sc), "line error %x\n", c & TTY_ERRORMASK);
845 * Handle software flow control of output.
847 if (tp->t_iflag & IXON) {
848 if (c == tp->t_cc[VSTOP] && tp->t_cc[VSTOP] != _POSIX_VDISABLE) {
849 if ((tp->t_state & TS_TTSTOP) == 0) {
850 tp->t_state |= TS_TTSTOP;
855 if (c == tp->t_cc[VSTART] && tp->t_cc[VSTART] != _POSIX_VDISABLE) {
856 tp->t_state &= ~TS_TTSTOP;
864 sc->sc_flags |= SC_RCV_B7_1;
866 sc->sc_flags |= SC_RCV_B7_0;
867 if (paritytab[c >> 5] & (1 << (c & 0x1F)))
868 sc->sc_flags |= SC_RCV_ODDP;
870 sc->sc_flags |= SC_RCV_EVNP;
873 if (sc->sc_flags & SC_LOG_RAWIN)
880 if (sc->sc_rawin_count > 0)
884 * If SC_ESCAPED is set, then we've seen the packet
885 * abort sequence "}~".
887 if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
888 || (ilen > 0 && sc->sc_fcs != PPP_GOODFCS)) {
890 sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */
891 if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
892 if (sc->sc_flags & SC_DEBUG)
893 if_printf(PPP2IFP(sc), "bad fcs %x, pkt len %d\n",
895 PPP2IFP(sc)->if_ierrors++;
896 sc->sc_stats.ppp_ierrors++;
898 sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
903 if (ilen < PPP_HDRLEN + PPP_FCSLEN) {
905 if (sc->sc_flags & SC_DEBUG)
906 if_printf(PPP2IFP(sc), "too short (%d)\n", ilen);
908 PPP2IFP(sc)->if_ierrors++;
909 sc->sc_stats.ppp_ierrors++;
910 sc->sc_flags |= SC_PKTLOST;
917 * Remove FCS trailer. Somewhat painful...
920 if (--sc->sc_mc->m_len == 0) {
921 for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next)
927 /* excise this mbuf chain */
929 sc->sc_m = sc->sc_mc->m_next;
930 sc->sc_mc->m_next = NULL;
932 ppppktin(sc, m, sc->sc_flags & SC_PKTLOST);
933 if (sc->sc_flags & SC_PKTLOST) {
935 sc->sc_flags &= ~SC_PKTLOST;
943 if (sc->sc_flags & SC_FLUSH) {
944 if (sc->sc_flags & SC_LOG_FLUSH)
949 if (c < 0x20 && (sc->sc_rasyncmap & (1 << c)))
953 if (sc->sc_flags & SC_ESCAPED) {
954 sc->sc_flags &= ~SC_ESCAPED;
956 } else if (c == PPP_ESCAPE) {
957 sc->sc_flags |= SC_ESCAPED;
964 * Initialize buffer on first octet received.
965 * First octet could be address or protocol (when compressing
967 * Second octet is control.
968 * Third octet is first or second (when compressing protocol)
970 * Fourth octet is second octet of protocol.
972 if (sc->sc_ilen == 0) {
973 /* reset the first input mbuf */
974 if (sc->sc_m == NULL) {
976 if (sc->sc_m == NULL) {
977 if (sc->sc_flags & SC_DEBUG)
978 if_printf(PPP2IFP(sc), "no input mbufs!\n");
984 m->m_data = M_DATASTART(sc->sc_m);
986 sc->sc_mp = mtod(m, char *);
987 sc->sc_fcs = PPP_INITFCS;
988 if (c != PPP_ALLSTATIONS) {
989 if (sc->sc_flags & SC_REJ_COMP_AC) {
990 if (sc->sc_flags & SC_DEBUG)
991 if_printf(PPP2IFP(sc),
992 "garbage received: 0x%x (need 0xFF)\n", c);
995 *sc->sc_mp++ = PPP_ALLSTATIONS;
996 *sc->sc_mp++ = PPP_UI;
1001 if (sc->sc_ilen == 1 && c != PPP_UI) {
1002 if (sc->sc_flags & SC_DEBUG)
1003 if_printf(PPP2IFP(sc), "missing UI (0x3), got 0x%x\n", c);
1006 if (sc->sc_ilen == 2 && (c & 1) == 1) {
1007 /* a compressed protocol */
1012 if (sc->sc_ilen == 3 && (c & 1) == 0) {
1013 if (sc->sc_flags & SC_DEBUG)
1014 if_printf(PPP2IFP(sc), "bad protocol %x\n",
1015 (sc->sc_mp[-1] << 8) + c);
1019 /* packet beyond configured mru? */
1020 if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) {
1021 if (sc->sc_flags & SC_DEBUG)
1022 if_printf(PPP2IFP(sc), "packet too big\n");
1026 /* is this mbuf full? */
1028 if (M_TRAILINGSPACE(m) <= 0) {
1029 if (m->m_next == NULL) {
1031 if (m->m_next == NULL) {
1032 if (sc->sc_flags & SC_DEBUG)
1033 if_printf(PPP2IFP(sc), "too few input mbufs!\n");
1037 sc->sc_mc = m = m->m_next;
1039 m->m_data = M_DATASTART(m);
1040 sc->sc_mp = mtod(m, char *);
1045 sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);
1049 if (!(sc->sc_flags & SC_FLUSH)) {
1051 PPP2IFP(sc)->if_ierrors++;
1052 sc->sc_stats.ppp_ierrors++;
1053 sc->sc_flags |= SC_FLUSH;
1055 if (sc->sc_flags & SC_LOG_FLUSH)
1061 #define MAX_DUMP_BYTES 128
1065 struct ppp_softc *sc;
1069 sc->sc_rawin[sc->sc_rawin_count++] = c;
1070 if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
1071 || (c < 0 && sc->sc_rawin_count > 0)) {
1072 printf("%s input: %*D", PPP2IFP(sc)->if_xname,
1073 sc->sc_rawin_count, sc->sc_rawin, " ");
1074 sc->sc_rawin_count = 0;