178189Sbrian/*- 278189Sbrian * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org> 378189Sbrian * based on work by Toshiharu OHNO <tony-o@iij.ad.jp> 478189Sbrian * Internet Initiative Japan, Inc (IIJ) 578189Sbrian * All rights reserved. 66059Samurai * 778189Sbrian * Redistribution and use in source and binary forms, with or without 878189Sbrian * modification, are permitted provided that the following conditions 978189Sbrian * are met: 1078189Sbrian * 1. Redistributions of source code must retain the above copyright 1178189Sbrian * notice, this list of conditions and the following disclaimer. 1278189Sbrian * 2. Redistributions in binary form must reproduce the above copyright 1378189Sbrian * notice, this list of conditions and the following disclaimer in the 1478189Sbrian * documentation and/or other materials provided with the distribution. 156059Samurai * 1678189Sbrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1778189Sbrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1878189Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1978189Sbrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2078189Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2178189Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2278189Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2378189Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2478189Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2578189Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2678189Sbrian * SUCH DAMAGE. 276059Samurai * 2850479Speter * $FreeBSD$ 296059Samurai */ 306735Samurai 316059Samurai/* 326059Samurai * State of machine 336059Samurai */ 346059Samurai#define ST_INITIAL 0 356059Samurai#define ST_STARTING 1 366059Samurai#define ST_CLOSED 2 376059Samurai#define ST_STOPPED 3 386059Samurai#define ST_CLOSING 4 396059Samurai#define ST_STOPPING 5 406059Samurai#define ST_REQSENT 6 416059Samurai#define ST_ACKRCVD 7 426059Samurai#define ST_ACKSENT 8 436059Samurai#define ST_OPENED 9 446059Samurai 456059Samurai#define ST_MAX 10 466059Samurai#define ST_UNDEF -1 476059Samurai 486059Samurai#define MODE_REQ 0 496059Samurai#define MODE_NAK 1 506059Samurai#define MODE_REJ 2 516735Samurai#define MODE_NOP 3 5231514Sbrian#define MODE_ACK 4 /* pseudo mode for ccp negotiations */ 536059Samurai 5432658Sbrian#define OPEN_PASSIVE -1 556059Samurai 5644305Sbrian#define FSM_REQ_TIMER 1 5744305Sbrian#define FSM_TRM_TIMER 2 5844305Sbrian 5994894Sbrian#define FSM_OPTLEN 100 6094894Sbrian 6136285Sbrianstruct fsm; 6236285Sbrian 6344305Sbrianstruct fsm_retry { 6444305Sbrian u_int timeout; /* FSM retry frequency */ 6544305Sbrian u_int maxreq; /* Max Config REQ retries */ 6644305Sbrian u_int maxtrm; /* Max Term REQ retries */ 6744305Sbrian}; 6844305Sbrian 6936285Sbrianstruct fsm_decode { 7094894Sbrian u_char ack[FSM_OPTLEN], *ackend; 7194894Sbrian u_char nak[FSM_OPTLEN], *nakend; 7294894Sbrian u_char rej[FSM_OPTLEN], *rejend; 7336285Sbrian}; 7436285Sbrian 7536285Sbrianstruct fsm_callbacks { 7694894Sbrian int (*LayerUp)(struct fsm *); /* Layer is now up (tlu) */ 7794894Sbrian void (*LayerDown)(struct fsm *); /* About to come down (tld) */ 7894894Sbrian void (*LayerStart)(struct fsm *); /* Layer about to start (tls) */ 7994894Sbrian void (*LayerFinish)(struct fsm *); /* Layer now down (tlf) */ 8094894Sbrian void (*InitRestartCounter)(struct fsm *, int);/* Set fsm timer load */ 8194894Sbrian void (*SendConfigReq)(struct fsm *); /* Send REQ please */ 8294894Sbrian void (*SentTerminateReq)(struct fsm *); /* Term REQ just sent */ 8394894Sbrian void (*SendTerminateAck)(struct fsm *, u_char); /* Send Term ACK please */ 8494894Sbrian void (*DecodeConfig)(struct fsm *, u_char *, u_char *, int, 8594894Sbrian struct fsm_decode *); /* Deal with incoming data */ 8694894Sbrian int (*RecvResetReq)(struct fsm *fp); /* Reset output */ 8794894Sbrian void (*RecvResetAck)(struct fsm *fp, u_char); /* Reset input */ 8836285Sbrian}; 8936285Sbrian 9036285Sbrianstruct fsm_parent { 9136285Sbrian void (*LayerStart) (void *, struct fsm *); /* tls */ 9236285Sbrian void (*LayerUp) (void *, struct fsm *); /* tlu */ 9336285Sbrian void (*LayerDown) (void *, struct fsm *); /* tld */ 9436285Sbrian void (*LayerFinish) (void *, struct fsm *); /* tlf */ 9536285Sbrian void *object; 9636285Sbrian}; 9736285Sbrian 9836285Sbrianstruct link; 9936285Sbrianstruct bundle; 10036285Sbrian 1016059Samuraistruct fsm { 10231343Sbrian const char *name; /* Name of protocol */ 1036059Samurai u_short proto; /* Protocol number */ 10436285Sbrian u_short min_code; 1056059Samurai u_short max_code; 10636285Sbrian int open_mode; /* Delay before config REQ (-1 forever) */ 107134789Sbrian unsigned state; /* State of the machine */ 10832381Sbrian u_char reqid; /* Next request id */ 10928679Sbrian int restart; /* Restart counter value */ 1106059Samurai 11144305Sbrian struct { 11244305Sbrian int reqs; /* Max config REQs before a close() */ 11344305Sbrian int naks; /* Max config NAKs before a close() */ 11444305Sbrian int rejs; /* Max config REJs before a close() */ 11544305Sbrian } more; 11644305Sbrian 1176059Samurai struct pppTimer FsmTimer; /* Restart Timer */ 11832658Sbrian struct pppTimer OpenTimer; /* Delay before opening */ 1196059Samurai 12028461Sbrian /* 12128461Sbrian * This timer times the ST_STOPPED state out after the given value 12228679Sbrian * (specified via "set stopped ..."). Although this isn't specified in the 12328679Sbrian * rfc, the rfc *does* say that "the application may use higher level 12428679Sbrian * timers to avoid deadlock". The StoppedTimer takes effect when the other 12528679Sbrian * side ABENDs rather than going into ST_ACKSENT (and sending the ACK), 12628679Sbrian * causing ppp to time out and drop into ST_STOPPED. At this point, 12728679Sbrian * nothing will change this state :-( 12828461Sbrian */ 12928461Sbrian struct pppTimer StoppedTimer; 13028461Sbrian int LogLevel; 13128461Sbrian 13236285Sbrian /* The link layer active with this FSM (may be our bundle below) */ 13336285Sbrian struct link *link; 13436285Sbrian 13536285Sbrian /* Our high-level link */ 13636285Sbrian struct bundle *bundle; 13736285Sbrian 13836285Sbrian const struct fsm_parent *parent; 13936285Sbrian const struct fsm_callbacks *fn; 1406059Samurai}; 1416059Samurai 1426059Samuraistruct fsmheader { 14328679Sbrian u_char code; /* Request code */ 14428679Sbrian u_char id; /* Identification */ 14528679Sbrian u_short length; /* Length of packet */ 1466059Samurai}; 1476059Samurai 1486059Samurai#define CODE_CONFIGREQ 1 1496059Samurai#define CODE_CONFIGACK 2 1506059Samurai#define CODE_CONFIGNAK 3 1516059Samurai#define CODE_CONFIGREJ 4 1526059Samurai#define CODE_TERMREQ 5 1536059Samurai#define CODE_TERMACK 6 1546059Samurai#define CODE_CODEREJ 7 1556059Samurai#define CODE_PROTOREJ 8 15628679Sbrian#define CODE_ECHOREQ 9 /* Used in LCP */ 15728679Sbrian#define CODE_ECHOREP 10 /* Used in LCP */ 1586059Samurai#define CODE_DISCREQ 11 15928679Sbrian#define CODE_IDENT 12 /* Used in LCP Extension */ 16028679Sbrian#define CODE_TIMEREM 13 /* Used in LCP Extension */ 16128679Sbrian#define CODE_RESETREQ 14 /* Used in CCP */ 16228679Sbrian#define CODE_RESETACK 15 /* Used in CCP */ 1636059Samurai 16494894Sbrianstruct fsm_opt_hdr { 16594894Sbrian u_char id; 16694894Sbrian u_char len; 167165777Sticso} __packed; 1686059Samurai 16997141Sbrian#define MAX_FSM_OPT_LEN 52 17094894Sbrianstruct fsm_opt { 17194894Sbrian struct fsm_opt_hdr hdr; 17294894Sbrian u_char data[MAX_FSM_OPT_LEN-2]; 17394894Sbrian}; 17494894Sbrian 17594894Sbrian#define INC_FSM_OPT(ty, length, o) \ 17694894Sbrian do { \ 17794894Sbrian (o)->hdr.id = (ty); \ 17894894Sbrian (o)->hdr.len = (length); \ 17994894Sbrian (o) = (struct fsm_opt *)((u_char *)(o) + (length)); \ 18094894Sbrian } while (0) 18194894Sbrian 18294894Sbrian 18344305Sbrianextern void fsm_Init(struct fsm *, const char *, u_short, int, int, int, 18436285Sbrian struct bundle *, struct link *, const struct fsm_parent *, 18555146Sbrian struct fsm_callbacks *, const char * const [3]); 186134789Sbrianextern void fsm_Output(struct fsm *, u_int, u_int, u_char *, unsigned, int); 18736285Sbrianextern void fsm_Open(struct fsm *); 18836285Sbrianextern void fsm_Up(struct fsm *); 18936285Sbrianextern void fsm_Down(struct fsm *); 19036285Sbrianextern void fsm_Input(struct fsm *, struct mbuf *); 19136285Sbrianextern void fsm_Close(struct fsm *); 19278411Sbrianextern int fsm_NullRecvResetReq(struct fsm *); 19337060Sbrianextern void fsm_NullRecvResetAck(struct fsm *, u_char); 19437160Sbrianextern void fsm_Reopen(struct fsm *); 19537060Sbrianextern void fsm2initial(struct fsm *); 19636285Sbrianextern const char *State2Nam(u_int); 19794894Sbrianextern struct fsm_opt *fsm_readopt(u_char **); 19894894Sbrianextern void fsm_rej(struct fsm_decode *, const struct fsm_opt *); 19994894Sbrianextern void fsm_ack(struct fsm_decode *, const struct fsm_opt *); 20094894Sbrianextern void fsm_nak(struct fsm_decode *, const struct fsm_opt *); 20194894Sbrianextern void fsm_opt_normalise(struct fsm_decode *); 202