Official mbed lwIP library (version 1.4.0)

Dependents:   LwIPNetworking NetServicesMin EthernetInterface EthernetInterface_RSF ... more

Legacy Networking Libraries

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

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

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

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

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

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

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

Increased allocated netbufs to handle DTLS handshakes

Who changed what in which revision?

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