2 * ppp_ahdlc.c - STREAMS module for doing PPP asynchronous HDLC.
4 * Re-written by Adi Masputra <adi.masputra@sun.com>, based on
5 * the original ppp_ahdlc.c
7 * Copyright (c) 2000 by Sun Microsystems, Inc.
10 * Permission to use, copy, modify, and distribute this software and its
11 * documentation is hereby granted, provided that the above copyright
12 * notice appears in all copies.
14 * SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF
15 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
16 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
17 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
18 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
19 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES
21 * Copyright (c) 1994 The Australian National University.
22 * All rights reserved.
24 * Permission to use, copy, modify, and distribute this software and its
25 * documentation is hereby granted, provided that the above copyright
26 * notice appears in all copies. This software is provided without any
27 * warranty, express or implied. The Australian National University
28 * makes no representations about the suitability of this software for
31 * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
32 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
33 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
34 * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY
37 * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
38 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
39 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
40 * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
41 * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
44 * $Id: ppp_ahdlc.c,v 1.15 2000/02/18 10:00:58 masputra Exp $
48 * This file is used under Solaris 2, SVR4, SunOS 4, and Digital UNIX.
50 #include <sys/types.h>
51 #include <sys/param.h>
52 #include <sys/stream.h>
53 #include <sys/errno.h>
58 #include <sys/cmn_err.h>
63 #include <sys/cmn_err.h>
67 #include <net/ppp_defs.h>
68 #include <net/pppio.h>
72 * Right now, mutex is only enabled for Solaris 2.x
78 MOD_OPEN_DECL(ahdlc_open);
79 MOD_CLOSE_DECL(ahdlc_close);
80 static int ahdlc_wput __P((queue_t *, mblk_t *));
81 static int ahdlc_rput __P((queue_t *, mblk_t *));
82 static void ahdlc_encode __P((queue_t *, mblk_t *));
83 static void ahdlc_decode __P((queue_t *, mblk_t *));
84 static int msg_byte __P((mblk_t *, unsigned int));
88 * Don't send HDLC start flag is last transmit is within 1.5 seconds -
89 * FLAG_TIME is defined is microseconds
91 #define FLAG_TIME 1500
92 #define ABS(x) (x >= 0 ? x : (-x))
96 * Extract byte i of message mp
98 #define MSG_BYTE(mp, i) ((i) < (mp)->b_wptr - (mp)->b_rptr? (mp)->b_rptr[i]: \
102 * Is this LCP packet one we have to transmit using LCP defaults?
104 #define LCP_USE_DFLT(mp) (1 <= (code = MSG_BYTE((mp), 4)) && code <= 7)
107 * Standard STREAMS declarations
109 static struct module_info minfo = {
110 0x7d23, "ppp_ahdl", 0, INFPSZ, 32768, 512
113 static struct qinit rinit = {
114 ahdlc_rput, NULL, ahdlc_open, ahdlc_close, NULL, &minfo, NULL
117 static struct qinit winit = {
118 ahdlc_wput, NULL, NULL, NULL, NULL, &minfo, NULL
121 #if defined(SVR4) && !defined(SOL2)
123 #define ppp_ahdlcinfo phdlinfo
124 #endif /* defined(SVR4) && !defined(SOL2) */
126 struct streamtab ppp_ahdlcinfo = {
127 &rinit, /* ptr to st_rdinit */
128 &winit, /* ptr to st_wrinit */
129 NULL, /* ptr to st_muxrinit */
130 NULL, /* ptr to st_muxwinit */
132 NULL /* ptr to ptr to st_modlist */
137 int ppp_ahdlc_count = 0; /* open counter */
141 * Per-stream state structure
143 typedef struct ahdlc_state {
144 #if defined(USE_MUTEX)
145 kmutex_t lock; /* lock for this structure */
146 #endif /* USE_MUTEX */
147 int flags; /* link flags */
148 mblk_t *rx_buf; /* ptr to receive buffer */
149 int rx_buf_size; /* receive buffer size */
150 ushort_t infcs; /* calculated rx HDLC FCS */
151 u_int32_t xaccm[8]; /* 256-bit xmit ACCM */
152 u_int32_t raccm; /* 32-bit rcv ACCM */
153 int mtu; /* interface MTU */
154 int mru; /* link MRU */
155 int unit; /* current PPP unit number */
156 struct pppstat stats; /* statistic structure */
158 clock_t flag_time; /* time in usec between flags */
159 clock_t lbolt; /* last updated lbolt */
166 #define ESCAPED 0x100 /* last saw escape char on input */
167 #define IFLUSH 0x200 /* flushing input due to error */
170 * RCV_B7_1, etc., defined in net/pppio.h, are stored in flags also.
172 #define RCV_FLAGS (RCV_B7_1|RCV_B7_0|RCV_ODDP|RCV_EVNP)
175 * FCS lookup table as calculated by genfcstab.
177 static u_short fcstab[256] = {
178 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
179 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
180 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
181 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
182 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
183 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
184 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
185 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
186 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
187 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
188 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
189 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
190 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
191 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
192 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
193 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
194 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
195 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
196 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
197 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
198 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
199 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
200 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
201 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
202 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
203 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
204 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
205 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
206 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
207 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
208 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
209 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
212 static u_int32_t paritytab[8] =
214 0x96696996, 0x69969669, 0x69969669, 0x96696996,
215 0x69969669, 0x96696996, 0x96696996, 0x69969669
219 * STREAMS module open (entry) point
223 ahdlc_state_t *state;
226 * Return if it's already opened
233 * This can only be opened as a module
235 if (sflag != MODOPEN) {
239 state = (ahdlc_state_t *) ALLOC_NOSLEEP(sizeof(ahdlc_state_t));
242 bzero((caddr_t) state, sizeof(ahdlc_state_t));
244 q->q_ptr = (caddr_t) state;
245 WR(q)->q_ptr = (caddr_t) state;
247 #if defined(USE_MUTEX)
248 mutex_init(&state->lock, NULL, MUTEX_DEFAULT, NULL);
249 mutex_enter(&state->lock);
250 #endif /* USE_MUTEX */
252 state->xaccm[0] = ~0; /* escape 0x00 through 0x1f */
253 state->xaccm[3] = 0x60000000; /* escape 0x7d and 0x7e */
254 state->mru = PPP_MRU; /* default of 1500 bytes */
256 state->flag_time = drv_usectohz(FLAG_TIME);
259 #if defined(USE_MUTEX)
260 mutex_exit(&state->lock);
261 #endif /* USE_MUTEX */
273 * STREAMS module close (exit) point
275 MOD_CLOSE(ahdlc_close)
277 ahdlc_state_t *state;
281 state = (ahdlc_state_t *) q->q_ptr;
284 DPRINT("state == 0 in ahdlc_close\n");
288 #if defined(USE_MUTEX)
289 mutex_enter(&state->lock);
290 #endif /* USE_MUTEX */
292 if (state->rx_buf != 0) {
293 freemsg(state->rx_buf);
297 #if defined(USE_MUTEX)
298 mutex_exit(&state->lock);
299 mutex_destroy(&state->lock);
300 #endif /* USE_MUTEX */
302 FREE(q->q_ptr, sizeof(ahdlc_state_t));
304 OTHERQ(q)->q_ptr = NULL;
315 * Write side put routine
322 ahdlc_state_t *state;
326 struct ppp_stats *psp;
328 state = (ahdlc_state_t *) q->q_ptr;
330 DPRINT("state == 0 in ahdlc_wput\n");
335 switch (mp->b_datap->db_type) {
338 * A data packet - do character-stuffing and FCS, and
346 iop = (struct iocblk *) mp->b_rptr;
348 switch (iop->ioc_cmd) {
350 if ((iop->ioc_count < sizeof(u_int32_t)) ||
351 (iop->ioc_count > sizeof(ext_accm))) {
354 if (mp->b_cont == 0) {
355 DPRINT1("ahdlc_wput/%d: PPPIO_XACCM b_cont = 0!\n", state->unit);
358 #if defined(USE_MUTEX)
359 mutex_enter(&state->lock);
360 #endif /* USE_MUTEX */
361 bcopy((caddr_t)mp->b_cont->b_rptr, (caddr_t)state->xaccm,
363 state->xaccm[2] &= ~0x40000000; /* don't escape 0x5e */
364 state->xaccm[3] |= 0x60000000; /* do escape 0x7d, 0x7e */
365 #if defined(USE_MUTEX)
366 mutex_exit(&state->lock);
367 #endif /* USE_MUTEX */
373 if (iop->ioc_count != sizeof(u_int32_t))
375 if (mp->b_cont == 0) {
376 DPRINT1("ahdlc_wput/%d: PPPIO_RACCM b_cont = 0!\n", state->unit);
379 #if defined(USE_MUTEX)
380 mutex_enter(&state->lock);
381 #endif /* USE_MUTEX */
382 bcopy((caddr_t)mp->b_cont->b_rptr, (caddr_t)&state->raccm,
384 #if defined(USE_MUTEX)
385 mutex_exit(&state->lock);
386 #endif /* USE_MUTEX */
392 np = allocb(sizeof(int), BPRI_HI);
400 #if defined(USE_MUTEX)
401 mutex_enter(&state->lock);
402 #endif /* USE_MUTEX */
403 *(int *)np->b_wptr = state->flags & RCV_FLAGS;
404 #if defined(USE_MUTEX)
405 mutex_exit(&state->lock);
406 #endif /* USE_MUTEX */
407 np->b_wptr += sizeof(int);
408 iop->ioc_count = sizeof(int);
413 np = allocb(sizeof(struct ppp_stats), BPRI_HI);
421 psp = (struct ppp_stats *) np->b_wptr;
422 np->b_wptr += sizeof(struct ppp_stats);
423 bzero((caddr_t)psp, sizeof(struct ppp_stats));
424 psp->p = state->stats;
425 iop->ioc_count = sizeof(struct ppp_stats);
430 /* we knew this anyway */
441 else if (error == 0) {
442 mp->b_datap->db_type = M_IOCACK;
445 mp->b_datap->db_type = M_IOCNAK;
447 iop->ioc_error = error;
453 switch (*mp->b_rptr) {
455 #if defined(USE_MUTEX)
456 mutex_enter(&state->lock);
457 #endif /* USE_MUTEX */
458 state->mtu = ((unsigned short *)mp->b_rptr)[1];
459 #if defined(USE_MUTEX)
460 mutex_exit(&state->lock);
461 #endif /* USE_MUTEX */
465 #if defined(USE_MUTEX)
466 mutex_enter(&state->lock);
467 #endif /* USE_MUTEX */
468 state->mru = ((unsigned short *)mp->b_rptr)[1];
469 #if defined(USE_MUTEX)
470 mutex_exit(&state->lock);
471 #endif /* USE_MUTEX */
475 #if defined(USE_MUTEX)
476 mutex_enter(&state->lock);
477 #endif /* USE_MUTEX */
478 state->unit = mp->b_rptr[1];
479 #if defined(USE_MUTEX)
480 mutex_exit(&state->lock);
481 #endif /* USE_MUTEX */
496 * Read side put routine
503 ahdlc_state_t *state;
505 state = (ahdlc_state_t *) q->q_ptr;
507 DPRINT("state == 0 in ahdlc_rput\n");
512 switch (mp->b_datap->db_type) {
519 #if defined(USE_MUTEX)
520 mutex_enter(&state->lock);
521 #endif /* USE_MUTEX */
522 if (state->rx_buf != 0) {
523 /* XXX would like to send this up for debugging */
524 freemsg(state->rx_buf);
527 state->flags = IFLUSH;
528 #if defined(USE_MUTEX)
529 mutex_exit(&state->lock);
530 #endif /* USE_MUTEX */
541 * Extract bit c from map m, to determine if c needs to be escaped
543 #define IN_TX_MAP(c, m) ((m)[(c) >> 5] & (1 << ((c) & 0x1f)))
550 ahdlc_state_t *state;
551 u_int32_t *xaccm, loc_xaccm[8];
555 uchar_t *dp, fcs_val;
561 if (msgdsize(mp) < 4) {
565 state = (ahdlc_state_t *)q->q_ptr;
566 #if defined(USE_MUTEX)
567 mutex_enter(&state->lock);
568 #endif /* USE_MUTEX */
571 * Allocate an output buffer large enough to handle a case where all
572 * characters need to be escaped
574 outmp_len = (msgdsize(mp) << 1) + /* input block x 2 */
575 (sizeof(fcs) << 2) + /* HDLC FCS x 4 */
576 (sizeof(uchar_t) << 1); /* HDLC flags x 2 */
578 outmp = allocb(outmp_len, BPRI_MED);
580 state->stats.ppp_oerrors++;
581 #if defined(USE_MUTEX)
582 mutex_exit(&state->lock);
583 #endif /* USE_MUTEX */
584 putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR);
590 * Check if our last transmit happenned within flag_time, using
591 * the system's LBOLT value in clock ticks
593 if (drv_getparm(LBOLT, &lbolt) != -1) {
594 if (ABS((clock_t)lbolt - state->lbolt) > state->flag_time) {
595 *outmp->b_wptr++ = PPP_FLAG;
597 state->lbolt = lbolt;
599 *outmp->b_wptr++ = PPP_FLAG;
603 * If the driver below still has a message to process, skip the
604 * HDLC flag, otherwise, put one in the beginning
606 if (qsize(q->q_next) == 0) {
607 *outmp->b_wptr++ = PPP_FLAG;
612 * All control characters must be escaped for LCP packets with code
613 * values between 1 (Conf-Req) and 7 (Code-Rej).
615 is_lcp = ((MSG_BYTE(mp, 0) == PPP_ALLSTATIONS) &&
616 (MSG_BYTE(mp, 1) == PPP_UI) &&
617 (MSG_BYTE(mp, 2) == (PPP_LCP >> 8)) &&
618 (MSG_BYTE(mp, 3) == (PPP_LCP & 0xff)) &&
621 xaccm = state->xaccm;
623 bcopy((caddr_t)state->xaccm, (caddr_t)loc_xaccm, sizeof(loc_xaccm));
624 loc_xaccm[0] = ~0; /* force escape on 0x00 through 0x1f */
628 fcs = PPP_INITFCS; /* Initial FCS is 0xffff */
631 * Process this block and the rest (if any) attached to the this one
633 for (tmp = mp; tmp; tmp = tmp->b_cont) {
634 if (tmp->b_datap->db_type == M_DATA) {
635 for (dp = tmp->b_rptr; dp < tmp->b_wptr; dp++) {
636 fcs = PPP_FCS(fcs, *dp);
637 if (IN_TX_MAP(*dp, xaccm)) {
638 *outmp->b_wptr++ = PPP_ESCAPE;
639 *outmp->b_wptr++ = *dp ^ PPP_TRANS;
641 *outmp->b_wptr++ = *dp;
645 continue; /* skip if db_type is something other than M_DATA */
650 * Append the HDLC FCS, making sure that escaping is done on any
653 fcs_val = (fcs ^ 0xffff) & 0xff;
654 if (IN_TX_MAP(fcs_val, xaccm)) {
655 *outmp->b_wptr++ = PPP_ESCAPE;
656 *outmp->b_wptr++ = fcs_val ^ PPP_TRANS;
658 *outmp->b_wptr++ = fcs_val;
661 fcs_val = ((fcs ^ 0xffff) >> 8) & 0xff;
662 if (IN_TX_MAP(fcs_val, xaccm)) {
663 *outmp->b_wptr++ = PPP_ESCAPE;
664 *outmp->b_wptr++ = fcs_val ^ PPP_TRANS;
666 *outmp->b_wptr++ = fcs_val;
670 * And finally, append the HDLC flag, and send it away
672 *outmp->b_wptr++ = PPP_FLAG;
674 state->stats.ppp_obytes += msgdsize(outmp);
675 state->stats.ppp_opackets++;
677 #if defined(USE_MUTEX)
678 mutex_exit(&state->lock);
679 #endif /* USE_MUTEX */
686 * Checks the 32-bit receive ACCM to see if the byte needs un-escaping
688 #define IN_RX_MAP(c, m) ((((unsigned int) (uchar_t) (c)) < 0x20) && \
692 * SunOS 4.x does not have intptr_t or uintptr_t defined, so
696 typedef int intptr_t;
697 typedef unsigned int uintptr_t;
701 * Process received characters.
708 ahdlc_state_t *state;
718 * In case the driver (or something below) doesn't send
719 * data upstream in one message block, concatenate everything
721 if (!((mp->b_wptr - mp->b_rptr == msgdsize(mp)) &&
722 ((intptr_t)mp->b_rptr % sizeof(intptr_t) == 0))) {
724 zmp = msgpullup(mp, -1);
732 state = (ahdlc_state_t *) q->q_ptr;
734 #if defined(USE_MUTEX)
735 mutex_enter(&state->lock);
736 #endif /* USE_MUTEX */
738 state->stats.ppp_ibytes += msgdsize(mp);
740 for (dp = mp->b_rptr; dp < mp->b_wptr; dp++) {
743 * This should detect the lack of 8-bit communication channel
744 * which is necessary for PPP to work. In addition, it also
745 * checks on the parity.
748 state->flags |= RCV_B7_1;
750 state->flags |= RCV_B7_0;
752 if (paritytab[*dp >> 5] & (1 << (*dp & 0x1f)))
753 state->flags |= RCV_ODDP;
755 state->flags |= RCV_EVNP;
758 * So we have a HDLC flag ...
760 if (*dp == PPP_FLAG) {
763 * If we think that it marks the beginning of the frame,
764 * then continue to process the next octects
766 if ((state->flags & IFLUSH) ||
767 (state->rx_buf == 0) ||
768 (msgdsize(state->rx_buf) == 0)) {
770 state->flags &= ~IFLUSH;
775 * We get here because the above condition isn't true,
776 * in which case the HDLC flag was there to mark the end
777 * of the frame (or so we think)
781 if (state->infcs == PPP_GOODFCS) {
782 state->stats.ppp_ipackets++;
783 adjmsg(om, -PPP_FCSLEN);
786 DPRINT2("ppp%d: bad fcs (len=%d)\n",
787 state->unit, msgdsize(state->rx_buf));
788 freemsg(state->rx_buf);
789 state->flags &= ~(IFLUSH | ESCAPED);
790 state->stats.ppp_ierrors++;
791 putctl1(q->q_next, M_CTL, PPPCTL_IERROR);
798 if (state->flags & IFLUSH) {
803 * Allocate a receive buffer, large enough to store a frame (after
804 * un-escaping) of at least 1500 octets. If MRU is negotiated to
805 * be more than the default, then allocate that much. In addition,
806 * we add an extra 32-bytes for a fudge factor
808 if (state->rx_buf == 0) {
809 state->rx_buf_size = (state->mru < PPP_MRU ? PPP_MRU : state->mru);
810 state->rx_buf_size += (sizeof(u_int32_t) << 3);
811 state->rx_buf = allocb(state->rx_buf_size, BPRI_MED);
814 * If allocation fails, try again on the next frame
816 if (state->rx_buf == 0) {
817 state->flags |= IFLUSH;
820 state->flags &= ~(IFLUSH | ESCAPED);
821 state->infcs = PPP_INITFCS;
824 if (*dp == PPP_ESCAPE) {
825 state->flags |= ESCAPED;
830 * Make sure we un-escape the necessary characters, as well as the
831 * ones in our receive async control character map
833 if (state->flags & ESCAPED) {
835 state->flags &= ~ESCAPED;
836 } else if (IN_RX_MAP(*dp, state->raccm))
840 * Unless the peer lied to us about the negotiated MRU, we should
841 * never get a frame which is too long. If it happens, toss it away
842 * and grab the next incoming one
844 if (msgdsize(state->rx_buf) < state->rx_buf_size) {
845 state->infcs = PPP_FCS(state->infcs, *dp);
846 *state->rx_buf->b_wptr++ = *dp;
848 DPRINT2("ppp%d: frame too long (%d)\n",
849 state->unit, msgdsize(state->rx_buf));
850 freemsg(state->rx_buf);
852 state->flags |= IFLUSH;
856 #if defined(USE_MUTEX)
857 mutex_exit(&state->lock);
858 #endif /* USE_MUTEX */
866 while (mp != 0 && i >= mp->b_wptr - mp->b_rptr)
870 return mp->b_rptr[i];