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

📄 lcp.c

📁 经典的ppp程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * lcp_protrej - A Protocol-Reject was received. *//*ARGSUSED*/static voidlcp_protrej(unit)    int unit;{    /*     * Can't reject LCP!     */    error("Received Protocol-Reject for LCP!");    fsm_protreject(&lcp_fsm[unit]);}/* * lcp_sprotrej - Send a Protocol-Reject for some protocol. */voidlcp_sprotrej(unit, p, len)    int unit;    u_char *p;    int len;{    /*     * Send back the protocol and the information field of the     * rejected packet.  We only get here if LCP is in the OPENED state.     */    p += 2;    len -= 2;    fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id,	      p, len);}/* * lcp_resetci - Reset our CI. */static voidlcp_resetci(f)    fsm *f;{    lcp_options *wo = &lcp_wantoptions[f->unit];    lcp_options *go = &lcp_gotoptions[f->unit];    lcp_options *ao = &lcp_allowoptions[f->unit];    wo->magicnumber = magic();    wo->numloops = 0;    *go = *wo;    if (!multilink) {	go->neg_mrru = 0;	go->neg_ssnhf = 0;	go->neg_endpoint = 0;    }    if (noendpoint)	ao->neg_endpoint = 0;    peer_mru[f->unit] = PPP_MRU;    auth_reset(f->unit);}/* * lcp_cilen - Return length of our CI. */static intlcp_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) +	    LENCISHORT(go->neg_mrru) +	    LENCIVOID(go->neg_ssnhf) +	    (go->neg_endpoint? CILEN_CHAR + go->endpoint.length: 0));}/* * lcp_addci - Add our desired CIs to a packet. */static voidlcp_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); \    }#define ADDCIENDP(opt, neg, class, val, len) \    if (neg) { \	int i; \	PUTCHAR(opt, ucp); \	PUTCHAR(CILEN_CHAR + len, ucp); \	PUTCHAR(class, ucp); \	for (i = 0; i < len; ++i) \	    PUTCHAR(val[i], 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);    ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru);    ADDCIVOID(CI_SSNHF, go->neg_ssnhf);    ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class,	      go->endpoint.value, go->endpoint.length);    if (ucp - start_ucp != *lenp) {	/* this should never happen, because peer_mtu should be 1500 */	error("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 intlcp_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; \    }#define ACKCIENDP(opt, neg, class, val, vlen) \    if (neg) { \	int i; \	if ((len -= CILEN_CHAR + vlen) < 0) \	    goto bad; \	GETCHAR(citype, p); \	GETCHAR(cilen, p); \	if (cilen != CILEN_CHAR + vlen || \	    citype != opt) \	    goto bad; \	GETCHAR(cichar, p); \	if (cichar != class) \	    goto bad; \	for (i = 0; i < vlen; ++i) { \	    GETCHAR(cichar, p); \	    if (cichar != val[i]) \		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);    ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru);    ACKCIVOID(CI_SSNHF, go->neg_ssnhf);    ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class,	      go->endpoint.value, go->endpoint.length);    /*     * If there are any remaining CIs, then this packet is bad.     */    if (len != 0)	goto bad;    return (1);bad:    LCPDEBUG(("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 intlcp_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) \    if (go->neg && \	len >= CILEN_VOID && \	p[1] == CILEN_VOID && \	p[0] == opt) { \	len -= CILEN_VOID; \	INCPTR(CILEN_VOID, p); \	no.neg = 1; \	try.neg = 0; \    }#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 \    }#define NAKCIENDP(opt, neg) \    if (go->neg && \	len >= CILEN_CHAR && \	p[0] == opt && \	p[1] >= CILEN_CHAR && \	p[1] <= len) { \	len -= p[1]; \	INCPTR(p[1], p); \	no.neg = 1; \	try.neg = 0; \    }    /*     * 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 can ask for M$-CHAP		 * if we support it, otherwise we'll have to stop		 * asking for CHAP.		 */		if (cichar != go->chap_mdtype) {#ifdef CHAPMS		    if (cichar == CHAP_MICROSOFT)			go->chap_mdtype = CHAP_MICROSOFT;		    else#endif /* CHAPMS */			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

⌨️ 快捷键说明

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