Official mbed lwIP library (version 1.4.0)

Dependents:   LwIPNetworking NetServicesMin EthernetInterface EthernetInterface_RSF ... more

Legacy Networking Libraries

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

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

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

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

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

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

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

Increased allocated netbufs to handle DTLS handshakes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 0:51ac1d130fd4 1 /*** WARNING - THIS HAS NEVER BEEN FINISHED ***/
mbed_official 0:51ac1d130fd4 2 /*****************************************************************************
mbed_official 0:51ac1d130fd4 3 * chap.c - Network Challenge Handshake Authentication Protocol program file.
mbed_official 0:51ac1d130fd4 4 *
mbed_official 0:51ac1d130fd4 5 * Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
mbed_official 0:51ac1d130fd4 6 * portions Copyright (c) 1997 by Global Election Systems Inc.
mbed_official 0:51ac1d130fd4 7 *
mbed_official 0:51ac1d130fd4 8 * The authors hereby grant permission to use, copy, modify, distribute,
mbed_official 0:51ac1d130fd4 9 * and license this software and its documentation for any purpose, provided
mbed_official 0:51ac1d130fd4 10 * that existing copyright notices are retained in all copies and that this
mbed_official 0:51ac1d130fd4 11 * notice and the following disclaimer are included verbatim in any
mbed_official 0:51ac1d130fd4 12 * distributions. No written agreement, license, or royalty fee is required
mbed_official 0:51ac1d130fd4 13 * for any of the authorized uses.
mbed_official 0:51ac1d130fd4 14 *
mbed_official 0:51ac1d130fd4 15 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
mbed_official 0:51ac1d130fd4 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
mbed_official 0:51ac1d130fd4 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
mbed_official 0:51ac1d130fd4 18 * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
mbed_official 0:51ac1d130fd4 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
mbed_official 0:51ac1d130fd4 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
mbed_official 0:51ac1d130fd4 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
mbed_official 0:51ac1d130fd4 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
mbed_official 0:51ac1d130fd4 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
mbed_official 0:51ac1d130fd4 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
mbed_official 0:51ac1d130fd4 25 *
mbed_official 0:51ac1d130fd4 26 ******************************************************************************
mbed_official 0:51ac1d130fd4 27 * REVISION HISTORY
mbed_official 0:51ac1d130fd4 28 *
mbed_official 0:51ac1d130fd4 29 * 03-01-01 Marc Boucher <marc@mbsi.ca>
mbed_official 0:51ac1d130fd4 30 * Ported to lwIP.
mbed_official 0:51ac1d130fd4 31 * 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
mbed_official 0:51ac1d130fd4 32 * Original based on BSD chap.c.
mbed_official 0:51ac1d130fd4 33 *****************************************************************************/
mbed_official 0:51ac1d130fd4 34 /*
mbed_official 0:51ac1d130fd4 35 * chap.c - Challenge Handshake Authentication Protocol.
mbed_official 0:51ac1d130fd4 36 *
mbed_official 0:51ac1d130fd4 37 * Copyright (c) 1993 The Australian National 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 the Australian National University. The name of the University
mbed_official 0:51ac1d130fd4 46 * may not be used to endorse or promote products derived from this
mbed_official 0:51ac1d130fd4 47 * 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 * Copyright (c) 1991 Gregory M. Christy.
mbed_official 0:51ac1d130fd4 53 * All rights reserved.
mbed_official 0:51ac1d130fd4 54 *
mbed_official 0:51ac1d130fd4 55 * Redistribution and use in source and binary forms are permitted
mbed_official 0:51ac1d130fd4 56 * provided that the above copyright notice and this paragraph are
mbed_official 0:51ac1d130fd4 57 * duplicated in all such forms and that any documentation,
mbed_official 0:51ac1d130fd4 58 * advertising materials, and other materials related to such
mbed_official 0:51ac1d130fd4 59 * distribution and use acknowledge that the software was developed
mbed_official 0:51ac1d130fd4 60 * by Gregory M. Christy. The name of the author may not be used to
mbed_official 0:51ac1d130fd4 61 * endorse or promote products derived from this software without
mbed_official 0:51ac1d130fd4 62 * specific prior written permission.
mbed_official 0:51ac1d130fd4 63 *
mbed_official 0:51ac1d130fd4 64 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
mbed_official 0:51ac1d130fd4 65 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
mbed_official 0:51ac1d130fd4 66 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
mbed_official 0:51ac1d130fd4 67 */
mbed_official 0:51ac1d130fd4 68
mbed_official 0:51ac1d130fd4 69 #include "lwip/opt.h"
mbed_official 0:51ac1d130fd4 70
mbed_official 0:51ac1d130fd4 71 #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
mbed_official 0:51ac1d130fd4 72
mbed_official 0:51ac1d130fd4 73 #if CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */
mbed_official 0:51ac1d130fd4 74
mbed_official 0:51ac1d130fd4 75 #include "ppp.h"
mbed_official 0:51ac1d130fd4 76 #include "pppdebug.h"
mbed_official 0:51ac1d130fd4 77
mbed_official 0:51ac1d130fd4 78 #include "magic.h"
mbed_official 0:51ac1d130fd4 79 #include "randm.h"
mbed_official 0:51ac1d130fd4 80 #include "auth.h"
mbed_official 0:51ac1d130fd4 81 #include "md5.h"
mbed_official 0:51ac1d130fd4 82 #include "chap.h"
mbed_official 0:51ac1d130fd4 83 #include "chpms.h"
mbed_official 0:51ac1d130fd4 84
mbed_official 0:51ac1d130fd4 85 #include <string.h>
mbed_official 0:51ac1d130fd4 86
mbed_official 0:51ac1d130fd4 87 #if 0 /* UNUSED */
mbed_official 0:51ac1d130fd4 88 /*
mbed_official 0:51ac1d130fd4 89 * Command-line options.
mbed_official 0:51ac1d130fd4 90 */
mbed_official 0:51ac1d130fd4 91 static option_t chap_option_list[] = {
mbed_official 0:51ac1d130fd4 92 { "chap-restart", o_int, &chap[0].timeouttime,
mbed_official 0:51ac1d130fd4 93 "Set timeout for CHAP" },
mbed_official 0:51ac1d130fd4 94 { "chap-max-challenge", o_int, &chap[0].max_transmits,
mbed_official 0:51ac1d130fd4 95 "Set max #xmits for challenge" },
mbed_official 0:51ac1d130fd4 96 { "chap-interval", o_int, &chap[0].chal_interval,
mbed_official 0:51ac1d130fd4 97 "Set interval for rechallenge" },
mbed_official 0:51ac1d130fd4 98 #ifdef MSLANMAN
mbed_official 0:51ac1d130fd4 99 { "ms-lanman", o_bool, &ms_lanman,
mbed_official 0:51ac1d130fd4 100 "Use LanMan passwd when using MS-CHAP", 1 },
mbed_official 0:51ac1d130fd4 101 #endif
mbed_official 0:51ac1d130fd4 102 { NULL }
mbed_official 0:51ac1d130fd4 103 };
mbed_official 0:51ac1d130fd4 104 #endif /* UNUSED */
mbed_official 0:51ac1d130fd4 105
mbed_official 0:51ac1d130fd4 106 /*
mbed_official 0:51ac1d130fd4 107 * Protocol entry points.
mbed_official 0:51ac1d130fd4 108 */
mbed_official 0:51ac1d130fd4 109 static void ChapInit (int);
mbed_official 0:51ac1d130fd4 110 static void ChapLowerUp (int);
mbed_official 0:51ac1d130fd4 111 static void ChapLowerDown (int);
mbed_official 0:51ac1d130fd4 112 static void ChapInput (int, u_char *, int);
mbed_official 0:51ac1d130fd4 113 static void ChapProtocolReject (int);
mbed_official 0:51ac1d130fd4 114 #if PPP_ADDITIONAL_CALLBACKS
mbed_official 0:51ac1d130fd4 115 static int ChapPrintPkt (u_char *, int, void (*) (void *, char *, ...), void *);
mbed_official 0:51ac1d130fd4 116 #endif
mbed_official 0:51ac1d130fd4 117
mbed_official 0:51ac1d130fd4 118 struct protent chap_protent = {
mbed_official 0:51ac1d130fd4 119 PPP_CHAP,
mbed_official 0:51ac1d130fd4 120 ChapInit,
mbed_official 0:51ac1d130fd4 121 ChapInput,
mbed_official 0:51ac1d130fd4 122 ChapProtocolReject,
mbed_official 0:51ac1d130fd4 123 ChapLowerUp,
mbed_official 0:51ac1d130fd4 124 ChapLowerDown,
mbed_official 0:51ac1d130fd4 125 NULL,
mbed_official 0:51ac1d130fd4 126 NULL,
mbed_official 0:51ac1d130fd4 127 #if PPP_ADDITIONAL_CALLBACKS
mbed_official 0:51ac1d130fd4 128 ChapPrintPkt,
mbed_official 0:51ac1d130fd4 129 NULL,
mbed_official 0:51ac1d130fd4 130 #endif /* PPP_ADDITIONAL_CALLBACKS */
mbed_official 0:51ac1d130fd4 131 1,
mbed_official 0:51ac1d130fd4 132 "CHAP",
mbed_official 0:51ac1d130fd4 133 #if PPP_ADDITIONAL_CALLBACKS
mbed_official 0:51ac1d130fd4 134 NULL,
mbed_official 0:51ac1d130fd4 135 NULL,
mbed_official 0:51ac1d130fd4 136 NULL
mbed_official 0:51ac1d130fd4 137 #endif /* PPP_ADDITIONAL_CALLBACKS */
mbed_official 0:51ac1d130fd4 138 };
mbed_official 0:51ac1d130fd4 139
mbed_official 0:51ac1d130fd4 140 chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */
mbed_official 0:51ac1d130fd4 141
mbed_official 0:51ac1d130fd4 142 static void ChapChallengeTimeout (void *);
mbed_official 0:51ac1d130fd4 143 static void ChapResponseTimeout (void *);
mbed_official 0:51ac1d130fd4 144 static void ChapReceiveChallenge (chap_state *, u_char *, u_char, int);
mbed_official 0:51ac1d130fd4 145 static void ChapRechallenge (void *);
mbed_official 0:51ac1d130fd4 146 static void ChapReceiveResponse (chap_state *, u_char *, int, int);
mbed_official 0:51ac1d130fd4 147 static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len);
mbed_official 0:51ac1d130fd4 148 static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len);
mbed_official 0:51ac1d130fd4 149 static void ChapSendStatus (chap_state *, int);
mbed_official 0:51ac1d130fd4 150 static void ChapSendChallenge (chap_state *);
mbed_official 0:51ac1d130fd4 151 static void ChapSendResponse (chap_state *);
mbed_official 0:51ac1d130fd4 152 static void ChapGenChallenge (chap_state *);
mbed_official 0:51ac1d130fd4 153
mbed_official 0:51ac1d130fd4 154 /*
mbed_official 0:51ac1d130fd4 155 * ChapInit - Initialize a CHAP unit.
mbed_official 0:51ac1d130fd4 156 */
mbed_official 0:51ac1d130fd4 157 static void
mbed_official 0:51ac1d130fd4 158 ChapInit(int unit)
mbed_official 0:51ac1d130fd4 159 {
mbed_official 0:51ac1d130fd4 160 chap_state *cstate = &chap[unit];
mbed_official 0:51ac1d130fd4 161
mbed_official 0:51ac1d130fd4 162 BZERO(cstate, sizeof(*cstate));
mbed_official 0:51ac1d130fd4 163 cstate->unit = unit;
mbed_official 0:51ac1d130fd4 164 cstate->clientstate = CHAPCS_INITIAL;
mbed_official 0:51ac1d130fd4 165 cstate->serverstate = CHAPSS_INITIAL;
mbed_official 0:51ac1d130fd4 166 cstate->timeouttime = CHAP_DEFTIMEOUT;
mbed_official 0:51ac1d130fd4 167 cstate->max_transmits = CHAP_DEFTRANSMITS;
mbed_official 0:51ac1d130fd4 168 /* random number generator is initialized in magic_init */
mbed_official 0:51ac1d130fd4 169 }
mbed_official 0:51ac1d130fd4 170
mbed_official 0:51ac1d130fd4 171
mbed_official 0:51ac1d130fd4 172 /*
mbed_official 0:51ac1d130fd4 173 * ChapAuthWithPeer - Authenticate us with our peer (start client).
mbed_official 0:51ac1d130fd4 174 *
mbed_official 0:51ac1d130fd4 175 */
mbed_official 0:51ac1d130fd4 176 void
mbed_official 0:51ac1d130fd4 177 ChapAuthWithPeer(int unit, char *our_name, u_char digest)
mbed_official 0:51ac1d130fd4 178 {
mbed_official 0:51ac1d130fd4 179 chap_state *cstate = &chap[unit];
mbed_official 0:51ac1d130fd4 180
mbed_official 0:51ac1d130fd4 181 cstate->resp_name = our_name;
mbed_official 0:51ac1d130fd4 182 cstate->resp_type = digest;
mbed_official 0:51ac1d130fd4 183
mbed_official 0:51ac1d130fd4 184 if (cstate->clientstate == CHAPCS_INITIAL ||
mbed_official 0:51ac1d130fd4 185 cstate->clientstate == CHAPCS_PENDING) {
mbed_official 0:51ac1d130fd4 186 /* lower layer isn't up - wait until later */
mbed_official 0:51ac1d130fd4 187 cstate->clientstate = CHAPCS_PENDING;
mbed_official 0:51ac1d130fd4 188 return;
mbed_official 0:51ac1d130fd4 189 }
mbed_official 0:51ac1d130fd4 190
mbed_official 0:51ac1d130fd4 191 /*
mbed_official 0:51ac1d130fd4 192 * We get here as a result of LCP coming up.
mbed_official 0:51ac1d130fd4 193 * So even if CHAP was open before, we will
mbed_official 0:51ac1d130fd4 194 * have to re-authenticate ourselves.
mbed_official 0:51ac1d130fd4 195 */
mbed_official 0:51ac1d130fd4 196 cstate->clientstate = CHAPCS_LISTEN;
mbed_official 0:51ac1d130fd4 197 }
mbed_official 0:51ac1d130fd4 198
mbed_official 0:51ac1d130fd4 199
mbed_official 0:51ac1d130fd4 200 /*
mbed_official 0:51ac1d130fd4 201 * ChapAuthPeer - Authenticate our peer (start server).
mbed_official 0:51ac1d130fd4 202 */
mbed_official 0:51ac1d130fd4 203 void
mbed_official 0:51ac1d130fd4 204 ChapAuthPeer(int unit, char *our_name, u_char digest)
mbed_official 0:51ac1d130fd4 205 {
mbed_official 0:51ac1d130fd4 206 chap_state *cstate = &chap[unit];
mbed_official 0:51ac1d130fd4 207
mbed_official 0:51ac1d130fd4 208 cstate->chal_name = our_name;
mbed_official 0:51ac1d130fd4 209 cstate->chal_type = digest;
mbed_official 0:51ac1d130fd4 210
mbed_official 0:51ac1d130fd4 211 if (cstate->serverstate == CHAPSS_INITIAL ||
mbed_official 0:51ac1d130fd4 212 cstate->serverstate == CHAPSS_PENDING) {
mbed_official 0:51ac1d130fd4 213 /* lower layer isn't up - wait until later */
mbed_official 0:51ac1d130fd4 214 cstate->serverstate = CHAPSS_PENDING;
mbed_official 0:51ac1d130fd4 215 return;
mbed_official 0:51ac1d130fd4 216 }
mbed_official 0:51ac1d130fd4 217
mbed_official 0:51ac1d130fd4 218 ChapGenChallenge(cstate);
mbed_official 0:51ac1d130fd4 219 ChapSendChallenge(cstate); /* crank it up dude! */
mbed_official 0:51ac1d130fd4 220 cstate->serverstate = CHAPSS_INITIAL_CHAL;
mbed_official 0:51ac1d130fd4 221 }
mbed_official 0:51ac1d130fd4 222
mbed_official 0:51ac1d130fd4 223
mbed_official 0:51ac1d130fd4 224 /*
mbed_official 0:51ac1d130fd4 225 * ChapChallengeTimeout - Timeout expired on sending challenge.
mbed_official 0:51ac1d130fd4 226 */
mbed_official 0:51ac1d130fd4 227 static void
mbed_official 0:51ac1d130fd4 228 ChapChallengeTimeout(void *arg)
mbed_official 0:51ac1d130fd4 229 {
mbed_official 0:51ac1d130fd4 230 chap_state *cstate = (chap_state *) arg;
mbed_official 0:51ac1d130fd4 231
mbed_official 0:51ac1d130fd4 232 /* if we aren't sending challenges, don't worry. then again we */
mbed_official 0:51ac1d130fd4 233 /* probably shouldn't be here either */
mbed_official 0:51ac1d130fd4 234 if (cstate->serverstate != CHAPSS_INITIAL_CHAL &&
mbed_official 0:51ac1d130fd4 235 cstate->serverstate != CHAPSS_RECHALLENGE) {
mbed_official 0:51ac1d130fd4 236 return;
mbed_official 0:51ac1d130fd4 237 }
mbed_official 0:51ac1d130fd4 238
mbed_official 0:51ac1d130fd4 239 if (cstate->chal_transmits >= cstate->max_transmits) {
mbed_official 0:51ac1d130fd4 240 /* give up on peer */
mbed_official 0:51ac1d130fd4 241 CHAPDEBUG(LOG_ERR, ("Peer failed to respond to CHAP challenge\n"));
mbed_official 0:51ac1d130fd4 242 cstate->serverstate = CHAPSS_BADAUTH;
mbed_official 0:51ac1d130fd4 243 auth_peer_fail(cstate->unit, PPP_CHAP);
mbed_official 0:51ac1d130fd4 244 return;
mbed_official 0:51ac1d130fd4 245 }
mbed_official 0:51ac1d130fd4 246
mbed_official 0:51ac1d130fd4 247 ChapSendChallenge(cstate); /* Re-send challenge */
mbed_official 0:51ac1d130fd4 248 }
mbed_official 0:51ac1d130fd4 249
mbed_official 0:51ac1d130fd4 250
mbed_official 0:51ac1d130fd4 251 /*
mbed_official 0:51ac1d130fd4 252 * ChapResponseTimeout - Timeout expired on sending response.
mbed_official 0:51ac1d130fd4 253 */
mbed_official 0:51ac1d130fd4 254 static void
mbed_official 0:51ac1d130fd4 255 ChapResponseTimeout(void *arg)
mbed_official 0:51ac1d130fd4 256 {
mbed_official 0:51ac1d130fd4 257 chap_state *cstate = (chap_state *) arg;
mbed_official 0:51ac1d130fd4 258
mbed_official 0:51ac1d130fd4 259 /* if we aren't sending a response, don't worry. */
mbed_official 0:51ac1d130fd4 260 if (cstate->clientstate != CHAPCS_RESPONSE) {
mbed_official 0:51ac1d130fd4 261 return;
mbed_official 0:51ac1d130fd4 262 }
mbed_official 0:51ac1d130fd4 263
mbed_official 0:51ac1d130fd4 264 ChapSendResponse(cstate); /* re-send response */
mbed_official 0:51ac1d130fd4 265 }
mbed_official 0:51ac1d130fd4 266
mbed_official 0:51ac1d130fd4 267
mbed_official 0:51ac1d130fd4 268 /*
mbed_official 0:51ac1d130fd4 269 * ChapRechallenge - Time to challenge the peer again.
mbed_official 0:51ac1d130fd4 270 */
mbed_official 0:51ac1d130fd4 271 static void
mbed_official 0:51ac1d130fd4 272 ChapRechallenge(void *arg)
mbed_official 0:51ac1d130fd4 273 {
mbed_official 0:51ac1d130fd4 274 chap_state *cstate = (chap_state *) arg;
mbed_official 0:51ac1d130fd4 275
mbed_official 0:51ac1d130fd4 276 /* if we aren't sending a response, don't worry. */
mbed_official 0:51ac1d130fd4 277 if (cstate->serverstate != CHAPSS_OPEN) {
mbed_official 0:51ac1d130fd4 278 return;
mbed_official 0:51ac1d130fd4 279 }
mbed_official 0:51ac1d130fd4 280
mbed_official 0:51ac1d130fd4 281 ChapGenChallenge(cstate);
mbed_official 0:51ac1d130fd4 282 ChapSendChallenge(cstate);
mbed_official 0:51ac1d130fd4 283 cstate->serverstate = CHAPSS_RECHALLENGE;
mbed_official 0:51ac1d130fd4 284 }
mbed_official 0:51ac1d130fd4 285
mbed_official 0:51ac1d130fd4 286
mbed_official 0:51ac1d130fd4 287 /*
mbed_official 0:51ac1d130fd4 288 * ChapLowerUp - The lower layer is up.
mbed_official 0:51ac1d130fd4 289 *
mbed_official 0:51ac1d130fd4 290 * Start up if we have pending requests.
mbed_official 0:51ac1d130fd4 291 */
mbed_official 0:51ac1d130fd4 292 static void
mbed_official 0:51ac1d130fd4 293 ChapLowerUp(int unit)
mbed_official 0:51ac1d130fd4 294 {
mbed_official 0:51ac1d130fd4 295 chap_state *cstate = &chap[unit];
mbed_official 0:51ac1d130fd4 296
mbed_official 0:51ac1d130fd4 297 if (cstate->clientstate == CHAPCS_INITIAL) {
mbed_official 0:51ac1d130fd4 298 cstate->clientstate = CHAPCS_CLOSED;
mbed_official 0:51ac1d130fd4 299 } else if (cstate->clientstate == CHAPCS_PENDING) {
mbed_official 0:51ac1d130fd4 300 cstate->clientstate = CHAPCS_LISTEN;
mbed_official 0:51ac1d130fd4 301 }
mbed_official 0:51ac1d130fd4 302
mbed_official 0:51ac1d130fd4 303 if (cstate->serverstate == CHAPSS_INITIAL) {
mbed_official 0:51ac1d130fd4 304 cstate->serverstate = CHAPSS_CLOSED;
mbed_official 0:51ac1d130fd4 305 } else if (cstate->serverstate == CHAPSS_PENDING) {
mbed_official 0:51ac1d130fd4 306 ChapGenChallenge(cstate);
mbed_official 0:51ac1d130fd4 307 ChapSendChallenge(cstate);
mbed_official 0:51ac1d130fd4 308 cstate->serverstate = CHAPSS_INITIAL_CHAL;
mbed_official 0:51ac1d130fd4 309 }
mbed_official 0:51ac1d130fd4 310 }
mbed_official 0:51ac1d130fd4 311
mbed_official 0:51ac1d130fd4 312
mbed_official 0:51ac1d130fd4 313 /*
mbed_official 0:51ac1d130fd4 314 * ChapLowerDown - The lower layer is down.
mbed_official 0:51ac1d130fd4 315 *
mbed_official 0:51ac1d130fd4 316 * Cancel all timeouts.
mbed_official 0:51ac1d130fd4 317 */
mbed_official 0:51ac1d130fd4 318 static void
mbed_official 0:51ac1d130fd4 319 ChapLowerDown(int unit)
mbed_official 0:51ac1d130fd4 320 {
mbed_official 0:51ac1d130fd4 321 chap_state *cstate = &chap[unit];
mbed_official 0:51ac1d130fd4 322
mbed_official 0:51ac1d130fd4 323 /* Timeout(s) pending? Cancel if so. */
mbed_official 0:51ac1d130fd4 324 if (cstate->serverstate == CHAPSS_INITIAL_CHAL ||
mbed_official 0:51ac1d130fd4 325 cstate->serverstate == CHAPSS_RECHALLENGE) {
mbed_official 0:51ac1d130fd4 326 UNTIMEOUT(ChapChallengeTimeout, cstate);
mbed_official 0:51ac1d130fd4 327 } else if (cstate->serverstate == CHAPSS_OPEN
mbed_official 0:51ac1d130fd4 328 && cstate->chal_interval != 0) {
mbed_official 0:51ac1d130fd4 329 UNTIMEOUT(ChapRechallenge, cstate);
mbed_official 0:51ac1d130fd4 330 }
mbed_official 0:51ac1d130fd4 331 if (cstate->clientstate == CHAPCS_RESPONSE) {
mbed_official 0:51ac1d130fd4 332 UNTIMEOUT(ChapResponseTimeout, cstate);
mbed_official 0:51ac1d130fd4 333 }
mbed_official 0:51ac1d130fd4 334 cstate->clientstate = CHAPCS_INITIAL;
mbed_official 0:51ac1d130fd4 335 cstate->serverstate = CHAPSS_INITIAL;
mbed_official 0:51ac1d130fd4 336 }
mbed_official 0:51ac1d130fd4 337
mbed_official 0:51ac1d130fd4 338
mbed_official 0:51ac1d130fd4 339 /*
mbed_official 0:51ac1d130fd4 340 * ChapProtocolReject - Peer doesn't grok CHAP.
mbed_official 0:51ac1d130fd4 341 */
mbed_official 0:51ac1d130fd4 342 static void
mbed_official 0:51ac1d130fd4 343 ChapProtocolReject(int unit)
mbed_official 0:51ac1d130fd4 344 {
mbed_official 0:51ac1d130fd4 345 chap_state *cstate = &chap[unit];
mbed_official 0:51ac1d130fd4 346
mbed_official 0:51ac1d130fd4 347 if (cstate->serverstate != CHAPSS_INITIAL &&
mbed_official 0:51ac1d130fd4 348 cstate->serverstate != CHAPSS_CLOSED) {
mbed_official 0:51ac1d130fd4 349 auth_peer_fail(unit, PPP_CHAP);
mbed_official 0:51ac1d130fd4 350 }
mbed_official 0:51ac1d130fd4 351 if (cstate->clientstate != CHAPCS_INITIAL &&
mbed_official 0:51ac1d130fd4 352 cstate->clientstate != CHAPCS_CLOSED) {
mbed_official 0:51ac1d130fd4 353 auth_withpeer_fail(unit, PPP_CHAP); /* lwip: just sets the PPP error code on this unit to PPPERR_AUTHFAIL */
mbed_official 0:51ac1d130fd4 354 }
mbed_official 0:51ac1d130fd4 355 ChapLowerDown(unit); /* shutdown chap */
mbed_official 0:51ac1d130fd4 356 }
mbed_official 0:51ac1d130fd4 357
mbed_official 0:51ac1d130fd4 358
mbed_official 0:51ac1d130fd4 359 /*
mbed_official 0:51ac1d130fd4 360 * ChapInput - Input CHAP packet.
mbed_official 0:51ac1d130fd4 361 */
mbed_official 0:51ac1d130fd4 362 static void
mbed_official 0:51ac1d130fd4 363 ChapInput(int unit, u_char *inpacket, int packet_len)
mbed_official 0:51ac1d130fd4 364 {
mbed_official 0:51ac1d130fd4 365 chap_state *cstate = &chap[unit];
mbed_official 0:51ac1d130fd4 366 u_char *inp;
mbed_official 0:51ac1d130fd4 367 u_char code, id;
mbed_official 0:51ac1d130fd4 368 int len;
mbed_official 0:51ac1d130fd4 369
mbed_official 0:51ac1d130fd4 370 /*
mbed_official 0:51ac1d130fd4 371 * Parse header (code, id and length).
mbed_official 0:51ac1d130fd4 372 * If packet too short, drop it.
mbed_official 0:51ac1d130fd4 373 */
mbed_official 0:51ac1d130fd4 374 inp = inpacket;
mbed_official 0:51ac1d130fd4 375 if (packet_len < CHAP_HEADERLEN) {
mbed_official 0:51ac1d130fd4 376 CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd short header.\n"));
mbed_official 0:51ac1d130fd4 377 return;
mbed_official 0:51ac1d130fd4 378 }
mbed_official 0:51ac1d130fd4 379 GETCHAR(code, inp);
mbed_official 0:51ac1d130fd4 380 GETCHAR(id, inp);
mbed_official 0:51ac1d130fd4 381 GETSHORT(len, inp);
mbed_official 0:51ac1d130fd4 382 if (len < CHAP_HEADERLEN) {
mbed_official 0:51ac1d130fd4 383 CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd illegal length.\n"));
mbed_official 0:51ac1d130fd4 384 return;
mbed_official 0:51ac1d130fd4 385 }
mbed_official 0:51ac1d130fd4 386 if (len > packet_len) {
mbed_official 0:51ac1d130fd4 387 CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd short packet.\n"));
mbed_official 0:51ac1d130fd4 388 return;
mbed_official 0:51ac1d130fd4 389 }
mbed_official 0:51ac1d130fd4 390 len -= CHAP_HEADERLEN;
mbed_official 0:51ac1d130fd4 391
mbed_official 0:51ac1d130fd4 392 /*
mbed_official 0:51ac1d130fd4 393 * Action depends on code (as in fact it usually does :-).
mbed_official 0:51ac1d130fd4 394 */
mbed_official 0:51ac1d130fd4 395 switch (code) {
mbed_official 0:51ac1d130fd4 396 case CHAP_CHALLENGE:
mbed_official 0:51ac1d130fd4 397 ChapReceiveChallenge(cstate, inp, id, len);
mbed_official 0:51ac1d130fd4 398 break;
mbed_official 0:51ac1d130fd4 399
mbed_official 0:51ac1d130fd4 400 case CHAP_RESPONSE:
mbed_official 0:51ac1d130fd4 401 ChapReceiveResponse(cstate, inp, id, len);
mbed_official 0:51ac1d130fd4 402 break;
mbed_official 0:51ac1d130fd4 403
mbed_official 0:51ac1d130fd4 404 case CHAP_FAILURE:
mbed_official 0:51ac1d130fd4 405 ChapReceiveFailure(cstate, inp, id, len);
mbed_official 0:51ac1d130fd4 406 break;
mbed_official 0:51ac1d130fd4 407
mbed_official 0:51ac1d130fd4 408 case CHAP_SUCCESS:
mbed_official 0:51ac1d130fd4 409 ChapReceiveSuccess(cstate, inp, id, len);
mbed_official 0:51ac1d130fd4 410 break;
mbed_official 0:51ac1d130fd4 411
mbed_official 0:51ac1d130fd4 412 default: /* Need code reject? */
mbed_official 0:51ac1d130fd4 413 CHAPDEBUG(LOG_WARNING, ("Unknown CHAP code (%d) received.\n", code));
mbed_official 0:51ac1d130fd4 414 break;
mbed_official 0:51ac1d130fd4 415 }
mbed_official 0:51ac1d130fd4 416 }
mbed_official 0:51ac1d130fd4 417
mbed_official 0:51ac1d130fd4 418
mbed_official 0:51ac1d130fd4 419 /*
mbed_official 0:51ac1d130fd4 420 * ChapReceiveChallenge - Receive Challenge and send Response.
mbed_official 0:51ac1d130fd4 421 */
mbed_official 0:51ac1d130fd4 422 static void
mbed_official 0:51ac1d130fd4 423 ChapReceiveChallenge(chap_state *cstate, u_char *inp, u_char id, int len)
mbed_official 0:51ac1d130fd4 424 {
mbed_official 0:51ac1d130fd4 425 int rchallenge_len;
mbed_official 0:51ac1d130fd4 426 u_char *rchallenge;
mbed_official 0:51ac1d130fd4 427 int secret_len;
mbed_official 0:51ac1d130fd4 428 char secret[MAXSECRETLEN];
mbed_official 0:51ac1d130fd4 429 char rhostname[256];
mbed_official 0:51ac1d130fd4 430 MD5_CTX mdContext;
mbed_official 0:51ac1d130fd4 431 u_char hash[MD5_SIGNATURE_SIZE];
mbed_official 0:51ac1d130fd4 432
mbed_official 0:51ac1d130fd4 433 CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: Rcvd id %d.\n", id));
mbed_official 0:51ac1d130fd4 434 if (cstate->clientstate == CHAPCS_CLOSED ||
mbed_official 0:51ac1d130fd4 435 cstate->clientstate == CHAPCS_PENDING) {
mbed_official 0:51ac1d130fd4 436 CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: in state %d\n",
mbed_official 0:51ac1d130fd4 437 cstate->clientstate));
mbed_official 0:51ac1d130fd4 438 return;
mbed_official 0:51ac1d130fd4 439 }
mbed_official 0:51ac1d130fd4 440
mbed_official 0:51ac1d130fd4 441 if (len < 2) {
mbed_official 0:51ac1d130fd4 442 CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: rcvd short packet.\n"));
mbed_official 0:51ac1d130fd4 443 return;
mbed_official 0:51ac1d130fd4 444 }
mbed_official 0:51ac1d130fd4 445
mbed_official 0:51ac1d130fd4 446 GETCHAR(rchallenge_len, inp);
mbed_official 0:51ac1d130fd4 447 len -= sizeof (u_char) + rchallenge_len; /* now name field length */
mbed_official 0:51ac1d130fd4 448 if (len < 0) {
mbed_official 0:51ac1d130fd4 449 CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: rcvd short packet.\n"));
mbed_official 0:51ac1d130fd4 450 return;
mbed_official 0:51ac1d130fd4 451 }
mbed_official 0:51ac1d130fd4 452 rchallenge = inp;
mbed_official 0:51ac1d130fd4 453 INCPTR(rchallenge_len, inp);
mbed_official 0:51ac1d130fd4 454
mbed_official 0:51ac1d130fd4 455 if (len >= (int)sizeof(rhostname)) {
mbed_official 0:51ac1d130fd4 456 len = sizeof(rhostname) - 1;
mbed_official 0:51ac1d130fd4 457 }
mbed_official 0:51ac1d130fd4 458 BCOPY(inp, rhostname, len);
mbed_official 0:51ac1d130fd4 459 rhostname[len] = '\000';
mbed_official 0:51ac1d130fd4 460
mbed_official 0:51ac1d130fd4 461 CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: received name field '%s'\n",
mbed_official 0:51ac1d130fd4 462 rhostname));
mbed_official 0:51ac1d130fd4 463
mbed_official 0:51ac1d130fd4 464 /* Microsoft doesn't send their name back in the PPP packet */
mbed_official 0:51ac1d130fd4 465 if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rhostname[0] == 0)) {
mbed_official 0:51ac1d130fd4 466 strncpy(rhostname, ppp_settings.remote_name, sizeof(rhostname));
mbed_official 0:51ac1d130fd4 467 rhostname[sizeof(rhostname) - 1] = 0;
mbed_official 0:51ac1d130fd4 468 CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: using '%s' as remote name\n",
mbed_official 0:51ac1d130fd4 469 rhostname));
mbed_official 0:51ac1d130fd4 470 }
mbed_official 0:51ac1d130fd4 471
mbed_official 0:51ac1d130fd4 472 /* get secret for authenticating ourselves with the specified host */
mbed_official 0:51ac1d130fd4 473 if (!get_secret(cstate->unit, cstate->resp_name, rhostname,
mbed_official 0:51ac1d130fd4 474 secret, &secret_len, 0)) {
mbed_official 0:51ac1d130fd4 475 secret_len = 0; /* assume null secret if can't find one */
mbed_official 0:51ac1d130fd4 476 CHAPDEBUG(LOG_WARNING, ("No CHAP secret found for authenticating us to %s\n",
mbed_official 0:51ac1d130fd4 477 rhostname));
mbed_official 0:51ac1d130fd4 478 }
mbed_official 0:51ac1d130fd4 479
mbed_official 0:51ac1d130fd4 480 /* cancel response send timeout if necessary */
mbed_official 0:51ac1d130fd4 481 if (cstate->clientstate == CHAPCS_RESPONSE) {
mbed_official 0:51ac1d130fd4 482 UNTIMEOUT(ChapResponseTimeout, cstate);
mbed_official 0:51ac1d130fd4 483 }
mbed_official 0:51ac1d130fd4 484
mbed_official 0:51ac1d130fd4 485 cstate->resp_id = id;
mbed_official 0:51ac1d130fd4 486 cstate->resp_transmits = 0;
mbed_official 0:51ac1d130fd4 487
mbed_official 0:51ac1d130fd4 488 /* generate MD based on negotiated type */
mbed_official 0:51ac1d130fd4 489 switch (cstate->resp_type) {
mbed_official 0:51ac1d130fd4 490
mbed_official 0:51ac1d130fd4 491 case CHAP_DIGEST_MD5:
mbed_official 0:51ac1d130fd4 492 MD5Init(&mdContext);
mbed_official 0:51ac1d130fd4 493 MD5Update(&mdContext, &cstate->resp_id, 1);
mbed_official 0:51ac1d130fd4 494 MD5Update(&mdContext, (u_char*)secret, secret_len);
mbed_official 0:51ac1d130fd4 495 MD5Update(&mdContext, rchallenge, rchallenge_len);
mbed_official 0:51ac1d130fd4 496 MD5Final(hash, &mdContext);
mbed_official 0:51ac1d130fd4 497 BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE);
mbed_official 0:51ac1d130fd4 498 cstate->resp_length = MD5_SIGNATURE_SIZE;
mbed_official 0:51ac1d130fd4 499 break;
mbed_official 0:51ac1d130fd4 500
mbed_official 0:51ac1d130fd4 501 #if MSCHAP_SUPPORT
mbed_official 0:51ac1d130fd4 502 case CHAP_MICROSOFT:
mbed_official 0:51ac1d130fd4 503 ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len);
mbed_official 0:51ac1d130fd4 504 break;
mbed_official 0:51ac1d130fd4 505 #endif
mbed_official 0:51ac1d130fd4 506
mbed_official 0:51ac1d130fd4 507 default:
mbed_official 0:51ac1d130fd4 508 CHAPDEBUG(LOG_INFO, ("unknown digest type %d\n", cstate->resp_type));
mbed_official 0:51ac1d130fd4 509 return;
mbed_official 0:51ac1d130fd4 510 }
mbed_official 0:51ac1d130fd4 511
mbed_official 0:51ac1d130fd4 512 BZERO(secret, sizeof(secret));
mbed_official 0:51ac1d130fd4 513 ChapSendResponse(cstate);
mbed_official 0:51ac1d130fd4 514 }
mbed_official 0:51ac1d130fd4 515
mbed_official 0:51ac1d130fd4 516
mbed_official 0:51ac1d130fd4 517 /*
mbed_official 0:51ac1d130fd4 518 * ChapReceiveResponse - Receive and process response.
mbed_official 0:51ac1d130fd4 519 */
mbed_official 0:51ac1d130fd4 520 static void
mbed_official 0:51ac1d130fd4 521 ChapReceiveResponse(chap_state *cstate, u_char *inp, int id, int len)
mbed_official 0:51ac1d130fd4 522 {
mbed_official 0:51ac1d130fd4 523 u_char *remmd, remmd_len;
mbed_official 0:51ac1d130fd4 524 int secret_len, old_state;
mbed_official 0:51ac1d130fd4 525 int code;
mbed_official 0:51ac1d130fd4 526 char rhostname[256];
mbed_official 0:51ac1d130fd4 527 MD5_CTX mdContext;
mbed_official 0:51ac1d130fd4 528 char secret[MAXSECRETLEN];
mbed_official 0:51ac1d130fd4 529 u_char hash[MD5_SIGNATURE_SIZE];
mbed_official 0:51ac1d130fd4 530
mbed_official 0:51ac1d130fd4 531 CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: Rcvd id %d.\n", id));
mbed_official 0:51ac1d130fd4 532
mbed_official 0:51ac1d130fd4 533 if (cstate->serverstate == CHAPSS_CLOSED ||
mbed_official 0:51ac1d130fd4 534 cstate->serverstate == CHAPSS_PENDING) {
mbed_official 0:51ac1d130fd4 535 CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: in state %d\n",
mbed_official 0:51ac1d130fd4 536 cstate->serverstate));
mbed_official 0:51ac1d130fd4 537 return;
mbed_official 0:51ac1d130fd4 538 }
mbed_official 0:51ac1d130fd4 539
mbed_official 0:51ac1d130fd4 540 if (id != cstate->chal_id) {
mbed_official 0:51ac1d130fd4 541 return; /* doesn't match ID of last challenge */
mbed_official 0:51ac1d130fd4 542 }
mbed_official 0:51ac1d130fd4 543
mbed_official 0:51ac1d130fd4 544 /*
mbed_official 0:51ac1d130fd4 545 * If we have received a duplicate or bogus Response,
mbed_official 0:51ac1d130fd4 546 * we have to send the same answer (Success/Failure)
mbed_official 0:51ac1d130fd4 547 * as we did for the first Response we saw.
mbed_official 0:51ac1d130fd4 548 */
mbed_official 0:51ac1d130fd4 549 if (cstate->serverstate == CHAPSS_OPEN) {
mbed_official 0:51ac1d130fd4 550 ChapSendStatus(cstate, CHAP_SUCCESS);
mbed_official 0:51ac1d130fd4 551 return;
mbed_official 0:51ac1d130fd4 552 }
mbed_official 0:51ac1d130fd4 553 if (cstate->serverstate == CHAPSS_BADAUTH) {
mbed_official 0:51ac1d130fd4 554 ChapSendStatus(cstate, CHAP_FAILURE);
mbed_official 0:51ac1d130fd4 555 return;
mbed_official 0:51ac1d130fd4 556 }
mbed_official 0:51ac1d130fd4 557
mbed_official 0:51ac1d130fd4 558 if (len < 2) {
mbed_official 0:51ac1d130fd4 559 CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: rcvd short packet.\n"));
mbed_official 0:51ac1d130fd4 560 return;
mbed_official 0:51ac1d130fd4 561 }
mbed_official 0:51ac1d130fd4 562 GETCHAR(remmd_len, inp); /* get length of MD */
mbed_official 0:51ac1d130fd4 563 remmd = inp; /* get pointer to MD */
mbed_official 0:51ac1d130fd4 564 INCPTR(remmd_len, inp);
mbed_official 0:51ac1d130fd4 565
mbed_official 0:51ac1d130fd4 566 len -= sizeof (u_char) + remmd_len;
mbed_official 0:51ac1d130fd4 567 if (len < 0) {
mbed_official 0:51ac1d130fd4 568 CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: rcvd short packet.\n"));
mbed_official 0:51ac1d130fd4 569 return;
mbed_official 0:51ac1d130fd4 570 }
mbed_official 0:51ac1d130fd4 571
mbed_official 0:51ac1d130fd4 572 UNTIMEOUT(ChapChallengeTimeout, cstate);
mbed_official 0:51ac1d130fd4 573
mbed_official 0:51ac1d130fd4 574 if (len >= (int)sizeof(rhostname)) {
mbed_official 0:51ac1d130fd4 575 len = sizeof(rhostname) - 1;
mbed_official 0:51ac1d130fd4 576 }
mbed_official 0:51ac1d130fd4 577 BCOPY(inp, rhostname, len);
mbed_official 0:51ac1d130fd4 578 rhostname[len] = '\000';
mbed_official 0:51ac1d130fd4 579
mbed_official 0:51ac1d130fd4 580 CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: received name field: %s\n",
mbed_official 0:51ac1d130fd4 581 rhostname));
mbed_official 0:51ac1d130fd4 582
mbed_official 0:51ac1d130fd4 583 /*
mbed_official 0:51ac1d130fd4 584 * Get secret for authenticating them with us,
mbed_official 0:51ac1d130fd4 585 * do the hash ourselves, and compare the result.
mbed_official 0:51ac1d130fd4 586 */
mbed_official 0:51ac1d130fd4 587 code = CHAP_FAILURE;
mbed_official 0:51ac1d130fd4 588 if (!get_secret(cstate->unit, rhostname, cstate->chal_name,
mbed_official 0:51ac1d130fd4 589 secret, &secret_len, 1)) {
mbed_official 0:51ac1d130fd4 590 CHAPDEBUG(LOG_WARNING, ("No CHAP secret found for authenticating %s\n",
mbed_official 0:51ac1d130fd4 591 rhostname));
mbed_official 0:51ac1d130fd4 592 } else {
mbed_official 0:51ac1d130fd4 593 /* generate MD based on negotiated type */
mbed_official 0:51ac1d130fd4 594 switch (cstate->chal_type) {
mbed_official 0:51ac1d130fd4 595
mbed_official 0:51ac1d130fd4 596 case CHAP_DIGEST_MD5: /* only MD5 is defined for now */
mbed_official 0:51ac1d130fd4 597 if (remmd_len != MD5_SIGNATURE_SIZE) {
mbed_official 0:51ac1d130fd4 598 break; /* it's not even the right length */
mbed_official 0:51ac1d130fd4 599 }
mbed_official 0:51ac1d130fd4 600 MD5Init(&mdContext);
mbed_official 0:51ac1d130fd4 601 MD5Update(&mdContext, &cstate->chal_id, 1);
mbed_official 0:51ac1d130fd4 602 MD5Update(&mdContext, (u_char*)secret, secret_len);
mbed_official 0:51ac1d130fd4 603 MD5Update(&mdContext, cstate->challenge, cstate->chal_len);
mbed_official 0:51ac1d130fd4 604 MD5Final(hash, &mdContext);
mbed_official 0:51ac1d130fd4 605
mbed_official 0:51ac1d130fd4 606 /* compare local and remote MDs and send the appropriate status */
mbed_official 0:51ac1d130fd4 607 if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0) {
mbed_official 0:51ac1d130fd4 608 code = CHAP_SUCCESS; /* they are the same! */
mbed_official 0:51ac1d130fd4 609 }
mbed_official 0:51ac1d130fd4 610 break;
mbed_official 0:51ac1d130fd4 611
mbed_official 0:51ac1d130fd4 612 default:
mbed_official 0:51ac1d130fd4 613 CHAPDEBUG(LOG_INFO, ("unknown digest type %d\n", cstate->chal_type));
mbed_official 0:51ac1d130fd4 614 }
mbed_official 0:51ac1d130fd4 615 }
mbed_official 0:51ac1d130fd4 616
mbed_official 0:51ac1d130fd4 617 BZERO(secret, sizeof(secret));
mbed_official 0:51ac1d130fd4 618 ChapSendStatus(cstate, code);
mbed_official 0:51ac1d130fd4 619
mbed_official 0:51ac1d130fd4 620 if (code == CHAP_SUCCESS) {
mbed_official 0:51ac1d130fd4 621 old_state = cstate->serverstate;
mbed_official 0:51ac1d130fd4 622 cstate->serverstate = CHAPSS_OPEN;
mbed_official 0:51ac1d130fd4 623 if (old_state == CHAPSS_INITIAL_CHAL) {
mbed_official 0:51ac1d130fd4 624 auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len);
mbed_official 0:51ac1d130fd4 625 }
mbed_official 0:51ac1d130fd4 626 if (cstate->chal_interval != 0) {
mbed_official 0:51ac1d130fd4 627 TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval);
mbed_official 0:51ac1d130fd4 628 }
mbed_official 0:51ac1d130fd4 629 } else {
mbed_official 0:51ac1d130fd4 630 CHAPDEBUG(LOG_ERR, ("CHAP peer authentication failed\n"));
mbed_official 0:51ac1d130fd4 631 cstate->serverstate = CHAPSS_BADAUTH;
mbed_official 0:51ac1d130fd4 632 auth_peer_fail(cstate->unit, PPP_CHAP);
mbed_official 0:51ac1d130fd4 633 }
mbed_official 0:51ac1d130fd4 634 }
mbed_official 0:51ac1d130fd4 635
mbed_official 0:51ac1d130fd4 636 /*
mbed_official 0:51ac1d130fd4 637 * ChapReceiveSuccess - Receive Success
mbed_official 0:51ac1d130fd4 638 */
mbed_official 0:51ac1d130fd4 639 static void
mbed_official 0:51ac1d130fd4 640 ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len)
mbed_official 0:51ac1d130fd4 641 {
mbed_official 0:51ac1d130fd4 642 LWIP_UNUSED_ARG(id);
mbed_official 0:51ac1d130fd4 643 LWIP_UNUSED_ARG(inp);
mbed_official 0:51ac1d130fd4 644
mbed_official 0:51ac1d130fd4 645 CHAPDEBUG(LOG_INFO, ("ChapReceiveSuccess: Rcvd id %d.\n", id));
mbed_official 0:51ac1d130fd4 646
mbed_official 0:51ac1d130fd4 647 if (cstate->clientstate == CHAPCS_OPEN) {
mbed_official 0:51ac1d130fd4 648 /* presumably an answer to a duplicate response */
mbed_official 0:51ac1d130fd4 649 return;
mbed_official 0:51ac1d130fd4 650 }
mbed_official 0:51ac1d130fd4 651
mbed_official 0:51ac1d130fd4 652 if (cstate->clientstate != CHAPCS_RESPONSE) {
mbed_official 0:51ac1d130fd4 653 /* don't know what this is */
mbed_official 0:51ac1d130fd4 654 CHAPDEBUG(LOG_INFO, ("ChapReceiveSuccess: in state %d\n",
mbed_official 0:51ac1d130fd4 655 cstate->clientstate));
mbed_official 0:51ac1d130fd4 656 return;
mbed_official 0:51ac1d130fd4 657 }
mbed_official 0:51ac1d130fd4 658
mbed_official 0:51ac1d130fd4 659 UNTIMEOUT(ChapResponseTimeout, cstate);
mbed_official 0:51ac1d130fd4 660
mbed_official 0:51ac1d130fd4 661 /*
mbed_official 0:51ac1d130fd4 662 * Print message.
mbed_official 0:51ac1d130fd4 663 */
mbed_official 0:51ac1d130fd4 664 if (len > 0) {
mbed_official 0:51ac1d130fd4 665 PRINTMSG(inp, len);
mbed_official 0:51ac1d130fd4 666 }
mbed_official 0:51ac1d130fd4 667
mbed_official 0:51ac1d130fd4 668 cstate->clientstate = CHAPCS_OPEN;
mbed_official 0:51ac1d130fd4 669
mbed_official 0:51ac1d130fd4 670 auth_withpeer_success(cstate->unit, PPP_CHAP);
mbed_official 0:51ac1d130fd4 671 }
mbed_official 0:51ac1d130fd4 672
mbed_official 0:51ac1d130fd4 673
mbed_official 0:51ac1d130fd4 674 /*
mbed_official 0:51ac1d130fd4 675 * ChapReceiveFailure - Receive failure.
mbed_official 0:51ac1d130fd4 676 */
mbed_official 0:51ac1d130fd4 677 static void
mbed_official 0:51ac1d130fd4 678 ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len)
mbed_official 0:51ac1d130fd4 679 {
mbed_official 0:51ac1d130fd4 680 LWIP_UNUSED_ARG(id);
mbed_official 0:51ac1d130fd4 681 LWIP_UNUSED_ARG(inp);
mbed_official 0:51ac1d130fd4 682
mbed_official 0:51ac1d130fd4 683 CHAPDEBUG(LOG_INFO, ("ChapReceiveFailure: Rcvd id %d.\n", id));
mbed_official 0:51ac1d130fd4 684
mbed_official 0:51ac1d130fd4 685 if (cstate->clientstate != CHAPCS_RESPONSE) {
mbed_official 0:51ac1d130fd4 686 /* don't know what this is */
mbed_official 0:51ac1d130fd4 687 CHAPDEBUG(LOG_INFO, ("ChapReceiveFailure: in state %d\n",
mbed_official 0:51ac1d130fd4 688 cstate->clientstate));
mbed_official 0:51ac1d130fd4 689 return;
mbed_official 0:51ac1d130fd4 690 }
mbed_official 0:51ac1d130fd4 691
mbed_official 0:51ac1d130fd4 692 UNTIMEOUT(ChapResponseTimeout, cstate);
mbed_official 0:51ac1d130fd4 693
mbed_official 0:51ac1d130fd4 694 /*
mbed_official 0:51ac1d130fd4 695 * Print message.
mbed_official 0:51ac1d130fd4 696 */
mbed_official 0:51ac1d130fd4 697 if (len > 0) {
mbed_official 0:51ac1d130fd4 698 PRINTMSG(inp, len);
mbed_official 0:51ac1d130fd4 699 }
mbed_official 0:51ac1d130fd4 700
mbed_official 0:51ac1d130fd4 701 CHAPDEBUG(LOG_ERR, ("CHAP authentication failed\n"));
mbed_official 0:51ac1d130fd4 702 auth_withpeer_fail(cstate->unit, PPP_CHAP); /* lwip: just sets the PPP error code on this unit to PPPERR_AUTHFAIL */
mbed_official 0:51ac1d130fd4 703 }
mbed_official 0:51ac1d130fd4 704
mbed_official 0:51ac1d130fd4 705
mbed_official 0:51ac1d130fd4 706 /*
mbed_official 0:51ac1d130fd4 707 * ChapSendChallenge - Send an Authenticate challenge.
mbed_official 0:51ac1d130fd4 708 */
mbed_official 0:51ac1d130fd4 709 static void
mbed_official 0:51ac1d130fd4 710 ChapSendChallenge(chap_state *cstate)
mbed_official 0:51ac1d130fd4 711 {
mbed_official 0:51ac1d130fd4 712 u_char *outp;
mbed_official 0:51ac1d130fd4 713 int chal_len, name_len;
mbed_official 0:51ac1d130fd4 714 int outlen;
mbed_official 0:51ac1d130fd4 715
mbed_official 0:51ac1d130fd4 716 chal_len = cstate->chal_len;
mbed_official 0:51ac1d130fd4 717 name_len = (int)strlen(cstate->chal_name);
mbed_official 0:51ac1d130fd4 718 outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len;
mbed_official 0:51ac1d130fd4 719 outp = outpacket_buf[cstate->unit];
mbed_official 0:51ac1d130fd4 720
mbed_official 0:51ac1d130fd4 721 MAKEHEADER(outp, PPP_CHAP); /* paste in a CHAP header */
mbed_official 0:51ac1d130fd4 722
mbed_official 0:51ac1d130fd4 723 PUTCHAR(CHAP_CHALLENGE, outp);
mbed_official 0:51ac1d130fd4 724 PUTCHAR(cstate->chal_id, outp);
mbed_official 0:51ac1d130fd4 725 PUTSHORT(outlen, outp);
mbed_official 0:51ac1d130fd4 726
mbed_official 0:51ac1d130fd4 727 PUTCHAR(chal_len, outp); /* put length of challenge */
mbed_official 0:51ac1d130fd4 728 BCOPY(cstate->challenge, outp, chal_len);
mbed_official 0:51ac1d130fd4 729 INCPTR(chal_len, outp);
mbed_official 0:51ac1d130fd4 730
mbed_official 0:51ac1d130fd4 731 BCOPY(cstate->chal_name, outp, name_len); /* append hostname */
mbed_official 0:51ac1d130fd4 732
mbed_official 0:51ac1d130fd4 733 pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
mbed_official 0:51ac1d130fd4 734
mbed_official 0:51ac1d130fd4 735 CHAPDEBUG(LOG_INFO, ("ChapSendChallenge: Sent id %d.\n", cstate->chal_id));
mbed_official 0:51ac1d130fd4 736
mbed_official 0:51ac1d130fd4 737 TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime);
mbed_official 0:51ac1d130fd4 738 ++cstate->chal_transmits;
mbed_official 0:51ac1d130fd4 739 }
mbed_official 0:51ac1d130fd4 740
mbed_official 0:51ac1d130fd4 741
mbed_official 0:51ac1d130fd4 742 /*
mbed_official 0:51ac1d130fd4 743 * ChapSendStatus - Send a status response (ack or nak).
mbed_official 0:51ac1d130fd4 744 */
mbed_official 0:51ac1d130fd4 745 static void
mbed_official 0:51ac1d130fd4 746 ChapSendStatus(chap_state *cstate, int code)
mbed_official 0:51ac1d130fd4 747 {
mbed_official 0:51ac1d130fd4 748 u_char *outp;
mbed_official 0:51ac1d130fd4 749 int outlen, msglen;
mbed_official 0:51ac1d130fd4 750 char msg[256]; /* @todo: this can be a char*, no strcpy needed */
mbed_official 0:51ac1d130fd4 751
mbed_official 0:51ac1d130fd4 752 if (code == CHAP_SUCCESS) {
mbed_official 0:51ac1d130fd4 753 strcpy(msg, "Welcome!");
mbed_official 0:51ac1d130fd4 754 } else {
mbed_official 0:51ac1d130fd4 755 strcpy(msg, "I don't like you. Go 'way.");
mbed_official 0:51ac1d130fd4 756 }
mbed_official 0:51ac1d130fd4 757 msglen = (int)strlen(msg);
mbed_official 0:51ac1d130fd4 758
mbed_official 0:51ac1d130fd4 759 outlen = CHAP_HEADERLEN + msglen;
mbed_official 0:51ac1d130fd4 760 outp = outpacket_buf[cstate->unit];
mbed_official 0:51ac1d130fd4 761
mbed_official 0:51ac1d130fd4 762 MAKEHEADER(outp, PPP_CHAP); /* paste in a header */
mbed_official 0:51ac1d130fd4 763
mbed_official 0:51ac1d130fd4 764 PUTCHAR(code, outp);
mbed_official 0:51ac1d130fd4 765 PUTCHAR(cstate->chal_id, outp);
mbed_official 0:51ac1d130fd4 766 PUTSHORT(outlen, outp);
mbed_official 0:51ac1d130fd4 767 BCOPY(msg, outp, msglen);
mbed_official 0:51ac1d130fd4 768 pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
mbed_official 0:51ac1d130fd4 769
mbed_official 0:51ac1d130fd4 770 CHAPDEBUG(LOG_INFO, ("ChapSendStatus: Sent code %d, id %d.\n", code,
mbed_official 0:51ac1d130fd4 771 cstate->chal_id));
mbed_official 0:51ac1d130fd4 772 }
mbed_official 0:51ac1d130fd4 773
mbed_official 0:51ac1d130fd4 774 /*
mbed_official 0:51ac1d130fd4 775 * ChapGenChallenge is used to generate a pseudo-random challenge string of
mbed_official 0:51ac1d130fd4 776 * a pseudo-random length between min_len and max_len. The challenge
mbed_official 0:51ac1d130fd4 777 * string and its length are stored in *cstate, and various other fields of
mbed_official 0:51ac1d130fd4 778 * *cstate are initialized.
mbed_official 0:51ac1d130fd4 779 */
mbed_official 0:51ac1d130fd4 780
mbed_official 0:51ac1d130fd4 781 static void
mbed_official 0:51ac1d130fd4 782 ChapGenChallenge(chap_state *cstate)
mbed_official 0:51ac1d130fd4 783 {
mbed_official 0:51ac1d130fd4 784 int chal_len;
mbed_official 0:51ac1d130fd4 785 u_char *ptr = cstate->challenge;
mbed_official 0:51ac1d130fd4 786 int i;
mbed_official 0:51ac1d130fd4 787
mbed_official 0:51ac1d130fd4 788 /* pick a random challenge length between MIN_CHALLENGE_LENGTH and
mbed_official 0:51ac1d130fd4 789 MAX_CHALLENGE_LENGTH */
mbed_official 0:51ac1d130fd4 790 chal_len = (unsigned)
mbed_official 0:51ac1d130fd4 791 ((((magic() >> 16) *
mbed_official 0:51ac1d130fd4 792 (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) >> 16)
mbed_official 0:51ac1d130fd4 793 + MIN_CHALLENGE_LENGTH);
mbed_official 0:51ac1d130fd4 794 LWIP_ASSERT("chal_len <= 0xff", chal_len <= 0xffff);
mbed_official 0:51ac1d130fd4 795 cstate->chal_len = (u_char)chal_len;
mbed_official 0:51ac1d130fd4 796 cstate->chal_id = ++cstate->id;
mbed_official 0:51ac1d130fd4 797 cstate->chal_transmits = 0;
mbed_official 0:51ac1d130fd4 798
mbed_official 0:51ac1d130fd4 799 /* generate a random string */
mbed_official 0:51ac1d130fd4 800 for (i = 0; i < chal_len; i++ ) {
mbed_official 0:51ac1d130fd4 801 *ptr++ = (char) (magic() & 0xff);
mbed_official 0:51ac1d130fd4 802 }
mbed_official 0:51ac1d130fd4 803 }
mbed_official 0:51ac1d130fd4 804
mbed_official 0:51ac1d130fd4 805 /*
mbed_official 0:51ac1d130fd4 806 * ChapSendResponse - send a response packet with values as specified
mbed_official 0:51ac1d130fd4 807 * in *cstate.
mbed_official 0:51ac1d130fd4 808 */
mbed_official 0:51ac1d130fd4 809 /* ARGSUSED */
mbed_official 0:51ac1d130fd4 810 static void
mbed_official 0:51ac1d130fd4 811 ChapSendResponse(chap_state *cstate)
mbed_official 0:51ac1d130fd4 812 {
mbed_official 0:51ac1d130fd4 813 u_char *outp;
mbed_official 0:51ac1d130fd4 814 int outlen, md_len, name_len;
mbed_official 0:51ac1d130fd4 815
mbed_official 0:51ac1d130fd4 816 md_len = cstate->resp_length;
mbed_official 0:51ac1d130fd4 817 name_len = (int)strlen(cstate->resp_name);
mbed_official 0:51ac1d130fd4 818 outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len;
mbed_official 0:51ac1d130fd4 819 outp = outpacket_buf[cstate->unit];
mbed_official 0:51ac1d130fd4 820
mbed_official 0:51ac1d130fd4 821 MAKEHEADER(outp, PPP_CHAP);
mbed_official 0:51ac1d130fd4 822
mbed_official 0:51ac1d130fd4 823 PUTCHAR(CHAP_RESPONSE, outp); /* we are a response */
mbed_official 0:51ac1d130fd4 824 PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */
mbed_official 0:51ac1d130fd4 825 PUTSHORT(outlen, outp); /* packet length */
mbed_official 0:51ac1d130fd4 826
mbed_official 0:51ac1d130fd4 827 PUTCHAR(md_len, outp); /* length of MD */
mbed_official 0:51ac1d130fd4 828 BCOPY(cstate->response, outp, md_len); /* copy MD to buffer */
mbed_official 0:51ac1d130fd4 829 INCPTR(md_len, outp);
mbed_official 0:51ac1d130fd4 830
mbed_official 0:51ac1d130fd4 831 BCOPY(cstate->resp_name, outp, name_len); /* append our name */
mbed_official 0:51ac1d130fd4 832
mbed_official 0:51ac1d130fd4 833 /* send the packet */
mbed_official 0:51ac1d130fd4 834 pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
mbed_official 0:51ac1d130fd4 835
mbed_official 0:51ac1d130fd4 836 cstate->clientstate = CHAPCS_RESPONSE;
mbed_official 0:51ac1d130fd4 837 TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime);
mbed_official 0:51ac1d130fd4 838 ++cstate->resp_transmits;
mbed_official 0:51ac1d130fd4 839 }
mbed_official 0:51ac1d130fd4 840
mbed_official 0:51ac1d130fd4 841 #if PPP_ADDITIONAL_CALLBACKS
mbed_official 0:51ac1d130fd4 842 static char *ChapCodenames[] = {
mbed_official 0:51ac1d130fd4 843 "Challenge", "Response", "Success", "Failure"
mbed_official 0:51ac1d130fd4 844 };
mbed_official 0:51ac1d130fd4 845 /*
mbed_official 0:51ac1d130fd4 846 * ChapPrintPkt - print the contents of a CHAP packet.
mbed_official 0:51ac1d130fd4 847 */
mbed_official 0:51ac1d130fd4 848 static int
mbed_official 0:51ac1d130fd4 849 ChapPrintPkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg)
mbed_official 0:51ac1d130fd4 850 {
mbed_official 0:51ac1d130fd4 851 int code, id, len;
mbed_official 0:51ac1d130fd4 852 int clen, nlen;
mbed_official 0:51ac1d130fd4 853 u_char x;
mbed_official 0:51ac1d130fd4 854
mbed_official 0:51ac1d130fd4 855 if (plen < CHAP_HEADERLEN) {
mbed_official 0:51ac1d130fd4 856 return 0;
mbed_official 0:51ac1d130fd4 857 }
mbed_official 0:51ac1d130fd4 858 GETCHAR(code, p);
mbed_official 0:51ac1d130fd4 859 GETCHAR(id, p);
mbed_official 0:51ac1d130fd4 860 GETSHORT(len, p);
mbed_official 0:51ac1d130fd4 861 if (len < CHAP_HEADERLEN || len > plen) {
mbed_official 0:51ac1d130fd4 862 return 0;
mbed_official 0:51ac1d130fd4 863 }
mbed_official 0:51ac1d130fd4 864
mbed_official 0:51ac1d130fd4 865 if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *)) {
mbed_official 0:51ac1d130fd4 866 printer(arg, " %s", ChapCodenames[code-1]);
mbed_official 0:51ac1d130fd4 867 } else {
mbed_official 0:51ac1d130fd4 868 printer(arg, " code=0x%x", code);
mbed_official 0:51ac1d130fd4 869 }
mbed_official 0:51ac1d130fd4 870 printer(arg, " id=0x%x", id);
mbed_official 0:51ac1d130fd4 871 len -= CHAP_HEADERLEN;
mbed_official 0:51ac1d130fd4 872 switch (code) {
mbed_official 0:51ac1d130fd4 873 case CHAP_CHALLENGE:
mbed_official 0:51ac1d130fd4 874 case CHAP_RESPONSE:
mbed_official 0:51ac1d130fd4 875 if (len < 1) {
mbed_official 0:51ac1d130fd4 876 break;
mbed_official 0:51ac1d130fd4 877 }
mbed_official 0:51ac1d130fd4 878 clen = p[0];
mbed_official 0:51ac1d130fd4 879 if (len < clen + 1) {
mbed_official 0:51ac1d130fd4 880 break;
mbed_official 0:51ac1d130fd4 881 }
mbed_official 0:51ac1d130fd4 882 ++p;
mbed_official 0:51ac1d130fd4 883 nlen = len - clen - 1;
mbed_official 0:51ac1d130fd4 884 printer(arg, " <");
mbed_official 0:51ac1d130fd4 885 for (; clen > 0; --clen) {
mbed_official 0:51ac1d130fd4 886 GETCHAR(x, p);
mbed_official 0:51ac1d130fd4 887 printer(arg, "%.2x", x);
mbed_official 0:51ac1d130fd4 888 }
mbed_official 0:51ac1d130fd4 889 printer(arg, ">, name = %.*Z", nlen, p);
mbed_official 0:51ac1d130fd4 890 break;
mbed_official 0:51ac1d130fd4 891 case CHAP_FAILURE:
mbed_official 0:51ac1d130fd4 892 case CHAP_SUCCESS:
mbed_official 0:51ac1d130fd4 893 printer(arg, " %.*Z", len, p);
mbed_official 0:51ac1d130fd4 894 break;
mbed_official 0:51ac1d130fd4 895 default:
mbed_official 0:51ac1d130fd4 896 for (clen = len; clen > 0; --clen) {
mbed_official 0:51ac1d130fd4 897 GETCHAR(x, p);
mbed_official 0:51ac1d130fd4 898 printer(arg, " %.2x", x);
mbed_official 0:51ac1d130fd4 899 }
mbed_official 0:51ac1d130fd4 900 }
mbed_official 0:51ac1d130fd4 901
mbed_official 0:51ac1d130fd4 902 return len + CHAP_HEADERLEN;
mbed_official 0:51ac1d130fd4 903 }
mbed_official 0:51ac1d130fd4 904 #endif /* PPP_ADDITIONAL_CALLBACKS */
mbed_official 0:51ac1d130fd4 905
mbed_official 0:51ac1d130fd4 906 #endif /* CHAP_SUPPORT */
mbed_official 0:51ac1d130fd4 907
mbed_official 0:51ac1d130fd4 908 #endif /* PPP_SUPPORT */