Home | History | Annotate | Download | only in src
      1 /*-
      2  * Copyright (c) 1996 - 2001 Brian Somers <brian (at) Awfulhak.org>
      3  *          based on work by Toshiharu OHNO <tony-o (at) iij.ad.jp>
      4  *                           Internet Initiative Japan, Inc (IIJ)
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  *
     28  * $FreeBSD: src/usr.sbin/ppp/fsm.h,v 1.29.14.1 2010/12/21 17:10:29 kensmith Exp $
     29  */
     30 
     31 /*
     32  *  State of machine
     33  */
     34 #define	ST_INITIAL	0
     35 #define	ST_STARTING	1
     36 #define	ST_CLOSED	2
     37 #define	ST_STOPPED	3
     38 #define	ST_CLOSING	4
     39 #define	ST_STOPPING	5
     40 #define	ST_REQSENT	6
     41 #define	ST_ACKRCVD	7
     42 #define	ST_ACKSENT	8
     43 #define	ST_OPENED	9
     44 
     45 #define	ST_MAX		10
     46 #define	ST_UNDEF	-1
     47 
     48 #define	MODE_REQ	0
     49 #define	MODE_NAK	1
     50 #define	MODE_REJ	2
     51 #define	MODE_NOP	3
     52 #define	MODE_ACK	4	/* pseudo mode for ccp negotiations */
     53 
     54 #define	OPEN_PASSIVE	-1
     55 
     56 #define FSM_REQ_TIMER	1
     57 #define FSM_TRM_TIMER	2
     58 
     59 #define FSM_OPTLEN	100
     60 
     61 struct fsm;
     62 
     63 struct fsm_retry {
     64   u_int timeout;                             /* FSM retry frequency */
     65   u_int maxreq;                              /* Max Config REQ retries */
     66   u_int maxtrm;                              /* Max Term REQ retries */
     67 };
     68 
     69 struct fsm_decode {
     70   u_char ack[FSM_OPTLEN], *ackend;
     71   u_char nak[FSM_OPTLEN], *nakend;
     72   u_char rej[FSM_OPTLEN], *rejend;
     73 };
     74 
     75 struct fsm_callbacks {
     76   int (*LayerUp)(struct fsm *);                 /* Layer is now up (tlu) */
     77   void (*LayerDown)(struct fsm *);              /* About to come down (tld) */
     78   void (*LayerStart)(struct fsm *);             /* Layer about to start (tls) */
     79   void (*LayerFinish)(struct fsm *);            /* Layer now down (tlf) */
     80   void (*InitRestartCounter)(struct fsm *, int);/* Set fsm timer load */
     81   void (*SendConfigReq)(struct fsm *);          /* Send REQ please */
     82   void (*SentTerminateReq)(struct fsm *);       /* Term REQ just sent */
     83   void (*SendTerminateAck)(struct fsm *, u_char); /* Send Term ACK please */
     84   void (*DecodeConfig)(struct fsm *, u_char *, u_char *, int,
     85                        struct fsm_decode *);    /* Deal with incoming data */
     86   int (*RecvResetReq)(struct fsm *fp);          /* Reset output */
     87   void (*RecvResetAck)(struct fsm *fp, u_char); /* Reset input */
     88 };
     89 
     90 struct fsm_parent {
     91   void (*LayerStart) (void *, struct fsm *);         /* tls */
     92   void (*LayerUp) (void *, struct fsm *);            /* tlu */
     93   void (*LayerDown) (void *, struct fsm *);          /* tld */
     94   void (*LayerFinish) (void *, struct fsm *);        /* tlf */
     95   void *object;
     96 };
     97 
     98 struct link;
     99 struct bundle;
    100 
    101 struct fsm {
    102   const char *name;		/* Name of protocol */
    103   u_short proto;		/* Protocol number */
    104   u_short min_code;
    105   u_short max_code;
    106   int open_mode;		/* Delay before config REQ (-1 forever) */
    107   unsigned state;		/* State of the machine */
    108   u_char reqid;			/* Next request id */
    109   int restart;			/* Restart counter value */
    110 
    111   struct {
    112     int reqs;			/* Max config REQs before a close() */
    113     int naks;			/* Max config NAKs before a close() */
    114     int rejs;			/* Max config REJs before a close() */
    115   } more;
    116 
    117   struct pppTimer FsmTimer;	/* Restart Timer */
    118   struct pppTimer OpenTimer;	/* Delay before opening */
    119 
    120   /*
    121    * This timer times the ST_STOPPED state out after the given value
    122    * (specified via "set stopped ...").  Although this isn't specified in the
    123    * rfc, the rfc *does* say that "the application may use higher level
    124    * timers to avoid deadlock". The StoppedTimer takes effect when the other
    125    * side ABENDs rather than going into ST_ACKSENT (and sending the ACK),
    126    * causing ppp to time out and drop into ST_STOPPED.  At this point,
    127    * nothing will change this state :-(
    128    */
    129   struct pppTimer StoppedTimer;
    130   int LogLevel;
    131 
    132   /* The link layer active with this FSM (may be our bundle below) */
    133   struct link *link;
    134 
    135   /* Our high-level link */
    136   struct bundle *bundle;
    137 
    138   const struct fsm_parent *parent;
    139   const struct fsm_callbacks *fn;
    140 };
    141 
    142 struct fsmheader {
    143   u_char code;			/* Request code */
    144   u_char id;			/* Identification */
    145   u_short length;		/* Length of packet */
    146 };
    147 
    148 #define	CODE_CONFIGREQ	1
    149 #define	CODE_CONFIGACK	2
    150 #define	CODE_CONFIGNAK	3
    151 #define	CODE_CONFIGREJ	4
    152 #define	CODE_TERMREQ	5
    153 #define	CODE_TERMACK	6
    154 #define	CODE_CODEREJ	7
    155 #define	CODE_PROTOREJ	8
    156 #define	CODE_ECHOREQ	9	/* Used in LCP */
    157 #define	CODE_ECHOREP	10	/* Used in LCP */
    158 #define	CODE_DISCREQ	11
    159 #define	CODE_IDENT	12	/* Used in LCP Extension */
    160 #define	CODE_TIMEREM	13	/* Used in LCP Extension */
    161 #define	CODE_RESETREQ	14	/* Used in CCP */
    162 #define	CODE_RESETACK	15	/* Used in CCP */
    163 
    164 struct fsm_opt_hdr {
    165   u_char id;
    166   u_char len;
    167 } __packed;
    168 
    169 #define MAX_FSM_OPT_LEN 52
    170 struct fsm_opt {
    171   struct fsm_opt_hdr hdr;
    172   u_char data[MAX_FSM_OPT_LEN-2];
    173 };
    174 
    175 #define INC_FSM_OPT(ty, length, o)                      \
    176   do {                                                  \
    177     (o)->hdr.id = (ty);                                 \
    178     (o)->hdr.len = (length);                            \
    179     (o) = (struct fsm_opt *)((u_char *)(o) + (length)); \
    180   } while (0)
    181 
    182 
    183 extern void fsm_Init(struct fsm *, const char *, u_short, int, int, int,
    184                      struct bundle *, struct link *, const  struct fsm_parent *,
    185                      struct fsm_callbacks *, const char * const [3]);
    186 extern void fsm_Output(struct fsm *, u_int, u_int, u_char *, unsigned, int);
    187 extern void fsm_Open(struct fsm *);
    188 extern void fsm_Up(struct fsm *);
    189 extern void fsm_Down(struct fsm *);
    190 extern void fsm_Input(struct fsm *, struct mbuf *);
    191 extern void fsm_Close(struct fsm *);
    192 extern int fsm_NullRecvResetReq(struct fsm *);
    193 extern void fsm_NullRecvResetAck(struct fsm *, u_char);
    194 extern void fsm_Reopen(struct fsm *);
    195 extern void fsm2initial(struct fsm *);
    196 extern const char *State2Nam(u_int);
    197 extern struct fsm_opt *fsm_readopt(u_char **);
    198 extern void fsm_rej(struct fsm_decode *, const struct fsm_opt *);
    199 extern void fsm_ack(struct fsm_decode *, const struct fsm_opt *);
    200 extern void fsm_nak(struct fsm_decode *, const struct fsm_opt *);
    201 extern void fsm_opt_normalise(struct fsm_decode *);
    202