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.12 2000/01/21 01:04:56 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 * Per-stream state structure
139 typedef struct ahdlc_state {
140 #if defined(USE_MUTEX)
141 kmutex_t lock; /* lock for this structure */
142 #endif /* USE_MUTEX */
143 int flags; /* link flags */
144 mblk_t *rx_buf; /* ptr to receive buffer */
145 int rx_buf_size; /* receive buffer size */
146 ushort_t infcs; /* calculated rx HDLC FCS */
147 u_int32_t xaccm[8]; /* 256-bit xmit ACCM */
148 u_int32_t raccm; /* 32-bit rcv ACCM */
149 int mtu; /* interface MTU */
150 int mru; /* link MRU */
151 int unit; /* current PPP unit number */
152 struct pppstat stats; /* statistic structure */
154 clock_t flag_time; /* time in usec between flags */
155 clock_t lbolt; /* last updated lbolt */
162 #define ESCAPED 0x100 /* last saw escape char on input */
163 #define IFLUSH 0x200 /* flushing input due to error */
166 * RCV_B7_1, etc., defined in net/pppio.h, are stored in flags also.
168 #define RCV_FLAGS (RCV_B7_1|RCV_B7_0|RCV_ODDP|RCV_EVNP)
171 * FCS lookup table as calculated by genfcstab.
173 static u_short fcstab[256] = {
174 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
175 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
176 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
177 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
178 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
179 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
180 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
181 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
182 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
183 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
184 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
185 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
186 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
187 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
188 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
189 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
190 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
191 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
192 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
193 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
194 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
195 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
196 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
197 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
198 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
199 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
200 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
201 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
202 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
203 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
204 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
205 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
208 static u_int32_t paritytab[8] =
210 0x96696996, 0x69969669, 0x69969669, 0x96696996,
211 0x69969669, 0x96696996, 0x96696996, 0x69969669
215 * STREAMS module open (entry) point
219 ahdlc_state_t *state;
222 * Return if it's already opened
229 * This can only be opened as a module
231 if (sflag != MODOPEN) {
235 state = (ahdlc_state_t *) ALLOC_NOSLEEP(sizeof(ahdlc_state_t));
238 bzero((caddr_t) state, sizeof(ahdlc_state_t));
240 q->q_ptr = (caddr_t) state;
241 WR(q)->q_ptr = (caddr_t) state;
243 #if defined(USE_MUTEX)
244 mutex_init(&state->lock, NULL, MUTEX_DEFAULT, NULL);
245 mutex_enter(&state->lock);
246 #endif /* USE_MUTEX */
248 state->xaccm[0] = ~0; /* escape 0x00 through 0x1f */
249 state->xaccm[3] = 0x60000000; /* escape 0x7d and 0x7e */
250 state->mru = PPP_MRU; /* default of 1500 bytes */
252 state->flag_time = drv_usectohz(FLAG_TIME);
255 #if defined(USE_MUTEX)
256 mutex_exit(&state->lock);
257 #endif /* USE_MUTEX */
265 * STREAMS module close (exit) point
267 MOD_CLOSE(ahdlc_close)
269 ahdlc_state_t *state;
273 state = (ahdlc_state_t *) q->q_ptr;
276 DPRINT("state == 0 in ahdlc_close\n");
280 #if defined(USE_MUTEX)
281 mutex_enter(&state->lock);
282 #endif /* USE_MUTEX */
284 if (state->rx_buf != 0) {
285 freemsg(state->rx_buf);
289 #if defined(USE_MUTEX)
290 mutex_exit(&state->lock);
291 mutex_destroy(&state->lock);
292 #endif /* USE_MUTEX */
294 FREE(q->q_ptr, sizeof(ahdlc_state_t));
296 OTHERQ(q)->q_ptr = NULL;
302 * Write side put routine
309 ahdlc_state_t *state;
313 struct ppp_stats *psp;
315 state = (ahdlc_state_t *) q->q_ptr;
317 DPRINT("state == 0 in ahdlc_wput\n");
322 switch (mp->b_datap->db_type) {
325 * A data packet - do character-stuffing and FCS, and
333 iop = (struct iocblk *) mp->b_rptr;
335 switch (iop->ioc_cmd) {
337 if ((iop->ioc_count < sizeof(u_int32_t)) ||
338 (iop->ioc_count > sizeof(ext_accm))) {
341 if (mp->b_cont == 0) {
342 DPRINT1("ahdlc_wput/%d: PPPIO_XACCM b_cont = 0!\n", state->unit);
345 #if defined(USE_MUTEX)
346 mutex_enter(&state->lock);
347 #endif /* USE_MUTEX */
348 bcopy((caddr_t)mp->b_cont->b_rptr, (caddr_t)state->xaccm,
350 state->xaccm[2] &= ~0x40000000; /* don't escape 0x5e */
351 state->xaccm[3] |= 0x60000000; /* do escape 0x7d, 0x7e */
352 #if defined(USE_MUTEX)
353 mutex_exit(&state->lock);
354 #endif /* USE_MUTEX */
360 if (iop->ioc_count != sizeof(u_int32_t))
362 if (mp->b_cont == 0) {
363 DPRINT1("ahdlc_wput/%d: PPPIO_RACCM b_cont = 0!\n", state->unit);
366 #if defined(USE_MUTEX)
367 mutex_enter(&state->lock);
368 #endif /* USE_MUTEX */
369 bcopy((caddr_t)mp->b_cont->b_rptr, (caddr_t)&state->raccm,
371 #if defined(USE_MUTEX)
372 mutex_exit(&state->lock);
373 #endif /* USE_MUTEX */
379 np = allocb(sizeof(int), BPRI_HI);
387 #if defined(USE_MUTEX)
388 mutex_enter(&state->lock);
389 #endif /* USE_MUTEX */
390 *(int *)np->b_wptr = state->flags & RCV_FLAGS;
391 #if defined(USE_MUTEX)
392 mutex_exit(&state->lock);
393 #endif /* USE_MUTEX */
394 np->b_wptr += sizeof(int);
395 iop->ioc_count = sizeof(int);
400 np = allocb(sizeof(struct ppp_stats), BPRI_HI);
408 psp = (struct ppp_stats *) np->b_wptr;
409 np->b_wptr += sizeof(struct ppp_stats);
410 bzero((caddr_t)psp, sizeof(struct ppp_stats));
411 psp->p = state->stats;
412 iop->ioc_count = sizeof(struct ppp_stats);
417 /* we knew this anyway */
428 else if (error == 0) {
429 mp->b_datap->db_type = M_IOCACK;
432 mp->b_datap->db_type = M_IOCNAK;
434 iop->ioc_error = error;
440 switch (*mp->b_rptr) {
442 #if defined(USE_MUTEX)
443 mutex_enter(&state->lock);
444 #endif /* USE_MUTEX */
445 state->mtu = ((unsigned short *)mp->b_rptr)[1];
446 #if defined(USE_MUTEX)
447 mutex_exit(&state->lock);
448 #endif /* USE_MUTEX */
452 #if defined(USE_MUTEX)
453 mutex_enter(&state->lock);
454 #endif /* USE_MUTEX */
455 state->mru = ((unsigned short *)mp->b_rptr)[1];
456 #if defined(USE_MUTEX)
457 mutex_exit(&state->lock);
458 #endif /* USE_MUTEX */
462 #if defined(USE_MUTEX)
463 mutex_enter(&state->lock);
464 #endif /* USE_MUTEX */
465 state->unit = mp->b_rptr[1];
466 #if defined(USE_MUTEX)
467 mutex_exit(&state->lock);
468 #endif /* USE_MUTEX */
483 * Read side put routine
490 ahdlc_state_t *state;
492 state = (ahdlc_state_t *) q->q_ptr;
494 DPRINT("state == 0 in ahdlc_rput\n");
499 switch (mp->b_datap->db_type) {
506 #if defined(USE_MUTEX)
507 mutex_enter(&state->lock);
508 #endif /* USE_MUTEX */
509 if (state->rx_buf != 0) {
510 /* XXX would like to send this up for debugging */
511 freemsg(state->rx_buf);
514 state->flags = IFLUSH;
515 #if defined(USE_MUTEX)
516 mutex_exit(&state->lock);
517 #endif /* USE_MUTEX */
528 * Extract bit c from map m, to determine if c needs to be escaped
530 #define IN_TX_MAP(c, m) ((m)[(c) >> 5] & (1 << ((c) & 0x1f)))
537 ahdlc_state_t *state;
538 u_int32_t *xaccm, loc_xaccm[8];
542 uchar_t *dp, fcs_val;
548 if (msgdsize(mp) < 4) {
552 state = (ahdlc_state_t *)q->q_ptr;
553 #if defined(USE_MUTEX)
554 mutex_enter(&state->lock);
555 #endif /* USE_MUTEX */
558 * Allocate an output buffer large enough to handle a case where all
559 * characters need to be escaped
561 outmp_len = (msgdsize(mp) << 1) + /* input block x 2 */
562 (sizeof(fcs) << 2) + /* HDLC FCS x 4 */
563 (sizeof(uchar_t) << 1); /* HDLC flags x 2 */
565 outmp = allocb(outmp_len, BPRI_MED);
567 state->stats.ppp_oerrors++;
568 #if defined(USE_MUTEX)
569 mutex_exit(&state->lock);
570 #endif /* USE_MUTEX */
571 putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR);
577 * Check if our last transmit happenned within flag_time, using
578 * the system's LBOLT value in clock ticks
580 if (drv_getparm(LBOLT, &lbolt) != -1) {
581 if (ABS((clock32_t)lbolt - state->lbolt) > state->flag_time) {
582 *outmp->b_wptr++ = PPP_FLAG;
584 state->lbolt = lbolt;
586 *outmp->b_wptr++ = PPP_FLAG;
590 * If the driver below still has a message to process, skip the
591 * HDLC flag, otherwise, put one in the beginning
593 if (qsize(q->q_next) == 0) {
594 *outmp->b_wptr++ = PPP_FLAG;
599 * All control characters must be escaped for LCP packets with code
600 * values between 1 (Conf-Req) and 7 (Code-Rej).
602 is_lcp = ((MSG_BYTE(mp, 0) == PPP_ALLSTATIONS) &&
603 (MSG_BYTE(mp, 1) == PPP_UI) &&
604 (MSG_BYTE(mp, 2) == (PPP_LCP >> 8)) &&
605 (MSG_BYTE(mp, 3) == (PPP_LCP & 0xff)) &&
608 xaccm = state->xaccm;
610 bcopy((caddr_t)state->xaccm, (caddr_t)loc_xaccm, sizeof(loc_xaccm));
611 loc_xaccm[0] = ~0; /* force escape on 0x00 through 0x1f */
615 fcs = PPP_INITFCS; /* Initial FCS is 0xffff */
618 * Process this block and the rest (if any) attached to the this one
620 for (tmp = mp; tmp; tmp = tmp->b_cont) {
621 if (tmp->b_datap->db_type == M_DATA) {
622 for (dp = tmp->b_rptr; dp < tmp->b_wptr; dp++) {
623 fcs = PPP_FCS(fcs, *dp);
624 if (IN_TX_MAP(*dp, xaccm)) {
625 *outmp->b_wptr++ = PPP_ESCAPE;
626 *outmp->b_wptr++ = *dp ^ PPP_TRANS;
628 *outmp->b_wptr++ = *dp;
632 continue; /* skip if db_type is something other than M_DATA */
637 * Append the HDLC FCS, making sure that escaping is done on any
640 fcs_val = (fcs ^ 0xffff) & 0xff;
641 if (IN_TX_MAP(fcs_val, xaccm)) {
642 *outmp->b_wptr++ = PPP_ESCAPE;
643 *outmp->b_wptr++ = fcs_val ^ PPP_TRANS;
645 *outmp->b_wptr++ = fcs_val;
648 fcs_val = ((fcs ^ 0xffff) >> 8) & 0xff;
649 if (IN_TX_MAP(fcs_val, xaccm)) {
650 *outmp->b_wptr++ = PPP_ESCAPE;
651 *outmp->b_wptr++ = fcs_val ^ PPP_TRANS;
653 *outmp->b_wptr++ = fcs_val;
657 * And finally, append the HDLC flag, and send it away
659 *outmp->b_wptr++ = PPP_FLAG;
661 state->stats.ppp_obytes += msgdsize(outmp);
662 state->stats.ppp_opackets++;
664 #if defined(USE_MUTEX)
665 mutex_exit(&state->lock);
666 #endif /* USE_MUTEX */
673 * Checks the 32-bit receive ACCM to see if the byte needs un-escaping
675 #define IN_RX_MAP(c, m) ((((unsigned int) (uchar_t) (c)) < 0x20) && \
679 * Process received characters.
686 ahdlc_state_t *state;
692 * In case the driver (or something below) doesn't send
693 * data upstream in one message block, concatenate everything
695 if (!((mp->b_wptr - mp->b_rptr == msgdsize(mp)) &&
696 ((intptr_t)mp->b_rptr % sizeof(intptr_t) == 0))) {
698 zmp = msgpullup(mp, -1);
705 state = (ahdlc_state_t *) q->q_ptr;
707 #if defined(USE_MUTEX)
708 mutex_enter(&state->lock);
709 #endif /* USE_MUTEX */
711 state->stats.ppp_ibytes += msgdsize(mp);
713 for (dp = mp->b_rptr; dp < mp->b_wptr; dp++) {
716 * This should detect the lack of 8-bit communication channel
717 * which is necessary for PPP to work. In addition, it also
718 * checks on the parity.
721 state->flags |= RCV_B7_1;
723 state->flags |= RCV_B7_0;
725 if (paritytab[*dp >> 5] & (1 << (*dp & 0x1f)))
726 state->flags |= RCV_ODDP;
728 state->flags |= RCV_EVNP;
731 * So we have a HDLC flag ...
733 if (*dp == PPP_FLAG) {
736 * If we think that it marks the beginning of the frame,
737 * then continue to process the next octects
739 if ((state->flags & IFLUSH) ||
740 (state->rx_buf == 0) ||
741 (msgdsize(state->rx_buf) == 0)) {
743 state->flags &= ~IFLUSH;
748 * We get here because the above condition isn't true,
749 * in which case the HDLC flag was there to mark the end
750 * of the frame (or so we think)
754 if (state->infcs == PPP_GOODFCS) {
755 state->stats.ppp_ipackets++;
756 adjmsg(om, -PPP_FCSLEN);
759 DPRINT2("ppp%d: bad fcs (len=%d)\n",
760 state->unit, msgdsize(state->rx_buf));
761 freemsg(state->rx_buf);
762 state->flags &= ~(IFLUSH | ESCAPED);
763 state->stats.ppp_ierrors++;
764 putctl1(q->q_next, M_CTL, PPPCTL_IERROR);
771 if (state->flags & IFLUSH) {
776 * Allocate a receive buffer, large enough to store a frame (after
777 * un-escaping) of at least 1500 octets. If MRU is negotiated to
778 * be more than the default, then allocate that much. In addition,
779 * we add an extra 32-bytes for a fudge factor
781 if (state->rx_buf == 0) {
782 state->rx_buf_size = (state->mru < PPP_MRU ? PPP_MRU : state->mru);
783 state->rx_buf_size += (sizeof(u_int32_t) << 3);
784 state->rx_buf = allocb(state->rx_buf_size, BPRI_MED);
787 * If allocation fails, try again on the next frame
789 if (state->rx_buf == 0) {
790 state->flags |= IFLUSH;
793 state->flags &= ~(IFLUSH | ESCAPED);
794 state->infcs = PPP_INITFCS;
797 if (*dp == PPP_ESCAPE) {
798 state->flags |= ESCAPED;
803 * Make sure we un-escape the necessary characters, as well as the
804 * ones in our receive async control character map
806 if (state->flags & ESCAPED) {
808 state->flags &= ~ESCAPED;
809 } else if (IN_RX_MAP(*dp, state->raccm))
813 * Unless the peer lied to us about the negotiated MRU, we should
814 * never get a frame which is too long. If it happens, toss it away
815 * and grab the next incoming one
817 if (msgdsize(state->rx_buf) < state->rx_buf_size) {
818 state->infcs = PPP_FCS(state->infcs, *dp);
819 *state->rx_buf->b_wptr++ = *dp;
821 DPRINT2("ppp%d: frame too long (%d)\n",
822 state->unit, msgdsize(state->rx_buf));
823 freemsg(state->rx_buf);
825 state->flags |= IFLUSH;
829 #if defined(USE_MUTEX)
830 mutex_exit(&state->lock);
831 #endif /* USE_MUTEX */
839 while (mp != 0 && i >= mp->b_wptr - mp->b_rptr)
843 return mp->b_rptr[i];