1 /* $Id: ppp_tty.c,v 1.1 1995/12/11 05:17:10 paulus Exp $ */
4 * ppp_tty.c - Point-to-Point Protocol (PPP) driver for asynchronous
7 * Copyright (c) 1989 Carnegie Mellon University.
10 * Redistribution and use in source and binary forms are permitted
11 * provided that the above copyright notice and this paragraph are
12 * duplicated in all such forms and that any documentation,
13 * advertising materials, and other materials related to such
14 * distribution and use acknowledge that the software was developed
15 * by Carnegie Mellon University. The name of the
16 * University may not be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 * Carnegie Mellon University
25 * Pittsburgh, PA 15213
30 * @(#)if_sl.c 7.6.1.2 (Berkeley) 2/15/89
32 * Copyright (c) 1987 Regents of the University of California.
33 * All rights reserved.
35 * Redistribution and use in source and binary forms are permitted
36 * provided that the above copyright notice and this paragraph are
37 * duplicated in all such forms and that any documentation,
38 * advertising materials, and other materials related to such
39 * distribution and use acknowledge that the software was developed
40 * by the University of California, Berkeley. The name of the
41 * University may not be used to endorse or promote products derived
42 * from this software without specific prior written permission.
43 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
44 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
45 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
47 * Serial Line interface
50 * Center for Seismic Studies
51 * 1300 N 17th Street, Suite 1450
52 * Arlington, Virginia 22209
57 * Pounded on heavily by Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris).
58 * Converted to 4.3BSD Beta by Chris Torek.
59 * Other changes made at Berkeley, based in part on code by Kirk Smith.
61 * Converted to 4.3BSD+ 386BSD by Brad Parker (brad@cayman.com)
62 * Added VJ tcp header compression; more unified ioctls
64 * Extensively modified by Paul Mackerras (paulus@cs.anu.edu.au).
65 * Cleaned up a lot of the mbuf-related code to fix bugs that
66 * caused system crashes and packet corruption. Changed pppstart
67 * so that it doesn't just give up with a collision if the whole
68 * packet doesn't fit in the output ring buffer.
70 * Added priority queueing for interactive IP packets, following
71 * the model of if_sl.c, plus hooks for bpf.
72 * Paul Mackerras (paulus@cs.anu.edu.au).
75 /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
76 /* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */
84 #include <sys/param.h>
87 #include <sys/dkstat.h>
88 #include <sys/socket.h>
89 #include <sys/ioctl.h>
92 #include <sys/kernel.h>
94 #include <sys/vnode.h>
97 #include <net/if_types.h>
100 #include <netinet/in.h>
101 #include <netinet/in_systm.h>
102 #include <netinet/ip.h>
103 #include <net/slcompress.h>
106 #include <net/ppp_defs.h>
107 #include <net/if_ppp.h>
108 #include <net/if_pppvar.h>
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_int16_t pppfcs __P((u_int16_t 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 NetBSD-1.0 or later kernel. */
151 #define CCOUNT(q) ((q)->c_cc)
153 #define PPP_HIWAT 400 /* Don't start a new packet if HIWAT on que */
156 * Line specific open routine for async tty devices.
157 * Attach the given tty to the first available ppp unit.
158 * Called from device open routine or ttioctl.
164 register struct tty *tp;
166 struct proc *p = curproc; /* XXX */
167 register struct ppp_softc *sc;
170 if (error = suser(p->p_ucred, &p->p_acflag))
175 if (tp->t_line == PPPDISC) {
176 sc = (struct ppp_softc *) tp->t_sc;
177 if (sc != NULL && sc->sc_devp == (void *) tp) {
183 if ((sc = pppalloc(p->p_pid)) == NULL) {
189 (*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;
204 sc->sc_if.if_baudrate = tp->t_ospeed;
206 tp->t_sc = (caddr_t) sc;
207 ttyflush(tp, FREAD | FWRITE);
214 * Line specific close routine, called from device close routine
216 * Detach the tty from the ppp unit.
217 * Mimics part of ttyclose().
224 register struct ppp_softc *sc;
229 ttyflush(tp, FREAD|FWRITE);
231 sc = (struct ppp_softc *) tp->t_sc;
234 if (tp == (struct tty *) sc->sc_devp) {
244 * Relinquish the interface unit to another device.
248 struct ppp_softc *sc;
254 m_freem(sc->sc_outm);
261 if (sc->sc_flags & SC_TIMEOUT) {
262 untimeout(ppp_timeout, (void *) sc);
263 sc->sc_flags &= ~SC_TIMEOUT;
269 * Line specific (tty) read routine.
272 pppread(tp, uio, flag)
273 register struct tty *tp;
277 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
285 * Loop waiting for input, checking that nothing disasterous
286 * happens in the meantime.
290 if (tp != (struct tty *) sc->sc_devp || tp->t_line != PPPDISC) {
294 if (sc->sc_inq.ifq_head != NULL)
296 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0
297 && (tp->t_state & TS_ISOPEN)) {
299 return 0; /* end of file */
301 if (tp->t_state & TS_ASYNC || flag & IO_NDELAY) {
303 return (EWOULDBLOCK);
305 error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI|PCATCH, ttyin, 0);
312 /* Pull place-holder byte out of canonical queue */
315 /* Get the packet from the input queue */
316 IF_DEQUEUE(&sc->sc_inq, m0);
319 for (m = m0; m && uio->uio_resid; m = m->m_next)
320 if (error = uiomove(mtod(m, u_char *), m->m_len, uio))
327 * Line specific (tty) write routine.
330 pppwrite(tp, uio, flag)
331 register struct tty *tp;
335 register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
336 struct mbuf *m, *m0, **mp;
340 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
341 return 0; /* wrote 0 bytes */
342 if (tp->t_line != PPPDISC)
344 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
346 if (uio->uio_resid > sc->sc_if.if_mtu + PPP_HDRLEN ||
347 uio->uio_resid < PPP_HDRLEN)
349 for (mp = &m0; uio->uio_resid; mp = &m->m_next) {
350 MGET(m, M_WAIT, MT_DATA);
351 if ((*mp = m) == NULL) {
356 if (uio->uio_resid >= MCLBYTES / 2)
357 MCLGET(m, M_DONTWAIT);
358 len = M_TRAILINGSPACE(m);
359 if (len > uio->uio_resid)
360 len = uio->uio_resid;
361 if (error = uiomove(mtod(m, u_char *), len, uio)) {
367 dst.sa_family = AF_UNSPEC;
368 bcopy(mtod(m0, u_char *), dst.sa_data, PPP_HDRLEN);
369 m0->m_data += PPP_HDRLEN;
370 m0->m_len -= PPP_HDRLEN;
371 return (pppoutput(&sc->sc_if, m0, &dst, (struct rtentry *)0));
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, p)
388 struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
391 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
396 case PPPIOCSASYNCMAP:
397 if (error = suser(p->p_ucred, &p->p_acflag))
399 sc->sc_asyncmap[0] = *(u_int *)data;
402 case PPPIOCGASYNCMAP:
403 *(u_int *)data = sc->sc_asyncmap[0];
406 case PPPIOCSRASYNCMAP:
407 if (error = suser(p->p_ucred, &p->p_acflag))
409 sc->sc_rasyncmap = *(u_int *)data;
412 case PPPIOCGRASYNCMAP:
413 *(u_int *)data = sc->sc_rasyncmap;
416 case PPPIOCSXASYNCMAP:
417 if (error = suser(p->p_ucred, &p->p_acflag))
420 bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
421 sc->sc_asyncmap[1] = 0; /* mustn't escape 0x20 - 0x3f */
422 sc->sc_asyncmap[2] &= ~0x40000000; /* mustn't escape 0x5e */
423 sc->sc_asyncmap[3] |= 0x60000000; /* must escape 0x7d, 0x7e */
427 case PPPIOCGXASYNCMAP:
428 bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));
432 error = pppioctl(sc, cmd, data, flag, p);
433 if (error == 0 && cmd == PPPIOCSMRU)
441 * FCS lookup table as calculated by genfcstab.
443 static u_int16_t fcstab[256] = {
444 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
445 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
446 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
447 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
448 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
449 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
450 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
451 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
452 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
453 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
454 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
455 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
456 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
457 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
458 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
459 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
460 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
461 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
462 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
463 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
464 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
465 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
466 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
467 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
468 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
469 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
470 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
471 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
472 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
473 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
474 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
475 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
479 * Calculate a new FCS given the current FCS and the new data.
483 register u_int16_t fcs;
488 fcs = PPP_FCS(fcs, *cp++);
493 * This gets called from pppoutput when a new packet is
494 * put on a queue, at splsoftnet.
498 register struct ppp_softc *sc;
500 register struct tty *tp = (struct tty *) sc->sc_devp;
509 * This gets called when a received packet is placed on
510 * the inq, at splsoftnet.
514 struct ppp_softc *sc;
519 /* Put a placeholder byte in canq for ttselect()/ttnread(). */
521 tp = (struct tty *) sc->sc_devp;
522 putc(0, &tp->t_canq);
528 * Start output on async tty interface. Get another datagram
529 * to send from the interface queue and start sending it.
530 * Called at spltty or higher.
534 register struct tty *tp;
536 register struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
537 register struct mbuf *m;
539 register u_char *start, *stop, *cp;
540 int n, s, ndone, done, idle;
543 if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0
544 || sc == NULL || tp != (struct tty *) sc->sc_devp) {
545 if (tp->t_oproc != NULL)
551 while (CCOUNT(&tp->t_outq) < PPP_HIWAT) {
553 * See if we have an existing packet partly sent.
554 * If not, get a new packet and start sending it.
559 * Get another packet to be sent.
568 * The extra PPP_FLAG will start up a new packet, and thus
569 * will flush any accumulated garbage. We do this whenever
570 * the line may have been idle for some time.
572 if (CCOUNT(&tp->t_outq) == 0) {
574 (void) putc(PPP_FLAG, &tp->t_outq);
577 /* Calculate the FCS for the first mbuf's worth. */
578 sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);
579 sc->sc_if.if_lastchange = time;
583 start = mtod(m, u_char *);
588 * Find out how many bytes in the string we can
589 * handle without doing something special.
591 for (cp = start; cp < stop; cp++)
596 /* NetBSD (0.9 or later), 4.3-Reno or similar. */
597 ndone = n - b_to_q(start, n, &tp->t_outq);
600 sc->sc_bytessent += ndone;
603 break; /* packet doesn't fit */
606 * If there are characters left in the mbuf,
607 * the first one must be special..
608 * Put it out in a different form.
611 if (putc(PPP_ESCAPE, &tp->t_outq))
613 if (putc(*start ^ PPP_TRANS, &tp->t_outq)) {
614 (void) unputc(&tp->t_outq);
617 sc->sc_bytessent += 2;
624 * If we didn't empty this mbuf, remember where we're up to.
625 * If we emptied the last mbuf, try to add the FCS and closing
626 * flag, and if we can't, leave sc_outm pointing to m, but with
627 * m->m_len == 0, to remind us to output the FCS and flag later.
630 if (done && m->m_next == NULL) {
636 * We may have to escape the bytes in the FCS.
639 c = ~sc->sc_outfcs & 0xFF;
642 *p++ = c ^ PPP_TRANS;
645 c = (~sc->sc_outfcs >> 8) & 0xFF;
648 *p++ = c ^ PPP_TRANS;
654 * Try to output the FCS and flag. If the bytes
655 * don't all fit, back out.
657 for (q = endseq; q < p; ++q)
658 if (putc(*q, &tp->t_outq)) {
660 for (; q > endseq; --q)
664 sc->sc_bytessent += q - endseq;
668 /* remember where we got to */
674 /* Finished with this mbuf; free it and move on. */
678 /* Finished a packet */
679 sc->sc_if.if_opackets++;
680 sc->sc_if.if_obytes = sc->sc_bytessent;
683 sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
687 * Here we have either finished a packet (m == NULL)
688 * or filled up the output queue (m != NULL).
696 * If there is stuff in the output queue, send it now.
697 * We are being called in lieu of ttstart and must do what it would.
699 if (tp->t_oproc != NULL)
703 * This timeout is needed for operation on a pseudo-tty,
704 * because the pty code doesn't call pppstart after it has
705 * drained the t_outq.
707 if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) {
708 timeout(ppp_timeout, (void *) sc, 1);
709 sc->sc_flags |= SC_TIMEOUT;
716 * Timeout routine - try to start some more output.
722 struct ppp_softc *sc = (struct ppp_softc *) x;
723 struct tty *tp = (struct tty *) sc->sc_devp;
727 sc->sc_flags &= ~SC_TIMEOUT;
733 * Allocate enough mbuf to handle current MRU.
737 register struct ppp_softc *sc;
739 struct mbuf *m, **mp;
745 for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
746 if ((m = *mp) == NULL) {
747 MGETHDR(m, M_DONTWAIT, MT_DATA);
751 MCLGET(m, M_DONTWAIT);
753 len -= M_DATASIZE(m);
760 * tty interface receiver interrupt.
762 static unsigned paritytab[8] = {
763 0x96696996, 0x69969669, 0x69969669, 0x96696996,
764 0x69969669, 0x96696996, 0x96696996, 0x69969669
770 register struct tty *tp;
772 register struct ppp_softc *sc;
776 sc = (struct ppp_softc *) tp->t_sc;
777 if (sc == NULL || tp != (struct tty *) sc->sc_devp)
780 s = spltty(); /* should be unnecessary */
785 /* framing error or overrun on this char - abort packet */
786 if (sc->sc_flags & SC_DEBUG)
787 printf("ppp%d: bad char %x\n", sc->sc_if.if_unit, c);
794 * Handle software flow control of output.
796 if (tp->t_iflag & IXON) {
797 if (c == tp->t_cc[VSTOP] && tp->t_cc[VSTOP] != _POSIX_VDISABLE) {
798 if ((tp->t_state & TS_TTSTOP) == 0) {
799 tp->t_state |= TS_TTSTOP;
800 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
804 if (c == tp->t_cc[VSTART] && tp->t_cc[VSTART] != _POSIX_VDISABLE) {
805 tp->t_state &= ~TS_TTSTOP;
806 if (tp->t_oproc != NULL)
813 sc->sc_flags |= SC_RCV_B7_1;
815 sc->sc_flags |= SC_RCV_B7_0;
816 if (paritytab[c >> 5] & (1 << (c & 0x1F)))
817 sc->sc_flags |= SC_RCV_ODDP;
819 sc->sc_flags |= SC_RCV_EVNP;
821 if (sc->sc_flags & SC_LOG_RAWIN)
827 sc->sc_if.if_ibytes = sc->sc_bytesrcvd;
829 if (sc->sc_rawin_count > 0)
833 * If SC_ESCAPED is set, then we've seen the packet
834 * abort sequence "}~".
836 if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
837 || ilen > 0 && sc->sc_fcs != PPP_GOODFCS) {
838 sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */
839 if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
840 if (sc->sc_flags & SC_DEBUG)
841 printf("ppp%d: bad fcs %x\n", sc->sc_if.if_unit,
843 sc->sc_if.if_ierrors++;
845 sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
850 if (ilen < PPP_HDRLEN + PPP_FCSLEN) {
852 if (sc->sc_flags & SC_DEBUG)
853 printf("ppp%d: too short (%d)\n", sc->sc_if.if_unit, ilen);
854 sc->sc_if.if_ierrors++;
855 sc->sc_flags |= SC_PKTLOST;
862 * Remove FCS trailer. Somewhat painful...
865 if (--sc->sc_mc->m_len == 0) {
866 for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next)
872 /* excise this mbuf chain */
874 sc->sc_m = sc->sc_mc->m_next;
875 sc->sc_mc->m_next = NULL;
877 ppppktin(sc, m, sc->sc_flags & SC_PKTLOST);
878 sc->sc_flags &= ~SC_PKTLOST;
885 if (sc->sc_flags & SC_FLUSH) {
886 if (sc->sc_flags & SC_LOG_FLUSH)
892 if (c < 0x20 && (sc->sc_rasyncmap & (1 << c))) {
897 if (sc->sc_flags & SC_ESCAPED) {
898 sc->sc_flags &= ~SC_ESCAPED;
900 } else if (c == PPP_ESCAPE) {
901 sc->sc_flags |= SC_ESCAPED;
907 * Initialize buffer on first octet received.
908 * First octet could be address or protocol (when compressing
910 * Second octet is control.
911 * Third octet is first or second (when compressing protocol)
913 * Fourth octet is second octet of protocol.
915 if (sc->sc_ilen == 0) {
916 /* reset the first input mbuf */
917 if (sc->sc_m == NULL) {
919 if (sc->sc_m == NULL) {
920 if (sc->sc_flags & SC_DEBUG)
921 printf("ppp%d: no input mbufs!\n", sc->sc_if.if_unit);
927 m->m_data = M_DATASTART(sc->sc_m);
929 sc->sc_mp = mtod(m, char *);
930 sc->sc_fcs = PPP_INITFCS;
931 if (c != PPP_ALLSTATIONS) {
932 if (sc->sc_flags & SC_REJ_COMP_AC) {
933 if (sc->sc_flags & SC_DEBUG)
934 printf("ppp%d: garbage received: 0x%x (need 0xFF)\n",
935 sc->sc_if.if_unit, c);
938 *sc->sc_mp++ = PPP_ALLSTATIONS;
939 *sc->sc_mp++ = PPP_UI;
944 if (sc->sc_ilen == 1 && c != PPP_UI) {
945 if (sc->sc_flags & SC_DEBUG)
946 printf("ppp%d: missing UI (0x3), got 0x%x\n",
947 sc->sc_if.if_unit, c);
950 if (sc->sc_ilen == 2 && (c & 1) == 1) {
951 /* a compressed protocol */
956 if (sc->sc_ilen == 3 && (c & 1) == 0) {
957 if (sc->sc_flags & SC_DEBUG)
958 printf("ppp%d: bad protocol %x\n", sc->sc_if.if_unit,
959 (sc->sc_mp[-1] << 8) + c);
963 /* packet beyond configured mru? */
964 if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) {
965 if (sc->sc_flags & SC_DEBUG)
966 printf("ppp%d: packet too big\n", sc->sc_if.if_unit);
970 /* is this mbuf full? */
972 if (M_TRAILINGSPACE(m) <= 0) {
973 if (m->m_next == NULL) {
975 if (m->m_next == NULL) {
976 if (sc->sc_flags & SC_DEBUG)
977 printf("ppp%d: too few input mbufs!\n", sc->sc_if.if_unit);
981 sc->sc_mc = m = m->m_next;
983 m->m_data = M_DATASTART(m);
984 sc->sc_mp = mtod(m, char *);
989 sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);
994 if (!(sc->sc_flags & SC_FLUSH)) {
995 sc->sc_if.if_ierrors++;
996 sc->sc_flags |= SC_FLUSH;
997 if (sc->sc_flags & SC_LOG_FLUSH)
1004 #define MAX_DUMP_BYTES 128
1008 struct ppp_softc *sc;
1012 sc->sc_rawin[sc->sc_rawin_count++] = c;
1013 if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
1014 || c < 0 && sc->sc_rawin_count > 0) {
1015 printf("ppp%d input: ", sc->sc_if.if_unit);
1016 pppdumpb(sc->sc_rawin, sc->sc_rawin_count);
1017 sc->sc_rawin_count = 0;
1026 char buf[3*MAX_DUMP_BYTES+4];
1028 static char digits[] = "0123456789abcdef";
1031 if (bp >= buf + sizeof(buf) - 3) {
1035 *bp++ = digits[*b >> 4]; /* convert byte to ascii hex */
1036 *bp++ = digits[*b++ & 0xf];
1041 printf("%s\n", buf);
1044 #endif /* NPPP > 0 */