xref: /freebsd/usr.sbin/ppp/fsm.h (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
165309e5cSBrian Somers /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
31de7b4b8SPedro F. Giffuni  *
465309e5cSBrian Somers  * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org>
565309e5cSBrian Somers  *          based on work by Toshiharu OHNO <tony-o@iij.ad.jp>
665309e5cSBrian Somers  *                           Internet Initiative Japan, Inc (IIJ)
765309e5cSBrian Somers  * All rights reserved.
8af57ed9fSAtsushi Murai  *
965309e5cSBrian Somers  * Redistribution and use in source and binary forms, with or without
1065309e5cSBrian Somers  * modification, are permitted provided that the following conditions
1165309e5cSBrian Somers  * are met:
1265309e5cSBrian Somers  * 1. Redistributions of source code must retain the above copyright
1365309e5cSBrian Somers  *    notice, this list of conditions and the following disclaimer.
1465309e5cSBrian Somers  * 2. Redistributions in binary form must reproduce the above copyright
1565309e5cSBrian Somers  *    notice, this list of conditions and the following disclaimer in the
1665309e5cSBrian Somers  *    documentation and/or other materials provided with the distribution.
17af57ed9fSAtsushi Murai  *
1865309e5cSBrian Somers  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1965309e5cSBrian Somers  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2065309e5cSBrian Somers  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2165309e5cSBrian Somers  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2265309e5cSBrian Somers  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2365309e5cSBrian Somers  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2465309e5cSBrian Somers  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2565309e5cSBrian Somers  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2665309e5cSBrian Somers  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2765309e5cSBrian Somers  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2865309e5cSBrian Somers  * SUCH DAMAGE.
29af57ed9fSAtsushi Murai  */
3053c9f6c0SAtsushi Murai 
31af57ed9fSAtsushi Murai /*
32af57ed9fSAtsushi Murai  *  State of machine
33af57ed9fSAtsushi Murai  */
34af57ed9fSAtsushi Murai #define	ST_INITIAL	0
35af57ed9fSAtsushi Murai #define	ST_STARTING	1
36af57ed9fSAtsushi Murai #define	ST_CLOSED	2
37af57ed9fSAtsushi Murai #define	ST_STOPPED	3
38af57ed9fSAtsushi Murai #define	ST_CLOSING	4
39af57ed9fSAtsushi Murai #define	ST_STOPPING	5
40af57ed9fSAtsushi Murai #define	ST_REQSENT	6
41af57ed9fSAtsushi Murai #define	ST_ACKRCVD	7
42af57ed9fSAtsushi Murai #define	ST_ACKSENT	8
43af57ed9fSAtsushi Murai #define	ST_OPENED	9
44af57ed9fSAtsushi Murai 
45af57ed9fSAtsushi Murai #define	ST_MAX		10
46af57ed9fSAtsushi Murai #define	ST_UNDEF	-1
47af57ed9fSAtsushi Murai 
48af57ed9fSAtsushi Murai #define	MODE_REQ	0
49af57ed9fSAtsushi Murai #define	MODE_NAK	1
50af57ed9fSAtsushi Murai #define	MODE_REJ	2
5153c9f6c0SAtsushi Murai #define	MODE_NOP	3
520053cc58SBrian Somers #define	MODE_ACK	4	/* pseudo mode for ccp negotiations */
53af57ed9fSAtsushi Murai 
5449b239e0SBrian Somers #define	OPEN_PASSIVE	-1
55af57ed9fSAtsushi Murai 
56479508cfSBrian Somers #define FSM_REQ_TIMER	1
57479508cfSBrian Somers #define FSM_TRM_TIMER	2
58479508cfSBrian Somers 
59ff360cc9SBrian Somers #define FSM_OPTLEN	100
60ff360cc9SBrian Somers 
6183d1af55SBrian Somers struct fsm;
6283d1af55SBrian Somers 
63479508cfSBrian Somers struct fsm_retry {
64479508cfSBrian Somers   u_int timeout;                             /* FSM retry frequency */
65479508cfSBrian Somers   u_int maxreq;                              /* Max Config REQ retries */
66479508cfSBrian Somers   u_int maxtrm;                              /* Max Term REQ retries */
67479508cfSBrian Somers };
68479508cfSBrian Somers 
6930c2f2ffSBrian Somers struct fsm_decode {
70ff360cc9SBrian Somers   u_char ack[FSM_OPTLEN], *ackend;
71ff360cc9SBrian Somers   u_char nak[FSM_OPTLEN], *nakend;
72ff360cc9SBrian Somers   u_char rej[FSM_OPTLEN], *rejend;
7330c2f2ffSBrian Somers };
7430c2f2ffSBrian Somers 
756d666775SBrian Somers struct fsm_callbacks {
766f384573SBrian Somers   int (*LayerUp)(struct fsm *);                 /* Layer is now up (tlu) */
7783d1af55SBrian Somers   void (*LayerDown)(struct fsm *);              /* About to come down (tld) */
78ff360cc9SBrian Somers   void (*LayerStart)(struct fsm *);             /* Layer about to start (tls) */
7983d1af55SBrian Somers   void (*LayerFinish)(struct fsm *);            /* Layer now down (tlf) */
80479508cfSBrian Somers   void (*InitRestartCounter)(struct fsm *, int);/* Set fsm timer load */
8183d1af55SBrian Somers   void (*SendConfigReq)(struct fsm *);          /* Send REQ please */
822267893fSBrian Somers   void (*SentTerminateReq)(struct fsm *);       /* Term REQ just sent */
832267893fSBrian Somers   void (*SendTerminateAck)(struct fsm *, u_char); /* Send Term ACK please */
84ff360cc9SBrian Somers   void (*DecodeConfig)(struct fsm *, u_char *, u_char *, int,
85ff360cc9SBrian Somers                        struct fsm_decode *);    /* Deal with incoming data */
866cf6ee76SBrian Somers   int (*RecvResetReq)(struct fsm *fp);          /* Reset output */
87503a7782SBrian Somers   void (*RecvResetAck)(struct fsm *fp, u_char); /* Reset input */
8883d1af55SBrian Somers };
8983d1af55SBrian Somers 
906d666775SBrian Somers struct fsm_parent {
916d666775SBrian Somers   void (*LayerStart) (void *, struct fsm *);         /* tls */
926d666775SBrian Somers   void (*LayerUp) (void *, struct fsm *);            /* tlu */
936d666775SBrian Somers   void (*LayerDown) (void *, struct fsm *);          /* tld */
946d666775SBrian Somers   void (*LayerFinish) (void *, struct fsm *);        /* tlf */
956d666775SBrian Somers   void *object;
966d666775SBrian Somers };
976d666775SBrian Somers 
982764b86aSBrian Somers struct link;
992764b86aSBrian Somers struct bundle;
1002764b86aSBrian Somers 
101af57ed9fSAtsushi Murai struct fsm {
102b6e82f33SBrian Somers   const char *name;		/* Name of protocol */
103af57ed9fSAtsushi Murai   u_short proto;		/* Protocol number */
1043b0f8d2eSBrian Somers   u_short min_code;
105af57ed9fSAtsushi Murai   u_short max_code;
1067308ec68SBrian Somers   int open_mode;		/* Delay before config REQ (-1 forever) */
107057f1760SBrian Somers   unsigned state;		/* State of the machine */
10898baf7c8SBrian Somers   u_char reqid;			/* Next request id */
109af57ed9fSAtsushi Murai   int restart;			/* Restart counter value */
110479508cfSBrian Somers 
111479508cfSBrian Somers   struct {
112479508cfSBrian Somers     int reqs;			/* Max config REQs before a close() */
113479508cfSBrian Somers     int naks;			/* Max config NAKs before a close() */
114479508cfSBrian Somers     int rejs;			/* Max config REJs before a close() */
115479508cfSBrian Somers   } more;
116af57ed9fSAtsushi Murai 
117af57ed9fSAtsushi Murai   struct pppTimer FsmTimer;	/* Restart Timer */
11849b239e0SBrian Somers   struct pppTimer OpenTimer;	/* Delay before opening */
119af57ed9fSAtsushi Murai 
120cb611434SBrian Somers   /*
121cb611434SBrian Somers    * This timer times the ST_STOPPED state out after the given value
122944f7098SBrian Somers    * (specified via "set stopped ...").  Although this isn't specified in the
123944f7098SBrian Somers    * rfc, the rfc *does* say that "the application may use higher level
124944f7098SBrian Somers    * timers to avoid deadlock". The StoppedTimer takes effect when the other
125944f7098SBrian Somers    * side ABENDs rather than going into ST_ACKSENT (and sending the ACK),
126944f7098SBrian Somers    * causing ppp to time out and drop into ST_STOPPED.  At this point,
127944f7098SBrian Somers    * nothing will change this state :-(
128cb611434SBrian Somers    */
129cb611434SBrian Somers   struct pppTimer StoppedTimer;
130cb611434SBrian Somers   int LogLevel;
131cb611434SBrian Somers 
1327a6f8720SBrian Somers   /* The link layer active with this FSM (may be our bundle below) */
1338c07a7b2SBrian Somers   struct link *link;
13463b73463SBrian Somers 
1357a6f8720SBrian Somers   /* Our high-level link */
1367a6f8720SBrian Somers   struct bundle *bundle;
1377a6f8720SBrian Somers 
1386d666775SBrian Somers   const struct fsm_parent *parent;
13983d1af55SBrian Somers   const struct fsm_callbacks *fn;
140af57ed9fSAtsushi Murai };
141af57ed9fSAtsushi Murai 
142af57ed9fSAtsushi Murai struct fsmheader {
143af57ed9fSAtsushi Murai   u_char code;			/* Request code */
144af57ed9fSAtsushi Murai   u_char id;			/* Identification */
145af57ed9fSAtsushi Murai   u_short length;		/* Length of packet */
146af57ed9fSAtsushi Murai };
147af57ed9fSAtsushi Murai 
148af57ed9fSAtsushi Murai #define	CODE_CONFIGREQ	1
149af57ed9fSAtsushi Murai #define	CODE_CONFIGACK	2
150af57ed9fSAtsushi Murai #define	CODE_CONFIGNAK	3
151af57ed9fSAtsushi Murai #define	CODE_CONFIGREJ	4
152af57ed9fSAtsushi Murai #define	CODE_TERMREQ	5
153af57ed9fSAtsushi Murai #define	CODE_TERMACK	6
154af57ed9fSAtsushi Murai #define	CODE_CODEREJ	7
155af57ed9fSAtsushi Murai #define	CODE_PROTOREJ	8
156af57ed9fSAtsushi Murai #define	CODE_ECHOREQ	9	/* Used in LCP */
157af57ed9fSAtsushi Murai #define	CODE_ECHOREP	10	/* Used in LCP */
158af57ed9fSAtsushi Murai #define	CODE_DISCREQ	11
159af57ed9fSAtsushi Murai #define	CODE_IDENT	12	/* Used in LCP Extension */
160af57ed9fSAtsushi Murai #define	CODE_TIMEREM	13	/* Used in LCP Extension */
161af57ed9fSAtsushi Murai #define	CODE_RESETREQ	14	/* Used in CCP */
162af57ed9fSAtsushi Murai #define	CODE_RESETACK	15	/* Used in CCP */
163af57ed9fSAtsushi Murai 
164ff360cc9SBrian Somers struct fsm_opt_hdr {
165ff360cc9SBrian Somers   u_char id;
166ff360cc9SBrian Somers   u_char len;
167f219cbb7SBernd Walter } __packed;
168af57ed9fSAtsushi Murai 
169d4ff125fSBrian Somers #define MAX_FSM_OPT_LEN 52
170ff360cc9SBrian Somers struct fsm_opt {
171ff360cc9SBrian Somers   struct fsm_opt_hdr hdr;
172ff360cc9SBrian Somers   u_char data[MAX_FSM_OPT_LEN-2];
173ff360cc9SBrian Somers };
174ff360cc9SBrian Somers 
175ff360cc9SBrian Somers #define INC_FSM_OPT(ty, length, o)                      \
176ff360cc9SBrian Somers   do {                                                  \
177ff360cc9SBrian Somers     (o)->hdr.id = (ty);                                 \
178ff360cc9SBrian Somers     (o)->hdr.len = (length);                            \
179ff360cc9SBrian Somers     (o) = (struct fsm_opt *)((u_char *)(o) + (length)); \
180ff360cc9SBrian Somers   } while (0)
181ff360cc9SBrian Somers 
182ff360cc9SBrian Somers 
183479508cfSBrian Somers extern void fsm_Init(struct fsm *, const char *, u_short, int, int, int,
1846d666775SBrian Somers                      struct bundle *, struct link *, const  struct fsm_parent *,
185182c898aSBrian Somers                      struct fsm_callbacks *, const char * const [3]);
186057f1760SBrian Somers extern void fsm_Output(struct fsm *, u_int, u_int, u_char *, unsigned, int);
187dd7e2610SBrian Somers extern void fsm_Open(struct fsm *);
188dd7e2610SBrian Somers extern void fsm_Up(struct fsm *);
189dd7e2610SBrian Somers extern void fsm_Down(struct fsm *);
190dd7e2610SBrian Somers extern void fsm_Input(struct fsm *, struct mbuf *);
191dd7e2610SBrian Somers extern void fsm_Close(struct fsm *);
1926cf6ee76SBrian Somers extern int fsm_NullRecvResetReq(struct fsm *);
19309206a6fSBrian Somers extern void fsm_NullRecvResetAck(struct fsm *, u_char);
194897f9429SBrian Somers extern void fsm_Reopen(struct fsm *);
19509206a6fSBrian Somers extern void fsm2initial(struct fsm *);
1961e991daaSBrian Somers extern const char *State2Nam(u_int);
197ff360cc9SBrian Somers extern struct fsm_opt *fsm_readopt(u_char **);
198ff360cc9SBrian Somers extern void fsm_rej(struct fsm_decode *, const struct fsm_opt *);
199ff360cc9SBrian Somers extern void fsm_ack(struct fsm_decode *, const struct fsm_opt *);
200ff360cc9SBrian Somers extern void fsm_nak(struct fsm_decode *, const struct fsm_opt *);
201ff360cc9SBrian Somers extern void fsm_opt_normalise(struct fsm_decode *);
202