dev

Dependents:   EthernetInterface

Fork of lwip by mbed official

Committer:
mbed_official
Date:
Fri Jun 22 09:25:39 2012 +0000
Revision:
0:51ac1d130fd4
Initial import from lwip-1.4.0: http://download.savannah.gnu.org/releases/lwip/lwip-1.4.0.zip

Who changed what in which revision?

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