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

📄 ccp.c

📁 自己精简过的PPPD代码。在嵌入中应用可以更好的发挥。比原先的小了很多
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * ccp.c - PPP Compression Control Protocol. * * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to *    endorse or promote products derived from this software without *    prior written permission. * * 3. Redistributions of any form whatsoever must retain the following *    acknowledgment: *    "This product includes software developed by Paul Mackerras *     <paulus@samba.org>". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */#define RCSID	"$Id: ccp.c,v 1.50 2005/06/26 19:34:41 carlsonj Exp $"#include <stdlib.h>#include <string.h>#include "pppd.h"#include "fsm.h"#include "ccp.h"#include <net/ppp-comp.h>#ifdef MPPE#include "chap_ms.h"	/* mppe_xxxx_key, mppe_keys_set */#include "lcp.h"	/* lcp_close(), lcp_fsm */#endifstatic const char rcsid[] = RCSID;/* * Unfortunately there is a bug in zlib which means that using a * size of 8 (window size = 256) for Deflate compression will cause * buffer overruns and kernel crashes in the deflate module. * Until this is fixed we only accept sizes in the range 9 .. 15. * Thanks to James Carlson for pointing this out. */#define DEFLATE_MIN_WORKS	9/* * Command-line options. */static int setbsdcomp __P((char **));static int setdeflate __P((char **));static char bsd_value[8];static char deflate_value[8];/* * Option variables. */#ifdef MPPEbool refuse_mppe_stateful = 1;		/* Allow stateful mode? */#endifstatic option_t ccp_option_list[] = {    { "noccp", o_bool, &ccp_protent.enabled_flag,      "Disable CCP negotiation" },    { "-ccp", o_bool, &ccp_protent.enabled_flag,      "Disable CCP negotiation", OPT_ALIAS },    { "bsdcomp", o_special, (void *)setbsdcomp,      "Request BSD-Compress packet compression",      OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, bsd_value },    { "nobsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress,      "don't allow BSD-Compress", OPT_PRIOSUB | OPT_A2CLR,      &ccp_allowoptions[0].bsd_compress },    { "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress,      "don't allow BSD-Compress", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,      &ccp_allowoptions[0].bsd_compress },    { "deflate", o_special, (void *)setdeflate,      "request Deflate compression",      OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, deflate_value },    { "nodeflate", o_bool, &ccp_wantoptions[0].deflate,      "don't allow Deflate compression", OPT_PRIOSUB | OPT_A2CLR,      &ccp_allowoptions[0].deflate },    { "-deflate", o_bool, &ccp_wantoptions[0].deflate,      "don't allow Deflate compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,      &ccp_allowoptions[0].deflate },    { "nodeflatedraft", o_bool, &ccp_wantoptions[0].deflate_draft,      "don't use draft deflate #", OPT_A2COPY,      &ccp_allowoptions[0].deflate_draft },    { "predictor1", o_bool, &ccp_wantoptions[0].predictor_1,      "request Predictor-1", OPT_PRIO | 1 },    { "nopredictor1", o_bool, &ccp_wantoptions[0].predictor_1,      "don't allow Predictor-1", OPT_PRIOSUB | OPT_A2CLR,      &ccp_allowoptions[0].predictor_1 },    { "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1,      "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,      &ccp_allowoptions[0].predictor_1 },#ifdef MPPE    /* MPPE options are symmetrical ... we only set wantoptions here */    { "require-mppe", o_bool, &ccp_wantoptions[0].mppe,      "require MPPE encryption",      OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },    { "+mppe", o_bool, &ccp_wantoptions[0].mppe,      "require MPPE encryption",      OPT_ALIAS | OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },    { "nomppe", o_bool, &ccp_wantoptions[0].mppe,      "don't allow MPPE encryption", OPT_PRIO },    { "-mppe", o_bool, &ccp_wantoptions[0].mppe,      "don't allow MPPE encryption", OPT_ALIAS | OPT_PRIO },    /* We use ccp_allowoptions[0].mppe as a junk var ... it is reset later */    { "require-mppe-40", o_bool, &ccp_allowoptions[0].mppe,      "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,      &ccp_wantoptions[0].mppe },    { "+mppe-40", o_bool, &ccp_allowoptions[0].mppe,      "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,      &ccp_wantoptions[0].mppe },    { "nomppe-40", o_bool, &ccp_allowoptions[0].mppe,      "don't allow MPPE 40-bit encryption",      OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, &ccp_wantoptions[0].mppe },    { "-mppe-40", o_bool, &ccp_allowoptions[0].mppe,      "don't allow MPPE 40-bit encryption",      OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40,      &ccp_wantoptions[0].mppe },    { "require-mppe-128", o_bool, &ccp_allowoptions[0].mppe,      "require MPPE 128-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_128,      &ccp_wantoptions[0].mppe },    { "+mppe-128", o_bool, &ccp_allowoptions[0].mppe,      "require MPPE 128-bit encryption",      OPT_ALIAS | OPT_PRIO | OPT_A2OR | MPPE_OPT_128,      &ccp_wantoptions[0].mppe },    { "nomppe-128", o_bool, &ccp_allowoptions[0].mppe,      "don't allow MPPE 128-bit encryption",      OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, &ccp_wantoptions[0].mppe },    { "-mppe-128", o_bool, &ccp_allowoptions[0].mppe,      "don't allow MPPE 128-bit encryption",      OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128,      &ccp_wantoptions[0].mppe },    /* strange one; we always request stateless, but will we allow stateful? */    { "mppe-stateful", o_bool, &refuse_mppe_stateful,      "allow MPPE stateful mode", OPT_PRIO },    { "nomppe-stateful", o_bool, &refuse_mppe_stateful,      "disallow MPPE stateful mode", OPT_PRIO | 1 },#endif /* MPPE */    { NULL }};/* * Protocol entry points from main code. */static void ccp_init __P((int unit));static void ccp_open __P((int unit));static void ccp_close __P((int unit, char *));static void ccp_lowerup __P((int unit));static void ccp_lowerdown __P((int));static void ccp_input __P((int unit, u_char *pkt, int len));static void ccp_protrej __P((int unit));static int  ccp_printpkt __P((u_char *pkt, int len,			      void (*printer) __P((void *, char *, ...)),			      void *arg));static void ccp_datainput __P((int unit, u_char *pkt, int len));struct protent ccp_protent = {    PPP_CCP,    ccp_init,    ccp_input,    ccp_protrej,    ccp_lowerup,    ccp_lowerdown,    ccp_open,    ccp_close,    ccp_printpkt,    ccp_datainput,    1,    "CCP",    "Compressed",    ccp_option_list,    NULL,    NULL,    NULL};fsm ccp_fsm[NUM_PPP];ccp_options ccp_wantoptions[NUM_PPP];	/* what to request the peer to use */ccp_options ccp_gotoptions[NUM_PPP];	/* what the peer agreed to do */ccp_options ccp_allowoptions[NUM_PPP];	/* what we'll agree to do */ccp_options ccp_hisoptions[NUM_PPP];	/* what we agreed to do *//* * Callbacks for fsm code. */static void ccp_resetci __P((fsm *));static int  ccp_cilen __P((fsm *));static void ccp_addci __P((fsm *, u_char *, int *));static int  ccp_ackci __P((fsm *, u_char *, int));static int  ccp_nakci __P((fsm *, u_char *, int, int));static int  ccp_rejci __P((fsm *, u_char *, int));static int  ccp_reqci __P((fsm *, u_char *, int *, int));static void ccp_up __P((fsm *));static void ccp_down __P((fsm *));static int  ccp_extcode __P((fsm *, int, int, u_char *, int));static void ccp_rack_timeout __P((void *));static char *method_name __P((ccp_options *, ccp_options *));static fsm_callbacks ccp_callbacks = {    ccp_resetci,    ccp_cilen,    ccp_addci,    ccp_ackci,    ccp_nakci,    ccp_rejci,    ccp_reqci,    ccp_up,    ccp_down,    NULL,    NULL,    NULL,    NULL,    ccp_extcode,    "CCP"};/* * Do we want / did we get any compression? */#define ANY_COMPRESS(opt)	((opt).deflate || (opt).bsd_compress \				 || (opt).predictor_1 || (opt).predictor_2 \				 || (opt).mppe)/* * Local state (mainly for handling reset-reqs and reset-acks). */static int ccp_localstate[NUM_PPP];#define RACK_PENDING	1	/* waiting for reset-ack */#define RREQ_REPEAT	2	/* send another reset-req if no reset-ack */#define RACKTIMEOUT	1	/* second */static int all_rejected[NUM_PPP];	/* we rejected all peer's options *//* * Option parsing. */static intsetbsdcomp(argv)    char **argv;{    int rbits, abits;    char *str, *endp;    str = *argv;    abits = rbits = strtol(str, &endp, 0);    if (endp != str && *endp == ',') {	str = endp + 1;	abits = strtol(str, &endp, 0);    }    if (*endp != 0 || endp == str) {	option_error("invalid parameter '%s' for bsdcomp option", *argv);	return 0;    }    if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS))	|| (abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS))) {	option_error("bsdcomp option values must be 0 or %d .. %d",		     BSD_MIN_BITS, BSD_MAX_BITS);	return 0;    }    if (rbits > 0) {	ccp_wantoptions[0].bsd_compress = 1;	ccp_wantoptions[0].bsd_bits = rbits;    } else	ccp_wantoptions[0].bsd_compress = 0;    if (abits > 0) {	ccp_allowoptions[0].bsd_compress = 1;	ccp_allowoptions[0].bsd_bits = abits;    } else	ccp_allowoptions[0].bsd_compress = 0;    slprintf(bsd_value, sizeof(bsd_value),	     rbits == abits? "%d": "%d,%d", rbits, abits);    return 1;}static intsetdeflate(argv)    char **argv;{    int rbits, abits;    char *str, *endp;    str = *argv;    abits = rbits = strtol(str, &endp, 0);    if (endp != str && *endp == ',') {	str = endp + 1;	abits = strtol(str, &endp, 0);    }    if (*endp != 0 || endp == str) {	option_error("invalid parameter '%s' for deflate option", *argv);	return 0;    }    if ((rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE))	|| (abits != 0 && (abits < DEFLATE_MIN_SIZE			  || abits > DEFLATE_MAX_SIZE))) {	option_error("deflate option values must be 0 or %d .. %d",		     DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE);	return 0;    }    if (rbits == DEFLATE_MIN_SIZE || abits == DEFLATE_MIN_SIZE) {	if (rbits == DEFLATE_MIN_SIZE)	    rbits = DEFLATE_MIN_WORKS;	if (abits == DEFLATE_MIN_SIZE)	    abits = DEFLATE_MIN_WORKS;	warn("deflate option value of %d changed to %d to avoid zlib bug",	     DEFLATE_MIN_SIZE, DEFLATE_MIN_WORKS);    }    if (rbits > 0) {	ccp_wantoptions[0].deflate = 1;	ccp_wantoptions[0].deflate_size = rbits;    } else	ccp_wantoptions[0].deflate = 0;    if (abits > 0) {	ccp_allowoptions[0].deflate = 1;	ccp_allowoptions[0].deflate_size = abits;    } else	ccp_allowoptions[0].deflate = 0;    slprintf(deflate_value, sizeof(deflate_value),	     rbits == abits? "%d": "%d,%d", rbits, abits);    return 1;}/* * ccp_init - initialize CCP. */static voidccp_init(unit)    int unit;{    fsm *f = &ccp_fsm[unit];    f->unit = unit;    f->protocol = PPP_CCP;    f->callbacks = &ccp_callbacks;    fsm_init(f);    memset(&ccp_wantoptions[unit],  0, sizeof(ccp_options));    memset(&ccp_gotoptions[unit],   0, sizeof(ccp_options));    memset(&ccp_allowoptions[unit], 0, sizeof(ccp_options));    memset(&ccp_hisoptions[unit],   0, sizeof(ccp_options));    ccp_wantoptions[0].deflate = 1;    ccp_wantoptions[0].deflate_size = DEFLATE_MAX_SIZE;    ccp_wantoptions[0].deflate_correct = 1;    ccp_wantoptions[0].deflate_draft = 1;    ccp_allowoptions[0].deflate = 1;    ccp_allowoptions[0].deflate_size = DEFLATE_MAX_SIZE;    ccp_allowoptions[0].deflate_correct = 1;    ccp_allowoptions[0].deflate_draft = 1;    ccp_wantoptions[0].bsd_compress = 1;    ccp_wantoptions[0].bsd_bits = BSD_MAX_BITS;    ccp_allowoptions[0].bsd_compress = 1;    ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS;    ccp_allowoptions[0].predictor_1 = 1;}/* * ccp_open - CCP is allowed to come up. */static voidccp_open(unit)    int unit;{    fsm *f = &ccp_fsm[unit];    if (f->state != OPENED)	ccp_flags_set(unit, 1, 0);    /*     * Find out which compressors the kernel supports before     * deciding whether to open in silent mode.     */    ccp_resetci(f);    if (!ANY_COMPRESS(ccp_gotoptions[unit]))	f->flags |= OPT_SILENT;    fsm_open(f);}/* * ccp_close - Terminate CCP. */static voidccp_close(unit, reason)    int unit;    char *reason;{    ccp_flags_set(unit, 0, 0);    fsm_close(&ccp_fsm[unit], reason);}/* * ccp_lowerup - we may now transmit CCP packets. */static voidccp_lowerup(unit)    int unit;{    fsm_lowerup(&ccp_fsm[unit]);}/* * ccp_lowerdown - we may not transmit CCP packets. */static voidccp_lowerdown(unit)    int unit;{    fsm_lowerdown(&ccp_fsm[unit]);}/* * ccp_input - process a received CCP packet. */static voidccp_input(unit, p, len)    int unit;    u_char *p;    int len;{    fsm *f = &ccp_fsm[unit];    int oldstate;    /*     * Check for a terminate-request so we can print a message.     */    oldstate = f->state;    fsm_input(f, p, len);    if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED) {	notice("Compression disabled by peer.");#ifdef MPPE	if (ccp_gotoptions[unit].mppe) {	    error("MPPE disabled, closing LCP");	    lcp_close(unit, "MPPE disabled by peer");	}#endif    }    /*     * If we get a terminate-ack and we're not asking for compression,     * close CCP.     */    if (oldstate == REQSENT && p[0] == TERMACK	&& !ANY_COMPRESS(ccp_gotoptions[unit]))	ccp_close(unit, "No compression negotiated");}/* * Handle a CCP-specific code. */static intccp_extcode(f, code, id, p, len)    fsm *f;    int code, id;    u_char *p;    int len;{    switch (code) {    case CCP_RESETREQ:	if (f->state != OPENED)	    break;	/* send a reset-ack, which the transmitter will see and	   reset its compression state. */	fsm_sdata(f, CCP_RESETACK, id, NULL, 0);	break;    case CCP_RESETACK:	if (ccp_localstate[f->unit] & RACK_PENDING && id == f->reqid) {	    ccp_localstate[f->unit] &= ~(RACK_PENDING | RREQ_REPEAT);	    UNTIMEOUT(ccp_rack_timeout, f);	}	break;    default:	return 0;    }    return 1;}/* * ccp_protrej - peer doesn't talk CCP. */static voidccp_protrej(unit)    int unit;{    ccp_flags_set(unit, 0, 0);    fsm_lowerdown(&ccp_fsm[unit]);#ifdef MPPE    if (ccp_gotoptions[unit].mppe) {	error("MPPE required but peer negotiation failed");	lcp_close(unit, "MPPE required but peer negotiation failed");    }#endif}/* * ccp_resetci - initialize at start of negotiation. */static voidccp_resetci(f)    fsm *f;{    ccp_options *go = &ccp_gotoptions[f->unit];    u_char opt_buf[CCP_MAX_OPTION_LENGTH];    *go = ccp_wantoptions[f->unit];    all_rejected[f->unit] = 0;#ifdef MPPE    if (go->mppe) {	ccp_options *ao = &ccp_allowoptions[f->unit];	int auth_mschap_bits = auth_done[f->unit];	int numbits;	/*	 * Start with a basic sanity check: mschap[v2] auth must be in	 * exactly one direction.  RFC 3079 says that the keys are	 * 'derived from the credentials of the peer that initiated the call',	 * however the PPP protocol doesn't have such a concept, and pppd	 * cannot get this info externally.  Instead we do the best we can.	 * NB: If MPPE is required, all other compression opts are invalid.	 *     So, we return right away if we can't do it.	 */	/* Leave only the mschap auth bits set */	auth_mschap_bits &= (CHAP_MS_WITHPEER  | CHAP_MS_PEER |			     CHAP_MS2_WITHPEER | CHAP_MS2_PEER);	/* Count the mschap auths */	auth_mschap_bits >>= CHAP_MS_SHIFT;	numbits = 0;

⌨️ 快捷键说明

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