diff options
author | Mystery Man <unknown@mandriva.org> | 2002-07-09 13:18:50 +0000 |
---|---|---|
committer | Mystery Man <unknown@mandriva.org> | 2002-07-09 13:18:50 +0000 |
commit | 061aa98f8ab5e8b097f3c67e8074f3b057d1d1bf (patch) | |
tree | 6a497ebd94857616d1351e47418c0c3d6db4f563 /mdk-stage1/ppp/pppd/fsm.c | |
parent | a6a904a31e39b74144c53f0cc4086d496b70c09a (diff) | |
download | drakx-061aa98f8ab5e8b097f3c67e8074f3b057d1d1bf.tar drakx-061aa98f8ab5e8b097f3c67e8074f3b057d1d1bf.tar.gz drakx-061aa98f8ab5e8b097f3c67e8074f3b057d1d1bf.tar.bz2 drakx-061aa98f8ab5e8b097f3c67e8074f3b057d1d1bf.tar.xz drakx-061aa98f8ab5e8b097f3c67e8074f3b057d1d1bf.zip |
This commit was manufactured by cvs2svn to create tag 'V1_1_8_3mdk'.V1_1_8_3mdk
Diffstat (limited to 'mdk-stage1/ppp/pppd/fsm.c')
-rw-r--r-- | mdk-stage1/ppp/pppd/fsm.c | 762 |
1 files changed, 0 insertions, 762 deletions
diff --git a/mdk-stage1/ppp/pppd/fsm.c b/mdk-stage1/ppp/pppd/fsm.c deleted file mode 100644 index 07a8c11f1..000000000 --- a/mdk-stage1/ppp/pppd/fsm.c +++ /dev/null @@ -1,762 +0,0 @@ -/* - * fsm.c - {Link, IP} Control Protocol Finite State Machine. - * - * 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$" - -/* - * TODO: - * Randomize fsm id on link/init. - * Deal with variable outgoing MTU. - */ - -#include <stdio.h> -#include <string.h> -#include <sys/types.h> - -#include "pppd.h" -#include "fsm.h" - -static const char rcsid[] = RCSID; - -static void fsm_timeout __P((void *)); -static void fsm_rconfreq __P((fsm *, int, u_char *, int)); -static void fsm_rconfack __P((fsm *, int, u_char *, int)); -static void fsm_rconfnakrej __P((fsm *, int, int, u_char *, int)); -static void fsm_rtermreq __P((fsm *, int, u_char *, int)); -static void fsm_rtermack __P((fsm *)); -static void fsm_rcoderej __P((fsm *, u_char *, int)); -static void fsm_sconfreq __P((fsm *, int)); - -#define PROTO_NAME(f) ((f)->callbacks->proto_name) - -int peer_mru[NUM_PPP]; - - -/* - * fsm_init - Initialize fsm. - * - * Initialize fsm state. - */ -void -fsm_init(f) - fsm *f; -{ - f->state = INITIAL; - f->flags = 0; - f->id = 0; /* XXX Start with random id? */ - f->timeouttime = DEFTIMEOUT; - f->maxconfreqtransmits = DEFMAXCONFREQS; - f->maxtermtransmits = DEFMAXTERMREQS; - f->maxnakloops = DEFMAXNAKLOOPS; - f->term_reason_len = 0; -} - - -/* - * fsm_lowerup - The lower layer is up. - */ -void -fsm_lowerup(f) - fsm *f; -{ - switch( f->state ){ - case INITIAL: - f->state = CLOSED; - break; - - case STARTING: - if( f->flags & OPT_SILENT ) - f->state = STOPPED; - else { - /* Send an initial configure-request */ - fsm_sconfreq(f, 0); - f->state = REQSENT; - } - break; - - default: - FSMDEBUG(("%s: Up event in state %d!", PROTO_NAME(f), f->state)); - } -} - - -/* - * fsm_lowerdown - The lower layer is down. - * - * Cancel all timeouts and inform upper layers. - */ -void -fsm_lowerdown(f) - fsm *f; -{ - switch( f->state ){ - case CLOSED: - f->state = INITIAL; - break; - - case STOPPED: - f->state = STARTING; - if( f->callbacks->starting ) - (*f->callbacks->starting)(f); - break; - - case CLOSING: - f->state = INITIAL; - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - break; - - case STOPPING: - case REQSENT: - case ACKRCVD: - case ACKSENT: - f->state = STARTING; - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - break; - - case OPENED: - if( f->callbacks->down ) - (*f->callbacks->down)(f); - f->state = STARTING; - break; - - default: - FSMDEBUG(("%s: Down event in state %d!", PROTO_NAME(f), f->state)); - } -} - - -/* - * fsm_open - Link is allowed to come up. - */ -void -fsm_open(f) - fsm *f; -{ - switch( f->state ){ - case INITIAL: - f->state = STARTING; - if( f->callbacks->starting ) - (*f->callbacks->starting)(f); - break; - - case CLOSED: - if( f->flags & OPT_SILENT ) - f->state = STOPPED; - else { - /* Send an initial configure-request */ - fsm_sconfreq(f, 0); - f->state = REQSENT; - } - break; - - case CLOSING: - f->state = STOPPING; - /* fall through */ - case STOPPED: - case OPENED: - if( f->flags & OPT_RESTART ){ - fsm_lowerdown(f); - fsm_lowerup(f); - } - break; - } -} - - -/* - * fsm_close - Start closing connection. - * - * Cancel timeouts and either initiate close or possibly go directly to - * the CLOSED state. - */ -void -fsm_close(f, reason) - fsm *f; - char *reason; -{ - f->term_reason = reason; - f->term_reason_len = (reason == NULL? 0: strlen(reason)); - switch( f->state ){ - case STARTING: - f->state = INITIAL; - break; - case STOPPED: - f->state = CLOSED; - break; - case STOPPING: - f->state = CLOSING; - break; - - case REQSENT: - case ACKRCVD: - case ACKSENT: - case OPENED: - if( f->state != OPENED ) - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - else if( f->callbacks->down ) - (*f->callbacks->down)(f); /* Inform upper layers we're down */ - - /* Init restart counter, send Terminate-Request */ - f->retransmits = f->maxtermtransmits; - fsm_sdata(f, TERMREQ, f->reqid = ++f->id, - (u_char *) f->term_reason, f->term_reason_len); - TIMEOUT(fsm_timeout, f, f->timeouttime); - --f->retransmits; - - f->state = CLOSING; - break; - } -} - - -/* - * fsm_timeout - Timeout expired. - */ -static void -fsm_timeout(arg) - void *arg; -{ - fsm *f = (fsm *) arg; - - switch (f->state) { - case CLOSING: - case STOPPING: - if( f->retransmits <= 0 ){ - /* - * We've waited for an ack long enough. Peer probably heard us. - */ - f->state = (f->state == CLOSING)? CLOSED: STOPPED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - } else { - /* Send Terminate-Request */ - fsm_sdata(f, TERMREQ, f->reqid = ++f->id, - (u_char *) f->term_reason, f->term_reason_len); - TIMEOUT(fsm_timeout, f, f->timeouttime); - --f->retransmits; - } - break; - - case REQSENT: - case ACKRCVD: - case ACKSENT: - if (f->retransmits <= 0) { - warn("%s: timeout sending Config-Requests\n", PROTO_NAME(f)); - f->state = STOPPED; - if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) - (*f->callbacks->finished)(f); - - } else { - /* Retransmit the configure-request */ - if (f->callbacks->retransmit) - (*f->callbacks->retransmit)(f); - fsm_sconfreq(f, 1); /* Re-send Configure-Request */ - if( f->state == ACKRCVD ) - f->state = REQSENT; - } - break; - - default: - FSMDEBUG(("%s: Timeout event in state %d!", PROTO_NAME(f), f->state)); - } -} - - -/* - * fsm_input - Input packet. - */ -void -fsm_input(f, inpacket, l) - fsm *f; - u_char *inpacket; - int l; -{ - u_char *inp; - u_char code, id; - int len; - - /* - * Parse header (code, id and length). - * If packet too short, drop it. - */ - inp = inpacket; - if (l < HEADERLEN) { - FSMDEBUG(("fsm_input(%x): Rcvd short header.", f->protocol)); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < HEADERLEN) { - FSMDEBUG(("fsm_input(%x): Rcvd illegal length.", f->protocol)); - return; - } - if (len > l) { - FSMDEBUG(("fsm_input(%x): Rcvd short packet.", f->protocol)); - return; - } - len -= HEADERLEN; /* subtract header length */ - - if( f->state == INITIAL || f->state == STARTING ){ - FSMDEBUG(("fsm_input(%x): Rcvd packet in state %d.", - f->protocol, f->state)); - return; - } - - /* - * Action depends on code. - */ - switch (code) { - case CONFREQ: - fsm_rconfreq(f, id, inp, len); - break; - - case CONFACK: - fsm_rconfack(f, id, inp, len); - break; - - case CONFNAK: - case CONFREJ: - fsm_rconfnakrej(f, code, id, inp, len); - break; - - case TERMREQ: - fsm_rtermreq(f, id, inp, len); - break; - - case TERMACK: - fsm_rtermack(f); - break; - - case CODEREJ: - fsm_rcoderej(f, inp, len); - break; - - default: - if( !f->callbacks->extcode - || !(*f->callbacks->extcode)(f, code, id, inp, len) ) - fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN); - break; - } -} - - -/* - * fsm_rconfreq - Receive Configure-Request. - */ -static void -fsm_rconfreq(f, id, inp, len) - fsm *f; - u_char id; - u_char *inp; - int len; -{ - int code, reject_if_disagree; - - switch( f->state ){ - case CLOSED: - /* Go away, we're closed */ - fsm_sdata(f, TERMACK, id, NULL, 0); - return; - case CLOSING: - case STOPPING: - return; - - case OPENED: - /* Go down and restart negotiation */ - if( f->callbacks->down ) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - break; - - case STOPPED: - /* Negotiation started by our peer */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = REQSENT; - break; - } - - /* - * Pass the requested configuration options - * to protocol-specific code for checking. - */ - if (f->callbacks->reqci){ /* Check CI */ - reject_if_disagree = (f->nakloops >= f->maxnakloops); - code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree); - } else if (len) - code = CONFREJ; /* Reject all CI */ - else - code = CONFACK; - - /* send the Ack, Nak or Rej to the peer */ - fsm_sdata(f, code, id, inp, len); - - if (code == CONFACK) { - if (f->state == ACKRCVD) { - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - f->state = OPENED; - if (f->callbacks->up) - (*f->callbacks->up)(f); /* Inform upper layers */ - } else - f->state = ACKSENT; - f->nakloops = 0; - - } else { - /* we sent CONFACK or CONFREJ */ - if (f->state != ACKRCVD) - f->state = REQSENT; - if( code == CONFNAK ) - ++f->nakloops; - } -} - - -/* - * fsm_rconfack - Receive Configure-Ack. - */ -static void -fsm_rconfack(f, id, inp, len) - fsm *f; - int id; - u_char *inp; - int len; -{ - if (id != f->reqid || f->seen_ack) /* Expected id? */ - return; /* Nope, toss... */ - if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): - (len == 0)) ){ - /* Ack is bad - ignore it */ - error("Received bad configure-ack: %P", inp, len); - return; - } - f->seen_ack = 1; - - switch (f->state) { - case CLOSED: - case STOPPED: - fsm_sdata(f, TERMACK, id, NULL, 0); - break; - - case REQSENT: - f->state = ACKRCVD; - f->retransmits = f->maxconfreqtransmits; - break; - - case ACKRCVD: - /* Huh? an extra valid Ack? oh well... */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - fsm_sconfreq(f, 0); - f->state = REQSENT; - break; - - case ACKSENT: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - f->state = OPENED; - f->retransmits = f->maxconfreqtransmits; - if (f->callbacks->up) - (*f->callbacks->up)(f); /* Inform upper layers */ - break; - - case OPENED: - /* Go down and restart negotiation */ - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = REQSENT; - break; - } -} - - -/* - * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. - */ -static void -fsm_rconfnakrej(f, code, id, inp, len) - fsm *f; - int code, id; - u_char *inp; - int len; -{ - int (*proc) __P((fsm *, u_char *, int)); - int ret; - - if (id != f->reqid || f->seen_ack) /* Expected id? */ - return; /* Nope, toss... */ - proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci; - if (!proc || !(ret = proc(f, inp, len))) { - /* Nak/reject is bad - ignore it */ - error("Received bad configure-nak/rej: %P", inp, len); - return; - } - f->seen_ack = 1; - - switch (f->state) { - case CLOSED: - case STOPPED: - fsm_sdata(f, TERMACK, id, NULL, 0); - break; - - case REQSENT: - case ACKSENT: - /* They didn't agree to what we wanted - try another request */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - if (ret < 0) - f->state = STOPPED; /* kludge for stopping CCP */ - else - fsm_sconfreq(f, 0); /* Send Configure-Request */ - break; - - case ACKRCVD: - /* Got a Nak/reject when we had already had an Ack?? oh well... */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - fsm_sconfreq(f, 0); - f->state = REQSENT; - break; - - case OPENED: - /* Go down and restart negotiation */ - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = REQSENT; - break; - } -} - - -/* - * fsm_rtermreq - Receive Terminate-Req. - */ -static void -fsm_rtermreq(f, id, p, len) - fsm *f; - int id; - u_char *p; - int len; -{ - switch (f->state) { - case ACKRCVD: - case ACKSENT: - f->state = REQSENT; /* Start over but keep trying */ - break; - - case OPENED: - if (len > 0) { - info("%s terminated by peer (%0.*v)", PROTO_NAME(f), len, p); - } else - info("%s terminated by peer", PROTO_NAME(f)); - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - f->retransmits = 0; - f->state = STOPPING; - TIMEOUT(fsm_timeout, f, f->timeouttime); - break; - } - - fsm_sdata(f, TERMACK, id, NULL, 0); -} - - -/* - * fsm_rtermack - Receive Terminate-Ack. - */ -static void -fsm_rtermack(f) - fsm *f; -{ - switch (f->state) { - case CLOSING: - UNTIMEOUT(fsm_timeout, f); - f->state = CLOSED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - case STOPPING: - UNTIMEOUT(fsm_timeout, f); - f->state = STOPPED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - - case ACKRCVD: - f->state = REQSENT; - break; - - case OPENED: - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); - break; - } -} - - -/* - * fsm_rcoderej - Receive an Code-Reject. - */ -static void -fsm_rcoderej(f, inp, len) - fsm *f; - u_char *inp; - int len; -{ - u_char code, id; - - if (len < HEADERLEN) { - FSMDEBUG(("fsm_rcoderej: Rcvd short Code-Reject packet!")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - warn("%s: Rcvd Code-Reject for code %d, id %d", PROTO_NAME(f), code, id); - - if( f->state == ACKRCVD ) - f->state = REQSENT; -} - - -/* - * fsm_protreject - Peer doesn't speak this protocol. - * - * Treat this as a catastrophic error (RXJ-). - */ -void -fsm_protreject(f) - fsm *f; -{ - switch( f->state ){ - case CLOSING: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - /* fall through */ - case CLOSED: - f->state = CLOSED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - - case STOPPING: - case REQSENT: - case ACKRCVD: - case ACKSENT: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - /* fall through */ - case STOPPED: - f->state = STOPPED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - - case OPENED: - if( f->callbacks->down ) - (*f->callbacks->down)(f); - - /* Init restart counter, send Terminate-Request */ - f->retransmits = f->maxtermtransmits; - fsm_sdata(f, TERMREQ, f->reqid = ++f->id, - (u_char *) f->term_reason, f->term_reason_len); - TIMEOUT(fsm_timeout, f, f->timeouttime); - --f->retransmits; - - f->state = STOPPING; - break; - - default: - FSMDEBUG(("%s: Protocol-reject event in state %d!", - PROTO_NAME(f), f->state)); - } -} - - -/* - * fsm_sconfreq - Send a Configure-Request. - */ -static void -fsm_sconfreq(f, retransmit) - fsm *f; - int retransmit; -{ - u_char *outp; - int cilen; - - if( f->state != REQSENT && f->state != ACKRCVD && f->state != ACKSENT ){ - /* Not currently negotiating - reset options */ - if( f->callbacks->resetci ) - (*f->callbacks->resetci)(f); - f->nakloops = 0; - } - - if( !retransmit ){ - /* New request - reset retransmission counter, use new ID */ - f->retransmits = f->maxconfreqtransmits; - f->reqid = ++f->id; - } - - f->seen_ack = 0; - - /* - * Make up the request packet - */ - outp = outpacket_buf + PPP_HDRLEN + HEADERLEN; - if( f->callbacks->cilen && f->callbacks->addci ){ - cilen = (*f->callbacks->cilen)(f); - if( cilen > peer_mru[f->unit] - HEADERLEN ) - cilen = peer_mru[f->unit] - HEADERLEN; - if (f->callbacks->addci) - (*f->callbacks->addci)(f, outp, &cilen); - } else - cilen = 0; - - /* send the request to our peer */ - fsm_sdata(f, CONFREQ, f->reqid, outp, cilen); - - /* start the retransmit timer */ - --f->retransmits; - TIMEOUT(fsm_timeout, f, f->timeouttime); -} - - -/* - * fsm_sdata - Send some data. - * - * Used for all packets sent to our peer by this module. - */ -void -fsm_sdata(f, code, id, data, datalen) - fsm *f; - u_char code, id; - u_char *data; - int datalen; -{ - u_char *outp; - int outlen; - - /* Adjust length to be smaller than MTU */ - outp = outpacket_buf; - if (datalen > peer_mru[f->unit] - HEADERLEN) - datalen = peer_mru[f->unit] - HEADERLEN; - if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) - BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen); - outlen = datalen + HEADERLEN; - MAKEHEADER(outp, f->protocol); - PUTCHAR(code, outp); - PUTCHAR(id, outp); - PUTSHORT(outlen, outp); - output(f->unit, outpacket_buf, outlen + PPP_HDRLEN); -} |