LwIP with PPP & Ethernet integration

Dependents:   NetworkingCoreLib

This is the mbed port of the LwIP stack: http://savannah.nongnu.org/projects/lwip/

It includes contributed content from NXP's port for LPCxxxx devices: http://www.lpcware.com/content/project/lightweight-ip-lwip-networking-stack

Licence

LwIP is licenced under the BSD licence:

Copyright (c) 2001-2004 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:
donatien
Date:
Thu May 24 15:53:48 2012 +0000
Revision:
0:8e01dca41002
Merge with Emilio's LwIp

Who changed what in which revision?

UserRevisionLine numberNew contents of line
donatien 0:8e01dca41002 1 /*****************************************************************************
donatien 0:8e01dca41002 2 * lcp.c - Network Link Control Protocol program file.
donatien 0:8e01dca41002 3 *
donatien 0:8e01dca41002 4 * Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
donatien 0:8e01dca41002 5 * portions Copyright (c) 1997 by Global Election Systems Inc.
donatien 0:8e01dca41002 6 *
donatien 0:8e01dca41002 7 * The authors hereby grant permission to use, copy, modify, distribute,
donatien 0:8e01dca41002 8 * and license this software and its documentation for any purpose, provided
donatien 0:8e01dca41002 9 * that existing copyright notices are retained in all copies and that this
donatien 0:8e01dca41002 10 * notice and the following disclaimer are included verbatim in any
donatien 0:8e01dca41002 11 * distributions. No written agreement, license, or royalty fee is required
donatien 0:8e01dca41002 12 * for any of the authorized uses.
donatien 0:8e01dca41002 13 *
donatien 0:8e01dca41002 14 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
donatien 0:8e01dca41002 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
donatien 0:8e01dca41002 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
donatien 0:8e01dca41002 17 * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
donatien 0:8e01dca41002 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
donatien 0:8e01dca41002 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
donatien 0:8e01dca41002 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
donatien 0:8e01dca41002 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
donatien 0:8e01dca41002 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
donatien 0:8e01dca41002 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
donatien 0:8e01dca41002 24 *
donatien 0:8e01dca41002 25 ******************************************************************************
donatien 0:8e01dca41002 26 * REVISION HISTORY
donatien 0:8e01dca41002 27 *
donatien 0:8e01dca41002 28 * 03-01-01 Marc Boucher <marc@mbsi.ca>
donatien 0:8e01dca41002 29 * Ported to lwIP.
donatien 0:8e01dca41002 30 * 97-12-01 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
donatien 0:8e01dca41002 31 * Original.
donatien 0:8e01dca41002 32 *****************************************************************************/
donatien 0:8e01dca41002 33
donatien 0:8e01dca41002 34 /*
donatien 0:8e01dca41002 35 * lcp.c - PPP Link Control Protocol.
donatien 0:8e01dca41002 36 *
donatien 0:8e01dca41002 37 * Copyright (c) 1989 Carnegie Mellon University.
donatien 0:8e01dca41002 38 * All rights reserved.
donatien 0:8e01dca41002 39 *
donatien 0:8e01dca41002 40 * Redistribution and use in source and binary forms are permitted
donatien 0:8e01dca41002 41 * provided that the above copyright notice and this paragraph are
donatien 0:8e01dca41002 42 * duplicated in all such forms and that any documentation,
donatien 0:8e01dca41002 43 * advertising materials, and other materials related to such
donatien 0:8e01dca41002 44 * distribution and use acknowledge that the software was developed
donatien 0:8e01dca41002 45 * by Carnegie Mellon University. The name of the
donatien 0:8e01dca41002 46 * University may not be used to endorse or promote products derived
donatien 0:8e01dca41002 47 * from this software without specific prior written permission.
donatien 0:8e01dca41002 48 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
donatien 0:8e01dca41002 49 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
donatien 0:8e01dca41002 50 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
donatien 0:8e01dca41002 51 */
donatien 0:8e01dca41002 52
donatien 0:8e01dca41002 53
donatien 0:8e01dca41002 54 #include "lwip/opt.h"
donatien 0:8e01dca41002 55
donatien 0:8e01dca41002 56 #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
donatien 0:8e01dca41002 57
donatien 0:8e01dca41002 58 #include "ppp.h"
donatien 0:8e01dca41002 59 #include "pppdebug.h"
donatien 0:8e01dca41002 60
donatien 0:8e01dca41002 61 #include "fsm.h"
donatien 0:8e01dca41002 62 #include "chap.h"
donatien 0:8e01dca41002 63 #include "magic.h"
donatien 0:8e01dca41002 64 #include "auth.h"
donatien 0:8e01dca41002 65 #include "lcp.h"
donatien 0:8e01dca41002 66
donatien 0:8e01dca41002 67 #include <string.h>
donatien 0:8e01dca41002 68
donatien 0:8e01dca41002 69 #if PPPOE_SUPPORT
donatien 0:8e01dca41002 70 #include "netif/ppp_oe.h"
donatien 0:8e01dca41002 71 #else
donatien 0:8e01dca41002 72 #define PPPOE_MAXMTU PPP_MAXMRU
donatien 0:8e01dca41002 73 #endif
donatien 0:8e01dca41002 74
donatien 0:8e01dca41002 75 #if 0 /* UNUSED */
donatien 0:8e01dca41002 76 /*
donatien 0:8e01dca41002 77 * LCP-related command-line options.
donatien 0:8e01dca41002 78 */
donatien 0:8e01dca41002 79 int lcp_echo_interval = 0; /* Interval between LCP echo-requests */
donatien 0:8e01dca41002 80 int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */
donatien 0:8e01dca41002 81 bool lax_recv = 0; /* accept control chars in asyncmap */
donatien 0:8e01dca41002 82
donatien 0:8e01dca41002 83 static int setescape (char **);
donatien 0:8e01dca41002 84
donatien 0:8e01dca41002 85 static option_t lcp_option_list[] = {
donatien 0:8e01dca41002 86 /* LCP options */
donatien 0:8e01dca41002 87 /* list stripped for simplicity */
donatien 0:8e01dca41002 88 {NULL}
donatien 0:8e01dca41002 89 };
donatien 0:8e01dca41002 90 #endif /* UNUSED */
donatien 0:8e01dca41002 91
donatien 0:8e01dca41002 92 /* options */
donatien 0:8e01dca41002 93 LinkPhase lcp_phase[NUM_PPP]; /* Phase of link session (RFC 1661) */
donatien 0:8e01dca41002 94 static u_int lcp_echo_interval = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */
donatien 0:8e01dca41002 95 static u_int lcp_echo_fails = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */
donatien 0:8e01dca41002 96
donatien 0:8e01dca41002 97 /* global vars */
donatien 0:8e01dca41002 98 static fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/
donatien 0:8e01dca41002 99 lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */
donatien 0:8e01dca41002 100 lcp_options lcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
donatien 0:8e01dca41002 101 lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
donatien 0:8e01dca41002 102 lcp_options lcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
donatien 0:8e01dca41002 103 ext_accm xmit_accm[NUM_PPP]; /* extended transmit ACCM */
donatien 0:8e01dca41002 104
donatien 0:8e01dca41002 105 static u32_t lcp_echos_pending = 0; /* Number of outstanding echo msgs */
donatien 0:8e01dca41002 106 static u32_t lcp_echo_number = 0; /* ID number of next echo frame */
donatien 0:8e01dca41002 107 static u32_t lcp_echo_timer_running = 0; /* TRUE if a timer is running */
donatien 0:8e01dca41002 108
donatien 0:8e01dca41002 109 /* @todo: do we really need such a large buffer? The typical 1500 bytes seem too much. */
donatien 0:8e01dca41002 110 static u_char nak_buffer[PPP_MRU] __attribute((section("AHBSRAM1"))); //Add DG; /* where we construct a nak packet */
donatien 0:8e01dca41002 111
donatien 0:8e01dca41002 112 /*
donatien 0:8e01dca41002 113 * Callbacks for fsm code. (CI = Configuration Information)
donatien 0:8e01dca41002 114 */
donatien 0:8e01dca41002 115 static void lcp_resetci (fsm*); /* Reset our CI */
donatien 0:8e01dca41002 116 static int lcp_cilen (fsm*); /* Return length of our CI */
donatien 0:8e01dca41002 117 static void lcp_addci (fsm*, u_char*, int*); /* Add our CI to pkt */
donatien 0:8e01dca41002 118 static int lcp_ackci (fsm*, u_char*, int); /* Peer ack'd our CI */
donatien 0:8e01dca41002 119 static int lcp_nakci (fsm*, u_char*, int); /* Peer nak'd our CI */
donatien 0:8e01dca41002 120 static int lcp_rejci (fsm*, u_char*, int); /* Peer rej'd our CI */
donatien 0:8e01dca41002 121 static int lcp_reqci (fsm*, u_char*, int*, int); /* Rcv peer CI */
donatien 0:8e01dca41002 122 static void lcp_up (fsm*); /* We're UP */
donatien 0:8e01dca41002 123 static void lcp_down (fsm*); /* We're DOWN */
donatien 0:8e01dca41002 124 static void lcp_starting (fsm*); /* We need lower layer up */
donatien 0:8e01dca41002 125 static void lcp_finished (fsm*); /* We need lower layer down */
donatien 0:8e01dca41002 126 static int lcp_extcode (fsm*, int, u_char, u_char*, int);
donatien 0:8e01dca41002 127 static void lcp_rprotrej (fsm*, u_char*, int);
donatien 0:8e01dca41002 128
donatien 0:8e01dca41002 129 /*
donatien 0:8e01dca41002 130 * routines to send LCP echos to peer
donatien 0:8e01dca41002 131 */
donatien 0:8e01dca41002 132
donatien 0:8e01dca41002 133 static void lcp_echo_lowerup (int);
donatien 0:8e01dca41002 134 static void lcp_echo_lowerdown (int);
donatien 0:8e01dca41002 135 static void LcpEchoTimeout (void*);
donatien 0:8e01dca41002 136 static void lcp_received_echo_reply (fsm*, int, u_char*, int);
donatien 0:8e01dca41002 137 static void LcpSendEchoRequest (fsm*);
donatien 0:8e01dca41002 138 static void LcpLinkFailure (fsm*);
donatien 0:8e01dca41002 139 static void LcpEchoCheck (fsm*);
donatien 0:8e01dca41002 140
donatien 0:8e01dca41002 141 static fsm_callbacks lcp_callbacks = { /* LCP callback routines */
donatien 0:8e01dca41002 142 lcp_resetci, /* Reset our Configuration Information */
donatien 0:8e01dca41002 143 lcp_cilen, /* Length of our Configuration Information */
donatien 0:8e01dca41002 144 lcp_addci, /* Add our Configuration Information */
donatien 0:8e01dca41002 145 lcp_ackci, /* ACK our Configuration Information */
donatien 0:8e01dca41002 146 lcp_nakci, /* NAK our Configuration Information */
donatien 0:8e01dca41002 147 lcp_rejci, /* Reject our Configuration Information */
donatien 0:8e01dca41002 148 lcp_reqci, /* Request peer's Configuration Information */
donatien 0:8e01dca41002 149 lcp_up, /* Called when fsm reaches LS_OPENED state */
donatien 0:8e01dca41002 150 lcp_down, /* Called when fsm leaves LS_OPENED state */
donatien 0:8e01dca41002 151 lcp_starting, /* Called when we want the lower layer up */
donatien 0:8e01dca41002 152 lcp_finished, /* Called when we want the lower layer down */
donatien 0:8e01dca41002 153 NULL, /* Called when Protocol-Reject received */
donatien 0:8e01dca41002 154 NULL, /* Retransmission is necessary */
donatien 0:8e01dca41002 155 lcp_extcode, /* Called to handle LCP-specific codes */
donatien 0:8e01dca41002 156 "LCP" /* String name of protocol */
donatien 0:8e01dca41002 157 };
donatien 0:8e01dca41002 158
donatien 0:8e01dca41002 159 /*
donatien 0:8e01dca41002 160 * Protocol entry points.
donatien 0:8e01dca41002 161 * Some of these are called directly.
donatien 0:8e01dca41002 162 */
donatien 0:8e01dca41002 163
donatien 0:8e01dca41002 164 static void lcp_input (int, u_char *, int);
donatien 0:8e01dca41002 165 static void lcp_protrej (int);
donatien 0:8e01dca41002 166
donatien 0:8e01dca41002 167 struct protent lcp_protent = {
donatien 0:8e01dca41002 168 PPP_LCP,
donatien 0:8e01dca41002 169 lcp_init,
donatien 0:8e01dca41002 170 lcp_input,
donatien 0:8e01dca41002 171 lcp_protrej,
donatien 0:8e01dca41002 172 lcp_lowerup,
donatien 0:8e01dca41002 173 lcp_lowerdown,
donatien 0:8e01dca41002 174 lcp_open,
donatien 0:8e01dca41002 175 lcp_close,
donatien 0:8e01dca41002 176 #if PPP_ADDITIONAL_CALLBACKS
donatien 0:8e01dca41002 177 lcp_printpkt,
donatien 0:8e01dca41002 178 NULL,
donatien 0:8e01dca41002 179 #endif /* PPP_ADDITIONAL_CALLBACKS */
donatien 0:8e01dca41002 180 1,
donatien 0:8e01dca41002 181 "LCP",
donatien 0:8e01dca41002 182 #if PPP_ADDITIONAL_CALLBACKS
donatien 0:8e01dca41002 183 NULL,
donatien 0:8e01dca41002 184 NULL,
donatien 0:8e01dca41002 185 NULL
donatien 0:8e01dca41002 186 #endif /* PPP_ADDITIONAL_CALLBACKS */
donatien 0:8e01dca41002 187 };
donatien 0:8e01dca41002 188
donatien 0:8e01dca41002 189 int lcp_loopbackfail = DEFLOOPBACKFAIL;
donatien 0:8e01dca41002 190
donatien 0:8e01dca41002 191 /*
donatien 0:8e01dca41002 192 * Length of each type of configuration option (in octets)
donatien 0:8e01dca41002 193 */
donatien 0:8e01dca41002 194 #define CILEN_VOID 2
donatien 0:8e01dca41002 195 #define CILEN_CHAR 3
donatien 0:8e01dca41002 196 #define CILEN_SHORT 4 /* CILEN_VOID + sizeof(short) */
donatien 0:8e01dca41002 197 #define CILEN_CHAP 5 /* CILEN_VOID + sizeof(short) + 1 */
donatien 0:8e01dca41002 198 #define CILEN_LONG 6 /* CILEN_VOID + sizeof(long) */
donatien 0:8e01dca41002 199 #define CILEN_LQR 8 /* CILEN_VOID + sizeof(short) + sizeof(long) */
donatien 0:8e01dca41002 200 #define CILEN_CBCP 3
donatien 0:8e01dca41002 201
donatien 0:8e01dca41002 202 #define CODENAME(x) ((x) == CONFACK ? "ACK" : (x) == CONFNAK ? "NAK" : "REJ")
donatien 0:8e01dca41002 203
donatien 0:8e01dca41002 204 #if 0 /* UNUSED */
donatien 0:8e01dca41002 205 /*
donatien 0:8e01dca41002 206 * setescape - add chars to the set we escape on transmission.
donatien 0:8e01dca41002 207 */
donatien 0:8e01dca41002 208 static int
donatien 0:8e01dca41002 209 setescape(argv)
donatien 0:8e01dca41002 210 char **argv;
donatien 0:8e01dca41002 211 {
donatien 0:8e01dca41002 212 int n, ret;
donatien 0:8e01dca41002 213 char *p, *endp;
donatien 0:8e01dca41002 214
donatien 0:8e01dca41002 215 p = *argv;
donatien 0:8e01dca41002 216 ret = 1;
donatien 0:8e01dca41002 217 while (*p) {
donatien 0:8e01dca41002 218 n = strtol(p, &endp, 16);
donatien 0:8e01dca41002 219 if (p == endp) {
donatien 0:8e01dca41002 220 option_error("escape parameter contains invalid hex number '%s'", p);
donatien 0:8e01dca41002 221 return 0;
donatien 0:8e01dca41002 222 }
donatien 0:8e01dca41002 223 p = endp;
donatien 0:8e01dca41002 224 if (n < 0 || n == 0x5E || n > 0xFF) {
donatien 0:8e01dca41002 225 option_error("can't escape character 0x%x", n);
donatien 0:8e01dca41002 226 ret = 0;
donatien 0:8e01dca41002 227 } else
donatien 0:8e01dca41002 228 xmit_accm[0][n >> 5] |= 1 << (n & 0x1F);
donatien 0:8e01dca41002 229 while (*p == ',' || *p == ' ')
donatien 0:8e01dca41002 230 ++p;
donatien 0:8e01dca41002 231 }
donatien 0:8e01dca41002 232 return ret;
donatien 0:8e01dca41002 233 }
donatien 0:8e01dca41002 234 #endif /* UNUSED */
donatien 0:8e01dca41002 235
donatien 0:8e01dca41002 236 /*
donatien 0:8e01dca41002 237 * lcp_init - Initialize LCP.
donatien 0:8e01dca41002 238 */
donatien 0:8e01dca41002 239 void
donatien 0:8e01dca41002 240 lcp_init(int unit)
donatien 0:8e01dca41002 241 {
donatien 0:8e01dca41002 242 fsm *f = &lcp_fsm[unit];
donatien 0:8e01dca41002 243 lcp_options *wo = &lcp_wantoptions[unit];
donatien 0:8e01dca41002 244 lcp_options *ao = &lcp_allowoptions[unit];
donatien 0:8e01dca41002 245
donatien 0:8e01dca41002 246 f->unit = unit;
donatien 0:8e01dca41002 247 f->protocol = PPP_LCP;
donatien 0:8e01dca41002 248 f->callbacks = &lcp_callbacks;
donatien 0:8e01dca41002 249
donatien 0:8e01dca41002 250 fsm_init(f);
donatien 0:8e01dca41002 251
donatien 0:8e01dca41002 252 wo->passive = 0;
donatien 0:8e01dca41002 253 wo->silent = 0;
donatien 0:8e01dca41002 254 wo->restart = 0; /* Set to 1 in kernels or multi-line implementations */
donatien 0:8e01dca41002 255 wo->neg_mru = 1;
donatien 0:8e01dca41002 256 wo->mru = PPP_DEFMRU;
donatien 0:8e01dca41002 257 wo->neg_asyncmap = 1;
donatien 0:8e01dca41002 258 wo->asyncmap = 0x00000000l; /* Assume don't need to escape any ctl chars. */
donatien 0:8e01dca41002 259 wo->neg_chap = 0; /* Set to 1 on server */
donatien 0:8e01dca41002 260 wo->neg_upap = 0; /* Set to 1 on server */
donatien 0:8e01dca41002 261 wo->chap_mdtype = CHAP_DIGEST_MD5;
donatien 0:8e01dca41002 262 wo->neg_magicnumber = 1;
donatien 0:8e01dca41002 263 wo->neg_pcompression = 1;
donatien 0:8e01dca41002 264 wo->neg_accompression = 1;
donatien 0:8e01dca41002 265 wo->neg_lqr = 0; /* no LQR implementation yet */
donatien 0:8e01dca41002 266 wo->neg_cbcp = 0;
donatien 0:8e01dca41002 267
donatien 0:8e01dca41002 268 ao->neg_mru = 1;
donatien 0:8e01dca41002 269 ao->mru = PPP_MAXMRU;
donatien 0:8e01dca41002 270 ao->neg_asyncmap = 1;
donatien 0:8e01dca41002 271 ao->asyncmap = 0x00000000l; /* Assume don't need to escape any ctl chars. */
donatien 0:8e01dca41002 272 ao->neg_chap = (CHAP_SUPPORT != 0);
donatien 0:8e01dca41002 273 ao->chap_mdtype = CHAP_DIGEST_MD5;
donatien 0:8e01dca41002 274 ao->neg_upap = (PAP_SUPPORT != 0);
donatien 0:8e01dca41002 275 ao->neg_magicnumber = 1;
donatien 0:8e01dca41002 276 ao->neg_pcompression = 1;
donatien 0:8e01dca41002 277 ao->neg_accompression = 1;
donatien 0:8e01dca41002 278 ao->neg_lqr = 0; /* no LQR implementation yet */
donatien 0:8e01dca41002 279 ao->neg_cbcp = (CBCP_SUPPORT != 0);
donatien 0:8e01dca41002 280
donatien 0:8e01dca41002 281 /*
donatien 0:8e01dca41002 282 * Set transmit escape for the flag and escape characters plus anything
donatien 0:8e01dca41002 283 * set for the allowable options.
donatien 0:8e01dca41002 284 */
donatien 0:8e01dca41002 285 memset(xmit_accm[unit], 0, sizeof(xmit_accm[0]));
donatien 0:8e01dca41002 286 xmit_accm[unit][15] = 0x60;
donatien 0:8e01dca41002 287 xmit_accm[unit][0] = (u_char)((ao->asyncmap & 0xFF));
donatien 0:8e01dca41002 288 xmit_accm[unit][1] = (u_char)((ao->asyncmap >> 8) & 0xFF);
donatien 0:8e01dca41002 289 xmit_accm[unit][2] = (u_char)((ao->asyncmap >> 16) & 0xFF);
donatien 0:8e01dca41002 290 xmit_accm[unit][3] = (u_char)((ao->asyncmap >> 24) & 0xFF);
donatien 0:8e01dca41002 291 LCPDEBUG(LOG_INFO, ("lcp_init: xmit_accm=%X %X %X %X\n",
donatien 0:8e01dca41002 292 xmit_accm[unit][0],
donatien 0:8e01dca41002 293 xmit_accm[unit][1],
donatien 0:8e01dca41002 294 xmit_accm[unit][2],
donatien 0:8e01dca41002 295 xmit_accm[unit][3]));
donatien 0:8e01dca41002 296
donatien 0:8e01dca41002 297 lcp_phase[unit] = PHASE_INITIALIZE;
donatien 0:8e01dca41002 298 }
donatien 0:8e01dca41002 299
donatien 0:8e01dca41002 300
donatien 0:8e01dca41002 301 /*
donatien 0:8e01dca41002 302 * lcp_open - LCP is allowed to come up.
donatien 0:8e01dca41002 303 */
donatien 0:8e01dca41002 304 void
donatien 0:8e01dca41002 305 lcp_open(int unit)
donatien 0:8e01dca41002 306 {
donatien 0:8e01dca41002 307 fsm *f = &lcp_fsm[unit];
donatien 0:8e01dca41002 308 lcp_options *wo = &lcp_wantoptions[unit];
donatien 0:8e01dca41002 309
donatien 0:8e01dca41002 310 f->flags = 0;
donatien 0:8e01dca41002 311 if (wo->passive) {
donatien 0:8e01dca41002 312 f->flags |= OPT_PASSIVE;
donatien 0:8e01dca41002 313 }
donatien 0:8e01dca41002 314 if (wo->silent) {
donatien 0:8e01dca41002 315 f->flags |= OPT_SILENT;
donatien 0:8e01dca41002 316 }
donatien 0:8e01dca41002 317 fsm_open(f);
donatien 0:8e01dca41002 318
donatien 0:8e01dca41002 319 lcp_phase[unit] = PHASE_ESTABLISH;
donatien 0:8e01dca41002 320 }
donatien 0:8e01dca41002 321
donatien 0:8e01dca41002 322
donatien 0:8e01dca41002 323 /*
donatien 0:8e01dca41002 324 * lcp_close - Take LCP down.
donatien 0:8e01dca41002 325 */
donatien 0:8e01dca41002 326 void
donatien 0:8e01dca41002 327 lcp_close(int unit, char *reason)
donatien 0:8e01dca41002 328 {
donatien 0:8e01dca41002 329 fsm *f = &lcp_fsm[unit];
donatien 0:8e01dca41002 330
donatien 0:8e01dca41002 331 if (lcp_phase[unit] != PHASE_DEAD) {
donatien 0:8e01dca41002 332 lcp_phase[unit] = PHASE_TERMINATE;
donatien 0:8e01dca41002 333 }
donatien 0:8e01dca41002 334 if (f->state == LS_STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {
donatien 0:8e01dca41002 335 /*
donatien 0:8e01dca41002 336 * This action is not strictly according to the FSM in RFC1548,
donatien 0:8e01dca41002 337 * but it does mean that the program terminates if you do an
donatien 0:8e01dca41002 338 * lcp_close() in passive/silent mode when a connection hasn't
donatien 0:8e01dca41002 339 * been established.
donatien 0:8e01dca41002 340 */
donatien 0:8e01dca41002 341 f->state = LS_CLOSED;
donatien 0:8e01dca41002 342 lcp_finished(f);
donatien 0:8e01dca41002 343 } else {
donatien 0:8e01dca41002 344 fsm_close(f, reason);
donatien 0:8e01dca41002 345 }
donatien 0:8e01dca41002 346 }
donatien 0:8e01dca41002 347
donatien 0:8e01dca41002 348
donatien 0:8e01dca41002 349 /*
donatien 0:8e01dca41002 350 * lcp_lowerup - The lower layer is up.
donatien 0:8e01dca41002 351 */
donatien 0:8e01dca41002 352 void
donatien 0:8e01dca41002 353 lcp_lowerup(int unit)
donatien 0:8e01dca41002 354 {
donatien 0:8e01dca41002 355 lcp_options *wo = &lcp_wantoptions[unit];
donatien 0:8e01dca41002 356
donatien 0:8e01dca41002 357 /*
donatien 0:8e01dca41002 358 * Don't use A/C or protocol compression on transmission,
donatien 0:8e01dca41002 359 * but accept A/C and protocol compressed packets
donatien 0:8e01dca41002 360 * if we are going to ask for A/C and protocol compression.
donatien 0:8e01dca41002 361 */
donatien 0:8e01dca41002 362 ppp_set_xaccm(unit, &xmit_accm[unit]);
donatien 0:8e01dca41002 363 ppp_send_config(unit, PPP_MRU, 0xffffffffl, 0, 0);
donatien 0:8e01dca41002 364 ppp_recv_config(unit, PPP_MRU, 0x00000000l,
donatien 0:8e01dca41002 365 wo->neg_pcompression, wo->neg_accompression);
donatien 0:8e01dca41002 366 peer_mru[unit] = PPP_MRU;
donatien 0:8e01dca41002 367 lcp_allowoptions[unit].asyncmap = (u_long)xmit_accm[unit][0]
donatien 0:8e01dca41002 368 | ((u_long)xmit_accm[unit][1] << 8)
donatien 0:8e01dca41002 369 | ((u_long)xmit_accm[unit][2] << 16)
donatien 0:8e01dca41002 370 | ((u_long)xmit_accm[unit][3] << 24);
donatien 0:8e01dca41002 371 LCPDEBUG(LOG_INFO, ("lcp_lowerup: asyncmap=%X %X %X %X\n",
donatien 0:8e01dca41002 372 xmit_accm[unit][3],
donatien 0:8e01dca41002 373 xmit_accm[unit][2],
donatien 0:8e01dca41002 374 xmit_accm[unit][1],
donatien 0:8e01dca41002 375 xmit_accm[unit][0]));
donatien 0:8e01dca41002 376
donatien 0:8e01dca41002 377 fsm_lowerup(&lcp_fsm[unit]);
donatien 0:8e01dca41002 378 }
donatien 0:8e01dca41002 379
donatien 0:8e01dca41002 380
donatien 0:8e01dca41002 381 /*
donatien 0:8e01dca41002 382 * lcp_lowerdown - The lower layer is down.
donatien 0:8e01dca41002 383 */
donatien 0:8e01dca41002 384 void
donatien 0:8e01dca41002 385 lcp_lowerdown(int unit)
donatien 0:8e01dca41002 386 {
donatien 0:8e01dca41002 387 fsm_lowerdown(&lcp_fsm[unit]);
donatien 0:8e01dca41002 388 }
donatien 0:8e01dca41002 389
donatien 0:8e01dca41002 390
donatien 0:8e01dca41002 391 /*
donatien 0:8e01dca41002 392 * lcp_input - Input LCP packet.
donatien 0:8e01dca41002 393 */
donatien 0:8e01dca41002 394 static void
donatien 0:8e01dca41002 395 lcp_input(int unit, u_char *p, int len)
donatien 0:8e01dca41002 396 {
donatien 0:8e01dca41002 397 fsm *f = &lcp_fsm[unit];
donatien 0:8e01dca41002 398
donatien 0:8e01dca41002 399 fsm_input(f, p, len);
donatien 0:8e01dca41002 400 }
donatien 0:8e01dca41002 401
donatien 0:8e01dca41002 402
donatien 0:8e01dca41002 403 /*
donatien 0:8e01dca41002 404 * lcp_extcode - Handle a LCP-specific code.
donatien 0:8e01dca41002 405 */
donatien 0:8e01dca41002 406 static int
donatien 0:8e01dca41002 407 lcp_extcode(fsm *f, int code, u_char id, u_char *inp, int len)
donatien 0:8e01dca41002 408 {
donatien 0:8e01dca41002 409 u_char *magp;
donatien 0:8e01dca41002 410
donatien 0:8e01dca41002 411 switch( code ){
donatien 0:8e01dca41002 412 case PROTREJ:
donatien 0:8e01dca41002 413 lcp_rprotrej(f, inp, len);
donatien 0:8e01dca41002 414 break;
donatien 0:8e01dca41002 415
donatien 0:8e01dca41002 416 case ECHOREQ:
donatien 0:8e01dca41002 417 if (f->state != LS_OPENED) {
donatien 0:8e01dca41002 418 break;
donatien 0:8e01dca41002 419 }
donatien 0:8e01dca41002 420 LCPDEBUG(LOG_INFO, ("lcp: Echo-Request, Rcvd id %d\n", id));
donatien 0:8e01dca41002 421 magp = inp;
donatien 0:8e01dca41002 422 PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
donatien 0:8e01dca41002 423 fsm_sdata(f, ECHOREP, id, inp, len);
donatien 0:8e01dca41002 424 break;
donatien 0:8e01dca41002 425
donatien 0:8e01dca41002 426 case ECHOREP:
donatien 0:8e01dca41002 427 lcp_received_echo_reply(f, id, inp, len);
donatien 0:8e01dca41002 428 break;
donatien 0:8e01dca41002 429
donatien 0:8e01dca41002 430 case DISCREQ:
donatien 0:8e01dca41002 431 break;
donatien 0:8e01dca41002 432
donatien 0:8e01dca41002 433 default:
donatien 0:8e01dca41002 434 return 0;
donatien 0:8e01dca41002 435 }
donatien 0:8e01dca41002 436 return 1;
donatien 0:8e01dca41002 437 }
donatien 0:8e01dca41002 438
donatien 0:8e01dca41002 439
donatien 0:8e01dca41002 440 /*
donatien 0:8e01dca41002 441 * lcp_rprotrej - Receive an Protocol-Reject.
donatien 0:8e01dca41002 442 *
donatien 0:8e01dca41002 443 * Figure out which protocol is rejected and inform it.
donatien 0:8e01dca41002 444 */
donatien 0:8e01dca41002 445 static void
donatien 0:8e01dca41002 446 lcp_rprotrej(fsm *f, u_char *inp, int len)
donatien 0:8e01dca41002 447 {
donatien 0:8e01dca41002 448 int i;
donatien 0:8e01dca41002 449 struct protent *protp;
donatien 0:8e01dca41002 450 u_short prot;
donatien 0:8e01dca41002 451
donatien 0:8e01dca41002 452 if (len < (int)sizeof (u_short)) {
donatien 0:8e01dca41002 453 LCPDEBUG(LOG_INFO, ("lcp_rprotrej: Rcvd short Protocol-Reject packet!\n"));
donatien 0:8e01dca41002 454 return;
donatien 0:8e01dca41002 455 }
donatien 0:8e01dca41002 456
donatien 0:8e01dca41002 457 GETSHORT(prot, inp);
donatien 0:8e01dca41002 458
donatien 0:8e01dca41002 459 LCPDEBUG(LOG_INFO, ("lcp_rprotrej: Rcvd Protocol-Reject packet for %x!\n", prot));
donatien 0:8e01dca41002 460
donatien 0:8e01dca41002 461 /*
donatien 0:8e01dca41002 462 * Protocol-Reject packets received in any state other than the LCP
donatien 0:8e01dca41002 463 * LS_OPENED state SHOULD be silently discarded.
donatien 0:8e01dca41002 464 */
donatien 0:8e01dca41002 465 if( f->state != LS_OPENED ) {
donatien 0:8e01dca41002 466 LCPDEBUG(LOG_INFO, ("Protocol-Reject discarded: LCP in state %d\n", f->state));
donatien 0:8e01dca41002 467 return;
donatien 0:8e01dca41002 468 }
donatien 0:8e01dca41002 469
donatien 0:8e01dca41002 470 /*
donatien 0:8e01dca41002 471 * Upcall the proper Protocol-Reject routine.
donatien 0:8e01dca41002 472 */
donatien 0:8e01dca41002 473 for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
donatien 0:8e01dca41002 474 if (protp->protocol == prot && protp->enabled_flag) {
donatien 0:8e01dca41002 475 (*protp->protrej)(f->unit);
donatien 0:8e01dca41002 476 return;
donatien 0:8e01dca41002 477 }
donatien 0:8e01dca41002 478 }
donatien 0:8e01dca41002 479
donatien 0:8e01dca41002 480 LCPDEBUG(LOG_WARNING, ("Protocol-Reject for unsupported protocol 0x%x\n", prot));
donatien 0:8e01dca41002 481 }
donatien 0:8e01dca41002 482
donatien 0:8e01dca41002 483
donatien 0:8e01dca41002 484 /*
donatien 0:8e01dca41002 485 * lcp_protrej - A Protocol-Reject was received.
donatien 0:8e01dca41002 486 */
donatien 0:8e01dca41002 487 static void
donatien 0:8e01dca41002 488 lcp_protrej(int unit)
donatien 0:8e01dca41002 489 {
donatien 0:8e01dca41002 490 LWIP_UNUSED_ARG(unit);
donatien 0:8e01dca41002 491 /*
donatien 0:8e01dca41002 492 * Can't reject LCP!
donatien 0:8e01dca41002 493 */
donatien 0:8e01dca41002 494 LCPDEBUG(LOG_WARNING, ("lcp_protrej: Received Protocol-Reject for LCP!\n"));
donatien 0:8e01dca41002 495 fsm_protreject(&lcp_fsm[unit]);
donatien 0:8e01dca41002 496 }
donatien 0:8e01dca41002 497
donatien 0:8e01dca41002 498
donatien 0:8e01dca41002 499 /*
donatien 0:8e01dca41002 500 * lcp_sprotrej - Send a Protocol-Reject for some protocol.
donatien 0:8e01dca41002 501 */
donatien 0:8e01dca41002 502 void
donatien 0:8e01dca41002 503 lcp_sprotrej(int unit, u_char *p, int len)
donatien 0:8e01dca41002 504 {
donatien 0:8e01dca41002 505 /*
donatien 0:8e01dca41002 506 * Send back the protocol and the information field of the
donatien 0:8e01dca41002 507 * rejected packet. We only get here if LCP is in the LS_OPENED state.
donatien 0:8e01dca41002 508 */
donatien 0:8e01dca41002 509
donatien 0:8e01dca41002 510 fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id, p, len);
donatien 0:8e01dca41002 511 }
donatien 0:8e01dca41002 512
donatien 0:8e01dca41002 513
donatien 0:8e01dca41002 514 /*
donatien 0:8e01dca41002 515 * lcp_resetci - Reset our CI.
donatien 0:8e01dca41002 516 */
donatien 0:8e01dca41002 517 static void
donatien 0:8e01dca41002 518 lcp_resetci(fsm *f)
donatien 0:8e01dca41002 519 {
donatien 0:8e01dca41002 520 lcp_wantoptions[f->unit].magicnumber = magic();
donatien 0:8e01dca41002 521 lcp_wantoptions[f->unit].numloops = 0;
donatien 0:8e01dca41002 522 lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit];
donatien 0:8e01dca41002 523 peer_mru[f->unit] = PPP_MRU;
donatien 0:8e01dca41002 524 auth_reset(f->unit);
donatien 0:8e01dca41002 525 }
donatien 0:8e01dca41002 526
donatien 0:8e01dca41002 527
donatien 0:8e01dca41002 528 /*
donatien 0:8e01dca41002 529 * lcp_cilen - Return length of our CI.
donatien 0:8e01dca41002 530 */
donatien 0:8e01dca41002 531 static int
donatien 0:8e01dca41002 532 lcp_cilen(fsm *f)
donatien 0:8e01dca41002 533 {
donatien 0:8e01dca41002 534 lcp_options *go = &lcp_gotoptions[f->unit];
donatien 0:8e01dca41002 535
donatien 0:8e01dca41002 536 #define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0)
donatien 0:8e01dca41002 537 #define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0)
donatien 0:8e01dca41002 538 #define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0)
donatien 0:8e01dca41002 539 #define LENCILONG(neg) ((neg) ? CILEN_LONG : 0)
donatien 0:8e01dca41002 540 #define LENCILQR(neg) ((neg) ? CILEN_LQR: 0)
donatien 0:8e01dca41002 541 #define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0)
donatien 0:8e01dca41002 542 /*
donatien 0:8e01dca41002 543 * NB: we only ask for one of CHAP and UPAP, even if we will
donatien 0:8e01dca41002 544 * accept either.
donatien 0:8e01dca41002 545 */
donatien 0:8e01dca41002 546 return (LENCISHORT(go->neg_mru && go->mru != PPP_DEFMRU) +
donatien 0:8e01dca41002 547 LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) +
donatien 0:8e01dca41002 548 LENCICHAP(go->neg_chap) +
donatien 0:8e01dca41002 549 LENCISHORT(!go->neg_chap && go->neg_upap) +
donatien 0:8e01dca41002 550 LENCILQR(go->neg_lqr) +
donatien 0:8e01dca41002 551 LENCICBCP(go->neg_cbcp) +
donatien 0:8e01dca41002 552 LENCILONG(go->neg_magicnumber) +
donatien 0:8e01dca41002 553 LENCIVOID(go->neg_pcompression) +
donatien 0:8e01dca41002 554 LENCIVOID(go->neg_accompression));
donatien 0:8e01dca41002 555 }
donatien 0:8e01dca41002 556
donatien 0:8e01dca41002 557
donatien 0:8e01dca41002 558 /*
donatien 0:8e01dca41002 559 * lcp_addci - Add our desired CIs to a packet.
donatien 0:8e01dca41002 560 */
donatien 0:8e01dca41002 561 static void
donatien 0:8e01dca41002 562 lcp_addci(fsm *f, u_char *ucp, int *lenp)
donatien 0:8e01dca41002 563 {
donatien 0:8e01dca41002 564 lcp_options *go = &lcp_gotoptions[f->unit];
donatien 0:8e01dca41002 565 u_char *start_ucp = ucp;
donatien 0:8e01dca41002 566
donatien 0:8e01dca41002 567 #define ADDCIVOID(opt, neg) \
donatien 0:8e01dca41002 568 if (neg) { \
donatien 0:8e01dca41002 569 LCPDEBUG(LOG_INFO, ("lcp_addci: opt=%d\n", opt)); \
donatien 0:8e01dca41002 570 PUTCHAR(opt, ucp); \
donatien 0:8e01dca41002 571 PUTCHAR(CILEN_VOID, ucp); \
donatien 0:8e01dca41002 572 }
donatien 0:8e01dca41002 573 #define ADDCISHORT(opt, neg, val) \
donatien 0:8e01dca41002 574 if (neg) { \
donatien 0:8e01dca41002 575 LCPDEBUG(LOG_INFO, ("lcp_addci: INT opt=%d %X\n", opt, val)); \
donatien 0:8e01dca41002 576 PUTCHAR(opt, ucp); \
donatien 0:8e01dca41002 577 PUTCHAR(CILEN_SHORT, ucp); \
donatien 0:8e01dca41002 578 PUTSHORT(val, ucp); \
donatien 0:8e01dca41002 579 }
donatien 0:8e01dca41002 580 #define ADDCICHAP(opt, neg, val, digest) \
donatien 0:8e01dca41002 581 if (neg) { \
donatien 0:8e01dca41002 582 LCPDEBUG(LOG_INFO, ("lcp_addci: CHAP opt=%d %X\n", opt, val)); \
donatien 0:8e01dca41002 583 PUTCHAR(opt, ucp); \
donatien 0:8e01dca41002 584 PUTCHAR(CILEN_CHAP, ucp); \
donatien 0:8e01dca41002 585 PUTSHORT(val, ucp); \
donatien 0:8e01dca41002 586 PUTCHAR(digest, ucp); \
donatien 0:8e01dca41002 587 }
donatien 0:8e01dca41002 588 #define ADDCILONG(opt, neg, val) \
donatien 0:8e01dca41002 589 if (neg) { \
donatien 0:8e01dca41002 590 LCPDEBUG(LOG_INFO, ("lcp_addci: L opt=%d %lX\n", opt, val)); \
donatien 0:8e01dca41002 591 PUTCHAR(opt, ucp); \
donatien 0:8e01dca41002 592 PUTCHAR(CILEN_LONG, ucp); \
donatien 0:8e01dca41002 593 PUTLONG(val, ucp); \
donatien 0:8e01dca41002 594 }
donatien 0:8e01dca41002 595 #define ADDCILQR(opt, neg, val) \
donatien 0:8e01dca41002 596 if (neg) { \
donatien 0:8e01dca41002 597 LCPDEBUG(LOG_INFO, ("lcp_addci: LQR opt=%d %lX\n", opt, val)); \
donatien 0:8e01dca41002 598 PUTCHAR(opt, ucp); \
donatien 0:8e01dca41002 599 PUTCHAR(CILEN_LQR, ucp); \
donatien 0:8e01dca41002 600 PUTSHORT(PPP_LQR, ucp); \
donatien 0:8e01dca41002 601 PUTLONG(val, ucp); \
donatien 0:8e01dca41002 602 }
donatien 0:8e01dca41002 603 #define ADDCICHAR(opt, neg, val) \
donatien 0:8e01dca41002 604 if (neg) { \
donatien 0:8e01dca41002 605 LCPDEBUG(LOG_INFO, ("lcp_addci: CHAR opt=%d %X '%z'\n", opt, val, val)); \
donatien 0:8e01dca41002 606 PUTCHAR(opt, ucp); \
donatien 0:8e01dca41002 607 PUTCHAR(CILEN_CHAR, ucp); \
donatien 0:8e01dca41002 608 PUTCHAR(val, ucp); \
donatien 0:8e01dca41002 609 }
donatien 0:8e01dca41002 610
donatien 0:8e01dca41002 611 ADDCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);
donatien 0:8e01dca41002 612 ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl, go->asyncmap);
donatien 0:8e01dca41002 613 ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
donatien 0:8e01dca41002 614 ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
donatien 0:8e01dca41002 615 ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
donatien 0:8e01dca41002 616 ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
donatien 0:8e01dca41002 617 ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
donatien 0:8e01dca41002 618 ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
donatien 0:8e01dca41002 619 ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
donatien 0:8e01dca41002 620
donatien 0:8e01dca41002 621 if (ucp - start_ucp != *lenp) {
donatien 0:8e01dca41002 622 /* this should never happen, because peer_mtu should be 1500 */
donatien 0:8e01dca41002 623 LCPDEBUG(LOG_ERR, ("Bug in lcp_addci: wrong length\n"));
donatien 0:8e01dca41002 624 }
donatien 0:8e01dca41002 625 }
donatien 0:8e01dca41002 626
donatien 0:8e01dca41002 627
donatien 0:8e01dca41002 628 /*
donatien 0:8e01dca41002 629 * lcp_ackci - Ack our CIs.
donatien 0:8e01dca41002 630 * This should not modify any state if the Ack is bad.
donatien 0:8e01dca41002 631 *
donatien 0:8e01dca41002 632 * Returns:
donatien 0:8e01dca41002 633 * 0 - Ack was bad.
donatien 0:8e01dca41002 634 * 1 - Ack was good.
donatien 0:8e01dca41002 635 */
donatien 0:8e01dca41002 636 static int
donatien 0:8e01dca41002 637 lcp_ackci(fsm *f, u_char *p, int len)
donatien 0:8e01dca41002 638 {
donatien 0:8e01dca41002 639 lcp_options *go = &lcp_gotoptions[f->unit];
donatien 0:8e01dca41002 640 u_char cilen, citype, cichar;
donatien 0:8e01dca41002 641 u_short cishort;
donatien 0:8e01dca41002 642 u32_t cilong;
donatien 0:8e01dca41002 643
donatien 0:8e01dca41002 644 /*
donatien 0:8e01dca41002 645 * CIs must be in exactly the same order that we sent.
donatien 0:8e01dca41002 646 * Check packet length and CI length at each step.
donatien 0:8e01dca41002 647 * If we find any deviations, then this packet is bad.
donatien 0:8e01dca41002 648 */
donatien 0:8e01dca41002 649 #define ACKCIVOID(opt, neg) \
donatien 0:8e01dca41002 650 if (neg) { \
donatien 0:8e01dca41002 651 if ((len -= CILEN_VOID) < 0) \
donatien 0:8e01dca41002 652 goto bad; \
donatien 0:8e01dca41002 653 GETCHAR(citype, p); \
donatien 0:8e01dca41002 654 GETCHAR(cilen, p); \
donatien 0:8e01dca41002 655 if (cilen != CILEN_VOID || citype != opt) \
donatien 0:8e01dca41002 656 goto bad; \
donatien 0:8e01dca41002 657 }
donatien 0:8e01dca41002 658 #define ACKCISHORT(opt, neg, val) \
donatien 0:8e01dca41002 659 if (neg) { \
donatien 0:8e01dca41002 660 if ((len -= CILEN_SHORT) < 0) \
donatien 0:8e01dca41002 661 goto bad; \
donatien 0:8e01dca41002 662 GETCHAR(citype, p); \
donatien 0:8e01dca41002 663 GETCHAR(cilen, p); \
donatien 0:8e01dca41002 664 if (cilen != CILEN_SHORT || citype != opt) \
donatien 0:8e01dca41002 665 goto bad; \
donatien 0:8e01dca41002 666 GETSHORT(cishort, p); \
donatien 0:8e01dca41002 667 if (cishort != val) \
donatien 0:8e01dca41002 668 goto bad; \
donatien 0:8e01dca41002 669 }
donatien 0:8e01dca41002 670 #define ACKCICHAR(opt, neg, val) \
donatien 0:8e01dca41002 671 if (neg) { \
donatien 0:8e01dca41002 672 if ((len -= CILEN_CHAR) < 0) \
donatien 0:8e01dca41002 673 goto bad; \
donatien 0:8e01dca41002 674 GETCHAR(citype, p); \
donatien 0:8e01dca41002 675 GETCHAR(cilen, p); \
donatien 0:8e01dca41002 676 if (cilen != CILEN_CHAR || citype != opt) \
donatien 0:8e01dca41002 677 goto bad; \
donatien 0:8e01dca41002 678 GETCHAR(cichar, p); \
donatien 0:8e01dca41002 679 if (cichar != val) \
donatien 0:8e01dca41002 680 goto bad; \
donatien 0:8e01dca41002 681 }
donatien 0:8e01dca41002 682 #define ACKCICHAP(opt, neg, val, digest) \
donatien 0:8e01dca41002 683 if (neg) { \
donatien 0:8e01dca41002 684 if ((len -= CILEN_CHAP) < 0) \
donatien 0:8e01dca41002 685 goto bad; \
donatien 0:8e01dca41002 686 GETCHAR(citype, p); \
donatien 0:8e01dca41002 687 GETCHAR(cilen, p); \
donatien 0:8e01dca41002 688 if (cilen != CILEN_CHAP || citype != opt) \
donatien 0:8e01dca41002 689 goto bad; \
donatien 0:8e01dca41002 690 GETSHORT(cishort, p); \
donatien 0:8e01dca41002 691 if (cishort != val) \
donatien 0:8e01dca41002 692 goto bad; \
donatien 0:8e01dca41002 693 GETCHAR(cichar, p); \
donatien 0:8e01dca41002 694 if (cichar != digest) \
donatien 0:8e01dca41002 695 goto bad; \
donatien 0:8e01dca41002 696 }
donatien 0:8e01dca41002 697 #define ACKCILONG(opt, neg, val) \
donatien 0:8e01dca41002 698 if (neg) { \
donatien 0:8e01dca41002 699 if ((len -= CILEN_LONG) < 0) \
donatien 0:8e01dca41002 700 goto bad; \
donatien 0:8e01dca41002 701 GETCHAR(citype, p); \
donatien 0:8e01dca41002 702 GETCHAR(cilen, p); \
donatien 0:8e01dca41002 703 if (cilen != CILEN_LONG || citype != opt) \
donatien 0:8e01dca41002 704 goto bad; \
donatien 0:8e01dca41002 705 GETLONG(cilong, p); \
donatien 0:8e01dca41002 706 if (cilong != val) \
donatien 0:8e01dca41002 707 goto bad; \
donatien 0:8e01dca41002 708 }
donatien 0:8e01dca41002 709 #define ACKCILQR(opt, neg, val) \
donatien 0:8e01dca41002 710 if (neg) { \
donatien 0:8e01dca41002 711 if ((len -= CILEN_LQR) < 0) \
donatien 0:8e01dca41002 712 goto bad; \
donatien 0:8e01dca41002 713 GETCHAR(citype, p); \
donatien 0:8e01dca41002 714 GETCHAR(cilen, p); \
donatien 0:8e01dca41002 715 if (cilen != CILEN_LQR || citype != opt) \
donatien 0:8e01dca41002 716 goto bad; \
donatien 0:8e01dca41002 717 GETSHORT(cishort, p); \
donatien 0:8e01dca41002 718 if (cishort != PPP_LQR) \
donatien 0:8e01dca41002 719 goto bad; \
donatien 0:8e01dca41002 720 GETLONG(cilong, p); \
donatien 0:8e01dca41002 721 if (cilong != val) \
donatien 0:8e01dca41002 722 goto bad; \
donatien 0:8e01dca41002 723 }
donatien 0:8e01dca41002 724
donatien 0:8e01dca41002 725 ACKCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);
donatien 0:8e01dca41002 726 ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl, go->asyncmap);
donatien 0:8e01dca41002 727 ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
donatien 0:8e01dca41002 728 ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
donatien 0:8e01dca41002 729 ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
donatien 0:8e01dca41002 730 ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
donatien 0:8e01dca41002 731 ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
donatien 0:8e01dca41002 732 ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
donatien 0:8e01dca41002 733 ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
donatien 0:8e01dca41002 734
donatien 0:8e01dca41002 735 /*
donatien 0:8e01dca41002 736 * If there are any remaining CIs, then this packet is bad.
donatien 0:8e01dca41002 737 */
donatien 0:8e01dca41002 738 if (len != 0) {
donatien 0:8e01dca41002 739 goto bad;
donatien 0:8e01dca41002 740 }
donatien 0:8e01dca41002 741 LCPDEBUG(LOG_INFO, ("lcp_acki: Ack\n"));
donatien 0:8e01dca41002 742 return (1);
donatien 0:8e01dca41002 743 bad:
donatien 0:8e01dca41002 744 LCPDEBUG(LOG_WARNING, ("lcp_acki: received bad Ack!\n"));
donatien 0:8e01dca41002 745 return (0);
donatien 0:8e01dca41002 746 }
donatien 0:8e01dca41002 747
donatien 0:8e01dca41002 748
donatien 0:8e01dca41002 749 /*
donatien 0:8e01dca41002 750 * lcp_nakci - Peer has sent a NAK for some of our CIs.
donatien 0:8e01dca41002 751 * This should not modify any state if the Nak is bad
donatien 0:8e01dca41002 752 * or if LCP is in the LS_OPENED state.
donatien 0:8e01dca41002 753 *
donatien 0:8e01dca41002 754 * Returns:
donatien 0:8e01dca41002 755 * 0 - Nak was bad.
donatien 0:8e01dca41002 756 * 1 - Nak was good.
donatien 0:8e01dca41002 757 */
donatien 0:8e01dca41002 758 static int
donatien 0:8e01dca41002 759 lcp_nakci(fsm *f, u_char *p, int len)
donatien 0:8e01dca41002 760 {
donatien 0:8e01dca41002 761 lcp_options *go = &lcp_gotoptions[f->unit];
donatien 0:8e01dca41002 762 lcp_options *wo = &lcp_wantoptions[f->unit];
donatien 0:8e01dca41002 763 u_char citype, cichar, *next;
donatien 0:8e01dca41002 764 u_short cishort;
donatien 0:8e01dca41002 765 u32_t cilong;
donatien 0:8e01dca41002 766 lcp_options no; /* options we've seen Naks for */
donatien 0:8e01dca41002 767 lcp_options try; /* options to request next time */
donatien 0:8e01dca41002 768 int looped_back = 0;
donatien 0:8e01dca41002 769 int cilen;
donatien 0:8e01dca41002 770
donatien 0:8e01dca41002 771 BZERO(&no, sizeof(no));
donatien 0:8e01dca41002 772 try = *go;
donatien 0:8e01dca41002 773
donatien 0:8e01dca41002 774 /*
donatien 0:8e01dca41002 775 * Any Nak'd CIs must be in exactly the same order that we sent.
donatien 0:8e01dca41002 776 * Check packet length and CI length at each step.
donatien 0:8e01dca41002 777 * If we find any deviations, then this packet is bad.
donatien 0:8e01dca41002 778 */
donatien 0:8e01dca41002 779 #define NAKCIVOID(opt, neg, code) \
donatien 0:8e01dca41002 780 if (go->neg && \
donatien 0:8e01dca41002 781 len >= CILEN_VOID && \
donatien 0:8e01dca41002 782 p[1] == CILEN_VOID && \
donatien 0:8e01dca41002 783 p[0] == opt) { \
donatien 0:8e01dca41002 784 len -= CILEN_VOID; \
donatien 0:8e01dca41002 785 INCPTR(CILEN_VOID, p); \
donatien 0:8e01dca41002 786 no.neg = 1; \
donatien 0:8e01dca41002 787 code \
donatien 0:8e01dca41002 788 }
donatien 0:8e01dca41002 789 #define NAKCICHAP(opt, neg, code) \
donatien 0:8e01dca41002 790 if (go->neg && \
donatien 0:8e01dca41002 791 len >= CILEN_CHAP && \
donatien 0:8e01dca41002 792 p[1] == CILEN_CHAP && \
donatien 0:8e01dca41002 793 p[0] == opt) { \
donatien 0:8e01dca41002 794 len -= CILEN_CHAP; \
donatien 0:8e01dca41002 795 INCPTR(2, p); \
donatien 0:8e01dca41002 796 GETSHORT(cishort, p); \
donatien 0:8e01dca41002 797 GETCHAR(cichar, p); \
donatien 0:8e01dca41002 798 no.neg = 1; \
donatien 0:8e01dca41002 799 code \
donatien 0:8e01dca41002 800 }
donatien 0:8e01dca41002 801 #define NAKCICHAR(opt, neg, code) \
donatien 0:8e01dca41002 802 if (go->neg && \
donatien 0:8e01dca41002 803 len >= CILEN_CHAR && \
donatien 0:8e01dca41002 804 p[1] == CILEN_CHAR && \
donatien 0:8e01dca41002 805 p[0] == opt) { \
donatien 0:8e01dca41002 806 len -= CILEN_CHAR; \
donatien 0:8e01dca41002 807 INCPTR(2, p); \
donatien 0:8e01dca41002 808 GETCHAR(cichar, p); \
donatien 0:8e01dca41002 809 no.neg = 1; \
donatien 0:8e01dca41002 810 code \
donatien 0:8e01dca41002 811 }
donatien 0:8e01dca41002 812 #define NAKCISHORT(opt, neg, code) \
donatien 0:8e01dca41002 813 if (go->neg && \
donatien 0:8e01dca41002 814 len >= CILEN_SHORT && \
donatien 0:8e01dca41002 815 p[1] == CILEN_SHORT && \
donatien 0:8e01dca41002 816 p[0] == opt) { \
donatien 0:8e01dca41002 817 len -= CILEN_SHORT; \
donatien 0:8e01dca41002 818 INCPTR(2, p); \
donatien 0:8e01dca41002 819 GETSHORT(cishort, p); \
donatien 0:8e01dca41002 820 no.neg = 1; \
donatien 0:8e01dca41002 821 code \
donatien 0:8e01dca41002 822 }
donatien 0:8e01dca41002 823 #define NAKCILONG(opt, neg, code) \
donatien 0:8e01dca41002 824 if (go->neg && \
donatien 0:8e01dca41002 825 len >= CILEN_LONG && \
donatien 0:8e01dca41002 826 p[1] == CILEN_LONG && \
donatien 0:8e01dca41002 827 p[0] == opt) { \
donatien 0:8e01dca41002 828 len -= CILEN_LONG; \
donatien 0:8e01dca41002 829 INCPTR(2, p); \
donatien 0:8e01dca41002 830 GETLONG(cilong, p); \
donatien 0:8e01dca41002 831 no.neg = 1; \
donatien 0:8e01dca41002 832 code \
donatien 0:8e01dca41002 833 }
donatien 0:8e01dca41002 834 #define NAKCILQR(opt, neg, code) \
donatien 0:8e01dca41002 835 if (go->neg && \
donatien 0:8e01dca41002 836 len >= CILEN_LQR && \
donatien 0:8e01dca41002 837 p[1] == CILEN_LQR && \
donatien 0:8e01dca41002 838 p[0] == opt) { \
donatien 0:8e01dca41002 839 len -= CILEN_LQR; \
donatien 0:8e01dca41002 840 INCPTR(2, p); \
donatien 0:8e01dca41002 841 GETSHORT(cishort, p); \
donatien 0:8e01dca41002 842 GETLONG(cilong, p); \
donatien 0:8e01dca41002 843 no.neg = 1; \
donatien 0:8e01dca41002 844 code \
donatien 0:8e01dca41002 845 }
donatien 0:8e01dca41002 846
donatien 0:8e01dca41002 847 /*
donatien 0:8e01dca41002 848 * We don't care if they want to send us smaller packets than
donatien 0:8e01dca41002 849 * we want. Therefore, accept any MRU less than what we asked for,
donatien 0:8e01dca41002 850 * but then ignore the new value when setting the MRU in the kernel.
donatien 0:8e01dca41002 851 * If they send us a bigger MRU than what we asked, accept it, up to
donatien 0:8e01dca41002 852 * the limit of the default MRU we'd get if we didn't negotiate.
donatien 0:8e01dca41002 853 */
donatien 0:8e01dca41002 854 if (go->neg_mru && go->mru != PPP_DEFMRU) {
donatien 0:8e01dca41002 855 NAKCISHORT(CI_MRU, neg_mru,
donatien 0:8e01dca41002 856 if (cishort <= wo->mru || cishort < PPP_DEFMRU) {
donatien 0:8e01dca41002 857 try.mru = cishort;
donatien 0:8e01dca41002 858 }
donatien 0:8e01dca41002 859 );
donatien 0:8e01dca41002 860 }
donatien 0:8e01dca41002 861
donatien 0:8e01dca41002 862 /*
donatien 0:8e01dca41002 863 * Add any characters they want to our (receive-side) asyncmap.
donatien 0:8e01dca41002 864 */
donatien 0:8e01dca41002 865 if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) {
donatien 0:8e01dca41002 866 NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
donatien 0:8e01dca41002 867 try.asyncmap = go->asyncmap | cilong;
donatien 0:8e01dca41002 868 );
donatien 0:8e01dca41002 869 }
donatien 0:8e01dca41002 870
donatien 0:8e01dca41002 871 /*
donatien 0:8e01dca41002 872 * If they've nak'd our authentication-protocol, check whether
donatien 0:8e01dca41002 873 * they are proposing a different protocol, or a different
donatien 0:8e01dca41002 874 * hash algorithm for CHAP.
donatien 0:8e01dca41002 875 */
donatien 0:8e01dca41002 876 if ((go->neg_chap || go->neg_upap)
donatien 0:8e01dca41002 877 && len >= CILEN_SHORT
donatien 0:8e01dca41002 878 && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {
donatien 0:8e01dca41002 879 cilen = p[1];
donatien 0:8e01dca41002 880 len -= cilen;
donatien 0:8e01dca41002 881 no.neg_chap = go->neg_chap;
donatien 0:8e01dca41002 882 no.neg_upap = go->neg_upap;
donatien 0:8e01dca41002 883 INCPTR(2, p);
donatien 0:8e01dca41002 884 GETSHORT(cishort, p);
donatien 0:8e01dca41002 885 if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
donatien 0:8e01dca41002 886 /*
donatien 0:8e01dca41002 887 * If we were asking for CHAP, they obviously don't want to do it.
donatien 0:8e01dca41002 888 * If we weren't asking for CHAP, then we were asking for PAP,
donatien 0:8e01dca41002 889 * in which case this Nak is bad.
donatien 0:8e01dca41002 890 */
donatien 0:8e01dca41002 891 if (!go->neg_chap) {
donatien 0:8e01dca41002 892 goto bad;
donatien 0:8e01dca41002 893 }
donatien 0:8e01dca41002 894 try.neg_chap = 0;
donatien 0:8e01dca41002 895
donatien 0:8e01dca41002 896 } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
donatien 0:8e01dca41002 897 GETCHAR(cichar, p);
donatien 0:8e01dca41002 898 if (go->neg_chap) {
donatien 0:8e01dca41002 899 /*
donatien 0:8e01dca41002 900 * We were asking for CHAP/MD5; they must want a different
donatien 0:8e01dca41002 901 * algorithm. If they can't do MD5, we'll have to stop
donatien 0:8e01dca41002 902 * asking for CHAP.
donatien 0:8e01dca41002 903 */
donatien 0:8e01dca41002 904 if (cichar != go->chap_mdtype) {
donatien 0:8e01dca41002 905 try.neg_chap = 0;
donatien 0:8e01dca41002 906 }
donatien 0:8e01dca41002 907 } else {
donatien 0:8e01dca41002 908 /*
donatien 0:8e01dca41002 909 * Stop asking for PAP if we were asking for it.
donatien 0:8e01dca41002 910 */
donatien 0:8e01dca41002 911 try.neg_upap = 0;
donatien 0:8e01dca41002 912 }
donatien 0:8e01dca41002 913
donatien 0:8e01dca41002 914 } else {
donatien 0:8e01dca41002 915 /*
donatien 0:8e01dca41002 916 * We don't recognize what they're suggesting.
donatien 0:8e01dca41002 917 * Stop asking for what we were asking for.
donatien 0:8e01dca41002 918 */
donatien 0:8e01dca41002 919 if (go->neg_chap) {
donatien 0:8e01dca41002 920 try.neg_chap = 0;
donatien 0:8e01dca41002 921 } else {
donatien 0:8e01dca41002 922 try.neg_upap = 0;
donatien 0:8e01dca41002 923 }
donatien 0:8e01dca41002 924 p += cilen - CILEN_SHORT;
donatien 0:8e01dca41002 925 }
donatien 0:8e01dca41002 926 }
donatien 0:8e01dca41002 927
donatien 0:8e01dca41002 928 /*
donatien 0:8e01dca41002 929 * If they can't cope with our link quality protocol, we'll have
donatien 0:8e01dca41002 930 * to stop asking for LQR. We haven't got any other protocol.
donatien 0:8e01dca41002 931 * If they Nak the reporting period, take their value XXX ?
donatien 0:8e01dca41002 932 */
donatien 0:8e01dca41002 933 NAKCILQR(CI_QUALITY, neg_lqr,
donatien 0:8e01dca41002 934 if (cishort != PPP_LQR) {
donatien 0:8e01dca41002 935 try.neg_lqr = 0;
donatien 0:8e01dca41002 936 } else {
donatien 0:8e01dca41002 937 try.lqr_period = cilong;
donatien 0:8e01dca41002 938 }
donatien 0:8e01dca41002 939 );
donatien 0:8e01dca41002 940
donatien 0:8e01dca41002 941 /*
donatien 0:8e01dca41002 942 * Only implementing CBCP...not the rest of the callback options
donatien 0:8e01dca41002 943 */
donatien 0:8e01dca41002 944 NAKCICHAR(CI_CALLBACK, neg_cbcp,
donatien 0:8e01dca41002 945 try.neg_cbcp = 0;
donatien 0:8e01dca41002 946 );
donatien 0:8e01dca41002 947
donatien 0:8e01dca41002 948 /*
donatien 0:8e01dca41002 949 * Check for a looped-back line.
donatien 0:8e01dca41002 950 */
donatien 0:8e01dca41002 951 NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
donatien 0:8e01dca41002 952 try.magicnumber = magic();
donatien 0:8e01dca41002 953 looped_back = 1;
donatien 0:8e01dca41002 954 );
donatien 0:8e01dca41002 955
donatien 0:8e01dca41002 956 /*
donatien 0:8e01dca41002 957 * Peer shouldn't send Nak for protocol compression or
donatien 0:8e01dca41002 958 * address/control compression requests; they should send
donatien 0:8e01dca41002 959 * a Reject instead. If they send a Nak, treat it as a Reject.
donatien 0:8e01dca41002 960 */
donatien 0:8e01dca41002 961 NAKCIVOID(CI_PCOMPRESSION, neg_pcompression,
donatien 0:8e01dca41002 962 try.neg_pcompression = 0;
donatien 0:8e01dca41002 963 );
donatien 0:8e01dca41002 964 NAKCIVOID(CI_ACCOMPRESSION, neg_accompression,
donatien 0:8e01dca41002 965 try.neg_accompression = 0;
donatien 0:8e01dca41002 966 );
donatien 0:8e01dca41002 967
donatien 0:8e01dca41002 968 /*
donatien 0:8e01dca41002 969 * There may be remaining CIs, if the peer is requesting negotiation
donatien 0:8e01dca41002 970 * on an option that we didn't include in our request packet.
donatien 0:8e01dca41002 971 * If we see an option that we requested, or one we've already seen
donatien 0:8e01dca41002 972 * in this packet, then this packet is bad.
donatien 0:8e01dca41002 973 * If we wanted to respond by starting to negotiate on the requested
donatien 0:8e01dca41002 974 * option(s), we could, but we don't, because except for the
donatien 0:8e01dca41002 975 * authentication type and quality protocol, if we are not negotiating
donatien 0:8e01dca41002 976 * an option, it is because we were told not to.
donatien 0:8e01dca41002 977 * For the authentication type, the Nak from the peer means
donatien 0:8e01dca41002 978 * `let me authenticate myself with you' which is a bit pointless.
donatien 0:8e01dca41002 979 * For the quality protocol, the Nak means `ask me to send you quality
donatien 0:8e01dca41002 980 * reports', but if we didn't ask for them, we don't want them.
donatien 0:8e01dca41002 981 * An option we don't recognize represents the peer asking to
donatien 0:8e01dca41002 982 * negotiate some option we don't support, so ignore it.
donatien 0:8e01dca41002 983 */
donatien 0:8e01dca41002 984 while (len > CILEN_VOID) {
donatien 0:8e01dca41002 985 GETCHAR(citype, p);
donatien 0:8e01dca41002 986 GETCHAR(cilen, p);
donatien 0:8e01dca41002 987 if (cilen < CILEN_VOID || (len -= cilen) < 0) {
donatien 0:8e01dca41002 988 goto bad;
donatien 0:8e01dca41002 989 }
donatien 0:8e01dca41002 990 next = p + cilen - 2;
donatien 0:8e01dca41002 991
donatien 0:8e01dca41002 992 switch (citype) {
donatien 0:8e01dca41002 993 case CI_MRU:
donatien 0:8e01dca41002 994 if ((go->neg_mru && go->mru != PPP_DEFMRU)
donatien 0:8e01dca41002 995 || no.neg_mru || cilen != CILEN_SHORT) {
donatien 0:8e01dca41002 996 goto bad;
donatien 0:8e01dca41002 997 }
donatien 0:8e01dca41002 998 GETSHORT(cishort, p);
donatien 0:8e01dca41002 999 if (cishort < PPP_DEFMRU) {
donatien 0:8e01dca41002 1000 try.mru = cishort;
donatien 0:8e01dca41002 1001 }
donatien 0:8e01dca41002 1002 break;
donatien 0:8e01dca41002 1003 case CI_ASYNCMAP:
donatien 0:8e01dca41002 1004 if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl)
donatien 0:8e01dca41002 1005 || no.neg_asyncmap || cilen != CILEN_LONG) {
donatien 0:8e01dca41002 1006 goto bad;
donatien 0:8e01dca41002 1007 }
donatien 0:8e01dca41002 1008 break;
donatien 0:8e01dca41002 1009 case CI_AUTHTYPE:
donatien 0:8e01dca41002 1010 if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap) {
donatien 0:8e01dca41002 1011 goto bad;
donatien 0:8e01dca41002 1012 }
donatien 0:8e01dca41002 1013 break;
donatien 0:8e01dca41002 1014 case CI_MAGICNUMBER:
donatien 0:8e01dca41002 1015 if (go->neg_magicnumber || no.neg_magicnumber ||
donatien 0:8e01dca41002 1016 cilen != CILEN_LONG) {
donatien 0:8e01dca41002 1017 goto bad;
donatien 0:8e01dca41002 1018 }
donatien 0:8e01dca41002 1019 break;
donatien 0:8e01dca41002 1020 case CI_PCOMPRESSION:
donatien 0:8e01dca41002 1021 if (go->neg_pcompression || no.neg_pcompression
donatien 0:8e01dca41002 1022 || cilen != CILEN_VOID) {
donatien 0:8e01dca41002 1023 goto bad;
donatien 0:8e01dca41002 1024 }
donatien 0:8e01dca41002 1025 break;
donatien 0:8e01dca41002 1026 case CI_ACCOMPRESSION:
donatien 0:8e01dca41002 1027 if (go->neg_accompression || no.neg_accompression
donatien 0:8e01dca41002 1028 || cilen != CILEN_VOID) {
donatien 0:8e01dca41002 1029 goto bad;
donatien 0:8e01dca41002 1030 }
donatien 0:8e01dca41002 1031 break;
donatien 0:8e01dca41002 1032 case CI_QUALITY:
donatien 0:8e01dca41002 1033 if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR) {
donatien 0:8e01dca41002 1034 goto bad;
donatien 0:8e01dca41002 1035 }
donatien 0:8e01dca41002 1036 break;
donatien 0:8e01dca41002 1037 }
donatien 0:8e01dca41002 1038 p = next;
donatien 0:8e01dca41002 1039 }
donatien 0:8e01dca41002 1040
donatien 0:8e01dca41002 1041 /* If there is still anything left, this packet is bad. */
donatien 0:8e01dca41002 1042 if (len != 0) {
donatien 0:8e01dca41002 1043 goto bad;
donatien 0:8e01dca41002 1044 }
donatien 0:8e01dca41002 1045
donatien 0:8e01dca41002 1046 /*
donatien 0:8e01dca41002 1047 * OK, the Nak is good. Now we can update state.
donatien 0:8e01dca41002 1048 */
donatien 0:8e01dca41002 1049 if (f->state != LS_OPENED) {
donatien 0:8e01dca41002 1050 if (looped_back) {
donatien 0:8e01dca41002 1051 if (++try.numloops >= lcp_loopbackfail) {
donatien 0:8e01dca41002 1052 LCPDEBUG(LOG_NOTICE, ("Serial line is looped back.\n"));
donatien 0:8e01dca41002 1053 lcp_close(f->unit, "Loopback detected");
donatien 0:8e01dca41002 1054 }
donatien 0:8e01dca41002 1055 } else {
donatien 0:8e01dca41002 1056 try.numloops = 0;
donatien 0:8e01dca41002 1057 }
donatien 0:8e01dca41002 1058 *go = try;
donatien 0:8e01dca41002 1059 }
donatien 0:8e01dca41002 1060
donatien 0:8e01dca41002 1061 return 1;
donatien 0:8e01dca41002 1062
donatien 0:8e01dca41002 1063 bad:
donatien 0:8e01dca41002 1064 LCPDEBUG(LOG_WARNING, ("lcp_nakci: received bad Nak!\n"));
donatien 0:8e01dca41002 1065 return 0;
donatien 0:8e01dca41002 1066 }
donatien 0:8e01dca41002 1067
donatien 0:8e01dca41002 1068
donatien 0:8e01dca41002 1069 /*
donatien 0:8e01dca41002 1070 * lcp_rejci - Peer has Rejected some of our CIs.
donatien 0:8e01dca41002 1071 * This should not modify any state if the Reject is bad
donatien 0:8e01dca41002 1072 * or if LCP is in the LS_OPENED state.
donatien 0:8e01dca41002 1073 *
donatien 0:8e01dca41002 1074 * Returns:
donatien 0:8e01dca41002 1075 * 0 - Reject was bad.
donatien 0:8e01dca41002 1076 * 1 - Reject was good.
donatien 0:8e01dca41002 1077 */
donatien 0:8e01dca41002 1078 static int
donatien 0:8e01dca41002 1079 lcp_rejci(fsm *f, u_char *p, int len)
donatien 0:8e01dca41002 1080 {
donatien 0:8e01dca41002 1081 lcp_options *go = &lcp_gotoptions[f->unit];
donatien 0:8e01dca41002 1082 u_char cichar;
donatien 0:8e01dca41002 1083 u_short cishort;
donatien 0:8e01dca41002 1084 u32_t cilong;
donatien 0:8e01dca41002 1085 lcp_options try; /* options to request next time */
donatien 0:8e01dca41002 1086
donatien 0:8e01dca41002 1087 try = *go;
donatien 0:8e01dca41002 1088
donatien 0:8e01dca41002 1089 /*
donatien 0:8e01dca41002 1090 * Any Rejected CIs must be in exactly the same order that we sent.
donatien 0:8e01dca41002 1091 * Check packet length and CI length at each step.
donatien 0:8e01dca41002 1092 * If we find any deviations, then this packet is bad.
donatien 0:8e01dca41002 1093 */
donatien 0:8e01dca41002 1094 #define REJCIVOID(opt, neg) \
donatien 0:8e01dca41002 1095 if (go->neg && \
donatien 0:8e01dca41002 1096 len >= CILEN_VOID && \
donatien 0:8e01dca41002 1097 p[1] == CILEN_VOID && \
donatien 0:8e01dca41002 1098 p[0] == opt) { \
donatien 0:8e01dca41002 1099 len -= CILEN_VOID; \
donatien 0:8e01dca41002 1100 INCPTR(CILEN_VOID, p); \
donatien 0:8e01dca41002 1101 try.neg = 0; \
donatien 0:8e01dca41002 1102 LCPDEBUG(LOG_INFO, ("lcp_rejci: void opt %d rejected\n", opt)); \
donatien 0:8e01dca41002 1103 }
donatien 0:8e01dca41002 1104 #define REJCISHORT(opt, neg, val) \
donatien 0:8e01dca41002 1105 if (go->neg && \
donatien 0:8e01dca41002 1106 len >= CILEN_SHORT && \
donatien 0:8e01dca41002 1107 p[1] == CILEN_SHORT && \
donatien 0:8e01dca41002 1108 p[0] == opt) { \
donatien 0:8e01dca41002 1109 len -= CILEN_SHORT; \
donatien 0:8e01dca41002 1110 INCPTR(2, p); \
donatien 0:8e01dca41002 1111 GETSHORT(cishort, p); \
donatien 0:8e01dca41002 1112 /* Check rejected value. */ \
donatien 0:8e01dca41002 1113 if (cishort != val) { \
donatien 0:8e01dca41002 1114 goto bad; \
donatien 0:8e01dca41002 1115 } \
donatien 0:8e01dca41002 1116 try.neg = 0; \
donatien 0:8e01dca41002 1117 LCPDEBUG(LOG_INFO, ("lcp_rejci: short opt %d rejected\n", opt)); \
donatien 0:8e01dca41002 1118 }
donatien 0:8e01dca41002 1119 #define REJCICHAP(opt, neg, val, digest) \
donatien 0:8e01dca41002 1120 if (go->neg && \
donatien 0:8e01dca41002 1121 len >= CILEN_CHAP && \
donatien 0:8e01dca41002 1122 p[1] == CILEN_CHAP && \
donatien 0:8e01dca41002 1123 p[0] == opt) { \
donatien 0:8e01dca41002 1124 len -= CILEN_CHAP; \
donatien 0:8e01dca41002 1125 INCPTR(2, p); \
donatien 0:8e01dca41002 1126 GETSHORT(cishort, p); \
donatien 0:8e01dca41002 1127 GETCHAR(cichar, p); \
donatien 0:8e01dca41002 1128 /* Check rejected value. */ \
donatien 0:8e01dca41002 1129 if (cishort != val || cichar != digest) { \
donatien 0:8e01dca41002 1130 goto bad; \
donatien 0:8e01dca41002 1131 } \
donatien 0:8e01dca41002 1132 try.neg = 0; \
donatien 0:8e01dca41002 1133 try.neg_upap = 0; \
donatien 0:8e01dca41002 1134 LCPDEBUG(LOG_INFO, ("lcp_rejci: chap opt %d rejected\n", opt)); \
donatien 0:8e01dca41002 1135 }
donatien 0:8e01dca41002 1136 #define REJCILONG(opt, neg, val) \
donatien 0:8e01dca41002 1137 if (go->neg && \
donatien 0:8e01dca41002 1138 len >= CILEN_LONG && \
donatien 0:8e01dca41002 1139 p[1] == CILEN_LONG && \
donatien 0:8e01dca41002 1140 p[0] == opt) { \
donatien 0:8e01dca41002 1141 len -= CILEN_LONG; \
donatien 0:8e01dca41002 1142 INCPTR(2, p); \
donatien 0:8e01dca41002 1143 GETLONG(cilong, p); \
donatien 0:8e01dca41002 1144 /* Check rejected value. */ \
donatien 0:8e01dca41002 1145 if (cilong != val) { \
donatien 0:8e01dca41002 1146 goto bad; \
donatien 0:8e01dca41002 1147 } \
donatien 0:8e01dca41002 1148 try.neg = 0; \
donatien 0:8e01dca41002 1149 LCPDEBUG(LOG_INFO, ("lcp_rejci: long opt %d rejected\n", opt)); \
donatien 0:8e01dca41002 1150 }
donatien 0:8e01dca41002 1151 #define REJCILQR(opt, neg, val) \
donatien 0:8e01dca41002 1152 if (go->neg && \
donatien 0:8e01dca41002 1153 len >= CILEN_LQR && \
donatien 0:8e01dca41002 1154 p[1] == CILEN_LQR && \
donatien 0:8e01dca41002 1155 p[0] == opt) { \
donatien 0:8e01dca41002 1156 len -= CILEN_LQR; \
donatien 0:8e01dca41002 1157 INCPTR(2, p); \
donatien 0:8e01dca41002 1158 GETSHORT(cishort, p); \
donatien 0:8e01dca41002 1159 GETLONG(cilong, p); \
donatien 0:8e01dca41002 1160 /* Check rejected value. */ \
donatien 0:8e01dca41002 1161 if (cishort != PPP_LQR || cilong != val) { \
donatien 0:8e01dca41002 1162 goto bad; \
donatien 0:8e01dca41002 1163 } \
donatien 0:8e01dca41002 1164 try.neg = 0; \
donatien 0:8e01dca41002 1165 LCPDEBUG(LOG_INFO, ("lcp_rejci: LQR opt %d rejected\n", opt)); \
donatien 0:8e01dca41002 1166 }
donatien 0:8e01dca41002 1167 #define REJCICBCP(opt, neg, val) \
donatien 0:8e01dca41002 1168 if (go->neg && \
donatien 0:8e01dca41002 1169 len >= CILEN_CBCP && \
donatien 0:8e01dca41002 1170 p[1] == CILEN_CBCP && \
donatien 0:8e01dca41002 1171 p[0] == opt) { \
donatien 0:8e01dca41002 1172 len -= CILEN_CBCP; \
donatien 0:8e01dca41002 1173 INCPTR(2, p); \
donatien 0:8e01dca41002 1174 GETCHAR(cichar, p); \
donatien 0:8e01dca41002 1175 /* Check rejected value. */ \
donatien 0:8e01dca41002 1176 if (cichar != val) { \
donatien 0:8e01dca41002 1177 goto bad; \
donatien 0:8e01dca41002 1178 } \
donatien 0:8e01dca41002 1179 try.neg = 0; \
donatien 0:8e01dca41002 1180 LCPDEBUG(LOG_INFO, ("lcp_rejci: Callback opt %d rejected\n", opt)); \
donatien 0:8e01dca41002 1181 }
donatien 0:8e01dca41002 1182
donatien 0:8e01dca41002 1183 REJCISHORT(CI_MRU, neg_mru, go->mru);
donatien 0:8e01dca41002 1184 REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
donatien 0:8e01dca41002 1185 REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype);
donatien 0:8e01dca41002 1186 if (!go->neg_chap) {
donatien 0:8e01dca41002 1187 REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
donatien 0:8e01dca41002 1188 }
donatien 0:8e01dca41002 1189 REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
donatien 0:8e01dca41002 1190 REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);
donatien 0:8e01dca41002 1191 REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
donatien 0:8e01dca41002 1192 REJCIVOID(CI_PCOMPRESSION, neg_pcompression);
donatien 0:8e01dca41002 1193 REJCIVOID(CI_ACCOMPRESSION, neg_accompression);
donatien 0:8e01dca41002 1194
donatien 0:8e01dca41002 1195 /*
donatien 0:8e01dca41002 1196 * If there are any remaining CIs, then this packet is bad.
donatien 0:8e01dca41002 1197 */
donatien 0:8e01dca41002 1198 if (len != 0) {
donatien 0:8e01dca41002 1199 goto bad;
donatien 0:8e01dca41002 1200 }
donatien 0:8e01dca41002 1201 /*
donatien 0:8e01dca41002 1202 * Now we can update state.
donatien 0:8e01dca41002 1203 */
donatien 0:8e01dca41002 1204 if (f->state != LS_OPENED) {
donatien 0:8e01dca41002 1205 *go = try;
donatien 0:8e01dca41002 1206 }
donatien 0:8e01dca41002 1207 return 1;
donatien 0:8e01dca41002 1208
donatien 0:8e01dca41002 1209 bad:
donatien 0:8e01dca41002 1210 LCPDEBUG(LOG_WARNING, ("lcp_rejci: received bad Reject!\n"));
donatien 0:8e01dca41002 1211 return 0;
donatien 0:8e01dca41002 1212 }
donatien 0:8e01dca41002 1213
donatien 0:8e01dca41002 1214
donatien 0:8e01dca41002 1215 /*
donatien 0:8e01dca41002 1216 * lcp_reqci - Check the peer's requested CIs and send appropriate response.
donatien 0:8e01dca41002 1217 *
donatien 0:8e01dca41002 1218 * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
donatien 0:8e01dca41002 1219 * appropriately. If reject_if_disagree is non-zero, doesn't return
donatien 0:8e01dca41002 1220 * CONFNAK; returns CONFREJ if it can't return CONFACK.
donatien 0:8e01dca41002 1221 */
donatien 0:8e01dca41002 1222 static int
donatien 0:8e01dca41002 1223 lcp_reqci(fsm *f,
donatien 0:8e01dca41002 1224 u_char *inp, /* Requested CIs */
donatien 0:8e01dca41002 1225 int *lenp, /* Length of requested CIs */
donatien 0:8e01dca41002 1226 int reject_if_disagree)
donatien 0:8e01dca41002 1227 {
donatien 0:8e01dca41002 1228 lcp_options *go = &lcp_gotoptions[f->unit];
donatien 0:8e01dca41002 1229 lcp_options *ho = &lcp_hisoptions[f->unit];
donatien 0:8e01dca41002 1230 lcp_options *ao = &lcp_allowoptions[f->unit];
donatien 0:8e01dca41002 1231 u_char *cip, *next; /* Pointer to current and next CIs */
donatien 0:8e01dca41002 1232 int cilen, citype; /* Parsed len, type */
donatien 0:8e01dca41002 1233 u_char cichar; /* Parsed char value */
donatien 0:8e01dca41002 1234 u_short cishort; /* Parsed short value */
donatien 0:8e01dca41002 1235 u32_t cilong; /* Parse long value */
donatien 0:8e01dca41002 1236 int rc = CONFACK; /* Final packet return code */
donatien 0:8e01dca41002 1237 int orc; /* Individual option return code */
donatien 0:8e01dca41002 1238 u_char *p; /* Pointer to next char to parse */
donatien 0:8e01dca41002 1239 u_char *rejp; /* Pointer to next char in reject frame */
donatien 0:8e01dca41002 1240 u_char *nakp; /* Pointer to next char in Nak frame */
donatien 0:8e01dca41002 1241 int l = *lenp; /* Length left */
donatien 0:8e01dca41002 1242 #if TRACELCP > 0
donatien 0:8e01dca41002 1243 char traceBuf[80];
donatien 0:8e01dca41002 1244 size_t traceNdx = 0;
donatien 0:8e01dca41002 1245 #endif
donatien 0:8e01dca41002 1246
donatien 0:8e01dca41002 1247 /*
donatien 0:8e01dca41002 1248 * Reset all his options.
donatien 0:8e01dca41002 1249 */
donatien 0:8e01dca41002 1250 BZERO(ho, sizeof(*ho));
donatien 0:8e01dca41002 1251
donatien 0:8e01dca41002 1252 /*
donatien 0:8e01dca41002 1253 * Process all his options.
donatien 0:8e01dca41002 1254 */
donatien 0:8e01dca41002 1255 next = inp;
donatien 0:8e01dca41002 1256 nakp = nak_buffer;
donatien 0:8e01dca41002 1257 rejp = inp;
donatien 0:8e01dca41002 1258 while (l) {
donatien 0:8e01dca41002 1259 orc = CONFACK; /* Assume success */
donatien 0:8e01dca41002 1260 cip = p = next; /* Remember begining of CI */
donatien 0:8e01dca41002 1261 if (l < 2 || /* Not enough data for CI header or */
donatien 0:8e01dca41002 1262 p[1] < 2 || /* CI length too small or */
donatien 0:8e01dca41002 1263 p[1] > l) { /* CI length too big? */
donatien 0:8e01dca41002 1264 LCPDEBUG(LOG_WARNING, ("lcp_reqci: bad CI length!\n"));
donatien 0:8e01dca41002 1265 orc = CONFREJ; /* Reject bad CI */
donatien 0:8e01dca41002 1266 cilen = l; /* Reject till end of packet */
donatien 0:8e01dca41002 1267 l = 0; /* Don't loop again */
donatien 0:8e01dca41002 1268 citype = 0;
donatien 0:8e01dca41002 1269 goto endswitch;
donatien 0:8e01dca41002 1270 }
donatien 0:8e01dca41002 1271 GETCHAR(citype, p); /* Parse CI type */
donatien 0:8e01dca41002 1272 GETCHAR(cilen, p); /* Parse CI length */
donatien 0:8e01dca41002 1273 l -= cilen; /* Adjust remaining length */
donatien 0:8e01dca41002 1274 next += cilen; /* Step to next CI */
donatien 0:8e01dca41002 1275
donatien 0:8e01dca41002 1276 switch (citype) { /* Check CI type */
donatien 0:8e01dca41002 1277 case CI_MRU:
donatien 0:8e01dca41002 1278 if (!ao->neg_mru) { /* Allow option? */
donatien 0:8e01dca41002 1279 LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject MRU - not allowed\n"));
donatien 0:8e01dca41002 1280 orc = CONFREJ; /* Reject CI */
donatien 0:8e01dca41002 1281 break;
donatien 0:8e01dca41002 1282 } else if (cilen != CILEN_SHORT) { /* Check CI length */
donatien 0:8e01dca41002 1283 LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject MRU - bad length\n"));
donatien 0:8e01dca41002 1284 orc = CONFREJ; /* Reject CI */
donatien 0:8e01dca41002 1285 break;
donatien 0:8e01dca41002 1286 }
donatien 0:8e01dca41002 1287 GETSHORT(cishort, p); /* Parse MRU */
donatien 0:8e01dca41002 1288
donatien 0:8e01dca41002 1289 /*
donatien 0:8e01dca41002 1290 * He must be able to receive at least our minimum.
donatien 0:8e01dca41002 1291 * No need to check a maximum. If he sends a large number,
donatien 0:8e01dca41002 1292 * we'll just ignore it.
donatien 0:8e01dca41002 1293 */
donatien 0:8e01dca41002 1294 if (cishort < PPP_MINMRU) {
donatien 0:8e01dca41002 1295 LCPDEBUG(LOG_INFO, ("lcp_reqci: Nak - MRU too small\n"));
donatien 0:8e01dca41002 1296 orc = CONFNAK; /* Nak CI */
donatien 0:8e01dca41002 1297 PUTCHAR(CI_MRU, nakp);
donatien 0:8e01dca41002 1298 PUTCHAR(CILEN_SHORT, nakp);
donatien 0:8e01dca41002 1299 PUTSHORT(PPP_MINMRU, nakp); /* Give him a hint */
donatien 0:8e01dca41002 1300 break;
donatien 0:8e01dca41002 1301 }
donatien 0:8e01dca41002 1302 ho->neg_mru = 1; /* Remember he sent MRU */
donatien 0:8e01dca41002 1303 ho->mru = cishort; /* And remember value */
donatien 0:8e01dca41002 1304 #if TRACELCP > 0
donatien 0:8e01dca41002 1305 snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MRU %d", cishort);
donatien 0:8e01dca41002 1306 traceNdx = strlen(traceBuf);
donatien 0:8e01dca41002 1307 #endif
donatien 0:8e01dca41002 1308 break;
donatien 0:8e01dca41002 1309
donatien 0:8e01dca41002 1310 case CI_ASYNCMAP:
donatien 0:8e01dca41002 1311 if (!ao->neg_asyncmap) {
donatien 0:8e01dca41002 1312 LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject ASYNCMAP not allowed\n"));
donatien 0:8e01dca41002 1313 orc = CONFREJ;
donatien 0:8e01dca41002 1314 break;
donatien 0:8e01dca41002 1315 } else if (cilen != CILEN_LONG) {
donatien 0:8e01dca41002 1316 LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject ASYNCMAP bad length\n"));
donatien 0:8e01dca41002 1317 orc = CONFREJ;
donatien 0:8e01dca41002 1318 break;
donatien 0:8e01dca41002 1319 }
donatien 0:8e01dca41002 1320 GETLONG(cilong, p);
donatien 0:8e01dca41002 1321
donatien 0:8e01dca41002 1322 /*
donatien 0:8e01dca41002 1323 * Asyncmap must have set at least the bits
donatien 0:8e01dca41002 1324 * which are set in lcp_allowoptions[unit].asyncmap.
donatien 0:8e01dca41002 1325 */
donatien 0:8e01dca41002 1326 if ((ao->asyncmap & ~cilong) != 0) {
donatien 0:8e01dca41002 1327 LCPDEBUG(LOG_INFO, ("lcp_reqci: Nak ASYNCMAP %lX missing %lX\n",
donatien 0:8e01dca41002 1328 cilong, ao->asyncmap));
donatien 0:8e01dca41002 1329 orc = CONFNAK;
donatien 0:8e01dca41002 1330 PUTCHAR(CI_ASYNCMAP, nakp);
donatien 0:8e01dca41002 1331 PUTCHAR(CILEN_LONG, nakp);
donatien 0:8e01dca41002 1332 PUTLONG(ao->asyncmap | cilong, nakp);
donatien 0:8e01dca41002 1333 break;
donatien 0:8e01dca41002 1334 }
donatien 0:8e01dca41002 1335 ho->neg_asyncmap = 1;
donatien 0:8e01dca41002 1336 ho->asyncmap = cilong;
donatien 0:8e01dca41002 1337 #if TRACELCP > 0
donatien 0:8e01dca41002 1338 snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ASYNCMAP=%lX", cilong);
donatien 0:8e01dca41002 1339 traceNdx = strlen(traceBuf);
donatien 0:8e01dca41002 1340 #endif
donatien 0:8e01dca41002 1341 break;
donatien 0:8e01dca41002 1342
donatien 0:8e01dca41002 1343 case CI_AUTHTYPE:
donatien 0:8e01dca41002 1344 if (cilen < CILEN_SHORT) {
donatien 0:8e01dca41002 1345 LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject AUTHTYPE missing arg\n"));
donatien 0:8e01dca41002 1346 orc = CONFREJ;
donatien 0:8e01dca41002 1347 break;
donatien 0:8e01dca41002 1348 } else if (!(ao->neg_upap || ao->neg_chap)) {
donatien 0:8e01dca41002 1349 /*
donatien 0:8e01dca41002 1350 * Reject the option if we're not willing to authenticate.
donatien 0:8e01dca41002 1351 */
donatien 0:8e01dca41002 1352 LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject AUTHTYPE not allowed\n"));
donatien 0:8e01dca41002 1353 orc = CONFREJ;
donatien 0:8e01dca41002 1354 break;
donatien 0:8e01dca41002 1355 }
donatien 0:8e01dca41002 1356 GETSHORT(cishort, p);
donatien 0:8e01dca41002 1357
donatien 0:8e01dca41002 1358 /*
donatien 0:8e01dca41002 1359 * Authtype must be UPAP or CHAP.
donatien 0:8e01dca41002 1360 *
donatien 0:8e01dca41002 1361 * Note: if both ao->neg_upap and ao->neg_chap are set,
donatien 0:8e01dca41002 1362 * and the peer sends a Configure-Request with two
donatien 0:8e01dca41002 1363 * authenticate-protocol requests, one for CHAP and one
donatien 0:8e01dca41002 1364 * for UPAP, then we will reject the second request.
donatien 0:8e01dca41002 1365 * Whether we end up doing CHAP or UPAP depends then on
donatien 0:8e01dca41002 1366 * the ordering of the CIs in the peer's Configure-Request.
donatien 0:8e01dca41002 1367 */
donatien 0:8e01dca41002 1368
donatien 0:8e01dca41002 1369 if (cishort == PPP_PAP) {
donatien 0:8e01dca41002 1370 if (ho->neg_chap) { /* we've already accepted CHAP */
donatien 0:8e01dca41002 1371 LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE PAP already accepted\n"));
donatien 0:8e01dca41002 1372 orc = CONFREJ;
donatien 0:8e01dca41002 1373 break;
donatien 0:8e01dca41002 1374 } else if (cilen != CILEN_SHORT) {
donatien 0:8e01dca41002 1375 LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE PAP bad len\n"));
donatien 0:8e01dca41002 1376 orc = CONFREJ;
donatien 0:8e01dca41002 1377 break;
donatien 0:8e01dca41002 1378 }
donatien 0:8e01dca41002 1379 if (!ao->neg_upap) { /* we don't want to do PAP */
donatien 0:8e01dca41002 1380 LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE PAP not allowed\n"));
donatien 0:8e01dca41002 1381 orc = CONFNAK; /* NAK it and suggest CHAP */
donatien 0:8e01dca41002 1382 PUTCHAR(CI_AUTHTYPE, nakp);
donatien 0:8e01dca41002 1383 PUTCHAR(CILEN_CHAP, nakp);
donatien 0:8e01dca41002 1384 PUTSHORT(PPP_CHAP, nakp);
donatien 0:8e01dca41002 1385 PUTCHAR(ao->chap_mdtype, nakp);
donatien 0:8e01dca41002 1386 break;
donatien 0:8e01dca41002 1387 }
donatien 0:8e01dca41002 1388 ho->neg_upap = 1;
donatien 0:8e01dca41002 1389 #if TRACELCP > 0
donatien 0:8e01dca41002 1390 snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PAP (%X)", cishort);
donatien 0:8e01dca41002 1391 traceNdx = strlen(traceBuf);
donatien 0:8e01dca41002 1392 #endif
donatien 0:8e01dca41002 1393 break;
donatien 0:8e01dca41002 1394 }
donatien 0:8e01dca41002 1395 if (cishort == PPP_CHAP) {
donatien 0:8e01dca41002 1396 if (ho->neg_upap) { /* we've already accepted PAP */
donatien 0:8e01dca41002 1397 LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE CHAP accepted PAP\n"));
donatien 0:8e01dca41002 1398 orc = CONFREJ;
donatien 0:8e01dca41002 1399 break;
donatien 0:8e01dca41002 1400 } else if (cilen != CILEN_CHAP) {
donatien 0:8e01dca41002 1401 LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE CHAP bad len\n"));
donatien 0:8e01dca41002 1402 orc = CONFREJ;
donatien 0:8e01dca41002 1403 break;
donatien 0:8e01dca41002 1404 }
donatien 0:8e01dca41002 1405 if (!ao->neg_chap) { /* we don't want to do CHAP */
donatien 0:8e01dca41002 1406 LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE CHAP not allowed\n"));
donatien 0:8e01dca41002 1407 orc = CONFNAK; /* NAK it and suggest PAP */
donatien 0:8e01dca41002 1408 PUTCHAR(CI_AUTHTYPE, nakp);
donatien 0:8e01dca41002 1409 PUTCHAR(CILEN_SHORT, nakp);
donatien 0:8e01dca41002 1410 PUTSHORT(PPP_PAP, nakp);
donatien 0:8e01dca41002 1411 break;
donatien 0:8e01dca41002 1412 }
donatien 0:8e01dca41002 1413 GETCHAR(cichar, p); /* get digest type*/
donatien 0:8e01dca41002 1414 if (cichar != CHAP_DIGEST_MD5
donatien 0:8e01dca41002 1415 #if MSCHAP_SUPPORT
donatien 0:8e01dca41002 1416 && cichar != CHAP_MICROSOFT
donatien 0:8e01dca41002 1417 #endif
donatien 0:8e01dca41002 1418 ) {
donatien 0:8e01dca41002 1419 LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE CHAP digest=%d\n", (int)cichar));
donatien 0:8e01dca41002 1420 orc = CONFNAK;
donatien 0:8e01dca41002 1421 PUTCHAR(CI_AUTHTYPE, nakp);
donatien 0:8e01dca41002 1422 PUTCHAR(CILEN_CHAP, nakp);
donatien 0:8e01dca41002 1423 PUTSHORT(PPP_CHAP, nakp);
donatien 0:8e01dca41002 1424 PUTCHAR(ao->chap_mdtype, nakp);
donatien 0:8e01dca41002 1425 break;
donatien 0:8e01dca41002 1426 }
donatien 0:8e01dca41002 1427 #if TRACELCP > 0
donatien 0:8e01dca41002 1428 snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CHAP %X,%d", cishort, (int)cichar);
donatien 0:8e01dca41002 1429 traceNdx = strlen(traceBuf);
donatien 0:8e01dca41002 1430 #endif
donatien 0:8e01dca41002 1431 ho->chap_mdtype = cichar; /* save md type */
donatien 0:8e01dca41002 1432 ho->neg_chap = 1;
donatien 0:8e01dca41002 1433 break;
donatien 0:8e01dca41002 1434 }
donatien 0:8e01dca41002 1435
donatien 0:8e01dca41002 1436 /*
donatien 0:8e01dca41002 1437 * We don't recognize the protocol they're asking for.
donatien 0:8e01dca41002 1438 * Nak it with something we're willing to do.
donatien 0:8e01dca41002 1439 * (At this point we know ao->neg_upap || ao->neg_chap.)
donatien 0:8e01dca41002 1440 */
donatien 0:8e01dca41002 1441 orc = CONFNAK;
donatien 0:8e01dca41002 1442 PUTCHAR(CI_AUTHTYPE, nakp);
donatien 0:8e01dca41002 1443 if (ao->neg_chap) {
donatien 0:8e01dca41002 1444 LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE %d req CHAP\n", cishort));
donatien 0:8e01dca41002 1445 PUTCHAR(CILEN_CHAP, nakp);
donatien 0:8e01dca41002 1446 PUTSHORT(PPP_CHAP, nakp);
donatien 0:8e01dca41002 1447 PUTCHAR(ao->chap_mdtype, nakp);
donatien 0:8e01dca41002 1448 } else {
donatien 0:8e01dca41002 1449 LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE %d req PAP\n", cishort));
donatien 0:8e01dca41002 1450 PUTCHAR(CILEN_SHORT, nakp);
donatien 0:8e01dca41002 1451 PUTSHORT(PPP_PAP, nakp);
donatien 0:8e01dca41002 1452 }
donatien 0:8e01dca41002 1453 break;
donatien 0:8e01dca41002 1454
donatien 0:8e01dca41002 1455 case CI_QUALITY:
donatien 0:8e01dca41002 1456 GETSHORT(cishort, p);
donatien 0:8e01dca41002 1457 GETLONG(cilong, p);
donatien 0:8e01dca41002 1458 #if TRACELCP > 0
donatien 0:8e01dca41002 1459 snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " QUALITY (%x %x)", cishort, (unsigned int) cilong);
donatien 0:8e01dca41002 1460 traceNdx = strlen(traceBuf);
donatien 0:8e01dca41002 1461 #endif
donatien 0:8e01dca41002 1462
donatien 0:8e01dca41002 1463 if (!ao->neg_lqr ||
donatien 0:8e01dca41002 1464 cilen != CILEN_LQR) {
donatien 0:8e01dca41002 1465 orc = CONFREJ;
donatien 0:8e01dca41002 1466 break;
donatien 0:8e01dca41002 1467 }
donatien 0:8e01dca41002 1468
donatien 0:8e01dca41002 1469 /*
donatien 0:8e01dca41002 1470 * Check the protocol and the reporting period.
donatien 0:8e01dca41002 1471 * XXX When should we Nak this, and what with?
donatien 0:8e01dca41002 1472 */
donatien 0:8e01dca41002 1473 if (cishort != PPP_LQR) {
donatien 0:8e01dca41002 1474 orc = CONFNAK;
donatien 0:8e01dca41002 1475 PUTCHAR(CI_QUALITY, nakp);
donatien 0:8e01dca41002 1476 PUTCHAR(CILEN_LQR, nakp);
donatien 0:8e01dca41002 1477 PUTSHORT(PPP_LQR, nakp);
donatien 0:8e01dca41002 1478 PUTLONG(ao->lqr_period, nakp);
donatien 0:8e01dca41002 1479 break;
donatien 0:8e01dca41002 1480 }
donatien 0:8e01dca41002 1481 break;
donatien 0:8e01dca41002 1482
donatien 0:8e01dca41002 1483 case CI_MAGICNUMBER:
donatien 0:8e01dca41002 1484 if (!(ao->neg_magicnumber || go->neg_magicnumber) ||
donatien 0:8e01dca41002 1485 cilen != CILEN_LONG) {
donatien 0:8e01dca41002 1486 orc = CONFREJ;
donatien 0:8e01dca41002 1487 break;
donatien 0:8e01dca41002 1488 }
donatien 0:8e01dca41002 1489 GETLONG(cilong, p);
donatien 0:8e01dca41002 1490 #if TRACELCP > 0
donatien 0:8e01dca41002 1491 snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MAGICNUMBER (%lX)", cilong);
donatien 0:8e01dca41002 1492 traceNdx = strlen(traceBuf);
donatien 0:8e01dca41002 1493 #endif
donatien 0:8e01dca41002 1494
donatien 0:8e01dca41002 1495 /*
donatien 0:8e01dca41002 1496 * He must have a different magic number.
donatien 0:8e01dca41002 1497 */
donatien 0:8e01dca41002 1498 if (go->neg_magicnumber &&
donatien 0:8e01dca41002 1499 cilong == go->magicnumber) {
donatien 0:8e01dca41002 1500 cilong = magic(); /* Don't put magic() inside macro! */
donatien 0:8e01dca41002 1501 orc = CONFNAK;
donatien 0:8e01dca41002 1502 PUTCHAR(CI_MAGICNUMBER, nakp);
donatien 0:8e01dca41002 1503 PUTCHAR(CILEN_LONG, nakp);
donatien 0:8e01dca41002 1504 PUTLONG(cilong, nakp);
donatien 0:8e01dca41002 1505 break;
donatien 0:8e01dca41002 1506 }
donatien 0:8e01dca41002 1507 ho->neg_magicnumber = 1;
donatien 0:8e01dca41002 1508 ho->magicnumber = cilong;
donatien 0:8e01dca41002 1509 break;
donatien 0:8e01dca41002 1510
donatien 0:8e01dca41002 1511
donatien 0:8e01dca41002 1512 case CI_PCOMPRESSION:
donatien 0:8e01dca41002 1513 #if TRACELCP > 0
donatien 0:8e01dca41002 1514 snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PCOMPRESSION");
donatien 0:8e01dca41002 1515 traceNdx = strlen(traceBuf);
donatien 0:8e01dca41002 1516 #endif
donatien 0:8e01dca41002 1517 if (!ao->neg_pcompression ||
donatien 0:8e01dca41002 1518 cilen != CILEN_VOID) {
donatien 0:8e01dca41002 1519 orc = CONFREJ;
donatien 0:8e01dca41002 1520 break;
donatien 0:8e01dca41002 1521 }
donatien 0:8e01dca41002 1522 ho->neg_pcompression = 1;
donatien 0:8e01dca41002 1523 break;
donatien 0:8e01dca41002 1524
donatien 0:8e01dca41002 1525 case CI_ACCOMPRESSION:
donatien 0:8e01dca41002 1526 #if TRACELCP > 0
donatien 0:8e01dca41002 1527 snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ACCOMPRESSION");
donatien 0:8e01dca41002 1528 traceNdx = strlen(traceBuf);
donatien 0:8e01dca41002 1529 #endif
donatien 0:8e01dca41002 1530 if (!ao->neg_accompression ||
donatien 0:8e01dca41002 1531 cilen != CILEN_VOID) {
donatien 0:8e01dca41002 1532 orc = CONFREJ;
donatien 0:8e01dca41002 1533 break;
donatien 0:8e01dca41002 1534 }
donatien 0:8e01dca41002 1535 ho->neg_accompression = 1;
donatien 0:8e01dca41002 1536 break;
donatien 0:8e01dca41002 1537
donatien 0:8e01dca41002 1538 case CI_MRRU:
donatien 0:8e01dca41002 1539 #if TRACELCP > 0
donatien 0:8e01dca41002 1540 snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_MRRU");
donatien 0:8e01dca41002 1541 traceNdx = strlen(traceBuf);
donatien 0:8e01dca41002 1542 #endif
donatien 0:8e01dca41002 1543 orc = CONFREJ;
donatien 0:8e01dca41002 1544 break;
donatien 0:8e01dca41002 1545
donatien 0:8e01dca41002 1546 case CI_SSNHF:
donatien 0:8e01dca41002 1547 #if TRACELCP > 0
donatien 0:8e01dca41002 1548 snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_SSNHF");
donatien 0:8e01dca41002 1549 traceNdx = strlen(traceBuf);
donatien 0:8e01dca41002 1550 #endif
donatien 0:8e01dca41002 1551 orc = CONFREJ;
donatien 0:8e01dca41002 1552 break;
donatien 0:8e01dca41002 1553
donatien 0:8e01dca41002 1554 case CI_EPDISC:
donatien 0:8e01dca41002 1555 #if TRACELCP > 0
donatien 0:8e01dca41002 1556 snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_EPDISC");
donatien 0:8e01dca41002 1557 traceNdx = strlen(traceBuf);
donatien 0:8e01dca41002 1558 #endif
donatien 0:8e01dca41002 1559 orc = CONFREJ;
donatien 0:8e01dca41002 1560 break;
donatien 0:8e01dca41002 1561
donatien 0:8e01dca41002 1562 default:
donatien 0:8e01dca41002 1563 #if TRACELCP
donatien 0:8e01dca41002 1564 snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " unknown %d", citype);
donatien 0:8e01dca41002 1565 traceNdx = strlen(traceBuf);
donatien 0:8e01dca41002 1566 #endif
donatien 0:8e01dca41002 1567 orc = CONFREJ;
donatien 0:8e01dca41002 1568 break;
donatien 0:8e01dca41002 1569 }
donatien 0:8e01dca41002 1570
donatien 0:8e01dca41002 1571 endswitch:
donatien 0:8e01dca41002 1572 #if TRACELCP
donatien 0:8e01dca41002 1573 if (traceNdx >= 80 - 32) {
donatien 0:8e01dca41002 1574 LCPDEBUG(LOG_INFO, ("lcp_reqci: rcvd%s\n", traceBuf));
donatien 0:8e01dca41002 1575 traceNdx = 0;
donatien 0:8e01dca41002 1576 }
donatien 0:8e01dca41002 1577 #endif
donatien 0:8e01dca41002 1578 if (orc == CONFACK && /* Good CI */
donatien 0:8e01dca41002 1579 rc != CONFACK) { /* but prior CI wasnt? */
donatien 0:8e01dca41002 1580 continue; /* Don't send this one */
donatien 0:8e01dca41002 1581 }
donatien 0:8e01dca41002 1582
donatien 0:8e01dca41002 1583 if (orc == CONFNAK) { /* Nak this CI? */
donatien 0:8e01dca41002 1584 if (reject_if_disagree /* Getting fed up with sending NAKs? */
donatien 0:8e01dca41002 1585 && citype != CI_MAGICNUMBER) {
donatien 0:8e01dca41002 1586 orc = CONFREJ; /* Get tough if so */
donatien 0:8e01dca41002 1587 } else {
donatien 0:8e01dca41002 1588 if (rc == CONFREJ) { /* Rejecting prior CI? */
donatien 0:8e01dca41002 1589 continue; /* Don't send this one */
donatien 0:8e01dca41002 1590 }
donatien 0:8e01dca41002 1591 rc = CONFNAK;
donatien 0:8e01dca41002 1592 }
donatien 0:8e01dca41002 1593 }
donatien 0:8e01dca41002 1594 if (orc == CONFREJ) { /* Reject this CI */
donatien 0:8e01dca41002 1595 rc = CONFREJ;
donatien 0:8e01dca41002 1596 if (cip != rejp) { /* Need to move rejected CI? */
donatien 0:8e01dca41002 1597 BCOPY(cip, rejp, cilen); /* Move it */
donatien 0:8e01dca41002 1598 }
donatien 0:8e01dca41002 1599 INCPTR(cilen, rejp); /* Update output pointer */
donatien 0:8e01dca41002 1600 }
donatien 0:8e01dca41002 1601 }
donatien 0:8e01dca41002 1602
donatien 0:8e01dca41002 1603 /*
donatien 0:8e01dca41002 1604 * If we wanted to send additional NAKs (for unsent CIs), the
donatien 0:8e01dca41002 1605 * code would go here. The extra NAKs would go at *nakp.
donatien 0:8e01dca41002 1606 * At present there are no cases where we want to ask the
donatien 0:8e01dca41002 1607 * peer to negotiate an option.
donatien 0:8e01dca41002 1608 */
donatien 0:8e01dca41002 1609
donatien 0:8e01dca41002 1610 switch (rc) {
donatien 0:8e01dca41002 1611 case CONFACK:
donatien 0:8e01dca41002 1612 *lenp = (int)(next - inp);
donatien 0:8e01dca41002 1613 break;
donatien 0:8e01dca41002 1614 case CONFNAK:
donatien 0:8e01dca41002 1615 /*
donatien 0:8e01dca41002 1616 * Copy the Nak'd options from the nak_buffer to the caller's buffer.
donatien 0:8e01dca41002 1617 */
donatien 0:8e01dca41002 1618 *lenp = (int)(nakp - nak_buffer);
donatien 0:8e01dca41002 1619 BCOPY(nak_buffer, inp, *lenp);
donatien 0:8e01dca41002 1620 break;
donatien 0:8e01dca41002 1621 case CONFREJ:
donatien 0:8e01dca41002 1622 *lenp = (int)(rejp - inp);
donatien 0:8e01dca41002 1623 break;
donatien 0:8e01dca41002 1624 }
donatien 0:8e01dca41002 1625
donatien 0:8e01dca41002 1626 #if TRACELCP > 0
donatien 0:8e01dca41002 1627 if (traceNdx > 0) {
donatien 0:8e01dca41002 1628 LCPDEBUG(LOG_INFO, ("lcp_reqci: %s\n", traceBuf));
donatien 0:8e01dca41002 1629 }
donatien 0:8e01dca41002 1630 #endif
donatien 0:8e01dca41002 1631 LCPDEBUG(LOG_INFO, ("lcp_reqci: returning CONF%s.\n", CODENAME(rc)));
donatien 0:8e01dca41002 1632 return (rc); /* Return final code */
donatien 0:8e01dca41002 1633 }
donatien 0:8e01dca41002 1634
donatien 0:8e01dca41002 1635
donatien 0:8e01dca41002 1636 /*
donatien 0:8e01dca41002 1637 * lcp_up - LCP has come UP.
donatien 0:8e01dca41002 1638 */
donatien 0:8e01dca41002 1639 static void
donatien 0:8e01dca41002 1640 lcp_up(fsm *f)
donatien 0:8e01dca41002 1641 {
donatien 0:8e01dca41002 1642 lcp_options *wo = &lcp_wantoptions[f->unit];
donatien 0:8e01dca41002 1643 lcp_options *ho = &lcp_hisoptions[f->unit];
donatien 0:8e01dca41002 1644 lcp_options *go = &lcp_gotoptions[f->unit];
donatien 0:8e01dca41002 1645 lcp_options *ao = &lcp_allowoptions[f->unit];
donatien 0:8e01dca41002 1646
donatien 0:8e01dca41002 1647 if (!go->neg_magicnumber) {
donatien 0:8e01dca41002 1648 go->magicnumber = 0;
donatien 0:8e01dca41002 1649 }
donatien 0:8e01dca41002 1650 if (!ho->neg_magicnumber) {
donatien 0:8e01dca41002 1651 ho->magicnumber = 0;
donatien 0:8e01dca41002 1652 }
donatien 0:8e01dca41002 1653
donatien 0:8e01dca41002 1654 /*
donatien 0:8e01dca41002 1655 * Set our MTU to the smaller of the MTU we wanted and
donatien 0:8e01dca41002 1656 * the MRU our peer wanted. If we negotiated an MRU,
donatien 0:8e01dca41002 1657 * set our MRU to the larger of value we wanted and
donatien 0:8e01dca41002 1658 * the value we got in the negotiation.
donatien 0:8e01dca41002 1659 */
donatien 0:8e01dca41002 1660 ppp_send_config(f->unit, LWIP_MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)),
donatien 0:8e01dca41002 1661 (ho->neg_asyncmap? ho->asyncmap: 0xffffffffl),
donatien 0:8e01dca41002 1662 ho->neg_pcompression, ho->neg_accompression);
donatien 0:8e01dca41002 1663 /*
donatien 0:8e01dca41002 1664 * If the asyncmap hasn't been negotiated, we really should
donatien 0:8e01dca41002 1665 * set the receive asyncmap to ffffffff, but we set it to 0
donatien 0:8e01dca41002 1666 * for backwards contemptibility.
donatien 0:8e01dca41002 1667 */
donatien 0:8e01dca41002 1668 ppp_recv_config(f->unit, (go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU),
donatien 0:8e01dca41002 1669 (go->neg_asyncmap? go->asyncmap: 0x00000000),
donatien 0:8e01dca41002 1670 go->neg_pcompression, go->neg_accompression);
donatien 0:8e01dca41002 1671
donatien 0:8e01dca41002 1672 if (ho->neg_mru) {
donatien 0:8e01dca41002 1673 peer_mru[f->unit] = ho->mru;
donatien 0:8e01dca41002 1674 }
donatien 0:8e01dca41002 1675
donatien 0:8e01dca41002 1676 lcp_echo_lowerup(f->unit); /* Enable echo messages */
donatien 0:8e01dca41002 1677
donatien 0:8e01dca41002 1678 link_established(f->unit); /* The link is up; authenticate now */
donatien 0:8e01dca41002 1679 }
donatien 0:8e01dca41002 1680
donatien 0:8e01dca41002 1681
donatien 0:8e01dca41002 1682 /*
donatien 0:8e01dca41002 1683 * lcp_down - LCP has gone DOWN.
donatien 0:8e01dca41002 1684 *
donatien 0:8e01dca41002 1685 * Alert other protocols.
donatien 0:8e01dca41002 1686 */
donatien 0:8e01dca41002 1687 static void
donatien 0:8e01dca41002 1688 lcp_down(fsm *f)
donatien 0:8e01dca41002 1689 {
donatien 0:8e01dca41002 1690 lcp_options *go = &lcp_gotoptions[f->unit];
donatien 0:8e01dca41002 1691
donatien 0:8e01dca41002 1692 lcp_echo_lowerdown(f->unit);
donatien 0:8e01dca41002 1693
donatien 0:8e01dca41002 1694 link_down(f->unit);
donatien 0:8e01dca41002 1695
donatien 0:8e01dca41002 1696 ppp_send_config(f->unit, PPP_MRU, 0xffffffffl, 0, 0);
donatien 0:8e01dca41002 1697 ppp_recv_config(f->unit, PPP_MRU,
donatien 0:8e01dca41002 1698 (go->neg_asyncmap? go->asyncmap: 0x00000000),
donatien 0:8e01dca41002 1699 go->neg_pcompression, go->neg_accompression);
donatien 0:8e01dca41002 1700 peer_mru[f->unit] = PPP_MRU;
donatien 0:8e01dca41002 1701 }
donatien 0:8e01dca41002 1702
donatien 0:8e01dca41002 1703
donatien 0:8e01dca41002 1704 /*
donatien 0:8e01dca41002 1705 * lcp_starting - LCP needs the lower layer up.
donatien 0:8e01dca41002 1706 */
donatien 0:8e01dca41002 1707 static void
donatien 0:8e01dca41002 1708 lcp_starting(fsm *f)
donatien 0:8e01dca41002 1709 {
donatien 0:8e01dca41002 1710 link_required(f->unit); /* lwip: currently does nothing */
donatien 0:8e01dca41002 1711 }
donatien 0:8e01dca41002 1712
donatien 0:8e01dca41002 1713
donatien 0:8e01dca41002 1714 /*
donatien 0:8e01dca41002 1715 * lcp_finished - LCP has finished with the lower layer.
donatien 0:8e01dca41002 1716 */
donatien 0:8e01dca41002 1717 static void
donatien 0:8e01dca41002 1718 lcp_finished(fsm *f)
donatien 0:8e01dca41002 1719 {
donatien 0:8e01dca41002 1720 link_terminated(f->unit); /* we are finished with the link */
donatien 0:8e01dca41002 1721 }
donatien 0:8e01dca41002 1722
donatien 0:8e01dca41002 1723
donatien 0:8e01dca41002 1724 #if PPP_ADDITIONAL_CALLBACKS
donatien 0:8e01dca41002 1725 /*
donatien 0:8e01dca41002 1726 * print_string - print a readable representation of a string using
donatien 0:8e01dca41002 1727 * printer.
donatien 0:8e01dca41002 1728 */
donatien 0:8e01dca41002 1729 static void
donatien 0:8e01dca41002 1730 print_string( char *p, int len, void (*printer) (void *, char *, ...), void *arg)
donatien 0:8e01dca41002 1731 {
donatien 0:8e01dca41002 1732 int c;
donatien 0:8e01dca41002 1733
donatien 0:8e01dca41002 1734 printer(arg, "\"");
donatien 0:8e01dca41002 1735 for (; len > 0; --len) {
donatien 0:8e01dca41002 1736 c = *p++;
donatien 0:8e01dca41002 1737 if (' ' <= c && c <= '~') {
donatien 0:8e01dca41002 1738 if (c == '\\' || c == '"') {
donatien 0:8e01dca41002 1739 printer(arg, "\\");
donatien 0:8e01dca41002 1740 }
donatien 0:8e01dca41002 1741 printer(arg, "%c", c);
donatien 0:8e01dca41002 1742 } else {
donatien 0:8e01dca41002 1743 switch (c) {
donatien 0:8e01dca41002 1744 case '\n':
donatien 0:8e01dca41002 1745 printer(arg, "\\n");
donatien 0:8e01dca41002 1746 break;
donatien 0:8e01dca41002 1747 case '\r':
donatien 0:8e01dca41002 1748 printer(arg, "\\r");
donatien 0:8e01dca41002 1749 break;
donatien 0:8e01dca41002 1750 case '\t':
donatien 0:8e01dca41002 1751 printer(arg, "\\t");
donatien 0:8e01dca41002 1752 break;
donatien 0:8e01dca41002 1753 default:
donatien 0:8e01dca41002 1754 printer(arg, "\\%.3o", c);
donatien 0:8e01dca41002 1755 }
donatien 0:8e01dca41002 1756 }
donatien 0:8e01dca41002 1757 }
donatien 0:8e01dca41002 1758 printer(arg, "\"");
donatien 0:8e01dca41002 1759 }
donatien 0:8e01dca41002 1760
donatien 0:8e01dca41002 1761
donatien 0:8e01dca41002 1762 /*
donatien 0:8e01dca41002 1763 * lcp_printpkt - print the contents of an LCP packet.
donatien 0:8e01dca41002 1764 */
donatien 0:8e01dca41002 1765 static char *lcp_codenames[] = {
donatien 0:8e01dca41002 1766 "ConfReq", "ConfAck", "ConfNak", "ConfRej",
donatien 0:8e01dca41002 1767 "TermReq", "TermAck", "CodeRej", "ProtRej",
donatien 0:8e01dca41002 1768 "EchoReq", "EchoRep", "DiscReq"
donatien 0:8e01dca41002 1769 };
donatien 0:8e01dca41002 1770
donatien 0:8e01dca41002 1771 static int
donatien 0:8e01dca41002 1772 lcp_printpkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg)
donatien 0:8e01dca41002 1773 {
donatien 0:8e01dca41002 1774 int code, id, len, olen;
donatien 0:8e01dca41002 1775 u_char *pstart, *optend;
donatien 0:8e01dca41002 1776 u_short cishort;
donatien 0:8e01dca41002 1777 u32_t cilong;
donatien 0:8e01dca41002 1778
donatien 0:8e01dca41002 1779 if (plen < HEADERLEN) {
donatien 0:8e01dca41002 1780 return 0;
donatien 0:8e01dca41002 1781 }
donatien 0:8e01dca41002 1782 pstart = p;
donatien 0:8e01dca41002 1783 GETCHAR(code, p);
donatien 0:8e01dca41002 1784 GETCHAR(id, p);
donatien 0:8e01dca41002 1785 GETSHORT(len, p);
donatien 0:8e01dca41002 1786 if (len < HEADERLEN || len > plen) {
donatien 0:8e01dca41002 1787 return 0;
donatien 0:8e01dca41002 1788 }
donatien 0:8e01dca41002 1789
donatien 0:8e01dca41002 1790 if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *)) {
donatien 0:8e01dca41002 1791 printer(arg, " %s", lcp_codenames[code-1]);
donatien 0:8e01dca41002 1792 } else {
donatien 0:8e01dca41002 1793 printer(arg, " code=0x%x", code);
donatien 0:8e01dca41002 1794 }
donatien 0:8e01dca41002 1795 printer(arg, " id=0x%x", id);
donatien 0:8e01dca41002 1796 len -= HEADERLEN;
donatien 0:8e01dca41002 1797 switch (code) {
donatien 0:8e01dca41002 1798 case CONFREQ:
donatien 0:8e01dca41002 1799 case CONFACK:
donatien 0:8e01dca41002 1800 case CONFNAK:
donatien 0:8e01dca41002 1801 case CONFREJ:
donatien 0:8e01dca41002 1802 /* print option list */
donatien 0:8e01dca41002 1803 while (len >= 2) {
donatien 0:8e01dca41002 1804 GETCHAR(code, p);
donatien 0:8e01dca41002 1805 GETCHAR(olen, p);
donatien 0:8e01dca41002 1806 p -= 2;
donatien 0:8e01dca41002 1807 if (olen < 2 || olen > len) {
donatien 0:8e01dca41002 1808 break;
donatien 0:8e01dca41002 1809 }
donatien 0:8e01dca41002 1810 printer(arg, " <");
donatien 0:8e01dca41002 1811 len -= olen;
donatien 0:8e01dca41002 1812 optend = p + olen;
donatien 0:8e01dca41002 1813 switch (code) {
donatien 0:8e01dca41002 1814 case CI_MRU:
donatien 0:8e01dca41002 1815 if (olen == CILEN_SHORT) {
donatien 0:8e01dca41002 1816 p += 2;
donatien 0:8e01dca41002 1817 GETSHORT(cishort, p);
donatien 0:8e01dca41002 1818 printer(arg, "mru %d", cishort);
donatien 0:8e01dca41002 1819 }
donatien 0:8e01dca41002 1820 break;
donatien 0:8e01dca41002 1821 case CI_ASYNCMAP:
donatien 0:8e01dca41002 1822 if (olen == CILEN_LONG) {
donatien 0:8e01dca41002 1823 p += 2;
donatien 0:8e01dca41002 1824 GETLONG(cilong, p);
donatien 0:8e01dca41002 1825 printer(arg, "asyncmap 0x%lx", cilong);
donatien 0:8e01dca41002 1826 }
donatien 0:8e01dca41002 1827 break;
donatien 0:8e01dca41002 1828 case CI_AUTHTYPE:
donatien 0:8e01dca41002 1829 if (olen >= CILEN_SHORT) {
donatien 0:8e01dca41002 1830 p += 2;
donatien 0:8e01dca41002 1831 printer(arg, "auth ");
donatien 0:8e01dca41002 1832 GETSHORT(cishort, p);
donatien 0:8e01dca41002 1833 switch (cishort) {
donatien 0:8e01dca41002 1834 case PPP_PAP:
donatien 0:8e01dca41002 1835 printer(arg, "pap");
donatien 0:8e01dca41002 1836 break;
donatien 0:8e01dca41002 1837 case PPP_CHAP:
donatien 0:8e01dca41002 1838 printer(arg, "chap");
donatien 0:8e01dca41002 1839 break;
donatien 0:8e01dca41002 1840 default:
donatien 0:8e01dca41002 1841 printer(arg, "0x%x", cishort);
donatien 0:8e01dca41002 1842 }
donatien 0:8e01dca41002 1843 }
donatien 0:8e01dca41002 1844 break;
donatien 0:8e01dca41002 1845 case CI_QUALITY:
donatien 0:8e01dca41002 1846 if (olen >= CILEN_SHORT) {
donatien 0:8e01dca41002 1847 p += 2;
donatien 0:8e01dca41002 1848 printer(arg, "quality ");
donatien 0:8e01dca41002 1849 GETSHORT(cishort, p);
donatien 0:8e01dca41002 1850 switch (cishort) {
donatien 0:8e01dca41002 1851 case PPP_LQR:
donatien 0:8e01dca41002 1852 printer(arg, "lqr");
donatien 0:8e01dca41002 1853 break;
donatien 0:8e01dca41002 1854 default:
donatien 0:8e01dca41002 1855 printer(arg, "0x%x", cishort);
donatien 0:8e01dca41002 1856 }
donatien 0:8e01dca41002 1857 }
donatien 0:8e01dca41002 1858 break;
donatien 0:8e01dca41002 1859 case CI_CALLBACK:
donatien 0:8e01dca41002 1860 if (olen >= CILEN_CHAR) {
donatien 0:8e01dca41002 1861 p += 2;
donatien 0:8e01dca41002 1862 printer(arg, "callback ");
donatien 0:8e01dca41002 1863 GETSHORT(cishort, p);
donatien 0:8e01dca41002 1864 switch (cishort) {
donatien 0:8e01dca41002 1865 case CBCP_OPT:
donatien 0:8e01dca41002 1866 printer(arg, "CBCP");
donatien 0:8e01dca41002 1867 break;
donatien 0:8e01dca41002 1868 default:
donatien 0:8e01dca41002 1869 printer(arg, "0x%x", cishort);
donatien 0:8e01dca41002 1870 }
donatien 0:8e01dca41002 1871 }
donatien 0:8e01dca41002 1872 break;
donatien 0:8e01dca41002 1873 case CI_MAGICNUMBER:
donatien 0:8e01dca41002 1874 if (olen == CILEN_LONG) {
donatien 0:8e01dca41002 1875 p += 2;
donatien 0:8e01dca41002 1876 GETLONG(cilong, p);
donatien 0:8e01dca41002 1877 printer(arg, "magic 0x%x", cilong);
donatien 0:8e01dca41002 1878 }
donatien 0:8e01dca41002 1879 break;
donatien 0:8e01dca41002 1880 case CI_PCOMPRESSION:
donatien 0:8e01dca41002 1881 if (olen == CILEN_VOID) {
donatien 0:8e01dca41002 1882 p += 2;
donatien 0:8e01dca41002 1883 printer(arg, "pcomp");
donatien 0:8e01dca41002 1884 }
donatien 0:8e01dca41002 1885 break;
donatien 0:8e01dca41002 1886 case CI_ACCOMPRESSION:
donatien 0:8e01dca41002 1887 if (olen == CILEN_VOID) {
donatien 0:8e01dca41002 1888 p += 2;
donatien 0:8e01dca41002 1889 printer(arg, "accomp");
donatien 0:8e01dca41002 1890 }
donatien 0:8e01dca41002 1891 break;
donatien 0:8e01dca41002 1892 }
donatien 0:8e01dca41002 1893 while (p < optend) {
donatien 0:8e01dca41002 1894 GETCHAR(code, p);
donatien 0:8e01dca41002 1895 printer(arg, " %.2x", code);
donatien 0:8e01dca41002 1896 }
donatien 0:8e01dca41002 1897 printer(arg, ">");
donatien 0:8e01dca41002 1898 }
donatien 0:8e01dca41002 1899 break;
donatien 0:8e01dca41002 1900
donatien 0:8e01dca41002 1901 case TERMACK:
donatien 0:8e01dca41002 1902 case TERMREQ:
donatien 0:8e01dca41002 1903 if (len > 0 && *p >= ' ' && *p < 0x7f) {
donatien 0:8e01dca41002 1904 printer(arg, " ");
donatien 0:8e01dca41002 1905 print_string((char*)p, len, printer, arg);
donatien 0:8e01dca41002 1906 p += len;
donatien 0:8e01dca41002 1907 len = 0;
donatien 0:8e01dca41002 1908 }
donatien 0:8e01dca41002 1909 break;
donatien 0:8e01dca41002 1910
donatien 0:8e01dca41002 1911 case ECHOREQ:
donatien 0:8e01dca41002 1912 case ECHOREP:
donatien 0:8e01dca41002 1913 case DISCREQ:
donatien 0:8e01dca41002 1914 if (len >= 4) {
donatien 0:8e01dca41002 1915 GETLONG(cilong, p);
donatien 0:8e01dca41002 1916 printer(arg, " magic=0x%x", cilong);
donatien 0:8e01dca41002 1917 p += 4;
donatien 0:8e01dca41002 1918 len -= 4;
donatien 0:8e01dca41002 1919 }
donatien 0:8e01dca41002 1920 break;
donatien 0:8e01dca41002 1921 }
donatien 0:8e01dca41002 1922
donatien 0:8e01dca41002 1923 /* print the rest of the bytes in the packet */
donatien 0:8e01dca41002 1924 for (; len > 0; --len) {
donatien 0:8e01dca41002 1925 GETCHAR(code, p);
donatien 0:8e01dca41002 1926 printer(arg, " %.2x", code);
donatien 0:8e01dca41002 1927 }
donatien 0:8e01dca41002 1928
donatien 0:8e01dca41002 1929 return (int)(p - pstart);
donatien 0:8e01dca41002 1930 }
donatien 0:8e01dca41002 1931 #endif /* PPP_ADDITIONAL_CALLBACKS */
donatien 0:8e01dca41002 1932
donatien 0:8e01dca41002 1933 /*
donatien 0:8e01dca41002 1934 * Time to shut down the link because there is nothing out there.
donatien 0:8e01dca41002 1935 */
donatien 0:8e01dca41002 1936 static void
donatien 0:8e01dca41002 1937 LcpLinkFailure (fsm *f)
donatien 0:8e01dca41002 1938 {
donatien 0:8e01dca41002 1939 if (f->state == LS_OPENED) {
donatien 0:8e01dca41002 1940 LCPDEBUG(LOG_INFO, ("No response to %d echo-requests\n", lcp_echos_pending));
donatien 0:8e01dca41002 1941 LCPDEBUG(LOG_NOTICE, ("Serial link appears to be disconnected.\n"));
donatien 0:8e01dca41002 1942 lcp_close(f->unit, "Peer not responding");
donatien 0:8e01dca41002 1943 }
donatien 0:8e01dca41002 1944 }
donatien 0:8e01dca41002 1945
donatien 0:8e01dca41002 1946 /*
donatien 0:8e01dca41002 1947 * Timer expired for the LCP echo requests from this process.
donatien 0:8e01dca41002 1948 */
donatien 0:8e01dca41002 1949 static void
donatien 0:8e01dca41002 1950 LcpEchoCheck (fsm *f)
donatien 0:8e01dca41002 1951 {
donatien 0:8e01dca41002 1952 LcpSendEchoRequest (f);
donatien 0:8e01dca41002 1953
donatien 0:8e01dca41002 1954 /*
donatien 0:8e01dca41002 1955 * Start the timer for the next interval.
donatien 0:8e01dca41002 1956 */
donatien 0:8e01dca41002 1957 LWIP_ASSERT("lcp_echo_timer_running == 0", lcp_echo_timer_running == 0);
donatien 0:8e01dca41002 1958
donatien 0:8e01dca41002 1959 TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval);
donatien 0:8e01dca41002 1960 lcp_echo_timer_running = 1;
donatien 0:8e01dca41002 1961 }
donatien 0:8e01dca41002 1962
donatien 0:8e01dca41002 1963 /*
donatien 0:8e01dca41002 1964 * LcpEchoTimeout - Timer expired on the LCP echo
donatien 0:8e01dca41002 1965 */
donatien 0:8e01dca41002 1966 static void
donatien 0:8e01dca41002 1967 LcpEchoTimeout (void *arg)
donatien 0:8e01dca41002 1968 {
donatien 0:8e01dca41002 1969 if (lcp_echo_timer_running != 0) {
donatien 0:8e01dca41002 1970 lcp_echo_timer_running = 0;
donatien 0:8e01dca41002 1971 LcpEchoCheck ((fsm *) arg);
donatien 0:8e01dca41002 1972 }
donatien 0:8e01dca41002 1973 }
donatien 0:8e01dca41002 1974
donatien 0:8e01dca41002 1975 /*
donatien 0:8e01dca41002 1976 * LcpEchoReply - LCP has received a reply to the echo
donatien 0:8e01dca41002 1977 */
donatien 0:8e01dca41002 1978 static void
donatien 0:8e01dca41002 1979 lcp_received_echo_reply (fsm *f, int id, u_char *inp, int len)
donatien 0:8e01dca41002 1980 {
donatien 0:8e01dca41002 1981 u32_t magic;
donatien 0:8e01dca41002 1982
donatien 0:8e01dca41002 1983 LWIP_UNUSED_ARG(id);
donatien 0:8e01dca41002 1984
donatien 0:8e01dca41002 1985 /* Check the magic number - don't count replies from ourselves. */
donatien 0:8e01dca41002 1986 if (len < 4) {
donatien 0:8e01dca41002 1987 LCPDEBUG(LOG_WARNING, ("lcp: received short Echo-Reply, length %d\n", len));
donatien 0:8e01dca41002 1988 return;
donatien 0:8e01dca41002 1989 }
donatien 0:8e01dca41002 1990 GETLONG(magic, inp);
donatien 0:8e01dca41002 1991 if (lcp_gotoptions[f->unit].neg_magicnumber && magic == lcp_gotoptions[f->unit].magicnumber) {
donatien 0:8e01dca41002 1992 LCPDEBUG(LOG_WARNING, ("appear to have received our own echo-reply!\n"));
donatien 0:8e01dca41002 1993 return;
donatien 0:8e01dca41002 1994 }
donatien 0:8e01dca41002 1995
donatien 0:8e01dca41002 1996 /* Reset the number of outstanding echo frames */
donatien 0:8e01dca41002 1997 lcp_echos_pending = 0;
donatien 0:8e01dca41002 1998 }
donatien 0:8e01dca41002 1999
donatien 0:8e01dca41002 2000 /*
donatien 0:8e01dca41002 2001 * LcpSendEchoRequest - Send an echo request frame to the peer
donatien 0:8e01dca41002 2002 */
donatien 0:8e01dca41002 2003 static void
donatien 0:8e01dca41002 2004 LcpSendEchoRequest (fsm *f)
donatien 0:8e01dca41002 2005 {
donatien 0:8e01dca41002 2006 u32_t lcp_magic;
donatien 0:8e01dca41002 2007 u_char pkt[4], *pktp;
donatien 0:8e01dca41002 2008
donatien 0:8e01dca41002 2009 /*
donatien 0:8e01dca41002 2010 * Detect the failure of the peer at this point.
donatien 0:8e01dca41002 2011 */
donatien 0:8e01dca41002 2012 if (lcp_echo_fails != 0) {
donatien 0:8e01dca41002 2013 if (lcp_echos_pending >= lcp_echo_fails) {
donatien 0:8e01dca41002 2014 LcpLinkFailure(f);
donatien 0:8e01dca41002 2015 lcp_echos_pending = 0;
donatien 0:8e01dca41002 2016 }
donatien 0:8e01dca41002 2017 }
donatien 0:8e01dca41002 2018
donatien 0:8e01dca41002 2019 /*
donatien 0:8e01dca41002 2020 * Make and send the echo request frame.
donatien 0:8e01dca41002 2021 */
donatien 0:8e01dca41002 2022 if (f->state == LS_OPENED) {
donatien 0:8e01dca41002 2023 lcp_magic = lcp_gotoptions[f->unit].magicnumber;
donatien 0:8e01dca41002 2024 pktp = pkt;
donatien 0:8e01dca41002 2025 PUTLONG(lcp_magic, pktp);
donatien 0:8e01dca41002 2026 fsm_sdata(f, ECHOREQ, (u_char)(lcp_echo_number++ & 0xFF), pkt, (int)(pktp - pkt));
donatien 0:8e01dca41002 2027 ++lcp_echos_pending;
donatien 0:8e01dca41002 2028 }
donatien 0:8e01dca41002 2029 }
donatien 0:8e01dca41002 2030
donatien 0:8e01dca41002 2031 /*
donatien 0:8e01dca41002 2032 * lcp_echo_lowerup - Start the timer for the LCP frame
donatien 0:8e01dca41002 2033 */
donatien 0:8e01dca41002 2034
donatien 0:8e01dca41002 2035 static void
donatien 0:8e01dca41002 2036 lcp_echo_lowerup (int unit)
donatien 0:8e01dca41002 2037 {
donatien 0:8e01dca41002 2038 fsm *f = &lcp_fsm[unit];
donatien 0:8e01dca41002 2039
donatien 0:8e01dca41002 2040 /* Clear the parameters for generating echo frames */
donatien 0:8e01dca41002 2041 lcp_echos_pending = 0;
donatien 0:8e01dca41002 2042 lcp_echo_number = 0;
donatien 0:8e01dca41002 2043 lcp_echo_timer_running = 0;
donatien 0:8e01dca41002 2044
donatien 0:8e01dca41002 2045 /* If a timeout interval is specified then start the timer */
donatien 0:8e01dca41002 2046 if (lcp_echo_interval != 0) {
donatien 0:8e01dca41002 2047 LcpEchoCheck (f);
donatien 0:8e01dca41002 2048 }
donatien 0:8e01dca41002 2049 }
donatien 0:8e01dca41002 2050
donatien 0:8e01dca41002 2051 /*
donatien 0:8e01dca41002 2052 * lcp_echo_lowerdown - Stop the timer for the LCP frame
donatien 0:8e01dca41002 2053 */
donatien 0:8e01dca41002 2054
donatien 0:8e01dca41002 2055 static void
donatien 0:8e01dca41002 2056 lcp_echo_lowerdown (int unit)
donatien 0:8e01dca41002 2057 {
donatien 0:8e01dca41002 2058 fsm *f = &lcp_fsm[unit];
donatien 0:8e01dca41002 2059
donatien 0:8e01dca41002 2060 if (lcp_echo_timer_running != 0) {
donatien 0:8e01dca41002 2061 UNTIMEOUT (LcpEchoTimeout, f);
donatien 0:8e01dca41002 2062 lcp_echo_timer_running = 0;
donatien 0:8e01dca41002 2063 }
donatien 0:8e01dca41002 2064 }
donatien 0:8e01dca41002 2065
donatien 0:8e01dca41002 2066 #endif /* PPP_SUPPORT */