⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppp_ahdlc.c

📁 经典的ppp程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	    error = 0;	    break;	case PPPIO_LASTMOD:	    /* we knew this anyway */	    error = 0;	    break;	default:	    error = -1;	    break;	}	if (error < 0)	    putnext(q, mp);	else if (error == 0) {	    mp->b_datap->db_type = M_IOCACK;	    qreply(q, mp);	} else {	    mp->b_datap->db_type = M_IOCNAK;	    iop->ioc_count = 0;	    iop->ioc_error = error;	    qreply(q, mp);	}	break;    case M_CTL:	switch (*mp->b_rptr) {	case PPPCTL_MTU:#if defined(USE_MUTEX)	    mutex_enter(&state->lock);#endif /* USE_MUTEX */	    state->mtu = ((unsigned short *)mp->b_rptr)[1];#if defined(USE_MUTEX)	    mutex_exit(&state->lock);#endif /* USE_MUTEX */	    freemsg(mp);	    break;	case PPPCTL_MRU:#if defined(USE_MUTEX)	    mutex_enter(&state->lock);#endif /* USE_MUTEX */	    state->mru = ((unsigned short *)mp->b_rptr)[1];#if defined(USE_MUTEX)	    mutex_exit(&state->lock);#endif /* USE_MUTEX */	    freemsg(mp);	    break;	case PPPCTL_UNIT:#if defined(USE_MUTEX)	    mutex_enter(&state->lock);#endif /* USE_MUTEX */	    state->unit = mp->b_rptr[1];#if defined(USE_MUTEX)	    mutex_exit(&state->lock);#endif /* USE_MUTEX */	    break;	default:	    putnext(q, mp);	}	break;    default:	putnext(q, mp);    }    return 0;}/* * Read side put routine */static intahdlc_rput(q, mp)    queue_t *q;    mblk_t  *mp;{    ahdlc_state_t *state;    state = (ahdlc_state_t *) q->q_ptr;    if (state == 0) {	DPRINT("state == 0 in ahdlc_rput\n");	freemsg(mp);	return 0;    }    switch (mp->b_datap->db_type) {    case M_DATA:	ahdlc_decode(q, mp);	freemsg(mp);	break;    case M_HANGUP:#if defined(USE_MUTEX)	mutex_enter(&state->lock);#endif /* USE_MUTEX */	if (state->rx_buf != 0) {	    /* XXX would like to send this up for debugging */	    freemsg(state->rx_buf);	    state->rx_buf = 0;	}	state->flags = IFLUSH;#if defined(USE_MUTEX)	mutex_exit(&state->lock);#endif /* USE_MUTEX */	putnext(q, mp);	break;    default:	putnext(q, mp);    }    return 0;}/* * Extract bit c from map m, to determine if c needs to be escaped */#define IN_TX_MAP(c, m)	((m)[(c) >> 5] & (1 << ((c) & 0x1f)))static voidahdlc_encode(q, mp)    queue_t	*q;    mblk_t	*mp;{    ahdlc_state_t	*state;    u_int32_t		*xaccm, loc_xaccm[8];    ushort_t		fcs;    size_t		outmp_len;    mblk_t		*outmp, *tmp;    uchar_t		*dp, fcs_val;    int			is_lcp, code;#if defined(SOL2)    clock_t		lbolt;#endif /* SOL2 */    if (msgdsize(mp) < 4) {	return;    }    state = (ahdlc_state_t *)q->q_ptr;#if defined(USE_MUTEX)    mutex_enter(&state->lock);#endif /* USE_MUTEX */    /*     * Allocate an output buffer large enough to handle a case where all     * characters need to be escaped     */    outmp_len = (msgdsize(mp)	 << 1) +		/* input block x 2 */		(sizeof(fcs)	 << 2) +		/* HDLC FCS x 4 */		(sizeof(uchar_t) << 1);			/* HDLC flags x 2 */    outmp = allocb(outmp_len, BPRI_MED);    if (outmp == NULL) {	state->stats.ppp_oerrors++;#if defined(USE_MUTEX)	mutex_exit(&state->lock);#endif /* USE_MUTEX */	putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR);	return;    }#if defined(SOL2)    /*     * Check if our last transmit happenned within flag_time, using     * the system's LBOLT value in clock ticks     */    if (drv_getparm(LBOLT, &lbolt) != -1) {	if (ABS((clock_t)lbolt - state->lbolt) > state->flag_time) {	    *outmp->b_wptr++ = PPP_FLAG;	} 	state->lbolt = lbolt;    } else {	*outmp->b_wptr++ = PPP_FLAG;    }#else    /*     * If the driver below still has a message to process, skip the     * HDLC flag, otherwise, put one in the beginning     */    if (qsize(q->q_next) == 0) {	*outmp->b_wptr++ = PPP_FLAG;    }#endif    /*     * All control characters must be escaped for LCP packets with code     * values between 1 (Conf-Req) and 7 (Code-Rej).     */    is_lcp = ((MSG_BYTE(mp, 0) == PPP_ALLSTATIONS) && 	      (MSG_BYTE(mp, 1) == PPP_UI) && 	      (MSG_BYTE(mp, 2) == (PPP_LCP >> 8)) &&	      (MSG_BYTE(mp, 3) == (PPP_LCP & 0xff)) &&	      LCP_USE_DFLT(mp));    xaccm = state->xaccm;    if (is_lcp) {	bcopy((caddr_t)state->xaccm, (caddr_t)loc_xaccm, sizeof(loc_xaccm));	loc_xaccm[0] = ~0;	/* force escape on 0x00 through 0x1f */	xaccm = loc_xaccm;    }    fcs = PPP_INITFCS;		/* Initial FCS is 0xffff */    /*     * Process this block and the rest (if any) attached to the this one     */    for (tmp = mp; tmp; tmp = tmp->b_cont) {	if (tmp->b_datap->db_type == M_DATA) {	    for (dp = tmp->b_rptr; dp < tmp->b_wptr; dp++) {		fcs = PPP_FCS(fcs, *dp);		if (IN_TX_MAP(*dp, xaccm)) {		    *outmp->b_wptr++ = PPP_ESCAPE;		    *outmp->b_wptr++ = *dp ^ PPP_TRANS;		} else {		    *outmp->b_wptr++ = *dp;		}	    }	} else {	    continue;	/* skip if db_type is something other than M_DATA */	}    }    /*     * Append the HDLC FCS, making sure that escaping is done on any     * necessary bytes     */    fcs_val = (fcs ^ 0xffff) & 0xff;    if (IN_TX_MAP(fcs_val, xaccm)) {	*outmp->b_wptr++ = PPP_ESCAPE;	*outmp->b_wptr++ = fcs_val ^ PPP_TRANS;    } else {	*outmp->b_wptr++ = fcs_val;    }    fcs_val = ((fcs ^ 0xffff) >> 8) & 0xff;    if (IN_TX_MAP(fcs_val, xaccm)) {	*outmp->b_wptr++ = PPP_ESCAPE;	*outmp->b_wptr++ = fcs_val ^ PPP_TRANS;    } else {	*outmp->b_wptr++ = fcs_val;    }    /*     * And finally, append the HDLC flag, and send it away     */    *outmp->b_wptr++ = PPP_FLAG;    state->stats.ppp_obytes += msgdsize(outmp);    state->stats.ppp_opackets++;#if defined(USE_MUTEX)    mutex_exit(&state->lock);#endif /* USE_MUTEX */    putnext(q, outmp);    return;}/* * Checks the 32-bit receive ACCM to see if the byte needs un-escaping */#define IN_RX_MAP(c, m)	((((unsigned int) (uchar_t) (c)) < 0x20) && \			(m) & (1 << (c)))/* * Process received characters. */static voidahdlc_decode(q, mp)    queue_t *q;    mblk_t  *mp;{    ahdlc_state_t   *state;    mblk_t	    *om;    uchar_t	    *dp;    ushort_t	    fcs;#if defined(SOL2)    mblk_t	    *zmp;#endif /* SOL2 */#if defined(SOL2)    /*     * In case the driver (or something below) doesn't send     * data upstream in one message block, concatenate everything     */    if (!((mp->b_wptr - mp->b_rptr == msgdsize(mp)) &&          ((intpointer_t)mp->b_rptr % sizeof(intpointer_t) == 0))) {	zmp = msgpullup(mp, -1);	freemsg(mp);	mp = zmp;	if (mp == 0)	    return;     }#endif /* SOL2 */    state = (ahdlc_state_t *) q->q_ptr;#if defined(USE_MUTEX)    mutex_enter(&state->lock);#endif /* USE_MUTEX */    state->stats.ppp_ibytes += msgdsize(mp);    for (dp = mp->b_rptr; dp < mp->b_wptr; dp++) {	/*	 * This should detect the lack of 8-bit communication channel	 * which is necessary for PPP to work. In addition, it also	 * checks on the parity.	 */	if (*dp & 0x80)	    state->flags |= RCV_B7_1;	else	    state->flags |= RCV_B7_0;	if (paritytab[*dp >> 5] & (1 << (*dp & 0x1f)))	    state->flags |= RCV_ODDP;	else	    state->flags |= RCV_EVNP;	/*	 * So we have a HDLC flag ...	 */	if (*dp == PPP_FLAG) {	    /*	     * If we think that it marks the beginning of the frame,	     * then continue to process the next octects	     */	    if ((state->flags & IFLUSH) ||		(state->rx_buf == 0) ||		(msgdsize(state->rx_buf) == 0)) {		state->flags &= ~IFLUSH;		continue;	    }	    /*	     * We get here because the above condition isn't true,	     * in which case the HDLC flag was there to mark the end	     * of the frame (or so we think)	     */	    om = state->rx_buf;	    if (state->infcs == PPP_GOODFCS) {		state->stats.ppp_ipackets++;		adjmsg(om, -PPP_FCSLEN);		putnext(q, om);	    } else {		DPRINT2("ppp%d: bad fcs (len=%d)\n",                    state->unit, msgdsize(state->rx_buf));		freemsg(state->rx_buf);		state->flags &= ~(IFLUSH | ESCAPED);		state->stats.ppp_ierrors++;		putctl1(q->q_next, M_CTL, PPPCTL_IERROR);	    }	    state->rx_buf = 0;	    continue;	}	if (state->flags & IFLUSH) {	    continue;	}	/*	 * Allocate a receive buffer, large enough to store a frame (after	 * un-escaping) of at least 1500 octets. If MRU is negotiated to	 * be more than the default, then allocate that much. In addition,	 * we add an extra 32-bytes for a fudge factor	 */ 	if (state->rx_buf == 0) {	    state->rx_buf_size  = (state->mru < PPP_MRU ? PPP_MRU : state->mru);	    state->rx_buf_size += (sizeof(u_int32_t) << 3);	    state->rx_buf = allocb(state->rx_buf_size, BPRI_MED);	    /*	     * If allocation fails, try again on the next frame	     */	    if (state->rx_buf == 0) {		state->flags |= IFLUSH;		continue;	    }	    state->flags &= ~(IFLUSH | ESCAPED);	    state->infcs  = PPP_INITFCS;	}	if (*dp == PPP_ESCAPE) {	    state->flags |= ESCAPED;	    continue;	}	/*	 * Make sure we un-escape the necessary characters, as well as the	 * ones in our receive async control character map	 */	if (state->flags & ESCAPED) {	    *dp ^= PPP_TRANS;	    state->flags &= ~ESCAPED;	} else if (IN_RX_MAP(*dp, state->raccm)) 	    continue;	/*	 * Unless the peer lied to us about the negotiated MRU, we should	 * never get a frame which is too long. If it happens, toss it away	 * and grab the next incoming one	 */	if (msgdsize(state->rx_buf) < state->rx_buf_size) {	    state->infcs = PPP_FCS(state->infcs, *dp);	    *state->rx_buf->b_wptr++ = *dp;	} else {	    DPRINT2("ppp%d: frame too long (%d)\n",		state->unit, msgdsize(state->rx_buf));	    freemsg(state->rx_buf);	    state->rx_buf     = 0;	    state->flags     |= IFLUSH;	}    }#if defined(USE_MUTEX)    mutex_exit(&state->lock);#endif /* USE_MUTEX */}static intmsg_byte(mp, i)    mblk_t *mp;    unsigned int i;{    while (mp != 0 && i >= mp->b_wptr - mp->b_rptr)	mp = mp->b_cont;    if (mp == 0)	return -1;    return mp->b_rptr[i];}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -