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

📄 lcp.c

📁 经典的ppp程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * lcp.c - PPP Link Control Protocol. * * Copyright (c) 1989 Carnegie Mellon University. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by Carnegie Mellon University.  The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#define RCSID	"$Id: lcp.c,v 1.57 2001/03/08 05:11:14 paulus Exp $"/* * TODO: */#include <stdio.h>#include <string.h>#include <stdlib.h>#include "pppd.h"#include "fsm.h"#include "lcp.h"#include "chap.h"#include "magic.h"static const char rcsid[] = RCSID;/* * When the link comes up we want to be able to wait for a short while, * or until seeing some input from the peer, before starting to send * configure-requests.  We do this by delaying the fsm_lowerup call. *//* steal a bit in fsm flags word */#define DELAYED_UP	0x100static void lcp_delayed_up __P((void *));/* * LCP-related command-line options. */int	lcp_echo_interval = 0; 	/* Interval between LCP echo-requests */int	lcp_echo_fails = 0;	/* Tolerance to unanswered echo-requests */bool	lax_recv = 0;		/* accept control chars in asyncmap */bool	noendpoint = 0;		/* don't send/accept endpoint discriminator */static int noopt __P((char **));#ifdef HAVE_MULTILINKstatic int setendpoint __P((char **));static void printendpoint __P((option_t *, void (*)(void *, char *, ...),			       void *));#endif /* HAVE_MULTILINK */static option_t lcp_option_list[] = {    /* LCP options */    { "-all", o_special_noarg, (void *)noopt,      "Don't request/allow any LCP options" },    { "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression,      "Disable address/control compression",      OPT_A2CLR, &lcp_allowoptions[0].neg_accompression },    { "-ac", o_bool, &lcp_wantoptions[0].neg_accompression,      "Disable address/control compression",      OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_accompression },    { "asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,      "Set asyncmap (for received packets)",      OPT_OR, &lcp_wantoptions[0].neg_asyncmap },    { "-as", o_uint32, &lcp_wantoptions[0].asyncmap,      "Set asyncmap (for received packets)",      OPT_ALIAS | OPT_OR, &lcp_wantoptions[0].neg_asyncmap },    { "default-asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,      "Disable asyncmap negotiation",      OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR,      &lcp_allowoptions[0].neg_asyncmap },    { "-am", o_uint32, &lcp_wantoptions[0].asyncmap,      "Disable asyncmap negotiation",      OPT_ALIAS | OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR,      &lcp_allowoptions[0].neg_asyncmap },    { "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber,      "Disable magic number negotiation (looped-back line detection)",      OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber },    { "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber,      "Disable magic number negotiation (looped-back line detection)",      OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber },    { "mru", o_int, &lcp_wantoptions[0].mru,      "Set MRU (maximum received packet size) for negotiation",      OPT_PRIO, &lcp_wantoptions[0].neg_mru },    { "default-mru", o_bool, &lcp_wantoptions[0].neg_mru,      "Disable MRU negotiation (use default 1500)",      OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru },    { "-mru", o_bool, &lcp_wantoptions[0].neg_mru,      "Disable MRU negotiation (use default 1500)",      OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru },    { "mtu", o_int, &lcp_allowoptions[0].mru,      "Set our MTU", OPT_LIMITS, NULL, MAXMRU, MINMRU },    { "nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression,      "Disable protocol field compression",      OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression },    { "-pc", o_bool, &lcp_wantoptions[0].neg_pcompression,      "Disable protocol field compression",      OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression },    { "passive", o_bool, &lcp_wantoptions[0].passive,      "Set passive mode", 1 },    { "-p", o_bool, &lcp_wantoptions[0].passive,      "Set passive mode", OPT_ALIAS | 1 },    { "silent", o_bool, &lcp_wantoptions[0].silent,      "Set silent mode", 1 },    { "lcp-echo-failure", o_int, &lcp_echo_fails,      "Set number of consecutive echo failures to indicate link failure",      OPT_PRIO },    { "lcp-echo-interval", o_int, &lcp_echo_interval,      "Set time in seconds between LCP echo requests", OPT_PRIO },    { "lcp-restart", o_int, &lcp_fsm[0].timeouttime,      "Set time in seconds between LCP retransmissions", OPT_PRIO },    { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits,      "Set maximum number of LCP terminate-request transmissions", OPT_PRIO },    { "lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits,      "Set maximum number of LCP configure-request transmissions", OPT_PRIO },    { "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops,      "Set limit on number of LCP configure-naks", OPT_PRIO },    { "receive-all", o_bool, &lax_recv,      "Accept all received control characters", 1 },#ifdef HAVE_MULTILINK    { "mrru", o_int, &lcp_wantoptions[0].mrru,      "Maximum received packet size for multilink bundle",      OPT_PRIO, &lcp_wantoptions[0].neg_mrru },    { "mpshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf,      "Use short sequence numbers in multilink headers",      OPT_PRIO | 1, &lcp_allowoptions[0].neg_ssnhf },    { "nompshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf,      "Don't use short sequence numbers in multilink headers",      OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_ssnhf },    { "endpoint", o_special, (void *) setendpoint,      "Endpoint discriminator for multilink",      OPT_PRIO | OPT_A2PRINTER, (void *) printendpoint },#endif /* HAVE_MULTILINK */    { "noendpoint", o_bool, &noendpoint,      "Don't send or accept multilink endpoint discriminator", 1 },    {NULL}};/* global vars */fsm lcp_fsm[NUM_PPP];			/* LCP fsm structure (global)*/lcp_options lcp_wantoptions[NUM_PPP];	/* Options that we want to request */lcp_options lcp_gotoptions[NUM_PPP];	/* Options that peer ack'd */lcp_options lcp_allowoptions[NUM_PPP];	/* Options we allow peer to request */lcp_options lcp_hisoptions[NUM_PPP];	/* Options that we ack'd */static int lcp_echos_pending = 0;	/* Number of outstanding echo msgs */static int lcp_echo_number   = 0;	/* ID number of next echo frame */static int lcp_echo_timer_running = 0;  /* set if a timer is running */static u_char nak_buffer[PPP_MRU];	/* where we construct a nak packet *//* * Callbacks for fsm code.  (CI = Configuration Information) */static void lcp_resetci __P((fsm *));	/* Reset our CI */static int  lcp_cilen __P((fsm *));		/* Return length of our CI */static void lcp_addci __P((fsm *, u_char *, int *)); /* Add our CI to pkt */static int  lcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */static int  lcp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */static int  lcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */static int  lcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv peer CI */static void lcp_up __P((fsm *));		/* We're UP */static void lcp_down __P((fsm *));		/* We're DOWN */static void lcp_starting __P((fsm *));	/* We need lower layer up */static void lcp_finished __P((fsm *));	/* We need lower layer down */static int  lcp_extcode __P((fsm *, int, int, u_char *, int));static void lcp_rprotrej __P((fsm *, u_char *, int));/* * routines to send LCP echos to peer */static void lcp_echo_lowerup __P((int));static void lcp_echo_lowerdown __P((int));static void LcpEchoTimeout __P((void *));static void lcp_received_echo_reply __P((fsm *, int, u_char *, int));static void LcpSendEchoRequest __P((fsm *));static void LcpLinkFailure __P((fsm *));static void LcpEchoCheck __P((fsm *));static fsm_callbacks lcp_callbacks = {	/* LCP callback routines */    lcp_resetci,		/* Reset our Configuration Information */    lcp_cilen,			/* Length of our Configuration Information */    lcp_addci,			/* Add our Configuration Information */    lcp_ackci,			/* ACK our Configuration Information */    lcp_nakci,			/* NAK our Configuration Information */    lcp_rejci,			/* Reject our Configuration Information */    lcp_reqci,			/* Request peer's Configuration Information */    lcp_up,			/* Called when fsm reaches OPENED state */    lcp_down,			/* Called when fsm leaves OPENED state */    lcp_starting,		/* Called when we want the lower layer up */    lcp_finished,		/* Called when we want the lower layer down */    NULL,			/* Called when Protocol-Reject received */    NULL,			/* Retransmission is necessary */    lcp_extcode,		/* Called to handle LCP-specific codes */    "LCP"			/* String name of protocol */};/* * Protocol entry points. * Some of these are called directly. */static void lcp_init __P((int));static void lcp_input __P((int, u_char *, int));static void lcp_protrej __P((int));static int  lcp_printpkt __P((u_char *, int,			      void (*) __P((void *, char *, ...)), void *));struct protent lcp_protent = {    PPP_LCP,    lcp_init,    lcp_input,    lcp_protrej,    lcp_lowerup,    lcp_lowerdown,    lcp_open,    lcp_close,    lcp_printpkt,    NULL,    1,    "LCP",    NULL,    lcp_option_list,    NULL,    NULL,    NULL};int lcp_loopbackfail = DEFLOOPBACKFAIL;/* * Length of each type of configuration option (in octets) */#define CILEN_VOID	2#define CILEN_CHAR	3#define CILEN_SHORT	4	/* CILEN_VOID + 2 */#define CILEN_CHAP	5	/* CILEN_VOID + 2 + 1 */#define CILEN_LONG	6	/* CILEN_VOID + 4 */#define CILEN_LQR	8	/* CILEN_VOID + 2 + 4 */#define CILEN_CBCP	3#define CODENAME(x)	((x) == CONFACK ? "ACK" : \			 (x) == CONFNAK ? "NAK" : "REJ")/* * noopt - Disable all options (why?). */static intnoopt(argv)    char **argv;{    BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options));    BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options));    return (1);}#ifdef HAVE_MULTILINKstatic intsetendpoint(argv)    char **argv;{    if (str_to_epdisc(&lcp_wantoptions[0].endpoint, *argv)) {	lcp_wantoptions[0].neg_endpoint = 1;	return 1;    }    option_error("Can't parse '%s' as an endpoint discriminator", *argv);    return 0;}static voidprintendpoint(opt, printer, arg)    option_t *opt;    void (*printer) __P((void *, char *, ...));    void *arg;{	printer(arg, "%s", epdisc_to_str(&lcp_wantoptions[0].endpoint));}#endif /* HAVE_MULTILINK *//* * lcp_init - Initialize LCP. */static voidlcp_init(unit)    int unit;{    fsm *f = &lcp_fsm[unit];    lcp_options *wo = &lcp_wantoptions[unit];    lcp_options *ao = &lcp_allowoptions[unit];    f->unit = unit;    f->protocol = PPP_LCP;    f->callbacks = &lcp_callbacks;    fsm_init(f);    BZERO(wo, sizeof(*wo));    wo->neg_mru = 1;    wo->mru = DEFMRU;    wo->neg_asyncmap = 1;    wo->chap_mdtype = CHAP_DIGEST_MD5;    wo->neg_magicnumber = 1;    wo->neg_pcompression = 1;    wo->neg_accompression = 1;    BZERO(ao, sizeof(*ao));    ao->neg_mru = 1;    ao->mru = MAXMRU;    ao->neg_asyncmap = 1;    ao->neg_chap = 1;    ao->chap_mdtype = CHAP_DIGEST_MD5;    ao->neg_upap = 1;    ao->neg_magicnumber = 1;    ao->neg_pcompression = 1;    ao->neg_accompression = 1;#ifdef CBCP_SUPPORT    ao->neg_cbcp = 1;#endif    ao->neg_endpoint = 1;}/* * lcp_open - LCP is allowed to come up. */voidlcp_open(unit)    int unit;{    fsm *f = &lcp_fsm[unit];    lcp_options *wo = &lcp_wantoptions[unit];    f->flags &= ~(OPT_PASSIVE | OPT_SILENT);    if (wo->passive)	f->flags |= OPT_PASSIVE;    if (wo->silent)	f->flags |= OPT_SILENT;    fsm_open(f);}/* * lcp_close - Take LCP down. */voidlcp_close(unit, reason)    int unit;    char *reason;{    fsm *f = &lcp_fsm[unit];    if (phase != PHASE_DEAD)	new_phase(PHASE_TERMINATE);    if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {	/*	 * This action is not strictly according to the FSM in RFC1548,	 * but it does mean that the program terminates if you do a	 * lcp_close() in passive/silent mode when a connection hasn't	 * been established.	 */	f->state = CLOSED;	lcp_finished(f);    } else	fsm_close(&lcp_fsm[unit], reason);}/* * lcp_lowerup - The lower layer is up. */voidlcp_lowerup(unit)    int unit;{    lcp_options *wo = &lcp_wantoptions[unit];    fsm *f = &lcp_fsm[unit];    /*     * Don't use A/C or protocol compression on transmission,     * but accept A/C and protocol compressed packets     * if we are going to ask for A/C and protocol compression.     */    ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0);    ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff),		    wo->neg_pcompression, wo->neg_accompression);    peer_mru[unit] = PPP_MRU;    if (listen_time != 0) {	f->flags |= DELAYED_UP;	timeout(lcp_delayed_up, f, 0, listen_time * 1000);    } else	fsm_lowerup(f);}/* * lcp_lowerdown - The lower layer is down. */voidlcp_lowerdown(unit)    int unit;{    fsm *f = &lcp_fsm[unit];    if (f->flags & DELAYED_UP)	f->flags &= ~DELAYED_UP;    else	fsm_lowerdown(&lcp_fsm[unit]);}/* * lcp_delayed_up - Bring the lower layer up now. */static voidlcp_delayed_up(arg)    void *arg;{    fsm *f = arg;    if (f->flags & DELAYED_UP) {	f->flags &= ~DELAYED_UP;	fsm_lowerup(f);    }}/* * lcp_input - Input LCP packet. */static voidlcp_input(unit, p, len)    int unit;    u_char *p;    int len;{    fsm *f = &lcp_fsm[unit];    if (f->flags & DELAYED_UP) {	f->flags &= ~DELAYED_UP;	fsm_lowerup(f);    }    fsm_input(f, p, len);}/* * lcp_extcode - Handle a LCP-specific code. */static intlcp_extcode(f, code, id, inp, len)    fsm *f;    int code, id;    u_char *inp;    int len;{    u_char *magp;    switch( code ){    case PROTREJ:	lcp_rprotrej(f, inp, len);	break;        case ECHOREQ:	if (f->state != OPENED)	    break;	magp = inp;	PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);	fsm_sdata(f, ECHOREP, id, inp, len);	break;        case ECHOREP:	lcp_received_echo_reply(f, id, inp, len);	break;    case DISCREQ:	break;    default:	return 0;    }    return 1;}    /* * lcp_rprotrej - Receive an Protocol-Reject. * * Figure out which protocol is rejected and inform it. */static voidlcp_rprotrej(f, inp, len)    fsm *f;    u_char *inp;    int len;{    int i;    struct protent *protp;    u_short prot;    if (len < 2) {	LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!"));	return;    }    GETSHORT(prot, inp);    /*     * Protocol-Reject packets received in any state other than the LCP     * OPENED state SHOULD be silently discarded.     */    if( f->state != OPENED ){	LCPDEBUG(("Protocol-Reject discarded: LCP in state %d", f->state));	return;    }    /*     * Upcall the proper Protocol-Reject routine.     */    for (i = 0; (protp = protocols[i]) != NULL; ++i)	if (protp->protocol == prot && protp->enabled_flag) {	    (*protp->protrej)(f->unit);	    return;	}    warn("Protocol-Reject for unsupported protocol 0x%x", prot);}

⌨️ 快捷键说明

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