Official mbed lwIP library (version 1.4.0)

Dependents:   LwIPNetworking NetServicesMin EthernetInterface EthernetInterface_RSF ... more

Legacy Networking Libraries

This is an mbed 2 networking library. For mbed OS 5, lwip has been integrated with built-in networking interfaces. The networking libraries have been revised to better support additional network stacks and thread safety here.

This library is based on the code of lwIP v1.4.0

Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
All rights reserved. 

Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
   derived from this software without specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
OF SUCH DAMAGE.
Committer:
mbed_official
Date:
Mon Mar 14 16:15:36 2016 +0000
Revision:
20:08f08bfc3f3d
Parent:
0:51ac1d130fd4
Synchronized with git revision fec574a5ed6db26aca1b13992ff271bf527d4a0d

Full URL: https://github.com/mbedmicro/mbed/commit/fec574a5ed6db26aca1b13992ff271bf527d4a0d/

Increased allocated netbufs to handle DTLS handshakes

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 */