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

📄 ccp.c

📁 自己精简过的PPPD代码。在嵌入中应用可以更好的发挥。比原先的小了很多
💻 C
📖 第 1 页 / 共 3 页
字号:
		/* Check state opt */		if (ho->mppe & MPPE_OPT_STATEFUL) {		    /*		     * We can Nak and request stateless, but it's a		     * lot easier to just assume the peer will request		     * it if he can do it; stateful mode is bad over		     * the Internet -- which is where we expect MPPE.		     */		   if (refuse_mppe_stateful) {			error("Refusing MPPE stateful mode offered by peer");			newret = CONFREJ;			break;		    }		}		/* Find out which of {S,L} are set. */		if ((ho->mppe & MPPE_OPT_128)		     && (ho->mppe & MPPE_OPT_40)) {		    /* Both are set, negotiate the strongest. */		    newret = CONFNAK;		    if (ao->mppe & MPPE_OPT_128)			ho->mppe &= ~MPPE_OPT_40;		    else if (ao->mppe & MPPE_OPT_40)			ho->mppe &= ~MPPE_OPT_128;		    else {			newret = CONFREJ;			break;		    }		} else if (ho->mppe & MPPE_OPT_128) {		    if (!(ao->mppe & MPPE_OPT_128)) {			newret = CONFREJ;			break;		    }		} else if (ho->mppe & MPPE_OPT_40) {		    if (!(ao->mppe & MPPE_OPT_40)) {			newret = CONFREJ;			break;		    }		} else {		    /* Neither are set. */		    /* We cannot accept this.  */		    newret = CONFNAK;		    /* Give the peer our idea of what can be used,		       so it can choose and confirm */		    ho->mppe = ao->mppe;		}		/* rebuild the opts */		MPPE_OPTS_TO_CI(ho->mppe, &p[2]);		if (newret == CONFACK) {		    u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];		    int mtu;		    BCOPY(p, opt_buf, CILEN_MPPE);		    BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],			  MPPE_MAX_KEY_LEN);		    if (ccp_test(f->unit, opt_buf,				 CILEN_MPPE + MPPE_MAX_KEY_LEN, 1) <= 0) {			/* This shouldn't happen, we've already tested it! */			error("MPPE required, but kernel has no support.");			lcp_close(f->unit, "MPPE required but not available");			newret = CONFREJ;			break;		    }		    /*		     * We need to decrease the interface MTU by MPPE_PAD		     * because MPPE frames **grow**.  The kernel [must]		     * allocate MPPE_PAD extra bytes in xmit buffers.		     */		    mtu = netif_get_mtu(f->unit);		    if (mtu)			netif_set_mtu(f->unit, mtu - MPPE_PAD);		    else			newret = CONFREJ;		}		/*		 * We have accepted MPPE or are willing to negotiate		 * MPPE parameters.  A CONFREJ is due to subsequent		 * (non-MPPE) processing.		 */		rej_for_ci_mppe = 0;		break;#endif /* MPPE */	    case CI_DEFLATE:	    case CI_DEFLATE_DRAFT:		if (!ao->deflate || clen != CILEN_DEFLATE		    || (!ao->deflate_correct && type == CI_DEFLATE)		    || (!ao->deflate_draft && type == CI_DEFLATE_DRAFT)) {		    newret = CONFREJ;		    break;		}		ho->deflate = 1;		ho->deflate_size = nb = DEFLATE_SIZE(p[2]);		if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL		    || p[3] != DEFLATE_CHK_SEQUENCE		    || nb > ao->deflate_size || nb < DEFLATE_MIN_WORKS) {		    newret = CONFNAK;		    if (!dont_nak) {			p[2] = DEFLATE_MAKE_OPT(ao->deflate_size);			p[3] = DEFLATE_CHK_SEQUENCE;			/* fall through to test this #bits below */		    } else			break;		}		/*		 * Check whether we can do Deflate with the window		 * size they want.  If the window is too big, reduce		 * it until the kernel can cope and nak with that.		 * We only check this for the first option.		 */		if (p == p0) {		    for (;;) {			res = ccp_test(f->unit, p, CILEN_DEFLATE, 1);			if (res > 0)			    break;		/* it's OK now */			if (res < 0 || nb == DEFLATE_MIN_WORKS || dont_nak) {			    newret = CONFREJ;			    p[2] = DEFLATE_MAKE_OPT(ho->deflate_size);			    break;			}			newret = CONFNAK;			--nb;			p[2] = DEFLATE_MAKE_OPT(nb);		    }		}		break;	    case CI_BSD_COMPRESS:		if (!ao->bsd_compress || clen != CILEN_BSD_COMPRESS) {		    newret = CONFREJ;		    break;		}		ho->bsd_compress = 1;		ho->bsd_bits = nb = BSD_NBITS(p[2]);		if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION		    || nb > ao->bsd_bits || nb < BSD_MIN_BITS) {		    newret = CONFNAK;		    if (!dont_nak) {			p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, ao->bsd_bits);			/* fall through to test this #bits below */		    } else			break;		}		/*		 * Check whether we can do BSD-Compress with the code		 * size they want.  If the code size is too big, reduce		 * it until the kernel can cope and nak with that.		 * We only check this for the first option.		 */		if (p == p0) {		    for (;;) {			res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 1);			if (res > 0)			    break;			if (res < 0 || nb == BSD_MIN_BITS || dont_nak) {			    newret = CONFREJ;			    p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION,						ho->bsd_bits);			    break;			}			newret = CONFNAK;			--nb;			p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, nb);		    }		}		break;	    case CI_PREDICTOR_1:		if (!ao->predictor_1 || clen != CILEN_PREDICTOR_1) {		    newret = CONFREJ;		    break;		}		ho->predictor_1 = 1;		if (p == p0		    && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 1) <= 0) {		    newret = CONFREJ;		}		break;	    case CI_PREDICTOR_2:		if (!ao->predictor_2 || clen != CILEN_PREDICTOR_2) {		    newret = CONFREJ;		    break;		}		ho->predictor_2 = 1;		if (p == p0		    && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 1) <= 0) {		    newret = CONFREJ;		}		break;	    default:		newret = CONFREJ;	    }	}	if (newret == CONFNAK && dont_nak)	    newret = CONFREJ;	if (!(newret == CONFACK || (newret == CONFNAK && ret == CONFREJ))) {	    /* we're returning this option */	    if (newret == CONFREJ && ret == CONFNAK)		retp = p0;	    ret = newret;	    if (p != retp)		BCOPY(p, retp, clen);	    retp += clen;	}	p += clen;	len -= clen;    }    if (ret != CONFACK) {	if (ret == CONFREJ && *lenp == retp - p0)	    all_rejected[f->unit] = 1;	else	    *lenp = retp - p0;    }#ifdef MPPE    if (ret == CONFREJ && ao->mppe && rej_for_ci_mppe) {	error("MPPE required but peer negotiation failed");	lcp_close(f->unit, "MPPE required but peer negotiation failed");    }#endif    return ret;}/* * Make a string name for a compression method (or 2). */static char *method_name(opt, opt2)    ccp_options *opt, *opt2;{    static char result[64];    if (!ANY_COMPRESS(*opt))	return "(none)";    switch (opt->method) {#ifdef MPPE    case CI_MPPE:    {	char *p = result;	char *q = result + sizeof(result); /* 1 past result */	slprintf(p, q - p, "MPPE ");	p += 5;	if (opt->mppe & MPPE_OPT_128) {	    slprintf(p, q - p, "128-bit ");	    p += 8;	}	if (opt->mppe & MPPE_OPT_40) {	    slprintf(p, q - p, "40-bit ");	    p += 7;	}	if (opt->mppe & MPPE_OPT_STATEFUL)	    slprintf(p, q - p, "stateful");	else	    slprintf(p, q - p, "stateless");	break;    }#endif    case CI_DEFLATE:    case CI_DEFLATE_DRAFT:	if (opt2 != NULL && opt2->deflate_size != opt->deflate_size)	    slprintf(result, sizeof(result), "Deflate%s (%d/%d)",		     (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),		     opt->deflate_size, opt2->deflate_size);	else	    slprintf(result, sizeof(result), "Deflate%s (%d)",		     (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),		     opt->deflate_size);	break;    case CI_BSD_COMPRESS:	if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits)	    slprintf(result, sizeof(result), "BSD-Compress (%d/%d)",		     opt->bsd_bits, opt2->bsd_bits);	else	    slprintf(result, sizeof(result), "BSD-Compress (%d)",		     opt->bsd_bits);	break;    case CI_PREDICTOR_1:	return "Predictor 1";    case CI_PREDICTOR_2:	return "Predictor 2";    default:	slprintf(result, sizeof(result), "Method %d", opt->method);    }    return result;}/* * CCP has come up - inform the kernel driver and log a message. */static voidccp_up(f)    fsm *f;{    ccp_options *go = &ccp_gotoptions[f->unit];    ccp_options *ho = &ccp_hisoptions[f->unit];    char method1[64];    ccp_flags_set(f->unit, 1, 1);    if (ANY_COMPRESS(*go)) {	if (ANY_COMPRESS(*ho)) {	    if (go->method == ho->method) {		notice("%s compression enabled", method_name(go, ho));	    } else {		strlcpy(method1, method_name(go, NULL), sizeof(method1));		notice("%s / %s compression enabled",		       method1, method_name(ho, NULL));	    }	} else	    notice("%s receive compression enabled", method_name(go, NULL));    } else if (ANY_COMPRESS(*ho))	notice("%s transmit compression enabled", method_name(ho, NULL));#ifdef MPPE    if (go->mppe) {	BZERO(mppe_recv_key, MPPE_MAX_KEY_LEN);	BZERO(mppe_send_key, MPPE_MAX_KEY_LEN);	continue_networks(f->unit);		/* Bring up IP et al */    }#endif}/* * CCP has gone down - inform the kernel driver. */static voidccp_down(f)    fsm *f;{    if (ccp_localstate[f->unit] & RACK_PENDING)	UNTIMEOUT(ccp_rack_timeout, f);    ccp_localstate[f->unit] = 0;    ccp_flags_set(f->unit, 1, 0);#ifdef MPPE    if (ccp_gotoptions[f->unit].mppe) {	ccp_gotoptions[f->unit].mppe = 0;	if (lcp_fsm[f->unit].state == OPENED) {	    /* If LCP is not already going down, make sure it does. */	    error("MPPE disabled");	    lcp_close(f->unit, "MPPE disabled");	}    }#endif}/* * Print the contents of a CCP packet. */static char *ccp_codenames[] = {    "ConfReq", "ConfAck", "ConfNak", "ConfRej",    "TermReq", "TermAck", "CodeRej",    NULL, NULL, NULL, NULL, NULL, NULL,    "ResetReq", "ResetAck",};static intccp_printpkt(p, plen, printer, arg)    u_char *p;    int plen;    void (*printer) __P((void *, char *, ...));    void *arg;{    u_char *p0, *optend;    int code, id, len;    int optlen;    p0 = p;    if (plen < HEADERLEN)	return 0;    code = p[0];    id = p[1];    len = (p[2] << 8) + p[3];    if (len < HEADERLEN || len > plen)	return 0;    if (code >= 1 && code <= sizeof(ccp_codenames) / sizeof(char *)	&& ccp_codenames[code-1] != NULL)	printer(arg, " %s", ccp_codenames[code-1]);    else	printer(arg, " code=0x%x", code);    printer(arg, " id=0x%x", id);    len -= HEADERLEN;    p += HEADERLEN;    switch (code) {    case CONFREQ:    case CONFACK:    case CONFNAK:    case CONFREJ:	/* print list of possible compression methods */	while (len >= 2) {	    code = p[0];	    optlen = p[1];	    if (optlen < 2 || optlen > len)		break;	    printer(arg, " <");	    len -= optlen;	    optend = p + optlen;	    switch (code) {#ifdef MPPE	    case CI_MPPE:		if (optlen >= CILEN_MPPE) {		    u_char mppe_opts;		    MPPE_CI_TO_OPTS(&p[2], mppe_opts);		    printer(arg, "mppe %s %s %s %s %s %s%s",			    (p[2] & MPPE_H_BIT)? "+H": "-H",			    (p[5] & MPPE_M_BIT)? "+M": "-M",			    (p[5] & MPPE_S_BIT)? "+S": "-S",			    (p[5] & MPPE_L_BIT)? "+L": "-L",			    (p[5] & MPPE_D_BIT)? "+D": "-D",			    (p[5] & MPPE_C_BIT)? "+C": "-C",			    (mppe_opts & MPPE_OPT_UNKNOWN)? " +U": "");		    if (mppe_opts & MPPE_OPT_UNKNOWN)			printer(arg, " (%.2x %.2x %.2x %.2x)",				p[2], p[3], p[4], p[5]);		    p += CILEN_MPPE;		}		break;#endif	    case CI_DEFLATE:	    case CI_DEFLATE_DRAFT:		if (optlen >= CILEN_DEFLATE) {		    printer(arg, "deflate%s %d",			    (code == CI_DEFLATE_DRAFT? "(old#)": ""),			    DEFLATE_SIZE(p[2]));		    if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL)			printer(arg, " method %d", DEFLATE_METHOD(p[2]));		    if (p[3] != DEFLATE_CHK_SEQUENCE)			printer(arg, " check %d", p[3]);		    p += CILEN_DEFLATE;		}		break;	    case CI_BSD_COMPRESS:		if (optlen >= CILEN_BSD_COMPRESS) {		    printer(arg, "bsd v%d %d", BSD_VERSION(p[2]),			    BSD_NBITS(p[2]));		    p += CILEN_BSD_COMPRESS;		}		break;	    case CI_PREDICTOR_1:		if (optlen >= CILEN_PREDICTOR_1) {		    printer(arg, "predictor 1");		    p += CILEN_PREDICTOR_1;		}		break;	    case CI_PREDICTOR_2:		if (optlen >= CILEN_PREDICTOR_2) {		    printer(arg, "predictor 2");		    p += CILEN_PREDICTOR_2;		}		break;	    }	    while (p < optend)		printer(arg, " %.2x", *p++);	    printer(arg, ">");	}	break;    case TERMACK:    case TERMREQ:	if (len > 0 && *p >= ' ' && *p < 0x7f) {	    print_string((char *)p, len, printer, arg);	    p += len;	    len = 0;	}	break;    }    /* dump out the rest of the packet in hex */    while (--len >= 0)	printer(arg, " %.2x", *p++);    return p - p0;}/* * We have received a packet that the decompressor failed to * decompress.  Here we would expect to issue a reset-request, but * Motorola has a patent on resetting the compressor as a result of * detecting an error in the decompressed data after decompression. * (See US patent 5,130,993; international patent publication number * WO 91/10289; Australian patent 73296/91.) * * So we ask the kernel whether the error was detected after * decompression; if it was, we take CCP down, thus disabling * compression :-(, otherwise we issue the reset-request. */static voidccp_datainput(unit, pkt, len)    int unit;    u_char *pkt;    int len;{    fsm *f;    f = &ccp_fsm[unit];    if (f->state == OPENED) {	if (ccp_fatal_error(unit)) {	    /*	     * Disable compression by taking CCP down.	     */	    error("Lost compression sync: disabling compression");	    ccp_close(unit, "Lost compression sync");#ifdef MPPE	    /*	     * If we were doing MPPE, we must also take the link down.	     */	    if (ccp_gotoptions[unit].mppe) {		error("Too many MPPE errors, closing LCP");		lcp_close(unit, "Too many MPPE errors");	    }#endif	} else {	    /*	     * Send a reset-request to reset the peer's compressor.	     * We don't do that if we are still waiting for an	     * acknowledgement to a previous reset-request.	     */	    if (!(ccp_localstate[f->unit] & RACK_PENDING)) {		fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0);		TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT);		ccp_localstate[f->unit] |= RACK_PENDING;	    } else		ccp_localstate[f->unit] |= RREQ_REPEAT;	}    }}/* * Timeout waiting for reset-ack. */static voidccp_rack_timeout(arg)    void *arg;{    fsm *f = arg;    if (f->state == OPENED && ccp_localstate[f->unit] & RREQ_REPEAT) {	fsm_sdata(f, CCP_RESETREQ, f->reqid, NULL, 0);	TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT);	ccp_localstate[f->unit] &= ~RREQ_REPEAT;    } else	ccp_localstate[f->unit] &= ~RACK_PENDING;}

⌨️ 快捷键说明

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