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

📄 netlcp.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 4 页
字号:

		return;

	}

	

	GETSHORT(prot, inp);

	

	LCPDEBUG((LOG_INFO,

			"lcp_rprotrej: Rcvd Protocol-Reject packet for %x!",

			prot));

	

	/*

	* Protocol-Reject packets received in any state other than the LCP

	* OPENED state SHOULD be silently discarded.

	*/

	if( f->state != OPENED ){

		LCPDEBUG((LOG_INFO, "Protocol-Reject discarded: LCP in state %d",

				f->state));

		return;

	}

	

	/*

	* Upcall the proper Protocol-Reject routine.

	*/

	for (i = 0; (protp = protocols[i]) != NULL; ++i)

		if (protp->protocol == prot && protp->enabled_flag) {

			(*protp->protrej)(f->unit);

			return;

		}

	

	LCPDEBUG((LOG_WARNING, "Protocol-Reject for unsupported protocol 0x%x",

			prot));

}





/*

 * lcp_protrej - A Protocol-Reject was received.

 */

//#pragma argsused

static void lcp_protrej(int unit)

{

	/*

	* Can't reject LCP!

	*/

	LCPDEBUG((LOG_WARNING,

			"lcp_protrej: Received Protocol-Reject for LCP!"));

	fsm_protreject(&lcp_fsm[unit]);

}





/*

 * lcp_resetci - Reset our CI.

 */

static void lcp_resetci(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(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 != 0xFFFFFFFFl) +

		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(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) { \
	    LCPDEBUG((LOG_INFO, "lcp_addci: opt=%d", opt)); \
		PUTCHAR(opt, ucp); \
		PUTCHAR(CILEN_VOID, ucp); \
	}

#define ADDCISHORT(opt, neg, val) \
	if (neg) { \
	    LCPDEBUG((LOG_INFO, "lcp_addci: INT opt=%d %X", opt, val)); \
		PUTCHAR(opt, ucp); \
		PUTCHAR(CILEN_SHORT, ucp); \
		PUTSHORT(val, ucp); \
	}

#define ADDCICHAP(opt, neg, val, digest) \
	if (neg) { \
	    LCPDEBUG((LOG_INFO, "lcp_addci: CHAP opt=%d %X", opt, val)); \
		PUTCHAR(opt, ucp); \
		PUTCHAR(CILEN_CHAP, ucp); \
		PUTSHORT(val, ucp); \
		PUTCHAR(digest, ucp); \
	}

#define ADDCILONG(opt, neg, val) \
	if (neg) { \
	    LCPDEBUG((LOG_INFO, "lcp_addci: L opt=%d %lX", opt, val)); \
		PUTCHAR(opt, ucp); \
		PUTCHAR(CILEN_LONG, ucp); \
		PUTLONG(val, ucp); \
	}

#define ADDCILQR(opt, neg, val) \
	if (neg) { \
	    LCPDEBUG((LOG_INFO, "lcp_addci: LQR opt=%d %lX", opt, val)); \
		PUTCHAR(opt, ucp); \
		PUTCHAR(CILEN_LQR, ucp); \
		PUTSHORT(PPP_LQR, ucp); \
		PUTLONG(val, ucp); \
	}

#define ADDCICHAR(opt, neg, val) \
	if (neg) { \
	    LCPDEBUG((LOG_INFO, "lcp_addci: CHAR opt=%d %X '%z'", opt, val, val)); \
		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 != 0xFFFFFFFFl,
			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 */

		LCPDEBUG((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(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 != 0xFFFFFFFFl,
			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;

	LCPDEBUG((LOG_INFO, "lcp_acki: Ack"));

	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(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 != 0xFFFFFFFFl) {

		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

	* reports', but if we didn't ask for them, we don't want them.

	* An option we don't recognize represents the peer asking to

	* negotiate some option we don't support, so ignore it.

	*/

	while (len > CILEN_VOID) {

		GETCHAR(citype, p);

		GETCHAR(cilen, p);

		if (cilen < CILEN_VOID || (len -= cilen) < 0)

			goto bad;

		next = p + cilen - 2;

		

		switch (citype) {

		case CI_MRU:

			if ((go->neg_mru && go->mru != DEFMRU)
					|| no.neg_mru || cilen != CILEN_SHORT)

				goto bad;

			GETSHORT(cishort, p);

			if (cishort < DEFMRU)

				try.mru = cishort;

			break;

		case CI_ASYNCMAP:

			if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl)
					|| no.neg_asyncmap || cilen != CILEN_LONG)

				goto bad;

			break;

		case CI_AUTHTYPE:

			if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap)

				goto bad;

			break;

		case CI_MAGICNUMBER:

			if (go->neg_magicnumber || no.neg_magicnumber ||
					cilen != CILEN_LONG)

				goto bad;

			break;

		case CI_PCOMPRESSION:

			if (go->neg_pcompression || no.neg_pcompression
					|| cilen != CILEN_VOID)

				goto bad;

			break;

		case CI_ACCOMPRESSION:

⌨️ 快捷键说明

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