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

📄 lcp.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 4 页
字号:

    fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id,
	      p, len);
}


/*
 * lcp_resetci - Reset our CI.
 */
static void
lcp_resetci(f)
    fsm *f;
{
    lcp_wantoptions[f->unit].magicnumber = magic();
    lcp_wantoptions[f->unit].numloops = 0;
    lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit];
    peer_mru[f->unit] = PPP_MRU;
    auth_reset(f->unit);
}


/*
 * lcp_cilen - Return length of our CI.
 */
static int
lcp_cilen(f)
    fsm *f;
{
    lcp_options *go = &lcp_gotoptions[f->unit];

#define LENCIVOID(neg)	((neg) ? CILEN_VOID : 0)
#define LENCICHAP(neg)	((neg) ? CILEN_CHAP : 0)
#define LENCISHORT(neg)	((neg) ? CILEN_SHORT : 0)
#define LENCILONG(neg)	((neg) ? CILEN_LONG : 0)
#define LENCILQR(neg)	((neg) ? CILEN_LQR: 0)
#define LENCICBCP(neg)	((neg) ? CILEN_CBCP: 0)
    /*
     * NB: we only ask for one of CHAP and UPAP, even if we will
     * accept either.
     */
    return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) +
	    LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) +
	    LENCICHAP(go->neg_chap) +
	    LENCISHORT(!go->neg_chap && go->neg_upap) +
	    LENCILQR(go->neg_lqr) +
	    LENCICBCP(go->neg_cbcp) +
	    LENCILONG(go->neg_magicnumber) +
	    LENCIVOID(go->neg_pcompression) +
	    LENCIVOID(go->neg_accompression));
}


/*
 * lcp_addci - Add our desired CIs to a packet.
 */
static void
lcp_addci(f, ucp, lenp)
    fsm *f;
    u_char *ucp;
    int *lenp;
{
    lcp_options *go = &lcp_gotoptions[f->unit];
    u_char *start_ucp = ucp;

#define ADDCIVOID(opt, neg) \    if (neg) { \	PUTCHAR(opt, ucp); \	PUTCHAR(CILEN_VOID, ucp); \    }
#define ADDCISHORT(opt, neg, val) \    if (neg) { \	PUTCHAR(opt, ucp); \	PUTCHAR(CILEN_SHORT, ucp); \	PUTSHORT(val, ucp); \    }
#define ADDCICHAP(opt, neg, val, digest) \    if (neg) { \	PUTCHAR(opt, ucp); \	PUTCHAR(CILEN_CHAP, ucp); \	PUTSHORT(val, ucp); \	PUTCHAR(digest, ucp); \    }
#define ADDCILONG(opt, neg, val) \    if (neg) { \	PUTCHAR(opt, ucp); \	PUTCHAR(CILEN_LONG, ucp); \	PUTLONG(val, ucp); \    }
#define ADDCILQR(opt, neg, val) \    if (neg) { \	PUTCHAR(opt, ucp); \	PUTCHAR(CILEN_LQR, ucp); \	PUTSHORT(PPP_LQR, ucp); \	PUTLONG(val, ucp); \    }
#define ADDCICHAR(opt, neg, val) \    if (neg) { \	PUTCHAR(opt, ucp); \	PUTCHAR(CILEN_CHAR, ucp); \	PUTCHAR(val, ucp); \    }

    ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
    ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
	      go->asyncmap);
    ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
    ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
    ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
    ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
    ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
    ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
    ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);

    if (ucp - start_ucp != *lenp) {
	/* this should never happen, because peer_mtu should be 1500 */
	syslog(LOG_ERR, "Bug in lcp_addci: wrong length");
    }
}


/*
 * lcp_ackci - Ack our CIs.
 * This should not modify any state if the Ack is bad.
 *
 * Returns:
 *	0 - Ack was bad.
 *	1 - Ack was good.
 */
static int
lcp_ackci(f, p, len)
    fsm *f;
    u_char *p;
    int len;
{
    lcp_options *go = &lcp_gotoptions[f->unit];
    u_char cilen, citype, cichar;
    u_short cishort;
    u_int32_t cilong;

    /*
     * CIs must be in exactly the same order that we sent.
     * Check packet length and CI length at each step.
     * If we find any deviations, then this packet is bad.
     */
#define ACKCIVOID(opt, neg) \    if (neg) { \	if ((len -= CILEN_VOID) < 0) \	    goto bad; \	GETCHAR(citype, p); \	GETCHAR(cilen, p); \	if (cilen != CILEN_VOID || \	    citype != opt) \	    goto bad; \    }
#define ACKCISHORT(opt, neg, val) \    if (neg) { \	if ((len -= CILEN_SHORT) < 0) \	    goto bad; \	GETCHAR(citype, p); \	GETCHAR(cilen, p); \	if (cilen != CILEN_SHORT || \	    citype != opt) \	    goto bad; \	GETSHORT(cishort, p); \	if (cishort != val) \	    goto bad; \    }
#define ACKCICHAR(opt, neg, val) \    if (neg) { \	if ((len -= CILEN_CHAR) < 0) \	    goto bad; \	GETCHAR(citype, p); \	GETCHAR(cilen, p); \	if (cilen != CILEN_CHAR || \	    citype != opt) \	    goto bad; \	GETCHAR(cichar, p); \	if (cichar != val) \	    goto bad; \    }
#define ACKCICHAP(opt, neg, val, digest) \    if (neg) { \	if ((len -= CILEN_CHAP) < 0) \	    goto bad; \	GETCHAR(citype, p); \	GETCHAR(cilen, p); \	if (cilen != CILEN_CHAP || \	    citype != opt) \	    goto bad; \	GETSHORT(cishort, p); \	if (cishort != val) \	    goto bad; \	GETCHAR(cichar, p); \	if (cichar != digest) \	  goto bad; \    }
#define ACKCILONG(opt, neg, val) \    if (neg) { \	if ((len -= CILEN_LONG) < 0) \	    goto bad; \	GETCHAR(citype, p); \	GETCHAR(cilen, p); \	if (cilen != CILEN_LONG || \	    citype != opt) \	    goto bad; \	GETLONG(cilong, p); \	if (cilong != val) \	    goto bad; \    }
#define ACKCILQR(opt, neg, val) \    if (neg) { \	if ((len -= CILEN_LQR) < 0) \	    goto bad; \	GETCHAR(citype, p); \	GETCHAR(cilen, p); \	if (cilen != CILEN_LQR || \	    citype != opt) \	    goto bad; \	GETSHORT(cishort, p); \	if (cishort != PPP_LQR) \	    goto bad; \	GETLONG(cilong, p); \	if (cilong != val) \	  goto bad; \    }

    ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
    ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
	      go->asyncmap);
    ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
    ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
    ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
    ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
    ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
    ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
    ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);

    /*
     * If there are any remaining CIs, then this packet is bad.
     */
    if (len != 0)
	goto bad;
    return (1);
bad:
    LCPDEBUG((LOG_WARNING, "lcp_acki: received bad Ack!"));
    return (0);
}


/*
 * lcp_nakci - Peer has sent a NAK for some of our CIs.
 * This should not modify any state if the Nak is bad
 * or if LCP is in the OPENED state.
 *
 * Returns:
 *	0 - Nak was bad.
 *	1 - Nak was good.
 */
static int
lcp_nakci(f, p, len)
    fsm *f;
    u_char *p;
    int len;
{
    lcp_options *go = &lcp_gotoptions[f->unit];
    lcp_options *wo = &lcp_wantoptions[f->unit];
    u_char citype, cichar, *next;
    u_short cishort;
    u_int32_t cilong;
    lcp_options no;		/* options we've seen Naks for */
    lcp_options try;		/* options to request next time */
    int looped_back = 0;
    int cilen;

    BZERO(&no, sizeof(no));
    try = *go;

    /*
     * Any Nak'd CIs must be in exactly the same order that we sent.
     * Check packet length and CI length at each step.
     * If we find any deviations, then this packet is bad.
     */
#define NAKCIVOID(opt, neg, code) \    if (go->neg && \	len >= CILEN_VOID && \	p[1] == CILEN_VOID && \	p[0] == opt) { \	len -= CILEN_VOID; \	INCPTR(CILEN_VOID, p); \	no.neg = 1; \	code \    }
#define NAKCICHAP(opt, neg, code) \    if (go->neg && \	len >= CILEN_CHAP && \	p[1] == CILEN_CHAP && \	p[0] == opt) { \	len -= CILEN_CHAP; \	INCPTR(2, p); \	GETSHORT(cishort, p); \	GETCHAR(cichar, p); \	no.neg = 1; \	code \    }
#define NAKCICHAR(opt, neg, code) \    if (go->neg && \	len >= CILEN_CHAR && \	p[1] == CILEN_CHAR && \	p[0] == opt) { \	len -= CILEN_CHAR; \	INCPTR(2, p); \	GETCHAR(cichar, p); \	no.neg = 1; \	code \    }
#define NAKCISHORT(opt, neg, code) \    if (go->neg && \	len >= CILEN_SHORT && \	p[1] == CILEN_SHORT && \	p[0] == opt) { \	len -= CILEN_SHORT; \	INCPTR(2, p); \	GETSHORT(cishort, p); \	no.neg = 1; \	code \    }
#define NAKCILONG(opt, neg, code) \    if (go->neg && \	len >= CILEN_LONG && \	p[1] == CILEN_LONG && \	p[0] == opt) { \	len -= CILEN_LONG; \	INCPTR(2, p); \	GETLONG(cilong, p); \	no.neg = 1; \	code \    }
#define NAKCILQR(opt, neg, code) \    if (go->neg && \	len >= CILEN_LQR && \	p[1] == CILEN_LQR && \	p[0] == opt) { \	len -= CILEN_LQR; \	INCPTR(2, p); \	GETSHORT(cishort, p); \	GETLONG(cilong, p); \	no.neg = 1; \	code \    }

    /*
     * We don't care if they want to send us smaller packets than
     * we want.  Therefore, accept any MRU less than what we asked for,
     * but then ignore the new value when setting the MRU in the kernel.
     * If they send us a bigger MRU than what we asked, accept it, up to
     * the limit of the default MRU we'd get if we didn't negotiate.
     */
    if (go->neg_mru && go->mru != DEFMRU) {
	NAKCISHORT(CI_MRU, neg_mru,
		   if (cishort <= wo->mru || cishort <= DEFMRU)
		       try.mru = cishort;
		   );
    }

    /*
     * Add any characters they want to our (receive-side) asyncmap.
     */
    if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) {
	NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
		  try.asyncmap = go->asyncmap | cilong;
		  );
    }

    /*
     * If they've nak'd our authentication-protocol, check whether
     * they are proposing a different protocol, or a different
     * hash algorithm for CHAP.
     */
    if ((go->neg_chap || go->neg_upap)
	&& len >= CILEN_SHORT
	&& p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {
	cilen = p[1];
	len -= cilen;
	no.neg_chap = go->neg_chap;
	no.neg_upap = go->neg_upap;
	INCPTR(2, p);
        GETSHORT(cishort, p);
	if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
	    /*
	     * If we were asking for CHAP, they obviously don't want to do it.
	     * If we weren't asking for CHAP, then we were asking for PAP,
	     * in which case this Nak is bad.
	     */
	    if (!go->neg_chap)
		goto bad;
	    try.neg_chap = 0;

	} else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
	    GETCHAR(cichar, p);
	    if (go->neg_chap) {
		/*
		 * We were asking for CHAP/MD5; they must want a different
		 * algorithm.  If they can't do MD5, we'll have to stop
		 * asking for CHAP.
		 */
		if (cichar != go->chap_mdtype)
		    try.neg_chap = 0;
	    } else {
		/*
		 * Stop asking for PAP if we were asking for it.
		 */
		try.neg_upap = 0;
	    }

	} else {
	    /*
	     * We don't recognize what they're suggesting.
	     * Stop asking for what we were asking for.
	     */
	    if (go->neg_chap)
		try.neg_chap = 0;
	    else
		try.neg_upap = 0;
	    p += cilen - CILEN_SHORT;
	}
    }

    /*
     * If they can't cope with our link quality protocol, we'll have
     * to stop asking for LQR.  We haven't got any other protocol.
     * If they Nak the reporting period, take their value XXX ?
     */
    NAKCILQR(CI_QUALITY, neg_lqr,
	     if (cishort != PPP_LQR)
		 try.neg_lqr = 0;
	     else
		 try.lqr_period = cilong;
	     );

    /*
     * Only implementing CBCP...not the rest of the callback options
     */
    NAKCICHAR(CI_CALLBACK, neg_cbcp,
              try.neg_cbcp = 0;
              );

    /*
     * Check for a looped-back line.
     */
    NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
	      try.magicnumber = magic();
	      looped_back = 1;
	      );

    /*
     * Peer shouldn't send Nak for protocol compression or
     * address/control compression requests; they should send
     * a Reject instead.  If they send a Nak, treat it as a Reject.
     */
    NAKCIVOID(CI_PCOMPRESSION, neg_pcompression,
	      try.neg_pcompression = 0;
	      );
    NAKCIVOID(CI_ACCOMPRESSION, neg_accompression,
	      try.neg_accompression = 0;
	      );

    /*
     * There may be remaining CIs, if the peer is requesting negotiation
     * on an option that we didn't include in our request packet.
     * If we see an option that we requested, or one we've already seen
     * in this packet, then this packet is bad.
     * If we wanted to respond by starting to negotiate on the requested
     * option(s), we could, but we don't, because except for the
     * authentication type and quality protocol, if we are not negotiating
     * an option, it is because we were told not to.
     * For the authentication type, the Nak from the peer means
     * `let me authenticate myself with you' which is a bit pointless.
     * For the quality protocol, the Nak means `ask me to send you quality

⌨️ 快捷键说明

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