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

📄 ppp.c

📁 经典的ppp程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	    DPRINT1("ppp%d: lower stream still connected on close?\n",		    up->mn);	    LOCK_LOWER_W;	    up->lowerq->q_ptr = 0;	    RD(up->lowerq)->q_ptr = 0;	    up->lowerq = 0;	    UNLOCK_LOWER;	}	/*	 * This stream represents a PPA:	 * For all streams attached to the PPA, clear their	 * references to this PPA.	 * Then remove this PPA from the list of PPAs.	 */	for (as = up->next; as != 0; as = asnext) {	    asnext = as->next;	    as->next = 0;	    as->ppa = 0;	    if (as->flags & US_BLOCKED) {		as->flags &= ~US_BLOCKED;		flushq(WR(as->q), FLUSHDATA);	    }	}	for (upp = &ppas; *upp != 0; upp = &(*upp)->nextppa)	    if (*upp == up) {		*upp = up->nextppa;		break;	    }#ifdef LACHTCP	/* Remove the statistics from the active list.  */	for (ifp = ifstats, pifp = 0; ifp; ifp = ifp->ifs_next) {	    if (ifp == &up->ifstats) {		if (pifp)		    pifp->ifs_next = ifp->ifs_next;		else		    ifstats = ifp->ifs_next;		break;	    }	    pifp = ifp;	}#endif    } else {	/*	 * If this stream is attached to a PPA,	 * remove it from the PPA's list.	 */	if ((as = up->ppa) != 0) {	    for (; as->next != 0; as = as->next)		if (as->next == up) {		    as->next = up->next;		    break;		}	}    }#ifdef SOL2    if (up->kstats)	kstat_delete(up->kstats);    mutex_destroy(&up->stats_lock);#endif    q->q_ptr = NULL;    WR(q)->q_ptr = NULL;    for (prevp = &minor_devs; *prevp != 0; prevp = &(*prevp)->nextmn) {	if (*prevp == up) {	    *prevp = up->nextmn;	    break;	}    }    FREE(up, sizeof(upperstr_t));    --ppp_count;    return 0;}/* * A message from on high.  We do one of three things: *	- qreply() *	- put the message on the lower write stream *	- queue it for our service routine */static intpppuwput(q, mp)    queue_t *q;    mblk_t *mp;{    upperstr_t *us, *ppa, *nps;    struct iocblk *iop;    struct linkblk *lb;#ifdef LACHTCP    struct ifreq *ifr;    int i;#endif    queue_t *lq;    int error, n, sap;    mblk_t *mq;    struct ppp_idle *pip;#ifdef PRIOQ    queue_t *tlq;#endif	/* PRIOQ */#ifdef NO_DLPI    upperstr_t *os;#endif    us = (upperstr_t *) q->q_ptr;    if (us == 0) {	DPRINT("pppuwput: q_ptr = 0!\n");	return 0;    }    if (mp == 0) {	DPRINT1("pppuwput/%d: mp = 0!\n", us->mn);	return 0;    }    if (mp->b_datap == 0) {	DPRINT1("pppuwput/%d: mp->b_datap = 0!\n", us->mn);	return 0;    }    switch (mp->b_datap->db_type) {#ifndef NO_DLPI    case M_PCPROTO:    case M_PROTO:	dlpi_request(q, mp, us);	break;#endif /* NO_DLPI */    case M_DATA:	if (us->flags & US_DBGLOG)	    DPRINT3("ppp/%d: uwput M_DATA len=%d flags=%x\n",		    us->mn, msgdsize(mp), us->flags);	if (us->ppa == 0 || msgdsize(mp) > us->ppa->mtu + PPP_HDRLEN#ifndef NO_DLPI	    || (us->flags & US_CONTROL) == 0#endif /* NO_DLPI */	    ) {	    DPRINT1("pppuwput: junk data len=%d\n", msgdsize(mp));	    freemsg(mp);	    break;	}#ifdef NO_DLPI	if ((us->flags & US_CONTROL) == 0 && !pass_packet(us, mp, 1))	    break;#endif	if (!send_data(mp, us))	    putq(q, mp);	break;    case M_IOCTL:	iop = (struct iocblk *) mp->b_rptr;	error = EINVAL;	if (us->flags & US_DBGLOG)	    DPRINT3("ppp/%d: ioctl %x count=%d\n",		    us->mn, iop->ioc_cmd, iop->ioc_count);	switch (iop->ioc_cmd) {#if defined(SOL2)	case DLIOCRAW:	    /* raw M_DATA mode */	    us->flags |= US_RAWDATA;	    error = 0;	    break;#endif /* defined(SOL2) */	case I_LINK:	    if ((us->flags & US_CONTROL) == 0 || us->lowerq != 0)		break;	    if (mp->b_cont == 0) {		DPRINT1("pppuwput/%d: ioctl I_LINK b_cont = 0!\n", us->mn);		break;	    }	    lb = (struct linkblk *) mp->b_cont->b_rptr;	    lq = lb->l_qbot;	    if (lq == 0) {		DPRINT1("pppuwput/%d: ioctl I_LINK l_qbot = 0!\n", us->mn);		break;	    }	    LOCK_LOWER_W;	    us->lowerq = lq;	    lq->q_ptr = (caddr_t) q;	    RD(lq)->q_ptr = (caddr_t) us->q;	    UNLOCK_LOWER;	    iop->ioc_count = 0;	    error = 0;	    us->flags &= ~US_LASTMOD;	    /* Unblock upper streams which now feed this lower stream. */	    qenable(q);	    /* Send useful information down to the modules which	       are now linked below us. */	    putctl2(lq, M_CTL, PPPCTL_UNIT, us->ppa_id);	    putctl4(lq, M_CTL, PPPCTL_MRU, us->mru);	    putctl4(lq, M_CTL, PPPCTL_MTU, us->mtu);#ifdef PRIOQ            /* Lower tty driver's queue hiwat/lowat from default 4096/128               to 256/128 since we don't want queueing of data on               output to physical device */            freezestr(lq);            for (tlq = lq; tlq->q_next != NULL; tlq = tlq->q_next)		;            strqset(tlq, QHIWAT, 0, 256);            strqset(tlq, QLOWAT, 0, 128);            unfreezestr(lq);#endif	/* PRIOQ */	    break;	case I_UNLINK:	    if (mp->b_cont == 0) {		DPRINT1("pppuwput/%d: ioctl I_UNLINK b_cont = 0!\n", us->mn);		break;	    }	    lb = (struct linkblk *) mp->b_cont->b_rptr;#if DEBUG	    if (us->lowerq != lb->l_qbot) {		DPRINT2("ppp unlink: lowerq=%x qbot=%x\n",			us->lowerq, lb->l_qbot);		break;	    }#endif	    iop->ioc_count = 0;	    qwriter(q, mp, detach_lower, PERIM_OUTER);	    error = -1;	    break;	case PPPIO_NEWPPA:	    if (us->flags & US_CONTROL)		break;	    if ((us->flags & US_PRIV) == 0) {		error = EPERM;		break;	    }	    /* Arrange to return an int */	    if ((mq = mp->b_cont) == 0		|| mq->b_datap->db_lim - mq->b_rptr < sizeof(int)) {		mq = allocb(sizeof(int), BPRI_HI);		if (mq == 0) {		    error = ENOSR;		    break;		}		if (mp->b_cont != 0)		    freemsg(mp->b_cont);		mp->b_cont = mq;		mq->b_cont = 0;	    }	    iop->ioc_count = sizeof(int);	    mq->b_wptr = mq->b_rptr + sizeof(int);	    qwriter(q, mp, new_ppa, PERIM_OUTER);	    error = -1;	    break;	case PPPIO_ATTACH:	    /* like dlpi_attach, for programs which can't write to	       the stream (like pppstats) */	    if (iop->ioc_count != sizeof(int) || us->ppa != 0)		break;	    if (mp->b_cont == 0) {		DPRINT1("pppuwput/%d: ioctl PPPIO_ATTACH b_cont = 0!\n", us->mn);		break;	    }	    n = *(int *)mp->b_cont->b_rptr;	    for (ppa = ppas; ppa != 0; ppa = ppa->nextppa)		if (ppa->ppa_id == n)		    break;	    if (ppa == 0)		break;	    us->ppa = ppa;	    iop->ioc_count = 0;	    qwriter(q, mp, attach_ppa, PERIM_OUTER);	    error = -1;	    break;#ifdef NO_DLPI	case PPPIO_BIND:	    /* Attach to a given SAP. */	    if (iop->ioc_count != sizeof(int) || us->ppa == 0)		break;	    if (mp->b_cont == 0) {		DPRINT1("pppuwput/%d: ioctl PPPIO_BIND b_cont = 0!\n", us->mn);		break;	    }	    n = *(int *)mp->b_cont->b_rptr;	    /* n must be a valid PPP network protocol number. */	    if (n < 0x21 || n > 0x3fff || (n & 0x101) != 1)		break;	    /* check that no other stream is bound to this sap already. */	    for (os = us->ppa; os != 0; os = os->next)		if (os->sap == n)		    break;	    if (os != 0)		break;	    us->sap = n;	    iop->ioc_count = 0;	    error = 0;	    break;#endif /* NO_DLPI */	case PPPIO_MRU:	    if (iop->ioc_count != sizeof(int) || (us->flags & US_CONTROL) == 0)		break;	    if (mp->b_cont == 0) {		DPRINT1("pppuwput/%d: ioctl PPPIO_MRU b_cont = 0!\n", us->mn);		break;	    }	    n = *(int *)mp->b_cont->b_rptr;	    if (n <= 0 || n > PPP_MAXMRU)		break;	    if (n < PPP_MRU)		n = PPP_MRU;	    us->mru = n;	    if (us->lowerq)		putctl4(us->lowerq, M_CTL, PPPCTL_MRU, n);	    error = 0;	    iop->ioc_count = 0;	    break;	case PPPIO_MTU:	    if (iop->ioc_count != sizeof(int) || (us->flags & US_CONTROL) == 0)		break;	    if (mp->b_cont == 0) {		DPRINT1("pppuwput/%d: ioctl PPPIO_MTU b_cont = 0!\n", us->mn);		break;	    }	    n = *(int *)mp->b_cont->b_rptr;	    if (n <= 0 || n > PPP_MAXMTU)		break;	    us->mtu = n;#ifdef LACHTCP	    /* The MTU reported in netstat, not used as IP max packet size! */	    us->ifstats.ifs_mtu = n;#endif	    if (us->lowerq)		putctl4(us->lowerq, M_CTL, PPPCTL_MTU, n);	    error = 0;	    iop->ioc_count = 0;	    break;	case PPPIO_LASTMOD:	    us->flags |= US_LASTMOD;	    error = 0;	    break;	case PPPIO_DEBUG:	    if (iop->ioc_count != sizeof(int))		break;	    if (mp->b_cont == 0) {		DPRINT1("pppuwput/%d: ioctl PPPIO_DEBUG b_cont = 0!\n", us->mn);		break;	    }	    n = *(int *)mp->b_cont->b_rptr;	    if (n == PPPDBG_DUMP + PPPDBG_DRIVER) {		qwriter(q, NULL, debug_dump, PERIM_OUTER);		iop->ioc_count = 0;		error = -1;	    } else if (n == PPPDBG_LOG + PPPDBG_DRIVER) {		DPRINT1("ppp/%d: debug log enabled\n", us->mn);		us->flags |= US_DBGLOG;		iop->ioc_count = 0;		error = 0;	    } else {		if (us->ppa == 0 || us->ppa->lowerq == 0)		    break;		putnext(us->ppa->lowerq, mp);		error = -1;	    }	    break;	case PPPIO_NPMODE:	    if (iop->ioc_count != 2 * sizeof(int))		break;	    if ((us->flags & US_CONTROL) == 0)		break;	    if (mp->b_cont == 0) {		DPRINT1("pppuwput/%d: ioctl PPPIO_NPMODE b_cont = 0!\n", us->mn);		break;	    }	    sap = ((int *)mp->b_cont->b_rptr)[0];	    for (nps = us->next; nps != 0; nps = nps->next) {		if (us->flags & US_DBGLOG)		    DPRINT2("us = 0x%x, us->next->sap = 0x%x\n", nps, nps->sap);		if (nps->sap == sap)		    break;	    }	    if (nps == 0) {		if (us->flags & US_DBGLOG)		    DPRINT2("ppp/%d: no stream for sap %x\n", us->mn, sap);		break;	    }	    /* XXX possibly should use qwriter here */	    nps->npmode = (enum NPmode) ((int *)mp->b_cont->b_rptr)[1];	    if (nps->npmode != NPMODE_QUEUE && (nps->flags & US_BLOCKED) != 0)		qenable(WR(nps->q));	    iop->ioc_count = 0;	    error = 0;	    break;	case PPPIO_GIDLE:	    if ((ppa = us->ppa) == 0)		break;	    mq = allocb(sizeof(struct ppp_idle), BPRI_HI);	    if (mq == 0) {		error = ENOSR;		break;	    }	    if (mp->b_cont != 0)		freemsg(mp->b_cont);	    mp->b_cont = mq;	    mq->b_cont = 0;	    pip = (struct ppp_idle *) mq->b_wptr;	    pip->xmit_idle = time - ppa->last_sent;	    pip->recv_idle = time - ppa->last_recv;	    mq->b_wptr += sizeof(struct ppp_idle);	    iop->ioc_count = sizeof(struct ppp_idle);	    error = 0;	    break;#ifdef LACHTCP	case SIOCSIFNAME:	    /* Sent from IP down to us.  Attach the ifstats structure.  */	    if (iop->ioc_count != sizeof(struct ifreq) || us->ppa == 0)	        break;	    ifr = (struct ifreq *)mp->b_cont->b_rptr;	    /* Find the unit number in the interface name.  */	    for (i = 0; i < IFNAMSIZ; i++) {		if (ifr->ifr_name[i] == 0 ||		    (ifr->ifr_name[i] >= '0' &&		     ifr->ifr_name[i] <= '9'))		    break;		else		    us->ifname[i] = ifr->ifr_name[i];	    }	    us->ifname[i] = 0;	    /* Convert the unit number to binary.  */	    for (n = 0; i < IFNAMSIZ; i++) {		if (ifr->ifr_name[i] == 0) {		    break;		}	        else {		    n = n * 10 + ifr->ifr_name[i] - '0';		}	    }	    /* Verify the ppa.  */	    if (us->ppa->ppa_id != n)		break;	    ppa = us->ppa;	    /* Set up the netstat block.  */	    strncpy (ppa->ifname, us->ifname, IFNAMSIZ);	    ppa->ifstats.ifs_name = ppa->ifname;	    ppa->ifstats.ifs_unit = n;	    ppa->ifstats.ifs_active = us->state != DL_UNBOUND;	    ppa->ifstats.ifs_mtu = ppa->mtu;	    /* Link in statistics used by netstat.  */	    ppa->ifstats.ifs_next = ifstats;	    ifstats = &ppa->ifstats;	    iop->ioc_count = 0;	    error = 0;	    break;	case SIOCGIFFLAGS:	    if (!(us->flags & US_CONTROL)) {		if (us->ppa)		    us = us->ppa;	        else		    break;	    }	    ((struct iocblk_in *)iop)->ioc_ifflags = us->ifflags;	    error = 0;	    break;	case SIOCSIFFLAGS:	    if (!(us->flags & US_CONTROL)) {		if (us->ppa)		    us = us->ppa;		else		    break;	    }	    us->ifflags = ((struct iocblk_in *)iop)->ioc_ifflags;	    error = 0;	    break;	case SIOCSIFADDR:	    if (!(us->flags & US_CONTROL)) {		if (us->ppa)		    us = us->ppa;		else		    break;	    }	    us->ifflags |= IFF_RUNNING;	    ((struct iocblk_in *)iop)->ioc_ifflags |= IFF_RUNNING;	    error = 0;	    break;	case SIOCSIFMTU:	    /*	     * Vanilla SVR4 systems don't handle SIOCSIFMTU, rather	     * they take the MTU from the DL_INFO_ACK we sent in response

⌨️ 快捷键说明

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