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

📄 if_ppp.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
ppp_btom(sc)    struct ppp_softc *sc;{    register struct mbuf *m, **mp;    struct mbuf *top = sc->sc_m;    /*     * First check current mbuf.  If we have more than a small mbuf,     * return the whole cluster and set beginning of buffer to the     * next mbuf.     * Else, copy the current bytes into a small mbuf, attach the new     * mbuf to the end of the chain and set beginning of buffer to the     * current mbuf.     */    if (sc->sc_mc->m_len > MHLEN) {	sc->sc_m = sc->sc_mc->m_next;	sc->sc_mc->m_next = NULL;    }    else {	/* rather than waste a whole cluster on <= MHLEN bytes,	   alloc a small mbuf and copy to it */	MGETHDR(m, M_DONTWAIT, MT_DATA);	if (m == NULL)	    return (NULL);	bcopy(mtod(sc->sc_mc, caddr_t), mtod(m, caddr_t), sc->sc_mc->m_len);	m->m_len = sc->sc_mc->m_len;	for (mp = &top; *mp != sc->sc_mc; mp = &(*mp)->m_next)	    ;	*mp = m;	sc->sc_m = sc->sc_mc;    }    /*     * Try to allocate enough extra mbufs to handle the next packet.     */    if (pppgetm(sc) == 0) {	m_freem(top);	if (pppgetm(sc) == 0)	{	    sc->sc_if.if_flags &= ~IFF_UP;	    microtime(&sc->sc_if.if_lastchange);	}	return (NULL);    }    return (top);}/* * 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)intppppktin(sc, m, ilen)    struct ppp_softc *sc;    struct mbuf *m;    int ilen;{    struct ifqueue *inq;    int s, xlen, proto, rv;    struct ppp_header hdr;    sc->sc_if.if_ipackets++;    rv = 0;    hdr = *mtod(m, struct ppp_header *);    proto = ntohs(hdr.ph_protocol);#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);	    sc->sc_if.if_ierrors++;	    return 0;	}	m->m_data += PPP_HDRLEN;	m->m_len -= PPP_HDRLEN;	ilen -= PPP_HDRLEN;	xlen = sl_uncompress_tcp_part((u_char **)(&m->m_data),					m->m_len, ilen,					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);	    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 */	hdr.ph_protocol = htons(PPP_IP);	*mtod(m, struct ppp_header *) = hdr;    }#endif /* VJC */    /* get this packet as an mbuf chain */    if ((m = ppp_btom(sc)) == NULL) {	sc->sc_if.if_ierrors++;	return 0;    }    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    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;	schednetisr(NETISR_IP);	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);    splx(s);    return rv;}/* * tty interface receiver interrupt. */static unsigned paritytab[8] = {    0x96696996, 0x69969669, 0x69969669, 0x96696996,    0x69969669, 0x96696996, 0x96696996, 0x69969669};intpppinput(c, tp)    int c;    register struct tty *tp;{    register struct ppp_softc *sc;    struct mbuf *m;    int ilen;    tk_nin++;    sc = (struct ppp_softc *) tp->t_sc;    if (sc == NULL || tp != (struct tty *) sc->sc_devp)	return 0;    ++sc->sc_bytesrcvd;    if ((tp->t_state & TS_CONNECTED) == 0) {	if (sc->sc_flags & SC_DEBUG)	    printf("ppp%d: no carrier\n", sc->sc_if.if_unit);	goto flush;    }    if (c & TTY_ERRORMASK) {	if (sc->sc_flags & SC_DEBUG)	    printf("ppp%d: line error %x\n", sc->sc_if.if_unit, c & TTY_ERRORMASK);	goto flush;    }    c &= TTY_CHARMASK;    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.	     */	    sl_uncompress_tcp(NULL, 0, TYPE_ERROR, &sc->sc_comp);#endif	    if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){		if (sc->sc_flags & SC_DEBUG)		    printf("ppp%d: bad fcs\n", sc->sc_if.if_unit);		sc->sc_if.if_ierrors++;	    } else		sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);	    return 0;	}	if (ilen < PPP_HDRLEN + PPP_FCSLEN) {	    if (ilen) {		if (sc->sc_flags & SC_DEBUG)		    printf("ppp%d: too short (%d)\n", sc->sc_if.if_unit, ilen);		sc->sc_if.if_ierrors++;	    }	    return 0;	}	/*	 * Remove FCS trailer.  Somewhat painful...	 */	ilen -= 2;	if (--sc->sc_mc->m_len == 0) {	    for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next)		;	    sc->sc_mc = m;	}	sc->sc_mc->m_len--;	m = sc->sc_m;	if (sc->sc_flags & SC_LOG_INPKT) {	    printf("ppp%d: got %d bytes\n", sc->sc_if.if_unit, ilen);	    pppdumpm(m, ilen);	}	if (ppppktin(sc, m, ilen)) {	    /* Put a placeholder byte in canq for ttselect()/ttnread(). */	    putc(0, &tp->t_canq);	    ttwakeup(tp);	}	return 0;    }    if (sc->sc_flags & SC_FLUSH) {	if (sc->sc_flags & SC_LOG_FLUSH)	    ppplogchar(sc, c);	return 0;    }    if (c < 0x20 && (sc->sc_rasyncmap & (1 << c)))	return 0;    if (sc->sc_flags & SC_ESCAPED) {	sc->sc_flags &= ~SC_ESCAPED;	c ^= PPP_TRANS;    } else if (c == PPP_ESCAPE) {	sc->sc_flags |= SC_ESCAPED;	return 0;    }    /*     * Initialize buffer on first octet received.     * First octet could be address or protocol (when compressing     * address/control).     * Second octet is control.     * Third octet is first or second (when compressing protocol)     * octet of protocol.     * Fourth octet is second octet of protocol.     */    if (sc->sc_ilen == 0) {	/* reset the first input mbuf */	m = sc->sc_m;	m->m_len = 0;	m->m_data = M_DATASTART(sc->sc_m) + HDROFF;	sc->sc_mc = m;	sc->sc_mp = mtod(m, char *);	sc->sc_fcs = PPP_INITFCS;	if (c != PPP_ALLSTATIONS) {	    if (sc->sc_flags & SC_REJ_COMP_AC) {		if (sc->sc_flags & SC_DEBUG)		    printf("ppp%d: garbage received: 0x%x (need 0xFF)\n",			   sc->sc_if.if_unit, c);		goto flush;	    }	    *sc->sc_mp++ = PPP_ALLSTATIONS;	    *sc->sc_mp++ = PPP_UI;	    sc->sc_ilen += 2;	    m->m_len += 2;	}    }    if (sc->sc_ilen == 1 && c != PPP_UI) {	if (sc->sc_flags & SC_DEBUG)	    printf("ppp%d: missing UI (0x3), got 0x%x\n",		   sc->sc_if.if_unit, c);	goto flush;    }    if (sc->sc_ilen == 2 && (c & 1) == 1) {	/* a compressed protocol */	*sc->sc_mp++ = 0;	sc->sc_ilen++;	sc->sc_mc->m_len++;    }    if (sc->sc_ilen == 3 && (c & 1) == 0) {	if (sc->sc_flags & SC_DEBUG)	    printf("ppp%d: bad protocol %x\n", sc->sc_if.if_unit,		   (sc->sc_mp[-1] << 8) + c);	goto flush;    }    /* packet beyond configured mru? */    if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) {	if (sc->sc_flags & SC_DEBUG)	    printf("ppp%d: packet too big\n", sc->sc_if.if_unit);	goto flush;    }    /* is this mbuf full? */    m = sc->sc_mc;    if (M_TRAILINGSPACE(m) <= 0) {	sc->sc_mc = m = m->m_next;	if (m == NULL) {	    printf("ppp%d: too few input mbufs!\n", sc->sc_if.if_unit);	    goto flush;	}	m->m_len = 0;	m->m_data = M_DATASTART(m);	sc->sc_mp = mtod(m, char *);    }    ++m->m_len;    *sc->sc_mp++ = c;    sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);    return 0; flush:    if (!(sc->sc_flags & SC_FLUSH)) {	sc->sc_if.if_ierrors++;	sc->sc_flags |= SC_FLUSH;	if (sc->sc_flags & SC_LOG_FLUSH)	    ppplogchar(sc, c);    }    return 0;}/* * Process an ioctl request to interface. */intpppioctl(ifp, cmd, data)    register struct ifnet *ifp;    int cmd;    caddr_t data;{    struct proc *p = curproc;	/* XXX */    register struct ppp_softc *sc = &ppp_softc[ifp->if_unit];    register struct ifaddr *ifa = (struct ifaddr *)data;    register struct ifreq *ifr = (struct ifreq *)data;    int s = splimp(), error = 0;    switch (cmd) {    case SIOCSIFFLAGS:	if ((ifp->if_flags & IFF_RUNNING) == 0)	    ifp->if_flags &= ~IFF_UP;	break;    case SIOCSIFADDR:	if (ifa->ifa_addr->sa_family != AF_INET)	    error = EAFNOSUPPORT;	break;    case SIOCSIFDSTADDR:	if (ifa->ifa_addr->sa_family != AF_INET)	    error = EAFNOSUPPORT;	break;    case SIOCSIFMTU:	if (error = suser(p->p_ucred, &p->p_acflag))	    return (error);	if (ifr->ifr_mtu > PPP_MAXMTU)	    error = EINVAL;	else {	    struct tty *tp;	    sc->sc_if.if_mtu = ifr->ifr_mtu;	    tp = (struct tty *) sc->sc_devp;	    if (tp != NULL)		clist_alloc_cblocks(&tp->t_outq, sc->sc_if.if_mtu + PPP_HIWAT,				    sc->sc_if.if_mtu + PPP_HIWAT);	}	break;    case SIOCGIFMTU:	ifr->ifr_mtu = sc->sc_if.if_mtu;	break;    case SIOCADDMULTI:    case SIOCDELMULTI:	switch(ifr->ifr_addr.sa_family) {#ifdef INET	case AF_INET:		break;#endif	default:		error = EAFNOSUPPORT;		break;	}	break;    default:	error = EINVAL;    }    splx(s);    return (error);}#define MAX_DUMP_BYTES	128static voidpppdumpm(m0, pktlen)    struct mbuf *m0;    int pktlen;{    char buf[3*MAX_DUMP_BYTES+4];    char *bp = buf;    struct mbuf *m;    static char digits[] = "0123456789abcdef";    for (m = m0; m && pktlen; m = m->m_next) {	int l = m->m_len;	u_char *rptr = (u_char *)m->m_data;	if (pktlen > 0) {	    if (l > pktlen)		l = pktlen;	    pktlen -= l;	}	while (l--) {	    if (bp > buf + sizeof(buf) - 4)		goto done;	    *bp++ = digits[*rptr >> 4]; /* convert byte to ascii hex */	    *bp++ = digits[*rptr++ & 0xf];	}	if (m->m_next) {	    if (bp > buf + sizeof(buf) - 3)		goto done;	    *bp++ = '|';	} else	    *bp++ = ' ';    }done:    if (m && pktlen)	*bp++ = '>';    *bp = 0;    printf("%s\n", buf);}static voidppplogchar(sc, c)    struct ppp_softc *sc;    int c;{    if (c >= 0)	sc->sc_rawin[sc->sc_rawin_count++] = c;    if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)	|| c < 0 && sc->sc_rawin_count > 0) {	printf("ppp%d input: ", sc->sc_if.if_unit);	pppdumpb(sc->sc_rawin, sc->sc_rawin_count);	sc->sc_rawin_count = 0;    }}static voidpppdumpb(b, l)    u_char *b;    int l;{    char buf[3*MAX_DUMP_BYTES+4];    char *bp = buf;    static char digits[] = "0123456789abcdef";    while (l--) {	if (bp >= buf + sizeof(buf) - 3) {	    *bp++ = '>';	    break;	}	*bp++ = digits[*b >> 4]; /* convert byte to ascii hex */	*bp++ = digits[*b++ & 0xf];	*bp++ = ' ';    }    *bp = 0;    printf("%s\n", buf);}PSEUDO_SET(pppattach, if_ppp);#endif	/* NPPP > 0 */

⌨️ 快捷键说明

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