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

📄 if_ppp.c

📁 vxworks的tcpip协议栈源码
💻 C
📖 第 1 页 / 共 4 页
字号:
                 */	        ioctl(fd, FIONWRITE, (int) &count);	        if (count == 0) {		    ++sc->sc_bytessent;		    ch = PPP_FLAG;		    (void) write(fd, &ch, 1);	        }                /* Calculate the FCS for the first mbuf's worth. */                sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);            }	    for (;;) {		start = mtod(m, u_char *);		len = m->m_len;		stop = start + len;	        while (len > 0) {                    /*                     * Find out how many bytes in the string we can                     * handle without doing something special.                     */                    for (cp = start; cp < stop; cp++)                        if (ESCAPE_P(*cp))                            break;                    n = cp - start;		    if (n) {                        int cc, nleft;                        for (nleft = n; nleft > 0; nleft -= cc) {                            if ((cc =  write(fd, (char *)start, n)) <= 0)                                break;                            if (cc > nleft)                                cc = nleft;                        }                        ndone = n - nleft;                        len -= ndone;                        start += ndone;                        sc->sc_bytessent += ndone;                        if (ndone < n)                            break;  /* packet doesn't fit */                    }		    /*		     * If there are characters left in the mbuf,		     * the first one must be special..		     * Put it out in a different form.		     */		    if (len) {			ch = PPP_ESCAPE;			if (write(fd, &ch, 1) != 1)			    break;    			ch = *start ^ PPP_TRANS;			if (write(fd, &ch, 1) != 1)			    break;    			sc->sc_bytessent += 2;			start++;			len--;		    }	        }                /*                 * If we didn't empty this mbuf, remember where we're up to.                 * If we emptied the last mbuf, try to add the FCS and closing                 * flag, and if we can't, leave sc_outm pointing to m, but with                 * m->m_len == 0, to remind us to output the FCS and flag later.                 */                done = len == 0;                if (done && m->m_next == NULL) {                    u_char *p;                    int c;                    u_char endseq[8];                    /*                     * We may have to escape the bytes in the FCS.                     */                    p = endseq;                    c = ~sc->sc_outfcs & 0xFF;                    if (ESCAPE_P(c)) {                        *p++ = PPP_ESCAPE;                        *p++ = c ^ PPP_TRANS;                    } else                        *p++ = c;                    c = (~sc->sc_outfcs >> 8) & 0xFF;                    if (ESCAPE_P(c)) {                        *p++ = PPP_ESCAPE;                        *p++ = c ^ PPP_TRANS;                    } else                        *p++ = c;                    *p++ = PPP_FLAG;                    /*                     * Try to output the FCS and flag.  If the bytes                     * don't all fit, back out.                     */                    write(fd, (char *)endseq, (int)p-(int)endseq);                }                if (!done) {		    m->m_data = (caddr_t)start;                     m->m_len = len;                    sc->sc_outm = m;                    break;         /* can't do any more at the moment */                }                /* Finished with this mbuf; free it and move on. */                m2 = m_free (m);                if (m2 == NULL)                    break;                m = m2;                sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);            }            /* Finished a packet */            sc->sc_outm = NULL;            sc->sc_bytessent++;     /* account for closing flag */            sc->sc_if.if_opackets++;	    sc->sc_if.if_obytes = sc->sc_bytessent;	}    }}/* * Allocate enough mbuf to handle current MRU. */static intpppgetm(sc)    register struct ppp_softc *sc;{    struct mbuf *m, **mp;    int len;    int s;    s = splimp();    mp = &sc->sc_m;    for (len = HDROFF + sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){	if ((m = *mp) == NULL) {	    m = mHdrClGet (M_DONTWAIT, MT_DATA, len, FALSE);	    if (m == NULL)		break;	    *mp = m;	}	len -= M_DATASIZE(m);	mp = &m->m_next;    }    splx(s);    return len <= 0;}/* * pppintr - PPP tty protocol hook routine */static intpppintr(unit, c)    int unit;    int c;{    register struct ppp_softc *sc = ppp_softc[unit];    TY_DEV * pTyDev;    RING_ID ringId;    if (ppp_softc[unit] == NULL)        return FALSE;    /* Set discard flag if this is a new packet and ring buffer full */    if ( sc->sc_qlen == 0 )    {        pTyDev = (TY_DEV *) iosFdDevFind(sc->sc_fd);        ringId = pTyDev->rdBuf;        if (rngIsFull (ringId))            sc->sc_flags |= SC_DISCARD_PKT;        else            sc->sc_flags &= ~SC_DISCARD_PKT;    }    ++sc->sc_qlen;    if (sc->sc_qlen > PPPBUFSIZE)        {        netJobAdd((FUNCPTR) ppp_tty_read, (int)unit, (int) sc,                  (int) sc->sc_qlen, 0, 0);        sc->sc_qlen = 0;        return (FALSE);        }         if (((ppp_if[unit]->lcp_fsm.state) != OPENED) && ((c & 0xff) == 'T'))        {        netJobAdd((FUNCPTR) ppp_tty_read, (int)unit, (int) sc,                  (int) sc->sc_qlen, 0, 0);        return (FALSE);        }    if ((c & 0xff) == PPP_FLAG)         {        netJobAdd((FUNCPTR) ppp_tty_read, (int)unit, (int) sc,                       (int) sc->sc_qlen, 0, 0);        sc->sc_qlen = 0;        }    return (FALSE);}/* * ppp_tty_read - read from ppp tty interface */static voidppp_tty_read(unit, sc, count)    int unit;    register struct ppp_softc *sc;    register int count;{    register int i;    register int num;    char buf[PPPBUFSIZE + 2];    /* count should never be greater than PPPBUFSIZE+1 */    num = read(sc->sc_fd, buf, count);    if (count > PPPBUFSIZE)       {       /* The received packet is greater than the MTU - Drop the packet */       sc->sc_if.if_ierrors++;       return;       }    if ((ppp_if[unit]->lcp_fsm.state) != OPENED)        {        if (strncmp("CLIENT", buf, strlen("CLIENT") )==0)           {           sc->sc_qlen = 0;           write(sc->sc_fd, "CLIENTSERVER", strlen("CLIENTSERVER"));           return;           }        }    if (sc->sc_flags & SC_DISCARD_PKT)        {        /* Packet discarded */        sc->sc_if.if_ierrors++;        sc->sc_flags &= ~SC_DISCARD_PKT;        return;        }    for (i = 0; i < num; i++)        pppinput(sc, buf[i]);}/* * PPP packet input routine. * The caller has checked and removed the FCS. * The return value is 1 if the packet was put on sc->sc_inq, * 0 otherwise. */#define COMPTYPE(proto) ((proto) == PPP_VJC_COMP? TYPE_COMPRESSED_TCP: \                         TYPE_UNCOMPRESSED_TCP)/******************************************************************************** ppppktin - pass the packet to the appropriate stack LCP or IP* * This routine determines packet type and queues the mbuf to the appropriate* queue. This routine returns a value of 1 if the packet type is other than* PPP_IP.** NOMANUAL** RETURNS: 0/1*/static intppppktin(sc, m)    struct ppp_softc *sc;    struct mbuf *m;{    struct ifqueue *inq;    int s, ilen, xlen, proto, rv;    u_char *cp, adrs, ctrl;    struct mbuf *mp;    char buf[PPPBUFSIZE];    sc->sc_if.if_ipackets++;    sc->sc_if.if_lastchange = tickGet (); 	/* record the last change */    rv = 0;    cp = mtod(m, u_char *);    adrs = cp[0];    ctrl = cp[1];    proto = (cp[2] << 8) + cp[3];    ilen = 0;    for (mp = m; mp != NULL; mp = mp->m_next)	ilen += mp->m_len;#ifdef VJC    /*     * See if we have a VJ-compressed packet to uncompress.     */    if (proto == PPP_VJC_COMP || proto == PPP_VJC_UNCOMP) {	char *pkttype = proto == PPP_VJC_COMP? "": "un";	if (sc->sc_flags & SC_REJ_COMP_TCP) {	    if (sc->sc_flags & SC_DEBUG)		printf("ppp%d: %scomp pkt w/o compression; flags 0x%x\n",			sc->sc_if.if_unit, pkttype, sc->sc_flags);	    m_freem(m);	    sc->sc_if.if_ierrors++;	    return 0;	}	if (proto == PPP_VJC_COMP && m->m_data - M_DATASTART(m) < MAX_HDR) {	    /*	     * We don't have room in the mbuf to decompress this packet.	     * XXX For now we just drop the packet.	     */	    if (sc->sc_flags & SC_DEBUG)		printf("ppp%d: no room to VJ-decompress packet\n",		       sc->sc_if.if_unit);	    m_freem(m);	    sc->sc_if.if_ierrors++;	    return 0;	}	m->m_data += PPP_HDRLEN;	m->m_len -= PPP_HDRLEN;	ilen -= PPP_HDRLEN;	xlen = sl_uncompress_tcp((u_char **)(&m->m_data), m->m_len,					  COMPTYPE(proto), &sc->sc_comp);	if (xlen == 0) {	    if (sc->sc_flags & SC_DEBUG)		printf("ppp%d: sl_uncompress failed on type %scomp\n",			sc->sc_if.if_unit, pkttype);	    m_freem(m);	    sc->sc_if.if_ierrors++;	    return 0;	}	/* adjust the first mbuf by the decompressed amt */	xlen += PPP_HDRLEN;	m->m_len += xlen - ilen;	ilen = xlen;	m->m_data -= PPP_HDRLEN;	proto = PPP_IP;	/* put the ppp header back in place */	if (cp != mtod(m, u_char *)) {	    cp = mtod(m, u_char *);	    cp[0] = adrs;	    cp[1] = ctrl;	    cp[2] = 0;	}	cp[3] = PPP_IP;    }#endif /* VJC */    /*     * If the packet will fit in a header mbuf, don't waste a     * whole cluster on it.     */    m->m_pkthdr.len = ilen;    m->m_pkthdr.rcvif = &sc->sc_if;#if NBPFILTER > 0    /* See if bpf wants to look at the packet. */    if (sc->sc_bpf)	bpf_mtap(sc->sc_bpf, m);#endif        /* call etherInputHookRtn here */    if (etherInputHookRtn != NULL) {        FAST char *p = (char *) buf; 	for (mp = m; mp != NULL; p += mp->m_len, mp = mp->m_next)	    bcopy(mtod (mp, char *), p, mp->m_len); 	if ((*etherInputHookRtn) (&sc->sc_if, buf, ilen) != 0)	    {	    m_freem (m); 	/* free mbuf, not handed to the upperlayer */	    return (OK);	    }    }    switch (proto) {#ifdef INET    case PPP_IP:	/*	 * IP packet - take off the ppp header and pass it up to IP.	 */	if ((sc->sc_if.if_flags & IFF_UP) == 0	    || (sc->sc_flags & SC_ENABLE_IP) == 0) {	    /* interface is down - drop the packet. */	    m_freem(m);	    return 0;	}	m->m_pkthdr.len -= PPP_HDRLEN;	m->m_data += PPP_HDRLEN;	m->m_len -= PPP_HDRLEN;	inq = &ipintrq;	break;#endif    default:	/*	 * Some other protocol - place on input queue for read().	 */	inq = &sc->sc_inq;	rv = 1;	break;    }    /*     * Put the packet on the appropriate input queue.     */    s = splimp();    if (IF_QFULL(inq)) {	IF_DROP(inq);	if (sc->sc_flags & SC_DEBUG)	    printf("ppp%d: queue full\n", sc->sc_if.if_unit);	sc->sc_if.if_ierrors++;	sc->sc_if.if_iqdrops++;	m_freem(m);	rv = 0;    } else{        IF_ENQUEUE(inq, m);	if (proto == PPP_IP) {	    sc->sc_iprcvd++;		/* incr ip packets received */	    ipintr();	} else 	    kill(sc->sc_tid, SIGIO); 	/* give to alternate processing */    }    splx(s);    return rv;}/* * tty interface receiver interrupt. */static unsigned paritytab[8] = {    0x96696996, 0x69969669, 0x69969669, 0x96696996,    0x69969669, 0x96696996, 0x96696996, 0x69969669};static voidpppinput(sc, c)    struct ppp_softc *sc;    register int c;{    struct mbuf *m;    int ilen;    ++sc->sc_bytesrcvd;    c &= 0xff;    if (c & 0x80)	sc->sc_flags |= SC_RCV_B7_1;    else	sc->sc_flags |= SC_RCV_B7_0;    if (paritytab[c >> 5] & (1 << (c & 0x1F)))	sc->sc_flags |= SC_RCV_ODDP;    else	sc->sc_flags |= SC_RCV_EVNP;    if (sc->sc_flags & SC_LOG_RAWIN)	ppplogchar(sc, c);    if (c == PPP_FLAG) {	ilen = sc->sc_ilen;	sc->sc_ilen = 0;	sc->sc_if.if_ibytes = sc->sc_bytesrcvd;	if (sc->sc_rawin_count > 0) 	    ppplogchar(sc, -1);	/*	 * If SC_ESCAPED is set, then we've seen the packet	 * abort sequence "}~".	 */	if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)	    || ilen > 0 && sc->sc_fcs != PPP_GOODFCS) {#ifdef VJC	    /*	     * If we've missed a packet, we must toss subsequent compressed	     * packets which don't have an explicit connection ID.	     */

⌨️ 快捷键说明

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