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

📄 ccp.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 2 页
字号:
//==========================================================================////      src/ccp.c////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Portions created by Nick Garnett are// Copyright (C) 2003 eCosCentric Ltd.//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//####BSDCOPYRIGHTBEGIN####//// -------------------------------------------//// Portions of this software may have been derived from OpenBSD, // FreeBSD or other sources, and are covered by the appropriate// copyright disclaimers included herein.//// -------------------------------------------////####BSDCOPYRIGHTEND####//==========================================================================/* * ccp.c - PPP Compression Control Protocol. * * Copyright (c) 1994 The Australian National University. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation is hereby granted, provided that the above copyright * notice appears in all copies.  This software is provided without any * warranty, express or implied. The Australian National University * makes no representations about the suitability of this software for * any purpose. * * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, * OR MODIFICATIONS. */#ifndef lint//static char rcsid[] = "$FreeBSD: src/usr.sbin/pppd/ccp.c,v 1.10 1999/08/28 01:19:00 peter Exp $";#endif#include <string.h>#include <cyg/ppp/syslog.h>#include <sys/ioctl.h>#include <sys/types.h>#include "cyg/ppp/pppd.h"#include "cyg/ppp/fsm.h"#include "cyg/ppp/ccp.h"#include <cyg/ppp/net/ppp_comp.h>/* * 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",    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));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)/* * 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 *//* * 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)	syslog(LOG_NOTICE, "Compression disabled by peer.");    /*     * 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]);}/* * ccp_resetci - initialize at start of negotiation. */static voidccp_resetci(f)    fsm *f;{    ccp_options *go = &ccp_gotoptions[f->unit];    u_char opt_buf[16];    *go = ccp_wantoptions[f->unit];    all_rejected[f->unit] = 0;    /*     * Check whether the kernel knows about the various     * compression methods we might request.     */    if (go->bsd_compress) {	opt_buf[0] = CI_BSD_COMPRESS;	opt_buf[1] = CILEN_BSD_COMPRESS;	opt_buf[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, BSD_MIN_BITS);	if (ccp_test(f->unit, opt_buf, CILEN_BSD_COMPRESS, 0) <= 0)	    go->bsd_compress = 0;    }    if (go->deflate) {	if (go->deflate_correct) {	    opt_buf[0] = CI_DEFLATE;	    opt_buf[1] = CILEN_DEFLATE;	    opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE);	    opt_buf[3] = DEFLATE_CHK_SEQUENCE;	    if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0)		go->deflate_correct = 0;	}	if (go->deflate_draft) {	    opt_buf[0] = CI_DEFLATE_DRAFT;	    opt_buf[1] = CILEN_DEFLATE;	    opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE);	    opt_buf[3] = DEFLATE_CHK_SEQUENCE;	    if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0)		go->deflate_draft = 0;	}	if (!go->deflate_correct && !go->deflate_draft)	    go->deflate = 0;    }    if (go->predictor_1) {	opt_buf[0] = CI_PREDICTOR_1;	opt_buf[1] = CILEN_PREDICTOR_1;	if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_1, 0) <= 0)	    go->predictor_1 = 0;    }    if (go->predictor_2) {	opt_buf[0] = CI_PREDICTOR_2;	opt_buf[1] = CILEN_PREDICTOR_2;	if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_2, 0) <= 0)	    go->predictor_2 = 0;    }}/* * ccp_cilen - Return total length of our configuration info. */static intccp_cilen(f)    fsm *f;{    ccp_options *go = &ccp_gotoptions[f->unit];    return (go->bsd_compress? CILEN_BSD_COMPRESS: 0)	+ (go->deflate? CILEN_DEFLATE: 0)	+ (go->predictor_1? CILEN_PREDICTOR_1: 0)	+ (go->predictor_2? CILEN_PREDICTOR_2: 0);}/* * ccp_addci - put our requests in a packet. */static voidccp_addci(f, p, lenp)    fsm *f;    u_char *p;    int *lenp;{    int res;    ccp_options *go = &ccp_gotoptions[f->unit];    u_char *p0 = p;    /*     * Add the compression types that we can receive, in decreasing     * preference order.  Get the kernel to allocate the first one     * in case it gets Acked.     */    if (go->deflate) {	p[0] = go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT;	p[1] = CILEN_DEFLATE;	p[2] = DEFLATE_MAKE_OPT(go->deflate_size);	p[3] = DEFLATE_CHK_SEQUENCE;	for (;;) {	    res = ccp_test(f->unit, p, CILEN_DEFLATE, 0);	    if (res > 0) {		p += CILEN_DEFLATE;		break;	    }	    if (res < 0 || go->deflate_size <= DEFLATE_MIN_SIZE) {		go->deflate = 0;		break;	    }	    --go->deflate_size;	    p[2] = DEFLATE_MAKE_OPT(go->deflate_size);	}	if (p != p0 && go->deflate_correct && go->deflate_draft) {	    p[0] = CI_DEFLATE_DRAFT;	    p[1] = CILEN_DEFLATE;	    p[2] = p[2 - CILEN_DEFLATE];	    p[3] = DEFLATE_CHK_SEQUENCE;	    p += CILEN_DEFLATE;	}    }    if (go->bsd_compress) {	p[0] = CI_BSD_COMPRESS;	p[1] = CILEN_BSD_COMPRESS;	p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits);	if (p != p0) {	    p += CILEN_BSD_COMPRESS;	/* not the first option */	} else {	    for (;;) {		res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 0);		if (res > 0) {		    p += CILEN_BSD_COMPRESS;		    break;		}		if (res < 0 || go->bsd_bits <= BSD_MIN_BITS) {		    go->bsd_compress = 0;		    break;		}		--go->bsd_bits;		p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits);	    }	}    }    /* XXX Should Predictor 2 be preferable to Predictor 1? */    if (go->predictor_1) {	p[0] = CI_PREDICTOR_1;	p[1] = CILEN_PREDICTOR_1;	if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 0) <= 0) {	    go->predictor_1 = 0;	} else {	    p += CILEN_PREDICTOR_1;	}    }    if (go->predictor_2) {	p[0] = CI_PREDICTOR_2;	p[1] = CILEN_PREDICTOR_2;	if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 0) <= 0) {	    go->predictor_2 = 0;	} else {	    p += CILEN_PREDICTOR_2;	}    }    go->method = (p > p0)? p0[0]: -1;    *lenp = p - p0;}/* * ccp_ackci - process a received configure-ack, and return * 1 iff the packet was OK. */static intccp_ackci(f, p, len)    fsm *f;    u_char *p;    int len;{    ccp_options *go = &ccp_gotoptions[f->unit];    u_char *p0 = p;    if (go->deflate) {	if (len < CILEN_DEFLATE	    || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)	    || p[1] != CILEN_DEFLATE	    || p[2] != DEFLATE_MAKE_OPT(go->deflate_size)	    || p[3] != DEFLATE_CHK_SEQUENCE)	    return 0;	p += CILEN_DEFLATE;	len -= CILEN_DEFLATE;	/* XXX Cope with first/fast ack */	if (len == 0)	    return 1;	if (go->deflate_correct && go->deflate_draft) {	    if (len < CILEN_DEFLATE		|| p[0] != CI_DEFLATE_DRAFT		|| p[1] != CILEN_DEFLATE		|| p[2] != DEFLATE_MAKE_OPT(go->deflate_size)		|| p[3] != DEFLATE_CHK_SEQUENCE)		return 0;	    p += CILEN_DEFLATE;	    len -= CILEN_DEFLATE;	}    }    if (go->bsd_compress) {	if (len < CILEN_BSD_COMPRESS	    || p[0] != CI_BSD_COMPRESS || p[1] != CILEN_BSD_COMPRESS	    || p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits))	    return 0;	p += CILEN_BSD_COMPRESS;	len -= CILEN_BSD_COMPRESS;	/* XXX Cope with first/fast ack */	if (p == p0 && len == 0)	    return 1;    }    if (go->predictor_1) {	if (len < CILEN_PREDICTOR_1	    || p[0] != CI_PREDICTOR_1 || p[1] != CILEN_PREDICTOR_1)	    return 0;	p += CILEN_PREDICTOR_1;	len -= CILEN_PREDICTOR_1;	/* XXX Cope with first/fast ack */	if (p == p0 && len == 0)	    return 1;    }    if (go->predictor_2) {	if (len < CILEN_PREDICTOR_2	    || p[0] != CI_PREDICTOR_2 || p[1] != CILEN_PREDICTOR_2)	    return 0;	p += CILEN_PREDICTOR_2;	len -= CILEN_PREDICTOR_2;	/* XXX Cope with first/fast ack */	if (p == p0 && len == 0)	    return 1;    }    if (len != 0)	return 0;    return 1;}/*

⌨️ 快捷键说明

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