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

📄 lcp.c

📁 Unix/Linux NAPT协议解析源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		    LCPDEBUG((LOG_WARNING,			      "lcp_reqci: rcvd AUTHTYPE PAP, rejecting..."));		    orc = CONFREJ;		    break;		}		if (!ao->neg_upap) {	/* we don't want to do PAP */		    orc = CONFNAK;	/* NAK it and suggest CHAP */		    PUTCHAR(CI_AUTHTYPE, nakp);		    PUTCHAR(CILEN_CHAP, nakp);		    PUTSHORT(PPP_CHAP, nakp);		    PUTCHAR(ao->chap_mdtype, nakp);		    break;		}		ho->neg_upap = 1;		break;	    }	    if (cishort == PPP_CHAP) {		if (ho->neg_upap ||	/* we've already accepted PAP */		    cilen != CILEN_CHAP) {		    LCPDEBUG((LOG_INFO,			      "lcp_reqci: rcvd AUTHTYPE CHAP, rejecting..."));		    orc = CONFREJ;		    break;		}		if (!ao->neg_chap) {	/* we don't want to do CHAP */		    orc = CONFNAK;	/* NAK it and suggest PAP */		    PUTCHAR(CI_AUTHTYPE, nakp);		    PUTCHAR(CILEN_SHORT, nakp);		    PUTSHORT(PPP_PAP, nakp);		    break;		}		GETCHAR(cichar, p);	/* get digest type*/		if (cichar != ao->chap_mdtype) {		    orc = CONFNAK;		    PUTCHAR(CI_AUTHTYPE, nakp);		    PUTCHAR(CILEN_CHAP, nakp);		    PUTSHORT(PPP_CHAP, nakp);		    PUTCHAR(ao->chap_mdtype, nakp);		    break;		}		ho->chap_mdtype = cichar; /* save md type */		ho->neg_chap = 1;		break;	    }	    /*	     * 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(PPP_CHAP, nakp);		PUTCHAR(ao->chap_mdtype, nakp);	    } else {		PUTCHAR(CILEN_SHORT, nakp);		PUTSHORT(PPP_PAP, 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 %x)", cishort, (unsigned int) cilong));	    /*	     * Check the protocol and the reporting period.	     * XXX When should we Nak this, and what with?	     */	    if (cishort != PPP_LQR) {		orc = CONFNAK;		PUTCHAR(CI_QUALITY, nakp);		PUTCHAR(CILEN_LQR, nakp);		PUTSHORT(PPP_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, "(%x)", (unsigned int) cilong));	    /*	     * He must have a different magic number.	     */	    if (go->neg_magicnumber &&		cilong == go->magicnumber) {		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 wasn't? */	    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 = &lcp_wantoptions[f->unit];    lcp_options *ho = &lcp_hisoptions[f->unit];    lcp_options *go = &lcp_gotoptions[f->unit];    lcp_options *ao = &lcp_allowoptions[f->unit];    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, (ho->neg_mru? ho->mru: PPP_MRU)),		    (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): PPP_MRU),		    (go->neg_asyncmap? go->asyncmap: 0x00000000),		    go->neg_pcompression, go->neg_accompression);    if (ho->neg_mru)	peer_mru[f->unit] = ho->mru;    ChapLowerUp(f->unit);	/* Enable CHAP */    upap_lowerup(f->unit);	/* Enable UPAP */    ipcp_lowerup(f->unit);	/* Enable IPCP */    ccp_lowerup(f->unit);	/* Enable CCP */    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);    ccp_lowerdown(f->unit);    ipcp_lowerdown(f->unit);    ChapLowerDown(f->unit);    upap_lowerdown(f->unit);    sifdown(f->unit);    ppp_send_config(f->unit, PPP_MRU, 0xffffffff, 0, 0);    ppp_recv_config(f->unit, PPP_MRU, 0x00000000, 0, 0);    peer_mru[f->unit] = PPP_MRU;    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;{    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) __P((void *, char *, ...));    void *arg;{    int code, id, len, olen;    u_char *pstart, *optend;    u_short cishort;    u_int32_t 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 PPP_PAP:			printer(arg, "upap");			break;		    case PPP_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 PPP_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) {        do_syslog(LOG_NOTICE, "Excessive lack of response to LCP echo frames.");        lcp_close(f->unit);		/* Reset connection */    }}/* * Timer expired for the LCP echo requests from this process. */static voidLcpEchoCheck (f)    fsm *f;{    long int delta;    LcpSendEchoRequest (f);    delta = (int) lcp_echo_interval;/* * Start the timer for the next interval. */    assert (lcp_echo_timer_running==0);    TIMEOUT (LcpEchoTimeout, (caddr_t) f, (u_int32_t) delta);    lcp_echo_timer_running = 1;}/* * LcpEchoTimeout - Timer expired on the LCP echo */static voidLcpEchoTimeout (arg)    caddr_t arg;{    if (lcp_echo_timer_running != 0) {        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_int32_t magic;    /* Check the magic number - don't count replies from ourselves. */    if (len < 4) {	do_syslog(LOG_DEBUG, "lcp: received short Echo-Reply, length %d", len);	return;    }    GETLONG(magic, inp);    if (lcp_gotoptions[f->unit].neg_magicnumber	&& magic == lcp_gotoptions[f->unit].magicnumber) {	do_syslog(LOG_WARNING, "appear to have received our own echo-reply!");	return;    }    /* Reset the number of outstanding echo frames */    lcp_echos_pending = 0;}/* * LcpSendEchoRequest - Send an echo request frame to the peer */static voidLcpSendEchoRequest (f)    fsm *f;{    u_int32_t lcp_magic;    u_char pkt[4], *pktp;/* * Detect the failure of the peer at this point. */    if (lcp_echo_fails != 0) {        if (lcp_echos_pending++ >= lcp_echo_fails) {            LcpLinkFailure(f);	    lcp_echos_pending = 0;	}    }/* * Make and send the echo request frame. */    if (f->state == OPENED) {        lcp_magic = lcp_gotoptions[f->unit].neg_magicnumber	            ? lcp_gotoptions[f->unit].magicnumber	            : 0L;	pktp = pkt;	PUTLONG(lcp_magic, pktp);              fsm_sdata(f, ECHOREQ,		  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 = &lcp_fsm[unit];    /* Clear the parameters for generating echo frames */    lcp_echos_pending      = 0;    lcp_echo_number        = 0;    lcp_echo_timer_running = 0;      /* If a timeout interval is specified then start the timer */    if (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 = &lcp_fsm[unit];    if (lcp_echo_timer_running != 0) {        UNTIMEOUT (LcpEchoTimeout, (caddr_t) f);        lcp_echo_timer_running = 0;    }}

⌨️ 快捷键说明

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