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

📄 lcp.c

📁 vxworks下的实现网络TCPIP协议的原代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	    }	    /*	     * We don't recognize the protocol they're asking for.	     * Nak it with something we're willing to do.	     * (At this point we know ao->neg_upap || ao->neg_chap.)	     */	    orc = CONFNAK;	    PUTCHAR(CI_AUTHTYPE, nakp);	    if (ao->neg_chap) {		PUTCHAR(CILEN_CHAP, nakp);		PUTSHORT(CHAP, nakp);		PUTCHAR(ao->chap_mdtype, nakp);	    } else {		PUTCHAR(CILEN_SHORT, nakp);		PUTSHORT(UPAP, nakp);	    }	    break;            	case CI_QUALITY:	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd QUALITY"));	    if (!ao->neg_lqr ||		cilen != CILEN_LQR) {		orc = CONFREJ;		break;	    }	    GETSHORT(cishort, p);	    GETLONG(cilong, p);	    LCPDEBUG((LOG_INFO, "(%x %lx)", cishort, cilong));	    /*	     * Check the protocol and the reporting period.	     * XXX When should we Nak this, and what with?	     */	    if (cishort != LQR) {		orc = CONFNAK;		PUTCHAR(CI_QUALITY, nakp);		PUTCHAR(CILEN_LQR, nakp);		PUTSHORT(LQR, nakp);		PUTLONG(ao->lqr_period, nakp);		break;	    }	    break;	case CI_MAGICNUMBER:	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd MAGICNUMBER"));	    if (!(ao->neg_magicnumber || go->neg_magicnumber) ||		cilen != CILEN_LONG) {		orc = CONFREJ;		break;	    }	    GETLONG(cilong, p);	    LCPDEBUG((LOG_INFO, "(%lx)", cilong));	    /*	     * He must have a different magic number.	     */	    if (go->neg_magicnumber &&		cilong == go->magicnumber) {		orc = CONFNAK;		cilong = magic();	/* Don't put magic() inside macro! */		orc = CONFNAK;		PUTCHAR(CI_MAGICNUMBER, nakp);		PUTCHAR(CILEN_LONG, nakp);		PUTLONG(cilong, nakp);		break;	    }	    ho->neg_magicnumber = 1;	    ho->magicnumber = cilong;	    break;	case CI_PCOMPRESSION:	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd PCOMPRESSION"));	    if (!ao->neg_pcompression ||		cilen != CILEN_VOID) {		orc = CONFREJ;		break;	    }	    ho->neg_pcompression = 1;	    break;	case CI_ACCOMPRESSION:	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd ACCOMPRESSION"));	    if (!ao->neg_accompression ||		cilen != CILEN_VOID) {		orc = CONFREJ;		break;	    }	    ho->neg_accompression = 1;	    break;	default:	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd unknown option %d",		      citype));	    orc = CONFREJ;	    break;	}endswitch:	LCPDEBUG((LOG_INFO, " (%s)", CODENAME(orc)));	if (orc == CONFACK &&		/* Good CI */	    rc != CONFACK)		/*  but prior CI wasnt? */	    continue;			/* Don't send this one */	if (orc == CONFNAK) {		/* Nak this CI? */	    if (reject_if_disagree	/* Getting fed up with sending NAKs? */		&& citype != CI_MAGICNUMBER) {		orc = CONFREJ;		/* Get tough if so */	    } else {		if (rc == CONFREJ)	/* Rejecting prior CI? */		    continue;		/* Don't send this one */		rc = CONFNAK;	    }	}	if (orc == CONFREJ) {		/* Reject this CI */	    rc = CONFREJ;	    if (cip != rejp)		/* Need to move rejected CI? */		BCOPY(cip, rejp, cilen); /* Move it */	    INCPTR(cilen, rejp);	/* Update output pointer */	}    }    /*     * If we wanted to send additional NAKs (for unsent CIs), the     * code would go here.  The extra NAKs would go at *nakp.     * At present there are no cases where we want to ask the     * peer to negotiate an option.     */    switch (rc) {    case CONFACK:	*lenp = next - inp;	break;    case CONFNAK:	/*	 * Copy the Nak'd options from the nak_buffer to the caller's buffer.	 */	*lenp = nakp - nak_buffer;	BCOPY(nak_buffer, inp, *lenp);	break;    case CONFREJ:	*lenp = rejp - inp;	break;    }    LCPDEBUG((LOG_INFO, "lcp_reqci: returning CONF%s.", CODENAME(rc)));    return (rc);			/* Return final code */}/* * lcp_up - LCP has come UP. * * Start UPAP, IPCP, etc. */static voidlcp_up(f)    fsm *f;{    lcp_options *wo = &ppp_if[f->unit]->lcp_wantoptions;    lcp_options *ho = &ppp_if[f->unit]->lcp_hisoptions;    lcp_options *go = &ppp_if[f->unit]->lcp_gotoptions;    lcp_options *ao = &ppp_if[f->unit]->lcp_allowoptions;    if (!go->neg_magicnumber)        go->magicnumber = 0;    if (!ho->neg_magicnumber)        ho->magicnumber = 0;    /*     * Set our MTU to the smaller of the MTU we wanted and     * the MRU our peer wanted.  If we negotiated an MRU,     * set our MRU to the larger of value we wanted and     * the value we got in the negotiation.     */    ppp_send_config(f->unit,                    MIN(ao->mru? ao->mru: MTU, (ho->neg_mru? ho->mru: MTU)),		    (ho->neg_asyncmap? ho->asyncmap: 0xffffffff),		    ho->neg_pcompression, ho->neg_accompression);    /*     * If the asyncmap hasn't been negotiated, we really should     * set the receive asyncmap to ffffffff, but we set it to 0     * for backwards contemptibility.     */    ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): MTU),                    (go->neg_asyncmap? go->asyncmap: 0x00000000),                    go->neg_pcompression, go->neg_accompression);    if (ho->neg_mru)	ppp_if[f->unit]->peer_mru = ho->mru;    ChapLowerUp(f->unit);	/* Enable CHAP */    upap_lowerup(f->unit);	/* Enable UPAP */    ipcp_lowerup(f->unit);	/* Enable IPCP */    lcp_echo_lowerup(f->unit);  /* Enable echo messages */    link_established(f->unit);}/* * lcp_down - LCP has gone DOWN. * * Alert other protocols. */static voidlcp_down(f)    fsm *f;{    lcp_echo_lowerdown(f->unit);    ipcp_lowerdown(f->unit);    ChapLowerDown(f->unit);    upap_lowerdown(f->unit);    sifdown(f->unit);    ppp_send_config(f->unit, MTU, 0xffffffff, 0, 0);    ppp_recv_config(f->unit, MTU, 0x00000000, 0, 0);    ppp_if[f->unit]->peer_mru = MTU;    link_down(f->unit);}/* * lcp_starting - LCP needs the lower layer up. */static voidlcp_starting(f)    fsm *f;{    link_required(f->unit);}/* * lcp_finished - LCP has finished with the lower layer. */static voidlcp_finished(f)    fsm *f;{    /* if passive or silent flags set and if lcp state is STOPPED or CLOSED      * then reopen the link for the next connection     */    if (((f->state == STOPPED) || (f->state == CLOSED)) && 	(f->flags & OPT_RESTART))	fsm_open (f);     else 	link_terminated(f->unit);}/* * lcp_printpkt - print the contents of an LCP packet. */char *lcp_codenames[] = {    "ConfReq", "ConfAck", "ConfNak", "ConfRej",    "TermReq", "TermAck", "CodeRej", "ProtRej",    "EchoReq", "EchoRep", "DiscReq"};intlcp_printpkt(p, plen, printer, arg)    u_char *p;    int plen;    void (*printer) __ARGS((void *, char *, ...));    void *arg;{    int code, id, len, olen;    u_char *pstart, *optend;    u_short cishort;    u_long cilong;    if (plen < HEADERLEN)        return 0;    pstart = p;    GETCHAR(code, p);    GETCHAR(id, p);    GETSHORT(len, p);    if (len < HEADERLEN || len > plen)        return 0;    if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *))        printer(arg, " %s", lcp_codenames[code-1]);    else        printer(arg, " code=0x%x", code);    printer(arg, " id=0x%x", id);    len -= HEADERLEN;    switch (code) {    case CONFREQ:    case CONFACK:    case CONFNAK:    case CONFREJ:        /* print option list */        while (len >= 2) {            GETCHAR(code, p);            GETCHAR(olen, p);            p -= 2;            if (olen < 2 || olen > len) {                break;            }            printer(arg, " <");            len -= olen;            optend = p + olen;            switch (code) {            case CI_MRU:                if (olen == CILEN_SHORT) {                    p += 2;                    GETSHORT(cishort, p);                    printer(arg, "mru %d", cishort);                }                break;            case CI_ASYNCMAP:                if (olen == CILEN_LONG) {                    p += 2;                    GETLONG(cilong, p);                    printer(arg, "asyncmap 0x%x", cilong);                }                break;            case CI_AUTHTYPE:                if (olen >= CILEN_SHORT) {                    p += 2;                    printer(arg, "auth ");                    GETSHORT(cishort, p);                    switch (cishort) {                    case UPAP:                        printer(arg, "upap");                        break;                    case CHAP:                        printer(arg, "chap");                        break;                    default:                        printer(arg, "0x%x", cishort);                    }                }                break;            case CI_QUALITY:                if (olen >= CILEN_SHORT) {                    p += 2;                    printer(arg, "quality ");                    GETSHORT(cishort, p);                    switch (cishort) {                    case LQR:                        printer(arg, "lqr");                        break;                    default:                        printer(arg, "0x%x", cishort);                    }                }                break;            case CI_MAGICNUMBER:                if (olen == CILEN_LONG) {                    p += 2;                    GETLONG(cilong, p);                    printer(arg, "magic 0x%x", cilong);                }                break;            case CI_PCOMPRESSION:                if (olen == CILEN_VOID) {                    p += 2;                    printer(arg, "pcomp");                }                break;            case CI_ACCOMPRESSION:                if (olen == CILEN_VOID) {                    p += 2;                    printer(arg, "accomp");                }                break;            }            while (p < optend) {                GETCHAR(code, p);                printer(arg, " %.2x", code);            }            printer(arg, ">");        }        break;    }    /* print the rest of the bytes in the packet */    for (; len > 0; --len) {        GETCHAR(code, p);        printer(arg, " %.2x", code);    }    return p - pstart;}/* * Time to shut down the link because there is nothing out there. */staticvoid LcpLinkFailure (f)    fsm *f;{    if (f->state == OPENED) {        syslog (LOG_NOTICE, "Excessive lack of response to LCP echo frames.");        lcp_lowerdown(f->unit);         /* Reset connection */	ppp_if[f->unit]->phase = PHASE_TERMINATE;    }}/* * Timer expired for the LCP echo requests from this process. */static voidLcpEchoCheck (f)    fsm *f;{    u_long             delta;#ifdef __linux__    struct ppp_ddinfo  ddinfo;    u_long             latest;/* * Read the time since the last packet was received. */    if (ioctl (fd, PPPIOCGTIME, &ddinfo) < 0) {        syslog (LOG_ERR, "ioctl(PPPIOCGTIME): %m");        die (1);    }/* * Choose the most recient frame received. It may be an IP or NON-IP frame. */    latest = ddinfo.nip_rjiffies < ddinfo.ip_rjiffies ? ddinfo.nip_rjiffies                                                      : ddinfo.ip_rjiffies;/* * Compute the time since the last packet was received. If the timer *  has expired then send the echo request and reset the timer to maximum. */    delta = (lcp_echo_interval * HZ) - latest;    if (delta < HZ || latest < 0L) {        LcpSendEchoRequest (f);        delta = lcp_echo_interval * HZ;    }    delta /= HZ;#else /* Other implementations do not have ability to find delta */    LcpSendEchoRequest (f);    delta = ppp_if[f->unit]->lcp_echo_interval;#endif/* * Start the timer for the next interval. */    assert (ppp_if[f->unit]->lcp_echo_timer_running==0);    PPP_TIMEOUT (LcpEchoTimeout, (caddr_t) f, delta);    ppp_if[f->unit]->lcp_echo_timer_running = 1;}/* * LcpEchoTimeout - Timer expired on the LCP echo */static voidLcpEchoTimeout (arg)    caddr_t arg;{    fsm *f = (fsm *)arg;    if (ppp_if[f->unit]->lcp_echo_timer_running != 0) {        ppp_if[f->unit]->lcp_echo_timer_running = 0;        LcpEchoCheck ((fsm *) arg);    }}/* * LcpEchoReply - LCP has received a reply to the echo */static voidlcp_received_echo_reply (f, id, inp, len)    fsm *f;    int id; u_char *inp; int len;{    u_long magic;    /* Check the magic number - don't count replies from ourselves. */#ifdef	notyet    if (len < CILEN_LONG)        return;#endif	/* notyet */    GETLONG(magic, inp);    if (ppp_if[f->unit]->lcp_gotoptions.neg_magicnumber        && magic == ppp_if[f->unit]->lcp_gotoptions.magicnumber)        return;    /* Reset the number of outstanding echo frames */    ppp_if[f->unit]->lcp_echos_pending = 0;}/* * LcpSendEchoRequest - Send an echo request frame to the peer */static voidLcpSendEchoRequest (f)    fsm *f;{    u_long lcp_magic;    u_char pkt[4], *pktp;/* * Detect the failure of the peer at this point. */    if (ppp_if[f->unit]->lcp_echo_fails != 0) {        if (ppp_if[f->unit]->lcp_echos_pending++ >= ppp_if[f->unit]->lcp_echo_fails) {            LcpLinkFailure(f);            ppp_if[f->unit]->lcp_echos_pending = 0;	    die(f->unit, 1);        }    }/* * Make and send the echo request frame. */    if (f->state == OPENED) {        lcp_magic = ppp_if[f->unit]->lcp_gotoptions.neg_magicnumber                    ? ppp_if[f->unit]->lcp_gotoptions.magicnumber                    : 0L;        pktp = pkt;        PUTLONG(lcp_magic, pktp);        fsm_sdata(f, ECHOREQ,                  ppp_if[f->unit]->lcp_echo_number++ & 0xFF, pkt, pktp - pkt);    }}/* * lcp_echo_lowerup - Start the timer for the LCP frame */static voidlcp_echo_lowerup (unit)    int unit;{    fsm *f = &ppp_if[unit]->lcp_fsm;    /* Clear the parameters for generating echo frames */    ppp_if[unit]->lcp_echos_pending      = 0;    ppp_if[unit]->lcp_echo_number        = 0;    ppp_if[unit]->lcp_echo_timer_running = 0;    /* If a timeout interval is specified then start the timer */    if (ppp_if[unit]->lcp_echo_interval != 0)        LcpEchoCheck (f);}/* * lcp_echo_lowerdown - Stop the timer for the LCP frame */static voidlcp_echo_lowerdown (unit)    int unit;{    fsm *f = &ppp_if[unit]->lcp_fsm;    if (ppp_if[unit]->lcp_echo_timer_running != 0) {        PPP_UNTIMEOUT (LcpEchoTimeout, (caddr_t) f);        ppp_if[unit]->lcp_echo_timer_running = 0;    }}

⌨️ 快捷键说明

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