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

📄 ccp.c

📁 经典的ppp程序
💻 C
📖 第 1 页 / 共 3 页
字号:
    ccp_options *ao = &ccp_allowoptions[f->unit];    ret = CONFACK;    retp = p0 = p;    len = *lenp;    memset(ho, 0, sizeof(ccp_options));    ho->method = (len > 0)? p[0]: -1;    while (len > 0) {	newret = CONFACK;	if (len < 2 || p[1] < 2 || p[1] > len) {	    /* length is bad */	    clen = len;	    newret = CONFREJ;	} else {	    type = p[0];	    clen = p[1];	    switch (type) {	    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;    }    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) {    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));}/* * 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);}/* * 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) {	    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");	} 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 + -