User | Revision | Line number | New contents of line |
mbed714 |
0:d616ece2d859
|
1
|
/*****************************************************************************
|
mbed714 |
0:d616ece2d859
|
2
|
* fsm.c - Network Control Protocol Finite State Machine program file.
|
mbed714 |
0:d616ece2d859
|
3
|
*
|
mbed714 |
0:d616ece2d859
|
4
|
* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
|
mbed714 |
0:d616ece2d859
|
5
|
* portions Copyright (c) 1997 by Global Election Systems Inc.
|
mbed714 |
0:d616ece2d859
|
6
|
*
|
mbed714 |
0:d616ece2d859
|
7
|
* The authors hereby grant permission to use, copy, modify, distribute,
|
mbed714 |
0:d616ece2d859
|
8
|
* and license this software and its documentation for any purpose, provided
|
mbed714 |
0:d616ece2d859
|
9
|
* that existing copyright notices are retained in all copies and that this
|
mbed714 |
0:d616ece2d859
|
10
|
* notice and the following disclaimer are included verbatim in any
|
mbed714 |
0:d616ece2d859
|
11
|
* distributions. No written agreement, license, or royalty fee is required
|
mbed714 |
0:d616ece2d859
|
12
|
* for any of the authorized uses.
|
mbed714 |
0:d616ece2d859
|
13
|
*
|
mbed714 |
0:d616ece2d859
|
14
|
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
|
mbed714 |
0:d616ece2d859
|
15
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
mbed714 |
0:d616ece2d859
|
16
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
mbed714 |
0:d616ece2d859
|
17
|
* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
mbed714 |
0:d616ece2d859
|
18
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
mbed714 |
0:d616ece2d859
|
19
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
mbed714 |
0:d616ece2d859
|
20
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
mbed714 |
0:d616ece2d859
|
21
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
mbed714 |
0:d616ece2d859
|
22
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
mbed714 |
0:d616ece2d859
|
23
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
mbed714 |
0:d616ece2d859
|
24
|
*
|
mbed714 |
0:d616ece2d859
|
25
|
******************************************************************************
|
mbed714 |
0:d616ece2d859
|
26
|
* REVISION HISTORY
|
mbed714 |
0:d616ece2d859
|
27
|
*
|
mbed714 |
0:d616ece2d859
|
28
|
* 03-01-01 Marc Boucher <marc@mbsi.ca>
|
mbed714 |
0:d616ece2d859
|
29
|
* Ported to lwIP.
|
mbed714 |
0:d616ece2d859
|
30
|
* 97-12-01 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
|
mbed714 |
0:d616ece2d859
|
31
|
* Original based on BSD fsm.c.
|
mbed714 |
0:d616ece2d859
|
32
|
*****************************************************************************/
|
mbed714 |
0:d616ece2d859
|
33
|
/*
|
mbed714 |
0:d616ece2d859
|
34
|
* fsm.c - {Link, IP} Control Protocol Finite State Machine.
|
mbed714 |
0:d616ece2d859
|
35
|
*
|
mbed714 |
0:d616ece2d859
|
36
|
* Copyright (c) 1989 Carnegie Mellon University.
|
mbed714 |
0:d616ece2d859
|
37
|
* All rights reserved.
|
mbed714 |
0:d616ece2d859
|
38
|
*
|
mbed714 |
0:d616ece2d859
|
39
|
* Redistribution and use in source and binary forms are permitted
|
mbed714 |
0:d616ece2d859
|
40
|
* provided that the above copyright notice and this paragraph are
|
mbed714 |
0:d616ece2d859
|
41
|
* duplicated in all such forms and that any documentation,
|
mbed714 |
0:d616ece2d859
|
42
|
* advertising materials, and other materials related to such
|
mbed714 |
0:d616ece2d859
|
43
|
* distribution and use acknowledge that the software was developed
|
mbed714 |
0:d616ece2d859
|
44
|
* by Carnegie Mellon University. The name of the
|
mbed714 |
0:d616ece2d859
|
45
|
* University may not be used to endorse or promote products derived
|
mbed714 |
0:d616ece2d859
|
46
|
* from this software without specific prior written permission.
|
mbed714 |
0:d616ece2d859
|
47
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
mbed714 |
0:d616ece2d859
|
48
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
mbed714 |
0:d616ece2d859
|
49
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
mbed714 |
0:d616ece2d859
|
50
|
*/
|
mbed714 |
0:d616ece2d859
|
51
|
|
mbed714 |
0:d616ece2d859
|
52
|
/*
|
mbed714 |
0:d616ece2d859
|
53
|
* TODO:
|
mbed714 |
0:d616ece2d859
|
54
|
* Randomize fsm id on link/init.
|
mbed714 |
0:d616ece2d859
|
55
|
* Deal with variable outgoing MTU.
|
mbed714 |
0:d616ece2d859
|
56
|
*/
|
mbed714 |
0:d616ece2d859
|
57
|
|
mbed714 |
0:d616ece2d859
|
58
|
#include "lwip/opt.h"
|
mbed714 |
0:d616ece2d859
|
59
|
|
mbed714 |
0:d616ece2d859
|
60
|
#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
|
mbed714 |
0:d616ece2d859
|
61
|
|
mbed714 |
0:d616ece2d859
|
62
|
#include "ppp.h"
|
mbed714 |
0:d616ece2d859
|
63
|
#include "pppdebug.h"
|
mbed714 |
0:d616ece2d859
|
64
|
|
mbed714 |
0:d616ece2d859
|
65
|
#include "fsm.h"
|
mbed714 |
0:d616ece2d859
|
66
|
|
mbed714 |
0:d616ece2d859
|
67
|
#include <string.h>
|
mbed714 |
0:d616ece2d859
|
68
|
|
mbed714 |
0:d616ece2d859
|
69
|
#if PPP_DEBUG
|
mbed714 |
0:d616ece2d859
|
70
|
static const char *ppperr_strerr[] = {
|
mbed714 |
0:d616ece2d859
|
71
|
"LS_INITIAL", /* LS_INITIAL 0 */
|
mbed714 |
0:d616ece2d859
|
72
|
"LS_STARTING", /* LS_STARTING 1 */
|
mbed714 |
0:d616ece2d859
|
73
|
"LS_CLOSED", /* LS_CLOSED 2 */
|
mbed714 |
0:d616ece2d859
|
74
|
"LS_STOPPED", /* LS_STOPPED 3 */
|
mbed714 |
0:d616ece2d859
|
75
|
"LS_CLOSING", /* LS_CLOSING 4 */
|
mbed714 |
0:d616ece2d859
|
76
|
"LS_STOPPING", /* LS_STOPPING 5 */
|
mbed714 |
0:d616ece2d859
|
77
|
"LS_REQSENT", /* LS_REQSENT 6 */
|
mbed714 |
0:d616ece2d859
|
78
|
"LS_ACKRCVD", /* LS_ACKRCVD 7 */
|
mbed714 |
0:d616ece2d859
|
79
|
"LS_ACKSENT", /* LS_ACKSENT 8 */
|
mbed714 |
0:d616ece2d859
|
80
|
"LS_OPENED" /* LS_OPENED 9 */
|
mbed714 |
0:d616ece2d859
|
81
|
};
|
mbed714 |
0:d616ece2d859
|
82
|
#endif /* PPP_DEBUG */
|
mbed714 |
0:d616ece2d859
|
83
|
|
mbed714 |
0:d616ece2d859
|
84
|
static void fsm_timeout (void *);
|
mbed714 |
0:d616ece2d859
|
85
|
static void fsm_rconfreq (fsm *, u_char, u_char *, int);
|
mbed714 |
0:d616ece2d859
|
86
|
static void fsm_rconfack (fsm *, int, u_char *, int);
|
mbed714 |
0:d616ece2d859
|
87
|
static void fsm_rconfnakrej (fsm *, int, int, u_char *, int);
|
mbed714 |
0:d616ece2d859
|
88
|
static void fsm_rtermreq (fsm *, int, u_char *, int);
|
mbed714 |
0:d616ece2d859
|
89
|
static void fsm_rtermack (fsm *);
|
mbed714 |
0:d616ece2d859
|
90
|
static void fsm_rcoderej (fsm *, u_char *, int);
|
mbed714 |
0:d616ece2d859
|
91
|
static void fsm_sconfreq (fsm *, int);
|
mbed714 |
0:d616ece2d859
|
92
|
|
mbed714 |
0:d616ece2d859
|
93
|
#define PROTO_NAME(f) ((f)->callbacks->proto_name)
|
mbed714 |
0:d616ece2d859
|
94
|
|
mbed714 |
0:d616ece2d859
|
95
|
int peer_mru[NUM_PPP];
|
mbed714 |
0:d616ece2d859
|
96
|
|
mbed714 |
0:d616ece2d859
|
97
|
|
mbed714 |
0:d616ece2d859
|
98
|
/*
|
mbed714 |
0:d616ece2d859
|
99
|
* fsm_init - Initialize fsm.
|
mbed714 |
0:d616ece2d859
|
100
|
*
|
mbed714 |
0:d616ece2d859
|
101
|
* Initialize fsm state.
|
mbed714 |
0:d616ece2d859
|
102
|
*/
|
mbed714 |
0:d616ece2d859
|
103
|
void
|
mbed714 |
0:d616ece2d859
|
104
|
fsm_init(fsm *f)
|
mbed714 |
0:d616ece2d859
|
105
|
{
|
mbed714 |
0:d616ece2d859
|
106
|
f->state = LS_INITIAL;
|
mbed714 |
0:d616ece2d859
|
107
|
f->flags = 0;
|
mbed714 |
0:d616ece2d859
|
108
|
f->id = 0; /* XXX Start with random id? */
|
mbed714 |
0:d616ece2d859
|
109
|
f->timeouttime = FSM_DEFTIMEOUT;
|
mbed714 |
0:d616ece2d859
|
110
|
f->maxconfreqtransmits = FSM_DEFMAXCONFREQS;
|
mbed714 |
0:d616ece2d859
|
111
|
f->maxtermtransmits = FSM_DEFMAXTERMREQS;
|
mbed714 |
0:d616ece2d859
|
112
|
f->maxnakloops = FSM_DEFMAXNAKLOOPS;
|
mbed714 |
0:d616ece2d859
|
113
|
f->term_reason_len = 0;
|
mbed714 |
0:d616ece2d859
|
114
|
}
|
mbed714 |
0:d616ece2d859
|
115
|
|
mbed714 |
0:d616ece2d859
|
116
|
|
mbed714 |
0:d616ece2d859
|
117
|
/*
|
mbed714 |
0:d616ece2d859
|
118
|
* fsm_lowerup - The lower layer is up.
|
mbed714 |
0:d616ece2d859
|
119
|
*/
|
mbed714 |
0:d616ece2d859
|
120
|
void
|
mbed714 |
0:d616ece2d859
|
121
|
fsm_lowerup(fsm *f)
|
mbed714 |
0:d616ece2d859
|
122
|
{
|
mbed714 |
0:d616ece2d859
|
123
|
int oldState = f->state;
|
mbed714 |
0:d616ece2d859
|
124
|
|
mbed714 |
0:d616ece2d859
|
125
|
LWIP_UNUSED_ARG(oldState);
|
mbed714 |
0:d616ece2d859
|
126
|
|
mbed714 |
0:d616ece2d859
|
127
|
switch( f->state ) {
|
mbed714 |
0:d616ece2d859
|
128
|
case LS_INITIAL:
|
mbed714 |
0:d616ece2d859
|
129
|
f->state = LS_CLOSED;
|
mbed714 |
0:d616ece2d859
|
130
|
break;
|
mbed714 |
0:d616ece2d859
|
131
|
|
mbed714 |
0:d616ece2d859
|
132
|
case LS_STARTING:
|
mbed714 |
0:d616ece2d859
|
133
|
if( f->flags & OPT_SILENT ) {
|
mbed714 |
0:d616ece2d859
|
134
|
f->state = LS_STOPPED;
|
mbed714 |
0:d616ece2d859
|
135
|
} else {
|
mbed714 |
0:d616ece2d859
|
136
|
/* Send an initial configure-request */
|
mbed714 |
0:d616ece2d859
|
137
|
fsm_sconfreq(f, 0);
|
mbed714 |
0:d616ece2d859
|
138
|
f->state = LS_REQSENT;
|
mbed714 |
0:d616ece2d859
|
139
|
}
|
mbed714 |
0:d616ece2d859
|
140
|
break;
|
mbed714 |
0:d616ece2d859
|
141
|
|
mbed714 |
0:d616ece2d859
|
142
|
default:
|
mbed714 |
0:d616ece2d859
|
143
|
FSMDEBUG(LOG_INFO, ("%s: Up event in state %d (%s)!\n",
|
mbed714 |
0:d616ece2d859
|
144
|
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
145
|
}
|
mbed714 |
0:d616ece2d859
|
146
|
|
mbed714 |
0:d616ece2d859
|
147
|
FSMDEBUG(LOG_INFO, ("%s: lowerup state %d (%s) -> %d (%s)\n",
|
mbed714 |
0:d616ece2d859
|
148
|
PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
149
|
}
|
mbed714 |
0:d616ece2d859
|
150
|
|
mbed714 |
0:d616ece2d859
|
151
|
|
mbed714 |
0:d616ece2d859
|
152
|
/*
|
mbed714 |
0:d616ece2d859
|
153
|
* fsm_lowerdown - The lower layer is down.
|
mbed714 |
0:d616ece2d859
|
154
|
*
|
mbed714 |
0:d616ece2d859
|
155
|
* Cancel all timeouts and inform upper layers.
|
mbed714 |
0:d616ece2d859
|
156
|
*/
|
mbed714 |
0:d616ece2d859
|
157
|
void
|
mbed714 |
0:d616ece2d859
|
158
|
fsm_lowerdown(fsm *f)
|
mbed714 |
0:d616ece2d859
|
159
|
{
|
mbed714 |
0:d616ece2d859
|
160
|
int oldState = f->state;
|
mbed714 |
0:d616ece2d859
|
161
|
|
mbed714 |
0:d616ece2d859
|
162
|
LWIP_UNUSED_ARG(oldState);
|
mbed714 |
0:d616ece2d859
|
163
|
|
mbed714 |
0:d616ece2d859
|
164
|
switch( f->state ) {
|
mbed714 |
0:d616ece2d859
|
165
|
case LS_CLOSED:
|
mbed714 |
0:d616ece2d859
|
166
|
f->state = LS_INITIAL;
|
mbed714 |
0:d616ece2d859
|
167
|
break;
|
mbed714 |
0:d616ece2d859
|
168
|
|
mbed714 |
0:d616ece2d859
|
169
|
case LS_STOPPED:
|
mbed714 |
0:d616ece2d859
|
170
|
f->state = LS_STARTING;
|
mbed714 |
0:d616ece2d859
|
171
|
if( f->callbacks->starting ) {
|
mbed714 |
0:d616ece2d859
|
172
|
(*f->callbacks->starting)(f);
|
mbed714 |
0:d616ece2d859
|
173
|
}
|
mbed714 |
0:d616ece2d859
|
174
|
break;
|
mbed714 |
0:d616ece2d859
|
175
|
|
mbed714 |
0:d616ece2d859
|
176
|
case LS_CLOSING:
|
mbed714 |
0:d616ece2d859
|
177
|
f->state = LS_INITIAL;
|
mbed714 |
0:d616ece2d859
|
178
|
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
mbed714 |
0:d616ece2d859
|
179
|
break;
|
mbed714 |
0:d616ece2d859
|
180
|
|
mbed714 |
0:d616ece2d859
|
181
|
case LS_STOPPING:
|
mbed714 |
0:d616ece2d859
|
182
|
case LS_REQSENT:
|
mbed714 |
0:d616ece2d859
|
183
|
case LS_ACKRCVD:
|
mbed714 |
0:d616ece2d859
|
184
|
case LS_ACKSENT:
|
mbed714 |
0:d616ece2d859
|
185
|
f->state = LS_STARTING;
|
mbed714 |
0:d616ece2d859
|
186
|
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
mbed714 |
0:d616ece2d859
|
187
|
break;
|
mbed714 |
0:d616ece2d859
|
188
|
|
mbed714 |
0:d616ece2d859
|
189
|
case LS_OPENED:
|
mbed714 |
0:d616ece2d859
|
190
|
if( f->callbacks->down ) {
|
mbed714 |
0:d616ece2d859
|
191
|
(*f->callbacks->down)(f);
|
mbed714 |
0:d616ece2d859
|
192
|
}
|
mbed714 |
0:d616ece2d859
|
193
|
f->state = LS_STARTING;
|
mbed714 |
0:d616ece2d859
|
194
|
break;
|
mbed714 |
0:d616ece2d859
|
195
|
|
mbed714 |
0:d616ece2d859
|
196
|
default:
|
mbed714 |
0:d616ece2d859
|
197
|
FSMDEBUG(LOG_INFO, ("%s: Down event in state %d (%s)!\n",
|
mbed714 |
0:d616ece2d859
|
198
|
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
199
|
}
|
mbed714 |
0:d616ece2d859
|
200
|
|
mbed714 |
0:d616ece2d859
|
201
|
FSMDEBUG(LOG_INFO, ("%s: lowerdown state %d (%s) -> %d (%s)\n",
|
mbed714 |
0:d616ece2d859
|
202
|
PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
203
|
}
|
mbed714 |
0:d616ece2d859
|
204
|
|
mbed714 |
0:d616ece2d859
|
205
|
|
mbed714 |
0:d616ece2d859
|
206
|
/*
|
mbed714 |
0:d616ece2d859
|
207
|
* fsm_open - Link is allowed to come up.
|
mbed714 |
0:d616ece2d859
|
208
|
*/
|
mbed714 |
0:d616ece2d859
|
209
|
void
|
mbed714 |
0:d616ece2d859
|
210
|
fsm_open(fsm *f)
|
mbed714 |
0:d616ece2d859
|
211
|
{
|
mbed714 |
0:d616ece2d859
|
212
|
int oldState = f->state;
|
mbed714 |
0:d616ece2d859
|
213
|
|
mbed714 |
0:d616ece2d859
|
214
|
LWIP_UNUSED_ARG(oldState);
|
mbed714 |
0:d616ece2d859
|
215
|
|
mbed714 |
0:d616ece2d859
|
216
|
switch( f->state ) {
|
mbed714 |
0:d616ece2d859
|
217
|
case LS_INITIAL:
|
mbed714 |
0:d616ece2d859
|
218
|
f->state = LS_STARTING;
|
mbed714 |
0:d616ece2d859
|
219
|
if( f->callbacks->starting ) {
|
mbed714 |
0:d616ece2d859
|
220
|
(*f->callbacks->starting)(f);
|
mbed714 |
0:d616ece2d859
|
221
|
}
|
mbed714 |
0:d616ece2d859
|
222
|
break;
|
mbed714 |
0:d616ece2d859
|
223
|
|
mbed714 |
0:d616ece2d859
|
224
|
case LS_CLOSED:
|
mbed714 |
0:d616ece2d859
|
225
|
if( f->flags & OPT_SILENT ) {
|
mbed714 |
0:d616ece2d859
|
226
|
f->state = LS_STOPPED;
|
mbed714 |
0:d616ece2d859
|
227
|
} else {
|
mbed714 |
0:d616ece2d859
|
228
|
/* Send an initial configure-request */
|
mbed714 |
0:d616ece2d859
|
229
|
fsm_sconfreq(f, 0);
|
mbed714 |
0:d616ece2d859
|
230
|
f->state = LS_REQSENT;
|
mbed714 |
0:d616ece2d859
|
231
|
}
|
mbed714 |
0:d616ece2d859
|
232
|
break;
|
mbed714 |
0:d616ece2d859
|
233
|
|
mbed714 |
0:d616ece2d859
|
234
|
case LS_CLOSING:
|
mbed714 |
0:d616ece2d859
|
235
|
f->state = LS_STOPPING;
|
mbed714 |
0:d616ece2d859
|
236
|
/* fall through */
|
mbed714 |
0:d616ece2d859
|
237
|
case LS_STOPPED:
|
mbed714 |
0:d616ece2d859
|
238
|
case LS_OPENED:
|
mbed714 |
0:d616ece2d859
|
239
|
if( f->flags & OPT_RESTART ) {
|
mbed714 |
0:d616ece2d859
|
240
|
fsm_lowerdown(f);
|
mbed714 |
0:d616ece2d859
|
241
|
fsm_lowerup(f);
|
mbed714 |
0:d616ece2d859
|
242
|
}
|
mbed714 |
0:d616ece2d859
|
243
|
break;
|
mbed714 |
0:d616ece2d859
|
244
|
}
|
mbed714 |
0:d616ece2d859
|
245
|
|
mbed714 |
0:d616ece2d859
|
246
|
FSMDEBUG(LOG_INFO, ("%s: open state %d (%s) -> %d (%s)\n",
|
mbed714 |
0:d616ece2d859
|
247
|
PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
248
|
}
|
mbed714 |
0:d616ece2d859
|
249
|
|
mbed714 |
0:d616ece2d859
|
250
|
#if 0 /* backport pppd 2.4.4b1; */
|
mbed714 |
0:d616ece2d859
|
251
|
/*
|
mbed714 |
0:d616ece2d859
|
252
|
* terminate_layer - Start process of shutting down the FSM
|
mbed714 |
0:d616ece2d859
|
253
|
*
|
mbed714 |
0:d616ece2d859
|
254
|
* Cancel any timeout running, notify upper layers we're done, and
|
mbed714 |
0:d616ece2d859
|
255
|
* send a terminate-request message as configured.
|
mbed714 |
0:d616ece2d859
|
256
|
*/
|
mbed714 |
0:d616ece2d859
|
257
|
static void
|
mbed714 |
0:d616ece2d859
|
258
|
terminate_layer(fsm *f, int nextstate)
|
mbed714 |
0:d616ece2d859
|
259
|
{
|
mbed714 |
0:d616ece2d859
|
260
|
/* @todo */
|
mbed714 |
0:d616ece2d859
|
261
|
}
|
mbed714 |
0:d616ece2d859
|
262
|
#endif
|
mbed714 |
0:d616ece2d859
|
263
|
|
mbed714 |
0:d616ece2d859
|
264
|
/*
|
mbed714 |
0:d616ece2d859
|
265
|
* fsm_close - Start closing connection.
|
mbed714 |
0:d616ece2d859
|
266
|
*
|
mbed714 |
0:d616ece2d859
|
267
|
* Cancel timeouts and either initiate close or possibly go directly to
|
mbed714 |
0:d616ece2d859
|
268
|
* the LS_CLOSED state.
|
mbed714 |
0:d616ece2d859
|
269
|
*/
|
mbed714 |
0:d616ece2d859
|
270
|
void
|
mbed714 |
0:d616ece2d859
|
271
|
fsm_close(fsm *f, char *reason)
|
mbed714 |
0:d616ece2d859
|
272
|
{
|
mbed714 |
0:d616ece2d859
|
273
|
int oldState = f->state;
|
mbed714 |
0:d616ece2d859
|
274
|
|
mbed714 |
0:d616ece2d859
|
275
|
LWIP_UNUSED_ARG(oldState);
|
mbed714 |
0:d616ece2d859
|
276
|
|
mbed714 |
0:d616ece2d859
|
277
|
f->term_reason = reason;
|
mbed714 |
0:d616ece2d859
|
278
|
f->term_reason_len = (reason == NULL ? 0 : (int)strlen(reason));
|
mbed714 |
0:d616ece2d859
|
279
|
switch( f->state ) {
|
mbed714 |
0:d616ece2d859
|
280
|
case LS_STARTING:
|
mbed714 |
0:d616ece2d859
|
281
|
f->state = LS_INITIAL;
|
mbed714 |
0:d616ece2d859
|
282
|
break;
|
mbed714 |
0:d616ece2d859
|
283
|
case LS_STOPPED:
|
mbed714 |
0:d616ece2d859
|
284
|
f->state = LS_CLOSED;
|
mbed714 |
0:d616ece2d859
|
285
|
break;
|
mbed714 |
0:d616ece2d859
|
286
|
case LS_STOPPING:
|
mbed714 |
0:d616ece2d859
|
287
|
f->state = LS_CLOSING;
|
mbed714 |
0:d616ece2d859
|
288
|
break;
|
mbed714 |
0:d616ece2d859
|
289
|
|
mbed714 |
0:d616ece2d859
|
290
|
case LS_REQSENT:
|
mbed714 |
0:d616ece2d859
|
291
|
case LS_ACKRCVD:
|
mbed714 |
0:d616ece2d859
|
292
|
case LS_ACKSENT:
|
mbed714 |
0:d616ece2d859
|
293
|
case LS_OPENED:
|
mbed714 |
0:d616ece2d859
|
294
|
if( f->state != LS_OPENED ) {
|
mbed714 |
0:d616ece2d859
|
295
|
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
mbed714 |
0:d616ece2d859
|
296
|
} else if( f->callbacks->down ) {
|
mbed714 |
0:d616ece2d859
|
297
|
(*f->callbacks->down)(f); /* Inform upper layers we're down */
|
mbed714 |
0:d616ece2d859
|
298
|
}
|
mbed714 |
0:d616ece2d859
|
299
|
/* Init restart counter, send Terminate-Request */
|
mbed714 |
0:d616ece2d859
|
300
|
f->retransmits = f->maxtermtransmits;
|
mbed714 |
0:d616ece2d859
|
301
|
fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
|
mbed714 |
0:d616ece2d859
|
302
|
(u_char *) f->term_reason, f->term_reason_len);
|
mbed714 |
0:d616ece2d859
|
303
|
TIMEOUT(fsm_timeout, f, f->timeouttime);
|
mbed714 |
0:d616ece2d859
|
304
|
--f->retransmits;
|
mbed714 |
0:d616ece2d859
|
305
|
|
mbed714 |
0:d616ece2d859
|
306
|
f->state = LS_CLOSING;
|
mbed714 |
0:d616ece2d859
|
307
|
break;
|
mbed714 |
0:d616ece2d859
|
308
|
}
|
mbed714 |
0:d616ece2d859
|
309
|
|
mbed714 |
0:d616ece2d859
|
310
|
FSMDEBUG(LOG_INFO, ("%s: close reason=%s state %d (%s) -> %d (%s)\n",
|
mbed714 |
0:d616ece2d859
|
311
|
PROTO_NAME(f), reason, oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
312
|
}
|
mbed714 |
0:d616ece2d859
|
313
|
|
mbed714 |
0:d616ece2d859
|
314
|
|
mbed714 |
0:d616ece2d859
|
315
|
/*
|
mbed714 |
0:d616ece2d859
|
316
|
* fsm_timeout - Timeout expired.
|
mbed714 |
0:d616ece2d859
|
317
|
*/
|
mbed714 |
0:d616ece2d859
|
318
|
static void
|
mbed714 |
0:d616ece2d859
|
319
|
fsm_timeout(void *arg)
|
mbed714 |
0:d616ece2d859
|
320
|
{
|
mbed714 |
0:d616ece2d859
|
321
|
fsm *f = (fsm *) arg;
|
mbed714 |
0:d616ece2d859
|
322
|
|
mbed714 |
0:d616ece2d859
|
323
|
switch (f->state) {
|
mbed714 |
0:d616ece2d859
|
324
|
case LS_CLOSING:
|
mbed714 |
0:d616ece2d859
|
325
|
case LS_STOPPING:
|
mbed714 |
0:d616ece2d859
|
326
|
if( f->retransmits <= 0 ) {
|
mbed714 |
0:d616ece2d859
|
327
|
FSMDEBUG(LOG_WARNING, ("%s: timeout sending Terminate-Request state=%d (%s)\n",
|
mbed714 |
0:d616ece2d859
|
328
|
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
329
|
/*
|
mbed714 |
0:d616ece2d859
|
330
|
* We've waited for an ack long enough. Peer probably heard us.
|
mbed714 |
0:d616ece2d859
|
331
|
*/
|
mbed714 |
0:d616ece2d859
|
332
|
f->state = (f->state == LS_CLOSING)? LS_CLOSED: LS_STOPPED;
|
mbed714 |
0:d616ece2d859
|
333
|
if( f->callbacks->finished ) {
|
mbed714 |
0:d616ece2d859
|
334
|
(*f->callbacks->finished)(f);
|
mbed714 |
0:d616ece2d859
|
335
|
}
|
mbed714 |
0:d616ece2d859
|
336
|
} else {
|
mbed714 |
0:d616ece2d859
|
337
|
FSMDEBUG(LOG_WARNING, ("%s: timeout resending Terminate-Requests state=%d (%s)\n",
|
mbed714 |
0:d616ece2d859
|
338
|
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
339
|
/* Send Terminate-Request */
|
mbed714 |
0:d616ece2d859
|
340
|
fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
|
mbed714 |
0:d616ece2d859
|
341
|
(u_char *) f->term_reason, f->term_reason_len);
|
mbed714 |
0:d616ece2d859
|
342
|
TIMEOUT(fsm_timeout, f, f->timeouttime);
|
mbed714 |
0:d616ece2d859
|
343
|
--f->retransmits;
|
mbed714 |
0:d616ece2d859
|
344
|
}
|
mbed714 |
0:d616ece2d859
|
345
|
break;
|
mbed714 |
0:d616ece2d859
|
346
|
|
mbed714 |
0:d616ece2d859
|
347
|
case LS_REQSENT:
|
mbed714 |
0:d616ece2d859
|
348
|
case LS_ACKRCVD:
|
mbed714 |
0:d616ece2d859
|
349
|
case LS_ACKSENT:
|
mbed714 |
0:d616ece2d859
|
350
|
if (f->retransmits <= 0) {
|
mbed714 |
0:d616ece2d859
|
351
|
FSMDEBUG(LOG_WARNING, ("%s: timeout sending Config-Requests state=%d (%s)\n",
|
mbed714 |
0:d616ece2d859
|
352
|
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
353
|
f->state = LS_STOPPED;
|
mbed714 |
0:d616ece2d859
|
354
|
if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) {
|
mbed714 |
0:d616ece2d859
|
355
|
(*f->callbacks->finished)(f);
|
mbed714 |
0:d616ece2d859
|
356
|
}
|
mbed714 |
0:d616ece2d859
|
357
|
} else {
|
mbed714 |
0:d616ece2d859
|
358
|
FSMDEBUG(LOG_WARNING, ("%s: timeout resending Config-Request state=%d (%s)\n",
|
mbed714 |
0:d616ece2d859
|
359
|
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
360
|
/* Retransmit the configure-request */
|
mbed714 |
0:d616ece2d859
|
361
|
if (f->callbacks->retransmit) {
|
mbed714 |
0:d616ece2d859
|
362
|
(*f->callbacks->retransmit)(f);
|
mbed714 |
0:d616ece2d859
|
363
|
}
|
mbed714 |
0:d616ece2d859
|
364
|
fsm_sconfreq(f, 1); /* Re-send Configure-Request */
|
mbed714 |
0:d616ece2d859
|
365
|
if( f->state == LS_ACKRCVD ) {
|
mbed714 |
0:d616ece2d859
|
366
|
f->state = LS_REQSENT;
|
mbed714 |
0:d616ece2d859
|
367
|
}
|
mbed714 |
0:d616ece2d859
|
368
|
}
|
mbed714 |
0:d616ece2d859
|
369
|
break;
|
mbed714 |
0:d616ece2d859
|
370
|
|
mbed714 |
0:d616ece2d859
|
371
|
default:
|
mbed714 |
0:d616ece2d859
|
372
|
FSMDEBUG(LOG_INFO, ("%s: UNHANDLED timeout event in state %d (%s)!\n",
|
mbed714 |
0:d616ece2d859
|
373
|
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
374
|
}
|
mbed714 |
0:d616ece2d859
|
375
|
}
|
mbed714 |
0:d616ece2d859
|
376
|
|
mbed714 |
0:d616ece2d859
|
377
|
|
mbed714 |
0:d616ece2d859
|
378
|
/*
|
mbed714 |
0:d616ece2d859
|
379
|
* fsm_input - Input packet.
|
mbed714 |
0:d616ece2d859
|
380
|
*/
|
mbed714 |
0:d616ece2d859
|
381
|
void
|
mbed714 |
0:d616ece2d859
|
382
|
fsm_input(fsm *f, u_char *inpacket, int l)
|
mbed714 |
0:d616ece2d859
|
383
|
{
|
mbed714 |
0:d616ece2d859
|
384
|
u_char *inp = inpacket;
|
mbed714 |
0:d616ece2d859
|
385
|
u_char code, id;
|
mbed714 |
0:d616ece2d859
|
386
|
int len;
|
mbed714 |
0:d616ece2d859
|
387
|
|
mbed714 |
0:d616ece2d859
|
388
|
/*
|
mbed714 |
0:d616ece2d859
|
389
|
* Parse header (code, id and length).
|
mbed714 |
0:d616ece2d859
|
390
|
* If packet too short, drop it.
|
mbed714 |
0:d616ece2d859
|
391
|
*/
|
mbed714 |
0:d616ece2d859
|
392
|
if (l < HEADERLEN) {
|
mbed714 |
0:d616ece2d859
|
393
|
FSMDEBUG(LOG_WARNING, ("fsm_input(%x): Rcvd short header.\n",
|
mbed714 |
0:d616ece2d859
|
394
|
f->protocol));
|
mbed714 |
0:d616ece2d859
|
395
|
return;
|
mbed714 |
0:d616ece2d859
|
396
|
}
|
mbed714 |
0:d616ece2d859
|
397
|
GETCHAR(code, inp);
|
mbed714 |
0:d616ece2d859
|
398
|
GETCHAR(id, inp);
|
mbed714 |
0:d616ece2d859
|
399
|
GETSHORT(len, inp);
|
mbed714 |
0:d616ece2d859
|
400
|
if (len < HEADERLEN) {
|
mbed714 |
0:d616ece2d859
|
401
|
FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd illegal length.\n",
|
mbed714 |
0:d616ece2d859
|
402
|
f->protocol));
|
mbed714 |
0:d616ece2d859
|
403
|
return;
|
mbed714 |
0:d616ece2d859
|
404
|
}
|
mbed714 |
0:d616ece2d859
|
405
|
if (len > l) {
|
mbed714 |
0:d616ece2d859
|
406
|
FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd short packet.\n",
|
mbed714 |
0:d616ece2d859
|
407
|
f->protocol));
|
mbed714 |
0:d616ece2d859
|
408
|
return;
|
mbed714 |
0:d616ece2d859
|
409
|
}
|
mbed714 |
0:d616ece2d859
|
410
|
len -= HEADERLEN; /* subtract header length */
|
mbed714 |
0:d616ece2d859
|
411
|
|
mbed714 |
0:d616ece2d859
|
412
|
if( f->state == LS_INITIAL || f->state == LS_STARTING ) {
|
mbed714 |
0:d616ece2d859
|
413
|
FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd packet in state %d (%s).\n",
|
mbed714 |
0:d616ece2d859
|
414
|
f->protocol, f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
415
|
return;
|
mbed714 |
0:d616ece2d859
|
416
|
}
|
mbed714 |
0:d616ece2d859
|
417
|
FSMDEBUG(LOG_INFO, ("fsm_input(%s):%d,%d,%d\n", PROTO_NAME(f), code, id, l));
|
mbed714 |
0:d616ece2d859
|
418
|
/*
|
mbed714 |
0:d616ece2d859
|
419
|
* Action depends on code.
|
mbed714 |
0:d616ece2d859
|
420
|
*/
|
mbed714 |
0:d616ece2d859
|
421
|
switch (code) {
|
mbed714 |
0:d616ece2d859
|
422
|
case CONFREQ:
|
mbed714 |
0:d616ece2d859
|
423
|
fsm_rconfreq(f, id, inp, len);
|
mbed714 |
0:d616ece2d859
|
424
|
break;
|
mbed714 |
0:d616ece2d859
|
425
|
|
mbed714 |
0:d616ece2d859
|
426
|
case CONFACK:
|
mbed714 |
0:d616ece2d859
|
427
|
fsm_rconfack(f, id, inp, len);
|
mbed714 |
0:d616ece2d859
|
428
|
break;
|
mbed714 |
0:d616ece2d859
|
429
|
|
mbed714 |
0:d616ece2d859
|
430
|
case CONFNAK:
|
mbed714 |
0:d616ece2d859
|
431
|
case CONFREJ:
|
mbed714 |
0:d616ece2d859
|
432
|
fsm_rconfnakrej(f, code, id, inp, len);
|
mbed714 |
0:d616ece2d859
|
433
|
break;
|
mbed714 |
0:d616ece2d859
|
434
|
|
mbed714 |
0:d616ece2d859
|
435
|
case TERMREQ:
|
mbed714 |
0:d616ece2d859
|
436
|
fsm_rtermreq(f, id, inp, len);
|
mbed714 |
0:d616ece2d859
|
437
|
break;
|
mbed714 |
0:d616ece2d859
|
438
|
|
mbed714 |
0:d616ece2d859
|
439
|
case TERMACK:
|
mbed714 |
0:d616ece2d859
|
440
|
fsm_rtermack(f);
|
mbed714 |
0:d616ece2d859
|
441
|
break;
|
mbed714 |
0:d616ece2d859
|
442
|
|
mbed714 |
0:d616ece2d859
|
443
|
case CODEREJ:
|
mbed714 |
0:d616ece2d859
|
444
|
fsm_rcoderej(f, inp, len);
|
mbed714 |
0:d616ece2d859
|
445
|
break;
|
mbed714 |
0:d616ece2d859
|
446
|
|
mbed714 |
0:d616ece2d859
|
447
|
default:
|
mbed714 |
0:d616ece2d859
|
448
|
FSMDEBUG(LOG_INFO, ("fsm_input(%s): default: \n", PROTO_NAME(f)));
|
mbed714 |
0:d616ece2d859
|
449
|
if( !f->callbacks->extcode ||
|
mbed714 |
0:d616ece2d859
|
450
|
!(*f->callbacks->extcode)(f, code, id, inp, len) ) {
|
mbed714 |
0:d616ece2d859
|
451
|
fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN);
|
mbed714 |
0:d616ece2d859
|
452
|
}
|
mbed714 |
0:d616ece2d859
|
453
|
break;
|
mbed714 |
0:d616ece2d859
|
454
|
}
|
mbed714 |
0:d616ece2d859
|
455
|
}
|
mbed714 |
0:d616ece2d859
|
456
|
|
mbed714 |
0:d616ece2d859
|
457
|
|
mbed714 |
0:d616ece2d859
|
458
|
/*
|
mbed714 |
0:d616ece2d859
|
459
|
* fsm_rconfreq - Receive Configure-Request.
|
mbed714 |
0:d616ece2d859
|
460
|
*/
|
mbed714 |
0:d616ece2d859
|
461
|
static void
|
mbed714 |
0:d616ece2d859
|
462
|
fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len)
|
mbed714 |
0:d616ece2d859
|
463
|
{
|
mbed714 |
0:d616ece2d859
|
464
|
int code, reject_if_disagree;
|
mbed714 |
0:d616ece2d859
|
465
|
|
mbed714 |
0:d616ece2d859
|
466
|
FSMDEBUG(LOG_INFO, ("fsm_rconfreq(%s): Rcvd id %d state=%d (%s)\n",
|
mbed714 |
0:d616ece2d859
|
467
|
PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
468
|
switch( f->state ) {
|
mbed714 |
0:d616ece2d859
|
469
|
case LS_CLOSED:
|
mbed714 |
0:d616ece2d859
|
470
|
/* Go away, we're closed */
|
mbed714 |
0:d616ece2d859
|
471
|
fsm_sdata(f, TERMACK, id, NULL, 0);
|
mbed714 |
0:d616ece2d859
|
472
|
return;
|
mbed714 |
0:d616ece2d859
|
473
|
case LS_CLOSING:
|
mbed714 |
0:d616ece2d859
|
474
|
case LS_STOPPING:
|
mbed714 |
0:d616ece2d859
|
475
|
return;
|
mbed714 |
0:d616ece2d859
|
476
|
|
mbed714 |
0:d616ece2d859
|
477
|
case LS_OPENED:
|
mbed714 |
0:d616ece2d859
|
478
|
/* Go down and restart negotiation */
|
mbed714 |
0:d616ece2d859
|
479
|
if( f->callbacks->down ) {
|
mbed714 |
0:d616ece2d859
|
480
|
(*f->callbacks->down)(f); /* Inform upper layers */
|
mbed714 |
0:d616ece2d859
|
481
|
}
|
mbed714 |
0:d616ece2d859
|
482
|
fsm_sconfreq(f, 0); /* Send initial Configure-Request */
|
mbed714 |
0:d616ece2d859
|
483
|
break;
|
mbed714 |
0:d616ece2d859
|
484
|
|
mbed714 |
0:d616ece2d859
|
485
|
case LS_STOPPED:
|
mbed714 |
0:d616ece2d859
|
486
|
/* Negotiation started by our peer */
|
mbed714 |
0:d616ece2d859
|
487
|
fsm_sconfreq(f, 0); /* Send initial Configure-Request */
|
mbed714 |
0:d616ece2d859
|
488
|
f->state = LS_REQSENT;
|
mbed714 |
0:d616ece2d859
|
489
|
break;
|
mbed714 |
0:d616ece2d859
|
490
|
}
|
mbed714 |
0:d616ece2d859
|
491
|
|
mbed714 |
0:d616ece2d859
|
492
|
/*
|
mbed714 |
0:d616ece2d859
|
493
|
* Pass the requested configuration options
|
mbed714 |
0:d616ece2d859
|
494
|
* to protocol-specific code for checking.
|
mbed714 |
0:d616ece2d859
|
495
|
*/
|
mbed714 |
0:d616ece2d859
|
496
|
if (f->callbacks->reqci) { /* Check CI */
|
mbed714 |
0:d616ece2d859
|
497
|
reject_if_disagree = (f->nakloops >= f->maxnakloops);
|
mbed714 |
0:d616ece2d859
|
498
|
code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree);
|
mbed714 |
0:d616ece2d859
|
499
|
} else if (len) {
|
mbed714 |
0:d616ece2d859
|
500
|
code = CONFREJ; /* Reject all CI */
|
mbed714 |
0:d616ece2d859
|
501
|
} else {
|
mbed714 |
0:d616ece2d859
|
502
|
code = CONFACK;
|
mbed714 |
0:d616ece2d859
|
503
|
}
|
mbed714 |
0:d616ece2d859
|
504
|
|
mbed714 |
0:d616ece2d859
|
505
|
/* send the Ack, Nak or Rej to the peer */
|
mbed714 |
0:d616ece2d859
|
506
|
fsm_sdata(f, (u_char)code, id, inp, len);
|
mbed714 |
0:d616ece2d859
|
507
|
|
mbed714 |
0:d616ece2d859
|
508
|
if (code == CONFACK) {
|
mbed714 |
0:d616ece2d859
|
509
|
if (f->state == LS_ACKRCVD) {
|
mbed714 |
0:d616ece2d859
|
510
|
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
mbed714 |
0:d616ece2d859
|
511
|
f->state = LS_OPENED;
|
mbed714 |
0:d616ece2d859
|
512
|
if (f->callbacks->up) {
|
mbed714 |
0:d616ece2d859
|
513
|
(*f->callbacks->up)(f); /* Inform upper layers */
|
mbed714 |
0:d616ece2d859
|
514
|
}
|
mbed714 |
0:d616ece2d859
|
515
|
} else {
|
mbed714 |
0:d616ece2d859
|
516
|
f->state = LS_ACKSENT;
|
mbed714 |
0:d616ece2d859
|
517
|
}
|
mbed714 |
0:d616ece2d859
|
518
|
f->nakloops = 0;
|
mbed714 |
0:d616ece2d859
|
519
|
} else {
|
mbed714 |
0:d616ece2d859
|
520
|
/* we sent CONFACK or CONFREJ */
|
mbed714 |
0:d616ece2d859
|
521
|
if (f->state != LS_ACKRCVD) {
|
mbed714 |
0:d616ece2d859
|
522
|
f->state = LS_REQSENT;
|
mbed714 |
0:d616ece2d859
|
523
|
}
|
mbed714 |
0:d616ece2d859
|
524
|
if( code == CONFNAK ) {
|
mbed714 |
0:d616ece2d859
|
525
|
++f->nakloops;
|
mbed714 |
0:d616ece2d859
|
526
|
}
|
mbed714 |
0:d616ece2d859
|
527
|
}
|
mbed714 |
0:d616ece2d859
|
528
|
}
|
mbed714 |
0:d616ece2d859
|
529
|
|
mbed714 |
0:d616ece2d859
|
530
|
|
mbed714 |
0:d616ece2d859
|
531
|
/*
|
mbed714 |
0:d616ece2d859
|
532
|
* fsm_rconfack - Receive Configure-Ack.
|
mbed714 |
0:d616ece2d859
|
533
|
*/
|
mbed714 |
0:d616ece2d859
|
534
|
static void
|
mbed714 |
0:d616ece2d859
|
535
|
fsm_rconfack(fsm *f, int id, u_char *inp, int len)
|
mbed714 |
0:d616ece2d859
|
536
|
{
|
mbed714 |
0:d616ece2d859
|
537
|
FSMDEBUG(LOG_INFO, ("fsm_rconfack(%s): Rcvd id %d state=%d (%s)\n",
|
mbed714 |
0:d616ece2d859
|
538
|
PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
539
|
|
mbed714 |
0:d616ece2d859
|
540
|
if (id != f->reqid || f->seen_ack) { /* Expected id? */
|
mbed714 |
0:d616ece2d859
|
541
|
return; /* Nope, toss... */
|
mbed714 |
0:d616ece2d859
|
542
|
}
|
mbed714 |
0:d616ece2d859
|
543
|
if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): (len == 0)) ) {
|
mbed714 |
0:d616ece2d859
|
544
|
/* Ack is bad - ignore it */
|
mbed714 |
0:d616ece2d859
|
545
|
FSMDEBUG(LOG_INFO, ("%s: received bad Ack (length %d)\n",
|
mbed714 |
0:d616ece2d859
|
546
|
PROTO_NAME(f), len));
|
mbed714 |
0:d616ece2d859
|
547
|
return;
|
mbed714 |
0:d616ece2d859
|
548
|
}
|
mbed714 |
0:d616ece2d859
|
549
|
f->seen_ack = 1;
|
mbed714 |
0:d616ece2d859
|
550
|
|
mbed714 |
0:d616ece2d859
|
551
|
switch (f->state) {
|
mbed714 |
0:d616ece2d859
|
552
|
case LS_CLOSED:
|
mbed714 |
0:d616ece2d859
|
553
|
case LS_STOPPED:
|
mbed714 |
0:d616ece2d859
|
554
|
fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
|
mbed714 |
0:d616ece2d859
|
555
|
break;
|
mbed714 |
0:d616ece2d859
|
556
|
|
mbed714 |
0:d616ece2d859
|
557
|
case LS_REQSENT:
|
mbed714 |
0:d616ece2d859
|
558
|
f->state = LS_ACKRCVD;
|
mbed714 |
0:d616ece2d859
|
559
|
f->retransmits = f->maxconfreqtransmits;
|
mbed714 |
0:d616ece2d859
|
560
|
break;
|
mbed714 |
0:d616ece2d859
|
561
|
|
mbed714 |
0:d616ece2d859
|
562
|
case LS_ACKRCVD:
|
mbed714 |
0:d616ece2d859
|
563
|
/* Huh? an extra valid Ack? oh well... */
|
mbed714 |
0:d616ece2d859
|
564
|
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
mbed714 |
0:d616ece2d859
|
565
|
fsm_sconfreq(f, 0);
|
mbed714 |
0:d616ece2d859
|
566
|
f->state = LS_REQSENT;
|
mbed714 |
0:d616ece2d859
|
567
|
break;
|
mbed714 |
0:d616ece2d859
|
568
|
|
mbed714 |
0:d616ece2d859
|
569
|
case LS_ACKSENT:
|
mbed714 |
0:d616ece2d859
|
570
|
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
mbed714 |
0:d616ece2d859
|
571
|
f->state = LS_OPENED;
|
mbed714 |
0:d616ece2d859
|
572
|
f->retransmits = f->maxconfreqtransmits;
|
mbed714 |
0:d616ece2d859
|
573
|
if (f->callbacks->up) {
|
mbed714 |
0:d616ece2d859
|
574
|
(*f->callbacks->up)(f); /* Inform upper layers */
|
mbed714 |
0:d616ece2d859
|
575
|
}
|
mbed714 |
0:d616ece2d859
|
576
|
break;
|
mbed714 |
0:d616ece2d859
|
577
|
|
mbed714 |
0:d616ece2d859
|
578
|
case LS_OPENED:
|
mbed714 |
0:d616ece2d859
|
579
|
/* Go down and restart negotiation */
|
mbed714 |
0:d616ece2d859
|
580
|
if (f->callbacks->down) {
|
mbed714 |
0:d616ece2d859
|
581
|
(*f->callbacks->down)(f); /* Inform upper layers */
|
mbed714 |
0:d616ece2d859
|
582
|
}
|
mbed714 |
0:d616ece2d859
|
583
|
fsm_sconfreq(f, 0); /* Send initial Configure-Request */
|
mbed714 |
0:d616ece2d859
|
584
|
f->state = LS_REQSENT;
|
mbed714 |
0:d616ece2d859
|
585
|
break;
|
mbed714 |
0:d616ece2d859
|
586
|
}
|
mbed714 |
0:d616ece2d859
|
587
|
}
|
mbed714 |
0:d616ece2d859
|
588
|
|
mbed714 |
0:d616ece2d859
|
589
|
|
mbed714 |
0:d616ece2d859
|
590
|
/*
|
mbed714 |
0:d616ece2d859
|
591
|
* fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
|
mbed714 |
0:d616ece2d859
|
592
|
*/
|
mbed714 |
0:d616ece2d859
|
593
|
static void
|
mbed714 |
0:d616ece2d859
|
594
|
fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len)
|
mbed714 |
0:d616ece2d859
|
595
|
{
|
mbed714 |
0:d616ece2d859
|
596
|
int (*proc) (fsm *, u_char *, int);
|
mbed714 |
0:d616ece2d859
|
597
|
int ret;
|
mbed714 |
0:d616ece2d859
|
598
|
|
mbed714 |
0:d616ece2d859
|
599
|
FSMDEBUG(LOG_INFO, ("fsm_rconfnakrej(%s): Rcvd id %d state=%d (%s)\n",
|
mbed714 |
0:d616ece2d859
|
600
|
PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
601
|
|
mbed714 |
0:d616ece2d859
|
602
|
if (id != f->reqid || f->seen_ack) { /* Expected id? */
|
mbed714 |
0:d616ece2d859
|
603
|
return; /* Nope, toss... */
|
mbed714 |
0:d616ece2d859
|
604
|
}
|
mbed714 |
0:d616ece2d859
|
605
|
proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
|
mbed714 |
0:d616ece2d859
|
606
|
if (!proc || !((ret = proc(f, inp, len)))) {
|
mbed714 |
0:d616ece2d859
|
607
|
/* Nak/reject is bad - ignore it */
|
mbed714 |
0:d616ece2d859
|
608
|
FSMDEBUG(LOG_INFO, ("%s: received bad %s (length %d)\n",
|
mbed714 |
0:d616ece2d859
|
609
|
PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));
|
mbed714 |
0:d616ece2d859
|
610
|
return;
|
mbed714 |
0:d616ece2d859
|
611
|
}
|
mbed714 |
0:d616ece2d859
|
612
|
f->seen_ack = 1;
|
mbed714 |
0:d616ece2d859
|
613
|
|
mbed714 |
0:d616ece2d859
|
614
|
switch (f->state) {
|
mbed714 |
0:d616ece2d859
|
615
|
case LS_CLOSED:
|
mbed714 |
0:d616ece2d859
|
616
|
case LS_STOPPED:
|
mbed714 |
0:d616ece2d859
|
617
|
fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
|
mbed714 |
0:d616ece2d859
|
618
|
break;
|
mbed714 |
0:d616ece2d859
|
619
|
|
mbed714 |
0:d616ece2d859
|
620
|
case LS_REQSENT:
|
mbed714 |
0:d616ece2d859
|
621
|
case LS_ACKSENT:
|
mbed714 |
0:d616ece2d859
|
622
|
/* They didn't agree to what we wanted - try another request */
|
mbed714 |
0:d616ece2d859
|
623
|
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
mbed714 |
0:d616ece2d859
|
624
|
if (ret < 0) {
|
mbed714 |
0:d616ece2d859
|
625
|
f->state = LS_STOPPED; /* kludge for stopping CCP */
|
mbed714 |
0:d616ece2d859
|
626
|
} else {
|
mbed714 |
0:d616ece2d859
|
627
|
fsm_sconfreq(f, 0); /* Send Configure-Request */
|
mbed714 |
0:d616ece2d859
|
628
|
}
|
mbed714 |
0:d616ece2d859
|
629
|
break;
|
mbed714 |
0:d616ece2d859
|
630
|
|
mbed714 |
0:d616ece2d859
|
631
|
case LS_ACKRCVD:
|
mbed714 |
0:d616ece2d859
|
632
|
/* Got a Nak/reject when we had already had an Ack?? oh well... */
|
mbed714 |
0:d616ece2d859
|
633
|
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
mbed714 |
0:d616ece2d859
|
634
|
fsm_sconfreq(f, 0);
|
mbed714 |
0:d616ece2d859
|
635
|
f->state = LS_REQSENT;
|
mbed714 |
0:d616ece2d859
|
636
|
break;
|
mbed714 |
0:d616ece2d859
|
637
|
|
mbed714 |
0:d616ece2d859
|
638
|
case LS_OPENED:
|
mbed714 |
0:d616ece2d859
|
639
|
/* Go down and restart negotiation */
|
mbed714 |
0:d616ece2d859
|
640
|
if (f->callbacks->down) {
|
mbed714 |
0:d616ece2d859
|
641
|
(*f->callbacks->down)(f); /* Inform upper layers */
|
mbed714 |
0:d616ece2d859
|
642
|
}
|
mbed714 |
0:d616ece2d859
|
643
|
fsm_sconfreq(f, 0); /* Send initial Configure-Request */
|
mbed714 |
0:d616ece2d859
|
644
|
f->state = LS_REQSENT;
|
mbed714 |
0:d616ece2d859
|
645
|
break;
|
mbed714 |
0:d616ece2d859
|
646
|
}
|
mbed714 |
0:d616ece2d859
|
647
|
}
|
mbed714 |
0:d616ece2d859
|
648
|
|
mbed714 |
0:d616ece2d859
|
649
|
|
mbed714 |
0:d616ece2d859
|
650
|
/*
|
mbed714 |
0:d616ece2d859
|
651
|
* fsm_rtermreq - Receive Terminate-Req.
|
mbed714 |
0:d616ece2d859
|
652
|
*/
|
mbed714 |
0:d616ece2d859
|
653
|
static void
|
mbed714 |
0:d616ece2d859
|
654
|
fsm_rtermreq(fsm *f, int id, u_char *p, int len)
|
mbed714 |
0:d616ece2d859
|
655
|
{
|
mbed714 |
0:d616ece2d859
|
656
|
LWIP_UNUSED_ARG(p);
|
mbed714 |
0:d616ece2d859
|
657
|
|
mbed714 |
0:d616ece2d859
|
658
|
FSMDEBUG(LOG_INFO, ("fsm_rtermreq(%s): Rcvd id %d state=%d (%s)\n",
|
mbed714 |
0:d616ece2d859
|
659
|
PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
660
|
|
mbed714 |
0:d616ece2d859
|
661
|
switch (f->state) {
|
mbed714 |
0:d616ece2d859
|
662
|
case LS_ACKRCVD:
|
mbed714 |
0:d616ece2d859
|
663
|
case LS_ACKSENT:
|
mbed714 |
0:d616ece2d859
|
664
|
f->state = LS_REQSENT; /* Start over but keep trying */
|
mbed714 |
0:d616ece2d859
|
665
|
break;
|
mbed714 |
0:d616ece2d859
|
666
|
|
mbed714 |
0:d616ece2d859
|
667
|
case LS_OPENED:
|
mbed714 |
0:d616ece2d859
|
668
|
if (len > 0) {
|
mbed714 |
0:d616ece2d859
|
669
|
FSMDEBUG(LOG_INFO, ("%s terminated by peer (%p)\n", PROTO_NAME(f), p));
|
mbed714 |
0:d616ece2d859
|
670
|
} else {
|
mbed714 |
0:d616ece2d859
|
671
|
FSMDEBUG(LOG_INFO, ("%s terminated by peer\n", PROTO_NAME(f)));
|
mbed714 |
0:d616ece2d859
|
672
|
}
|
mbed714 |
0:d616ece2d859
|
673
|
if (f->callbacks->down) {
|
mbed714 |
0:d616ece2d859
|
674
|
(*f->callbacks->down)(f); /* Inform upper layers */
|
mbed714 |
0:d616ece2d859
|
675
|
}
|
mbed714 |
0:d616ece2d859
|
676
|
f->retransmits = 0;
|
mbed714 |
0:d616ece2d859
|
677
|
f->state = LS_STOPPING;
|
mbed714 |
0:d616ece2d859
|
678
|
TIMEOUT(fsm_timeout, f, f->timeouttime);
|
mbed714 |
0:d616ece2d859
|
679
|
break;
|
mbed714 |
0:d616ece2d859
|
680
|
}
|
mbed714 |
0:d616ece2d859
|
681
|
|
mbed714 |
0:d616ece2d859
|
682
|
fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
|
mbed714 |
0:d616ece2d859
|
683
|
}
|
mbed714 |
0:d616ece2d859
|
684
|
|
mbed714 |
0:d616ece2d859
|
685
|
|
mbed714 |
0:d616ece2d859
|
686
|
/*
|
mbed714 |
0:d616ece2d859
|
687
|
* fsm_rtermack - Receive Terminate-Ack.
|
mbed714 |
0:d616ece2d859
|
688
|
*/
|
mbed714 |
0:d616ece2d859
|
689
|
static void
|
mbed714 |
0:d616ece2d859
|
690
|
fsm_rtermack(fsm *f)
|
mbed714 |
0:d616ece2d859
|
691
|
{
|
mbed714 |
0:d616ece2d859
|
692
|
FSMDEBUG(LOG_INFO, ("fsm_rtermack(%s): state=%d (%s)\n",
|
mbed714 |
0:d616ece2d859
|
693
|
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
694
|
|
mbed714 |
0:d616ece2d859
|
695
|
switch (f->state) {
|
mbed714 |
0:d616ece2d859
|
696
|
case LS_CLOSING:
|
mbed714 |
0:d616ece2d859
|
697
|
UNTIMEOUT(fsm_timeout, f);
|
mbed714 |
0:d616ece2d859
|
698
|
f->state = LS_CLOSED;
|
mbed714 |
0:d616ece2d859
|
699
|
if( f->callbacks->finished ) {
|
mbed714 |
0:d616ece2d859
|
700
|
(*f->callbacks->finished)(f);
|
mbed714 |
0:d616ece2d859
|
701
|
}
|
mbed714 |
0:d616ece2d859
|
702
|
break;
|
mbed714 |
0:d616ece2d859
|
703
|
|
mbed714 |
0:d616ece2d859
|
704
|
case LS_STOPPING:
|
mbed714 |
0:d616ece2d859
|
705
|
UNTIMEOUT(fsm_timeout, f);
|
mbed714 |
0:d616ece2d859
|
706
|
f->state = LS_STOPPED;
|
mbed714 |
0:d616ece2d859
|
707
|
if( f->callbacks->finished ) {
|
mbed714 |
0:d616ece2d859
|
708
|
(*f->callbacks->finished)(f);
|
mbed714 |
0:d616ece2d859
|
709
|
}
|
mbed714 |
0:d616ece2d859
|
710
|
break;
|
mbed714 |
0:d616ece2d859
|
711
|
|
mbed714 |
0:d616ece2d859
|
712
|
case LS_ACKRCVD:
|
mbed714 |
0:d616ece2d859
|
713
|
f->state = LS_REQSENT;
|
mbed714 |
0:d616ece2d859
|
714
|
break;
|
mbed714 |
0:d616ece2d859
|
715
|
|
mbed714 |
0:d616ece2d859
|
716
|
case LS_OPENED:
|
mbed714 |
0:d616ece2d859
|
717
|
if (f->callbacks->down) {
|
mbed714 |
0:d616ece2d859
|
718
|
(*f->callbacks->down)(f); /* Inform upper layers */
|
mbed714 |
0:d616ece2d859
|
719
|
}
|
mbed714 |
0:d616ece2d859
|
720
|
fsm_sconfreq(f, 0);
|
mbed714 |
0:d616ece2d859
|
721
|
break;
|
mbed714 |
0:d616ece2d859
|
722
|
default:
|
mbed714 |
0:d616ece2d859
|
723
|
FSMDEBUG(LOG_INFO, ("fsm_rtermack(%s): UNHANDLED state=%d (%s)!!!\n",
|
mbed714 |
0:d616ece2d859
|
724
|
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
725
|
}
|
mbed714 |
0:d616ece2d859
|
726
|
}
|
mbed714 |
0:d616ece2d859
|
727
|
|
mbed714 |
0:d616ece2d859
|
728
|
|
mbed714 |
0:d616ece2d859
|
729
|
/*
|
mbed714 |
0:d616ece2d859
|
730
|
* fsm_rcoderej - Receive an Code-Reject.
|
mbed714 |
0:d616ece2d859
|
731
|
*/
|
mbed714 |
0:d616ece2d859
|
732
|
static void
|
mbed714 |
0:d616ece2d859
|
733
|
fsm_rcoderej(fsm *f, u_char *inp, int len)
|
mbed714 |
0:d616ece2d859
|
734
|
{
|
mbed714 |
0:d616ece2d859
|
735
|
u_char code, id;
|
mbed714 |
0:d616ece2d859
|
736
|
|
mbed714 |
0:d616ece2d859
|
737
|
FSMDEBUG(LOG_INFO, ("fsm_rcoderej(%s): state=%d (%s)\n",
|
mbed714 |
0:d616ece2d859
|
738
|
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
739
|
|
mbed714 |
0:d616ece2d859
|
740
|
if (len < HEADERLEN) {
|
mbed714 |
0:d616ece2d859
|
741
|
FSMDEBUG(LOG_INFO, ("fsm_rcoderej: Rcvd short Code-Reject packet!\n"));
|
mbed714 |
0:d616ece2d859
|
742
|
return;
|
mbed714 |
0:d616ece2d859
|
743
|
}
|
mbed714 |
0:d616ece2d859
|
744
|
GETCHAR(code, inp);
|
mbed714 |
0:d616ece2d859
|
745
|
GETCHAR(id, inp);
|
mbed714 |
0:d616ece2d859
|
746
|
FSMDEBUG(LOG_WARNING, ("%s: Rcvd Code-Reject for code %d, id %d\n",
|
mbed714 |
0:d616ece2d859
|
747
|
PROTO_NAME(f), code, id));
|
mbed714 |
0:d616ece2d859
|
748
|
|
mbed714 |
0:d616ece2d859
|
749
|
if( f->state == LS_ACKRCVD ) {
|
mbed714 |
0:d616ece2d859
|
750
|
f->state = LS_REQSENT;
|
mbed714 |
0:d616ece2d859
|
751
|
}
|
mbed714 |
0:d616ece2d859
|
752
|
}
|
mbed714 |
0:d616ece2d859
|
753
|
|
mbed714 |
0:d616ece2d859
|
754
|
|
mbed714 |
0:d616ece2d859
|
755
|
/*
|
mbed714 |
0:d616ece2d859
|
756
|
* fsm_protreject - Peer doesn't speak this protocol.
|
mbed714 |
0:d616ece2d859
|
757
|
*
|
mbed714 |
0:d616ece2d859
|
758
|
* Treat this as a catastrophic error (RXJ-).
|
mbed714 |
0:d616ece2d859
|
759
|
*/
|
mbed714 |
0:d616ece2d859
|
760
|
void
|
mbed714 |
0:d616ece2d859
|
761
|
fsm_protreject(fsm *f)
|
mbed714 |
0:d616ece2d859
|
762
|
{
|
mbed714 |
0:d616ece2d859
|
763
|
switch( f->state ) {
|
mbed714 |
0:d616ece2d859
|
764
|
case LS_CLOSING:
|
mbed714 |
0:d616ece2d859
|
765
|
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
mbed714 |
0:d616ece2d859
|
766
|
/* fall through */
|
mbed714 |
0:d616ece2d859
|
767
|
case LS_CLOSED:
|
mbed714 |
0:d616ece2d859
|
768
|
f->state = LS_CLOSED;
|
mbed714 |
0:d616ece2d859
|
769
|
if( f->callbacks->finished ) {
|
mbed714 |
0:d616ece2d859
|
770
|
(*f->callbacks->finished)(f);
|
mbed714 |
0:d616ece2d859
|
771
|
}
|
mbed714 |
0:d616ece2d859
|
772
|
break;
|
mbed714 |
0:d616ece2d859
|
773
|
|
mbed714 |
0:d616ece2d859
|
774
|
case LS_STOPPING:
|
mbed714 |
0:d616ece2d859
|
775
|
case LS_REQSENT:
|
mbed714 |
0:d616ece2d859
|
776
|
case LS_ACKRCVD:
|
mbed714 |
0:d616ece2d859
|
777
|
case LS_ACKSENT:
|
mbed714 |
0:d616ece2d859
|
778
|
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
mbed714 |
0:d616ece2d859
|
779
|
/* fall through */
|
mbed714 |
0:d616ece2d859
|
780
|
case LS_STOPPED:
|
mbed714 |
0:d616ece2d859
|
781
|
f->state = LS_STOPPED;
|
mbed714 |
0:d616ece2d859
|
782
|
if( f->callbacks->finished ) {
|
mbed714 |
0:d616ece2d859
|
783
|
(*f->callbacks->finished)(f);
|
mbed714 |
0:d616ece2d859
|
784
|
}
|
mbed714 |
0:d616ece2d859
|
785
|
break;
|
mbed714 |
0:d616ece2d859
|
786
|
|
mbed714 |
0:d616ece2d859
|
787
|
case LS_OPENED:
|
mbed714 |
0:d616ece2d859
|
788
|
if( f->callbacks->down ) {
|
mbed714 |
0:d616ece2d859
|
789
|
(*f->callbacks->down)(f);
|
mbed714 |
0:d616ece2d859
|
790
|
}
|
mbed714 |
0:d616ece2d859
|
791
|
/* Init restart counter, send Terminate-Request */
|
mbed714 |
0:d616ece2d859
|
792
|
f->retransmits = f->maxtermtransmits;
|
mbed714 |
0:d616ece2d859
|
793
|
fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
|
mbed714 |
0:d616ece2d859
|
794
|
(u_char *) f->term_reason, f->term_reason_len);
|
mbed714 |
0:d616ece2d859
|
795
|
TIMEOUT(fsm_timeout, f, f->timeouttime);
|
mbed714 |
0:d616ece2d859
|
796
|
--f->retransmits;
|
mbed714 |
0:d616ece2d859
|
797
|
|
mbed714 |
0:d616ece2d859
|
798
|
f->state = LS_STOPPING;
|
mbed714 |
0:d616ece2d859
|
799
|
break;
|
mbed714 |
0:d616ece2d859
|
800
|
|
mbed714 |
0:d616ece2d859
|
801
|
default:
|
mbed714 |
0:d616ece2d859
|
802
|
FSMDEBUG(LOG_INFO, ("%s: Protocol-reject event in state %d (%s)!\n",
|
mbed714 |
0:d616ece2d859
|
803
|
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
mbed714 |
0:d616ece2d859
|
804
|
}
|
mbed714 |
0:d616ece2d859
|
805
|
}
|
mbed714 |
0:d616ece2d859
|
806
|
|
mbed714 |
0:d616ece2d859
|
807
|
|
mbed714 |
0:d616ece2d859
|
808
|
/*
|
mbed714 |
0:d616ece2d859
|
809
|
* fsm_sconfreq - Send a Configure-Request.
|
mbed714 |
0:d616ece2d859
|
810
|
*/
|
mbed714 |
0:d616ece2d859
|
811
|
static void
|
mbed714 |
0:d616ece2d859
|
812
|
fsm_sconfreq(fsm *f, int retransmit)
|
mbed714 |
0:d616ece2d859
|
813
|
{
|
mbed714 |
0:d616ece2d859
|
814
|
u_char *outp;
|
mbed714 |
0:d616ece2d859
|
815
|
int cilen;
|
mbed714 |
0:d616ece2d859
|
816
|
|
mbed714 |
0:d616ece2d859
|
817
|
if( f->state != LS_REQSENT && f->state != LS_ACKRCVD && f->state != LS_ACKSENT ) {
|
mbed714 |
0:d616ece2d859
|
818
|
/* Not currently negotiating - reset options */
|
mbed714 |
0:d616ece2d859
|
819
|
if( f->callbacks->resetci ) {
|
mbed714 |
0:d616ece2d859
|
820
|
(*f->callbacks->resetci)(f);
|
mbed714 |
0:d616ece2d859
|
821
|
}
|
mbed714 |
0:d616ece2d859
|
822
|
f->nakloops = 0;
|
mbed714 |
0:d616ece2d859
|
823
|
}
|
mbed714 |
0:d616ece2d859
|
824
|
|
mbed714 |
0:d616ece2d859
|
825
|
if( !retransmit ) {
|
mbed714 |
0:d616ece2d859
|
826
|
/* New request - reset retransmission counter, use new ID */
|
mbed714 |
0:d616ece2d859
|
827
|
f->retransmits = f->maxconfreqtransmits;
|
mbed714 |
0:d616ece2d859
|
828
|
f->reqid = ++f->id;
|
mbed714 |
0:d616ece2d859
|
829
|
}
|
mbed714 |
0:d616ece2d859
|
830
|
|
mbed714 |
0:d616ece2d859
|
831
|
f->seen_ack = 0;
|
mbed714 |
0:d616ece2d859
|
832
|
|
mbed714 |
0:d616ece2d859
|
833
|
/*
|
mbed714 |
0:d616ece2d859
|
834
|
* Make up the request packet
|
mbed714 |
0:d616ece2d859
|
835
|
*/
|
mbed714 |
0:d616ece2d859
|
836
|
outp = outpacket_buf[f->unit] + PPP_HDRLEN + HEADERLEN;
|
mbed714 |
0:d616ece2d859
|
837
|
if( f->callbacks->cilen && f->callbacks->addci ) {
|
mbed714 |
0:d616ece2d859
|
838
|
cilen = (*f->callbacks->cilen)(f);
|
mbed714 |
0:d616ece2d859
|
839
|
if( cilen > peer_mru[f->unit] - (int)HEADERLEN ) {
|
mbed714 |
0:d616ece2d859
|
840
|
cilen = peer_mru[f->unit] - HEADERLEN;
|
mbed714 |
0:d616ece2d859
|
841
|
}
|
mbed714 |
0:d616ece2d859
|
842
|
if (f->callbacks->addci) {
|
mbed714 |
0:d616ece2d859
|
843
|
(*f->callbacks->addci)(f, outp, &cilen);
|
mbed714 |
0:d616ece2d859
|
844
|
}
|
mbed714 |
0:d616ece2d859
|
845
|
} else {
|
mbed714 |
0:d616ece2d859
|
846
|
cilen = 0;
|
mbed714 |
0:d616ece2d859
|
847
|
}
|
mbed714 |
0:d616ece2d859
|
848
|
|
mbed714 |
0:d616ece2d859
|
849
|
/* send the request to our peer */
|
mbed714 |
0:d616ece2d859
|
850
|
fsm_sdata(f, CONFREQ, f->reqid, outp, cilen);
|
mbed714 |
0:d616ece2d859
|
851
|
|
mbed714 |
0:d616ece2d859
|
852
|
/* start the retransmit timer */
|
mbed714 |
0:d616ece2d859
|
853
|
--f->retransmits;
|
mbed714 |
0:d616ece2d859
|
854
|
TIMEOUT(fsm_timeout, f, f->timeouttime);
|
mbed714 |
0:d616ece2d859
|
855
|
|
mbed714 |
0:d616ece2d859
|
856
|
FSMDEBUG(LOG_INFO, ("%s: sending Configure-Request, id %d\n",
|
mbed714 |
0:d616ece2d859
|
857
|
PROTO_NAME(f), f->reqid));
|
mbed714 |
0:d616ece2d859
|
858
|
}
|
mbed714 |
0:d616ece2d859
|
859
|
|
mbed714 |
0:d616ece2d859
|
860
|
|
mbed714 |
0:d616ece2d859
|
861
|
/*
|
mbed714 |
0:d616ece2d859
|
862
|
* fsm_sdata - Send some data.
|
mbed714 |
0:d616ece2d859
|
863
|
*
|
mbed714 |
0:d616ece2d859
|
864
|
* Used for all packets sent to our peer by this module.
|
mbed714 |
0:d616ece2d859
|
865
|
*/
|
mbed714 |
0:d616ece2d859
|
866
|
void
|
mbed714 |
0:d616ece2d859
|
867
|
fsm_sdata( fsm *f, u_char code, u_char id, u_char *data, int datalen)
|
mbed714 |
0:d616ece2d859
|
868
|
{
|
mbed714 |
0:d616ece2d859
|
869
|
u_char *outp;
|
mbed714 |
0:d616ece2d859
|
870
|
int outlen;
|
mbed714 |
0:d616ece2d859
|
871
|
|
mbed714 |
0:d616ece2d859
|
872
|
/* Adjust length to be smaller than MTU */
|
mbed714 |
0:d616ece2d859
|
873
|
outp = outpacket_buf[f->unit];
|
mbed714 |
0:d616ece2d859
|
874
|
if (datalen > peer_mru[f->unit] - (int)HEADERLEN) {
|
mbed714 |
0:d616ece2d859
|
875
|
datalen = peer_mru[f->unit] - HEADERLEN;
|
mbed714 |
0:d616ece2d859
|
876
|
}
|
mbed714 |
0:d616ece2d859
|
877
|
if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) {
|
mbed714 |
0:d616ece2d859
|
878
|
BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen);
|
mbed714 |
0:d616ece2d859
|
879
|
}
|
mbed714 |
0:d616ece2d859
|
880
|
outlen = datalen + HEADERLEN;
|
mbed714 |
0:d616ece2d859
|
881
|
MAKEHEADER(outp, f->protocol);
|
mbed714 |
0:d616ece2d859
|
882
|
PUTCHAR(code, outp);
|
mbed714 |
0:d616ece2d859
|
883
|
PUTCHAR(id, outp);
|
mbed714 |
0:d616ece2d859
|
884
|
PUTSHORT(outlen, outp);
|
mbed714 |
0:d616ece2d859
|
885
|
pppWrite(f->unit, outpacket_buf[f->unit], outlen + PPP_HDRLEN);
|
mbed714 |
0:d616ece2d859
|
886
|
FSMDEBUG(LOG_INFO, ("fsm_sdata(%s): Sent code %d,%d,%d.\n",
|
mbed714 |
0:d616ece2d859
|
887
|
PROTO_NAME(f), code, id, outlen));
|
mbed714 |
0:d616ece2d859
|
888
|
}
|
mbed714 |
0:d616ece2d859
|
889
|
|
mbed714 |
0:d616ece2d859
|
890
|
#endif /* PPP_SUPPORT */
|