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

📄 if_ppp.c

📁 vxworks的tcpip协议栈源码
💻 C
📖 第 1 页 / 共 4 页
字号:
        m->m_len = len;    }    dst.sa_family = AF_UNSPEC;    ph1 = (struct ppp_header *) &dst.sa_data;    ph2 = mtod(m0, struct ppp_header *);    memcpy (ph1, ph2, sizeof (*ph1));		/* from RTP for bug on 29k */    m0->m_data += PPP_HDRLEN;    m0->m_len -= PPP_HDRLEN;    return (pppoutput(&sc->sc_if, m0, &dst, (struct rtentry *)0));}/* * Line specific (tty) ioctl routine. * Provide a way to get the ppp unit number. * This discipline requires that tty device drivers call * the line specific l_ioctl routine from their ioctl routines. */intppptioctl(unit, cmd, data)    int unit;    int cmd;    caddr_t data;{    register struct ppp_softc *sc = ppp_softc[unit];    int s, flags, mru;    int error = 0;     if (sc == NULL)        return -1;    switch (cmd) {    case FIONREAD:        *(int *)data = sc->sc_qlen;        break;    case PPPIOCGUNIT:        *(int *)data = sc->sc_if.if_unit;        break;    case PPPIOCGFLAGS:        *(u_int *)data = sc->sc_flags;        break;    case PPPIOCSFLAGS:        flags = *(int *)data & SC_MASK;        s = splimp();        sc->sc_flags = (sc->sc_flags & ~SC_MASK) | flags;        splx(s);        break;    case PPPIOCSASYNCMAP:        sc->sc_asyncmap[0] = *(u_int *)data;        break;    case PPPIOCGASYNCMAP:        *(u_int *)data = sc->sc_asyncmap[0];        break;    case PPPIOCSRASYNCMAP:        sc->sc_rasyncmap = *(u_int *)data;        break;    case PPPIOCGRASYNCMAP:        *(u_int *)data = sc->sc_rasyncmap;        break;    case PPPIOCSXASYNCMAP:        bcopy((char *)data, (char *)sc->sc_asyncmap, sizeof(sc->sc_asyncmap));        sc->sc_asyncmap[1] = 0;             /* mustn't escape 0x20 - 0x3f */        sc->sc_asyncmap[2] &= ~0x40000000;  /* mustn't escape 0x5e */        sc->sc_asyncmap[3] |= 0x60000000;   /* must escape 0x7d, 0x7e */        break;    case PPPIOCGXASYNCMAP:        bcopy((char *)sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));        break;    case PPPIOCSMRU:        mru = *(int *)data;        if (mru >= PPP_MRU && mru <= PPP_MAXMRU) {            sc->sc_mru = mru;            if (pppgetm(sc) == 0) {	        error = ENOBUFS;	        sc->sc_mru = PPP_MRU;	        if (pppgetm(sc) == 0)		sc->sc_if.if_flags &= ~IFF_UP;            }        }        break;    case PPPIOCGMRU:        *(int *)data = sc->sc_mru;        break;#ifdef VJC    case PPPIOCSMAXCID:	if (*(int *)data > MAX_STATES)	    {	    error = EINVAL; 	    break;	    }        sl_compress_init(&sc->sc_comp);        break;#endif    case PPPIOCXFERUNIT:        sc->sc_xfer = 0;        break;    case SIOCSIFMTU:	sc->sc_if.if_mtu = *(int *)data;	break;    case SIOCGIFMTU:        *(int *)data = sc->sc_if.if_mtu;        break;    case PPPIOCGFD:        *(int *)data = sc->sc_fd;        break;    default:        return (ENOTSUP);    }    return (error);}staticvoid pinit(unit)    int unit;{    struct ppp_softc *ppp = ppp_softc [unit];    ppp->sc_if.if_flags |= IFF_UP | IFF_RUNNING; /* open for business */}/* * FCS lookup table as calculated by genfcstab. */static u_short fcstab[256] = {	0x0000,	0x1189,	0x2312,	0x329b,	0x4624,	0x57ad,	0x6536,	0x74bf,	0x8c48,	0x9dc1,	0xaf5a,	0xbed3,	0xca6c,	0xdbe5,	0xe97e,	0xf8f7,	0x1081,	0x0108,	0x3393,	0x221a,	0x56a5,	0x472c,	0x75b7,	0x643e,	0x9cc9,	0x8d40,	0xbfdb,	0xae52,	0xdaed,	0xcb64,	0xf9ff,	0xe876,	0x2102,	0x308b,	0x0210,	0x1399,	0x6726,	0x76af,	0x4434,	0x55bd,	0xad4a,	0xbcc3,	0x8e58,	0x9fd1,	0xeb6e,	0xfae7,	0xc87c,	0xd9f5,	0x3183,	0x200a,	0x1291,	0x0318,	0x77a7,	0x662e,	0x54b5,	0x453c,	0xbdcb,	0xac42,	0x9ed9,	0x8f50,	0xfbef,	0xea66,	0xd8fd,	0xc974,	0x4204,	0x538d,	0x6116,	0x709f,	0x0420,	0x15a9,	0x2732,	0x36bb,	0xce4c,	0xdfc5,	0xed5e,	0xfcd7,	0x8868,	0x99e1,	0xab7a,	0xbaf3,	0x5285,	0x430c,	0x7197,	0x601e,	0x14a1,	0x0528,	0x37b3,	0x263a,	0xdecd,	0xcf44,	0xfddf,	0xec56,	0x98e9,	0x8960,	0xbbfb,	0xaa72,	0x6306,	0x728f,	0x4014,	0x519d,	0x2522,	0x34ab,	0x0630,	0x17b9,	0xef4e,	0xfec7,	0xcc5c,	0xddd5,	0xa96a,	0xb8e3,	0x8a78,	0x9bf1,	0x7387,	0x620e,	0x5095,	0x411c,	0x35a3,	0x242a,	0x16b1,	0x0738,	0xffcf,	0xee46,	0xdcdd,	0xcd54,	0xb9eb,	0xa862,	0x9af9,	0x8b70,	0x8408,	0x9581,	0xa71a,	0xb693,	0xc22c,	0xd3a5,	0xe13e,	0xf0b7,	0x0840,	0x19c9,	0x2b52,	0x3adb,	0x4e64,	0x5fed,	0x6d76,	0x7cff,	0x9489,	0x8500,	0xb79b,	0xa612,	0xd2ad,	0xc324,	0xf1bf,	0xe036,	0x18c1,	0x0948,	0x3bd3,	0x2a5a,	0x5ee5,	0x4f6c,	0x7df7,	0x6c7e,	0xa50a,	0xb483,	0x8618,	0x9791,	0xe32e,	0xf2a7,	0xc03c,	0xd1b5,	0x2942,	0x38cb,	0x0a50,	0x1bd9,	0x6f66,	0x7eef,	0x4c74,	0x5dfd,	0xb58b,	0xa402,	0x9699,	0x8710,	0xf3af,	0xe226,	0xd0bd,	0xc134,	0x39c3,	0x284a,	0x1ad1,	0x0b58,	0x7fe7,	0x6e6e,	0x5cf5,	0x4d7c,	0xc60c,	0xd785,	0xe51e,	0xf497,	0x8028,	0x91a1,	0xa33a,	0xb2b3,	0x4a44,	0x5bcd,	0x6956,	0x78df,	0x0c60,	0x1de9,	0x2f72,	0x3efb,	0xd68d,	0xc704,	0xf59f,	0xe416,	0x90a9,	0x8120,	0xb3bb,	0xa232,	0x5ac5,	0x4b4c,	0x79d7,	0x685e,	0x1ce1,	0x0d68,	0x3ff3,	0x2e7a,	0xe70e,	0xf687,	0xc41c,	0xd595,	0xa12a,	0xb0a3,	0x8238,	0x93b1,	0x6b46,	0x7acf,	0x4854,	0x59dd,	0x2d62,	0x3ceb,	0x0e70,	0x1ff9,	0xf78f,	0xe606,	0xd49d,	0xc514,	0xb1ab,	0xa022,	0x92b9,	0x8330,	0x7bc7,	0x6a4e,	0x58d5,	0x495c,	0x3de3,	0x2c6a,	0x1ef1,	0x0f78};/* * Calculate a new FCS given the current FCS and the new data. */static u_shortpppfcs(fcs, cp, len)    register u_short fcs;    register u_char *cp;    register int len;{    while (len--)        fcs = PPP_FCS(fcs, *cp++);    return (fcs);}/* * Queue a packet.  Start transmission if not active. * Packet is placed in Information field of PPP frame. */static intpppoutput(ifp, m0, dst, pRtEntry)    struct ifnet *ifp;    struct mbuf *m0;    struct sockaddr *dst;    struct rtentry * pRtEntry; 		/* to satisfy compiler */{    register struct ppp_softc *sc = ppp_softc[ifp->if_unit];    struct ppp_header *ph;    int protocol, address, control;    u_char *cp;    int s, error;    struct ip *ip;    struct ifqueue *ifq;    char buf[PPPBUFSIZE];    if ((sc->sc_fd == 0 || (ifp->if_flags & IFF_RUNNING) == 0        || (ifp->if_flags & IFF_UP) == 0) && dst->sa_family != AF_UNSPEC) {        error = ENETDOWN;	/* sort of */        goto bad;    }    /*     * Compute PPP header.     */    address = PPP_ALLSTATIONS;    control = PPP_UI;    ifq = &ifp->if_snd;    switch (dst->sa_family) {    case AF_INET:        protocol = PPP_IP;        if ((sc->sc_flags & SC_ENABLE_IP) == 0) {            error = ENETDOWN;            goto bad;        }	sc->sc_ipsent++;			/* incr ip packets sent */        /*         * If this is a TCP packet to or from an "interactive" port,         * put the packet on the fastq instead.         */        if ((ip = mtod(m0, struct ip *))->ip_p == IPPROTO_TCP) {            register int p = ntohl(((int *)ip)[ip->ip_hl]);            if (INTERACTIVE(p & 0xffff) || INTERACTIVE(p >> 16))                ifq = &sc->sc_fastq;        }        break;#ifdef NS    case AF_NS:        protocol = PPP_XNS;            break;#endif    case AF_UNSPEC:        ph = (struct ppp_header *)dst->sa_data;        address = ph->ph_address;        control = ph->ph_control;        protocol = ntohs(ph->ph_protocol);        break;    default:        printf("ppp%d: af%d not supported\n",        ifp->if_unit, dst->sa_family);        error = EAFNOSUPPORT;        goto bad;    }    /*     * Add PPP header.  If no space in first mbuf, allocate another.     * (This assumes M_LEADINGSPACE is always 0 for a cluster mbuf.)     */    if (M_LEADINGSPACE(m0) < PPP_HDRLEN) {        m0 = m_prepend(m0, PPP_HDRLEN, M_DONTWAIT);        if (m0 == 0) {            error = ENOBUFS;        goto bad;        }        m0->m_len = 0;    } else        m0->m_data -= PPP_HDRLEN;    cp = mtod(m0, u_char *);    *cp++ = address;    *cp++ = control;    *cp++ = protocol >> 8;    *cp++ = protocol & 0xff;    m0->m_len += PPP_HDRLEN;    if (sc->sc_flags & SC_LOG_OUTPKT) {        printf("ppp%d output: ", ifp->if_unit);        pppdumpm(m0, -1);    }    /* Process etherOutputHook */    if ((etherOutputHookRtn != NULL))	{	struct mbuf *mp;	int ilen;	FAST char *p = (char *)buf;	ilen = 0;	/* Calculate the packet len */	for (mp = m0; mp != NULL; mp = mp->m_next)        ilen += mp->m_len;	/* Copy the packet to the buffer */	for (mp = m0; mp != NULL; p += mp->m_len, mp = mp->m_next)            bcopy(mtod (mp, char *), p, mp->m_len);	if ((*etherOutputHookRtn) (ifp, buf, ilen) != 0)            {	    /* output hook has already processed this packet */            return (OK);            }	}    /*     * Put the packet on the appropriate queue.     */    s = splimp();    if (IF_QFULL(ifq)) {        IF_DROP(ifq);        splx(s);        sc->sc_if.if_oerrors++;        error = ENOBUFS;        goto bad;    }    IF_ENQUEUE(ifq, m0);    ifp->if_lastchange = tickGet (); 		/* record the last change */    /*     * Tell the device to send it out.     */    (*sc->sc_start)(sc);    splx(s);    return (OK);bad:    m_freem(m0);    errno = error;    return (error);}/* * Grab another packet off a queue and apply VJ compression, * address/control and/or protocol compression if appropriate. */static struct mbuf *ppp_dequeue(sc)    struct ppp_softc *sc;{    int s;    struct mbuf *m;    u_char *cp;    int address, control, protocol;    s = splimp();    IF_DEQUEUE(&sc->sc_fastq, m);    if (m == NULL)        IF_DEQUEUE(&sc->sc_if.if_snd, m);    splx(s);    if (m == NULL)        return NULL;    /*     * Extract the ppp header of the new packet.     * The ppp header will be in one mbuf.     */    cp = mtod(m, u_char *);    address = cp[0];    control = cp[1];    protocol = (cp[2] << 8) + cp[3];    switch (protocol) {#ifdef VJC    case PPP_IP:    /*     * If the packet is a TCP/IP packet, see if we can compress it.     */	if (sc->sc_flags & SC_COMP_TCP) {            struct ip *ip;	    int type;	    struct mbuf *mp;	    mp = m;	    ip = (struct ip *) (cp + PPP_HDRLEN);	    if (mp->m_len <= PPP_HDRLEN) {                mp = mp->m_next;		if (mp == NULL)		    break;		ip = mtod(mp, struct ip *);	    }        /* this code assumes the IP/TCP header is in one non-shared mbuf */	    if (ip->ip_p == IPPROTO_TCP) {                type = sl_compress_tcp(mp, ip, &sc->sc_comp,				       !(sc->sc_flags & SC_NO_TCP_CCID));		switch (type) {		case TYPE_UNCOMPRESSED_TCP:		    protocol = PPP_VJC_UNCOMP;		    break;		case TYPE_COMPRESSED_TCP:		    protocol = PPP_VJC_COMP;		    cp = mtod(m, u_char *);		    cp[0] = address;        /* header has moved */		    cp[1] = control;		    cp[2] = 0;		    break;		}		cp[3] = protocol;   /* update protocol in PPP header */	    }	}#endif  /* VJC */    }    /*     * Compress the address/control and protocol, if possible.     */    if (sc->sc_flags & SC_COMP_AC && address == PPP_ALLSTATIONS &&        control == PPP_UI && protocol != PPP_ALLSTATIONS &&        protocol != PPP_LCP) {        /* can compress address/control */        m->m_data += 2;        m->m_len -= 2;    }    if (sc->sc_flags & SC_COMP_PROT && protocol < 0xFF) {        /* can compress protocol */        if (mtod(m, u_char *) == cp) {            cp[2] = cp[1];      /* move address/control up */            cp[1] = cp[0];        }        ++m->m_data;        --m->m_len;    }    return m;}/* * This gets called from pppoutput when a new packet is * put on a queue. */static intpppasyncstart(sc)    register struct ppp_softc *sc;{    semGive(&sc->sc_wrtsem);    return 1;}/*  * Start output on interface.  Get another datagram * to send from the interface queue and map it to * the interface before starting output. */voidppp_wrt_task(sc)    register struct ppp_softc *sc;{    register struct mbuf *m;    register int len;    register u_char *start, *stop, *cp;    int n, ndone, done;    struct mbuf *m2;    int count, fd;    char ch;    fd = sc->sc_fd;    for (;;) {	semTake(&sc->sc_wrtsem, WAIT_FOREVER);	for (;;) {            /*             * See if we have an existing packet partly sent.             * If not, get a new packet and start sending it.             * We take packets on the priority queue ahead of those             * on the normal queue.             */            m = sc->sc_outm;            if (m == NULL) {                /*                 * Get another packet to be sent                 */                m = ppp_dequeue(sc);                if (m == NULL)                    break;                /*                 * The extra PPP_FLAG will start up a new packet, and thus                 * will flush any accumulated garbage.  We do this whenever                 * the line may have been idle for some time.

⌨️ 快捷键说明

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