00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 #include "lwip/opt.h"
00070
00071 #if PPP_SUPPORT
00072
00073 #if CHAP_SUPPORT
00074
00075 #include "ppp.h"
00076 #include "pppdebug.h"
00077
00078 #include "magic.h"
00079 #include "randm.h"
00080 #include "auth.h"
00081 #include "md5.h"
00082 #include "chap.h"
00083 #include "chpms.h"
00084
00085 #include <string.h>
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 static void ChapInit (int);
00104 static void ChapLowerUp (int);
00105 static void ChapLowerDown (int);
00106 static void ChapInput (int, u_char *, int);
00107 static void ChapProtocolReject (int);
00108 #if 0
00109 static int ChapPrintPkt (u_char *, int, void (*) (void *, char *, ...), void *);
00110 #endif
00111
00112 static void ChapChallengeTimeout (void *);
00113 static void ChapResponseTimeout (void *);
00114 static void ChapReceiveChallenge (chap_state *, u_char *, int, int);
00115 static void ChapRechallenge (void *);
00116 static void ChapReceiveResponse (chap_state *, u_char *, int, int);
00117 static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len);
00118 static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len);
00119 static void ChapSendStatus (chap_state *, int);
00120 static void ChapSendChallenge (chap_state *);
00121 static void ChapSendResponse (chap_state *);
00122 static void ChapGenChallenge (chap_state *);
00123
00124
00125
00126
00127
00128 chap_state chap[NUM_PPP];
00129
00130 struct protent chap_protent = {
00131 PPP_CHAP,
00132 ChapInit,
00133 ChapInput,
00134 ChapProtocolReject,
00135 ChapLowerUp,
00136 ChapLowerDown,
00137 NULL,
00138 NULL,
00139 #if 0
00140 ChapPrintPkt,
00141 NULL,
00142 #endif
00143 1,
00144 "CHAP",
00145 #if 0
00146 NULL,
00147 NULL,
00148 NULL
00149 #endif
00150 };
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 void
00161 ChapAuthWithPeer(int unit, char *our_name, int digest)
00162 {
00163 chap_state *cstate = &chap[unit];
00164
00165 cstate->resp_name = our_name;
00166 cstate->resp_type = digest;
00167
00168 if (cstate->clientstate == CHAPCS_INITIAL ||
00169 cstate->clientstate == CHAPCS_PENDING) {
00170
00171 cstate->clientstate = CHAPCS_PENDING;
00172 return;
00173 }
00174
00175
00176
00177
00178
00179
00180 cstate->clientstate = CHAPCS_LISTEN;
00181 }
00182
00183
00184
00185
00186
00187 void
00188 ChapAuthPeer(int unit, char *our_name, int digest)
00189 {
00190 chap_state *cstate = &chap[unit];
00191
00192 cstate->chal_name = our_name;
00193 cstate->chal_type = digest;
00194
00195 if (cstate->serverstate == CHAPSS_INITIAL ||
00196 cstate->serverstate == CHAPSS_PENDING) {
00197
00198 cstate->serverstate = CHAPSS_PENDING;
00199 return;
00200 }
00201
00202 ChapGenChallenge(cstate);
00203 ChapSendChallenge(cstate);
00204 cstate->serverstate = CHAPSS_INITIAL_CHAL;
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214 static void
00215 ChapInit(int unit)
00216 {
00217 chap_state *cstate = &chap[unit];
00218
00219 BZERO(cstate, sizeof(*cstate));
00220 cstate->unit = unit;
00221 cstate->clientstate = CHAPCS_INITIAL;
00222 cstate->serverstate = CHAPSS_INITIAL;
00223 cstate->timeouttime = CHAP_DEFTIMEOUT;
00224 cstate->max_transmits = CHAP_DEFTRANSMITS;
00225
00226 }
00227
00228
00229
00230
00231
00232 static void
00233 ChapChallengeTimeout(void *arg)
00234 {
00235 chap_state *cstate = (chap_state *) arg;
00236
00237
00238
00239 if (cstate->serverstate != CHAPSS_INITIAL_CHAL &&
00240 cstate->serverstate != CHAPSS_RECHALLENGE) {
00241 return;
00242 }
00243
00244 if (cstate->chal_transmits >= cstate->max_transmits) {
00245
00246 CHAPDEBUG((LOG_ERR, "Peer failed to respond to CHAP challenge\n"));
00247 cstate->serverstate = CHAPSS_BADAUTH;
00248 auth_peer_fail(cstate->unit, PPP_CHAP);
00249 return;
00250 }
00251
00252 ChapSendChallenge(cstate);
00253 }
00254
00255
00256
00257
00258
00259 static void
00260 ChapResponseTimeout(void *arg)
00261 {
00262 chap_state *cstate = (chap_state *) arg;
00263
00264
00265 if (cstate->clientstate != CHAPCS_RESPONSE) {
00266 return;
00267 }
00268
00269 ChapSendResponse(cstate);
00270 }
00271
00272
00273
00274
00275
00276 static void
00277 ChapRechallenge(void *arg)
00278 {
00279 chap_state *cstate = (chap_state *) arg;
00280
00281
00282 if (cstate->serverstate != CHAPSS_OPEN) {
00283 return;
00284 }
00285
00286 ChapGenChallenge(cstate);
00287 ChapSendChallenge(cstate);
00288 cstate->serverstate = CHAPSS_RECHALLENGE;
00289 }
00290
00291
00292
00293
00294
00295
00296
00297 static void
00298 ChapLowerUp(int unit)
00299 {
00300 chap_state *cstate = &chap[unit];
00301
00302 if (cstate->clientstate == CHAPCS_INITIAL) {
00303 cstate->clientstate = CHAPCS_CLOSED;
00304 } else if (cstate->clientstate == CHAPCS_PENDING) {
00305 cstate->clientstate = CHAPCS_LISTEN;
00306 }
00307
00308 if (cstate->serverstate == CHAPSS_INITIAL) {
00309 cstate->serverstate = CHAPSS_CLOSED;
00310 } else if (cstate->serverstate == CHAPSS_PENDING) {
00311 ChapGenChallenge(cstate);
00312 ChapSendChallenge(cstate);
00313 cstate->serverstate = CHAPSS_INITIAL_CHAL;
00314 }
00315 }
00316
00317
00318
00319
00320
00321
00322
00323 static void
00324 ChapLowerDown(int unit)
00325 {
00326 chap_state *cstate = &chap[unit];
00327
00328
00329 if (cstate->serverstate == CHAPSS_INITIAL_CHAL ||
00330 cstate->serverstate == CHAPSS_RECHALLENGE) {
00331 UNTIMEOUT(ChapChallengeTimeout, cstate);
00332 } else if (cstate->serverstate == CHAPSS_OPEN
00333 && cstate->chal_interval != 0) {
00334 UNTIMEOUT(ChapRechallenge, cstate);
00335 }
00336 if (cstate->clientstate == CHAPCS_RESPONSE) {
00337 UNTIMEOUT(ChapResponseTimeout, cstate);
00338 }
00339 cstate->clientstate = CHAPCS_INITIAL;
00340 cstate->serverstate = CHAPSS_INITIAL;
00341 }
00342
00343
00344
00345
00346
00347 static void
00348 ChapProtocolReject(int unit)
00349 {
00350 chap_state *cstate = &chap[unit];
00351
00352 if (cstate->serverstate != CHAPSS_INITIAL &&
00353 cstate->serverstate != CHAPSS_CLOSED) {
00354 auth_peer_fail(unit, PPP_CHAP);
00355 }
00356 if (cstate->clientstate != CHAPCS_INITIAL &&
00357 cstate->clientstate != CHAPCS_CLOSED) {
00358 auth_withpeer_fail(unit, PPP_CHAP);
00359 }
00360 ChapLowerDown(unit);
00361 }
00362
00363
00364
00365
00366
00367 static void
00368 ChapInput(int unit, u_char *inpacket, int packet_len)
00369 {
00370 chap_state *cstate = &chap[unit];
00371 u_char *inp;
00372 u_char code, id;
00373 int len;
00374
00375
00376
00377
00378
00379 inp = inpacket;
00380 if (packet_len < CHAP_HEADERLEN) {
00381 CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short header.\n"));
00382 return;
00383 }
00384 GETCHAR(code, inp);
00385 GETCHAR(id, inp);
00386 GETSHORT(len, inp);
00387 if (len < CHAP_HEADERLEN) {
00388 CHAPDEBUG((LOG_INFO, "ChapInput: rcvd illegal length.\n"));
00389 return;
00390 }
00391 if (len > packet_len) {
00392 CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short packet.\n"));
00393 return;
00394 }
00395 len -= CHAP_HEADERLEN;
00396
00397
00398
00399
00400 switch (code) {
00401 case CHAP_CHALLENGE:
00402 ChapReceiveChallenge(cstate, inp, id, len);
00403 break;
00404
00405 case CHAP_RESPONSE:
00406 ChapReceiveResponse(cstate, inp, id, len);
00407 break;
00408
00409 case CHAP_FAILURE:
00410 ChapReceiveFailure(cstate, inp, id, len);
00411 break;
00412
00413 case CHAP_SUCCESS:
00414 ChapReceiveSuccess(cstate, inp, id, len);
00415 break;
00416
00417 default:
00418 CHAPDEBUG((LOG_WARNING, "Unknown CHAP code (%d) received.\n", code));
00419 break;
00420 }
00421 }
00422
00423
00424
00425
00426
00427 static void
00428 ChapReceiveChallenge(chap_state *cstate, u_char *inp, int id, int len)
00429 {
00430 int rchallenge_len;
00431 u_char *rchallenge;
00432 int secret_len;
00433 char secret[MAXSECRETLEN];
00434 char rhostname[256];
00435 MD5_CTX mdContext;
00436 u_char hash[MD5_SIGNATURE_SIZE];
00437
00438 CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: Rcvd id %d.\n", id));
00439 if (cstate->clientstate == CHAPCS_CLOSED ||
00440 cstate->clientstate == CHAPCS_PENDING) {
00441 CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: in state %d\n",
00442 cstate->clientstate));
00443 return;
00444 }
00445
00446 if (len < 2) {
00447 CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.\n"));
00448 return;
00449 }
00450
00451 GETCHAR(rchallenge_len, inp);
00452 len -= sizeof (u_char) + rchallenge_len;
00453 if (len < 0) {
00454 CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.\n"));
00455 return;
00456 }
00457 rchallenge = inp;
00458 INCPTR(rchallenge_len, inp);
00459
00460 if (len >= sizeof(rhostname)) {
00461 len = sizeof(rhostname) - 1;
00462 }
00463 BCOPY(inp, rhostname, len);
00464 rhostname[len] = '\000';
00465
00466 CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field '%s'\n", rhostname));
00467
00468
00469 if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rhostname[0] == 0)) {
00470 strncpy(rhostname, ppp_settings.remote_name, sizeof(rhostname));
00471 rhostname[sizeof(rhostname) - 1] = 0;
00472 CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: using '%s' as remote name\n", rhostname));
00473 }
00474
00475
00476 if (!get_secret(cstate->unit, cstate->resp_name, rhostname, secret, &secret_len, 0)) {
00477 secret_len = 0;
00478 CHAPDEBUG((LOG_WARNING, "No CHAP secret found for authenticating us to %s\n", rhostname));
00479 }
00480
00481
00482 if (cstate->clientstate == CHAPCS_RESPONSE) {
00483 UNTIMEOUT(ChapResponseTimeout, cstate);
00484 }
00485
00486 cstate->resp_id = id;
00487 cstate->resp_transmits = 0;
00488
00489
00490 switch (cstate->resp_type) {
00491
00492 case CHAP_DIGEST_MD5:
00493 MD5Init(&mdContext);
00494 MD5Update(&mdContext, &cstate->resp_id, 1);
00495 MD5Update(&mdContext, (u_char*)secret, secret_len);
00496 MD5Update(&mdContext, rchallenge, rchallenge_len);
00497 MD5Final(hash, &mdContext);
00498 BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE);
00499 cstate->resp_length = MD5_SIGNATURE_SIZE;
00500 break;
00501
00502 #ifdef CHAPMS
00503 case CHAP_MICROSOFT:
00504 ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len);
00505 break;
00506 #endif
00507
00508 default:
00509 CHAPDEBUG((LOG_INFO, "unknown digest type %d\n", cstate->resp_type));
00510 return;
00511 }
00512
00513 BZERO(secret, sizeof(secret));
00514 ChapSendResponse(cstate);
00515 }
00516
00517
00518
00519
00520
00521 static void
00522 ChapReceiveResponse(chap_state *cstate, u_char *inp, int id, int len)
00523 {
00524 u_char *remmd, remmd_len;
00525 int secret_len, old_state;
00526 int code;
00527 char rhostname[256];
00528 MD5_CTX mdContext;
00529 char secret[MAXSECRETLEN];
00530 u_char hash[MD5_SIGNATURE_SIZE];
00531
00532 CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: Rcvd id %d.\n", id));
00533
00534 if (cstate->serverstate == CHAPSS_CLOSED ||
00535 cstate->serverstate == CHAPSS_PENDING) {
00536 CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: in state %d\n",
00537 cstate->serverstate));
00538 return;
00539 }
00540
00541 if (id != cstate->chal_id) {
00542 return;
00543 }
00544
00545
00546
00547
00548
00549
00550 if (cstate->serverstate == CHAPSS_OPEN) {
00551 ChapSendStatus(cstate, CHAP_SUCCESS);
00552 return;
00553 }
00554 if (cstate->serverstate == CHAPSS_BADAUTH) {
00555 ChapSendStatus(cstate, CHAP_FAILURE);
00556 return;
00557 }
00558
00559 if (len < 2) {
00560 CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.\n"));
00561 return;
00562 }
00563 GETCHAR(remmd_len, inp);
00564 remmd = inp;
00565 INCPTR(remmd_len, inp);
00566
00567 len -= sizeof (u_char) + remmd_len;
00568 if (len < 0) {
00569 CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.\n"));
00570 return;
00571 }
00572
00573 UNTIMEOUT(ChapChallengeTimeout, cstate);
00574
00575 if (len >= sizeof(rhostname)) {
00576 len = sizeof(rhostname) - 1;
00577 }
00578 BCOPY(inp, rhostname, len);
00579 rhostname[len] = '\000';
00580
00581 CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: received name field: %s\n", rhostname));
00582
00583
00584
00585
00586
00587 code = CHAP_FAILURE;
00588 if (!get_secret(cstate->unit, rhostname, cstate->chal_name, secret, &secret_len, 1)) {
00589
00590 CHAPDEBUG((LOG_WARNING, "No CHAP secret found for authenticating %s\n",
00591 rhostname));
00592 } else {
00593
00594 switch (cstate->chal_type) {
00595
00596 case CHAP_DIGEST_MD5:
00597 if (remmd_len != MD5_SIGNATURE_SIZE) {
00598 break;
00599 }
00600 MD5Init(&mdContext);
00601 MD5Update(&mdContext, &cstate->chal_id, 1);
00602 MD5Update(&mdContext, (u_char*)secret, secret_len);
00603 MD5Update(&mdContext, cstate->challenge, cstate->chal_len);
00604 MD5Final(hash, &mdContext);
00605
00606
00607 if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0) {
00608 code = CHAP_SUCCESS;
00609 }
00610 break;
00611
00612 default:
00613 CHAPDEBUG((LOG_INFO, "unknown digest type %d\n", cstate->chal_type));
00614 }
00615 }
00616
00617 BZERO(secret, sizeof(secret));
00618 ChapSendStatus(cstate, code);
00619
00620 if (code == CHAP_SUCCESS) {
00621 old_state = cstate->serverstate;
00622 cstate->serverstate = CHAPSS_OPEN;
00623 if (old_state == CHAPSS_INITIAL_CHAL) {
00624 auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len);
00625 }
00626 if (cstate->chal_interval != 0) {
00627 TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval);
00628 }
00629 } else {
00630 CHAPDEBUG((LOG_ERR, "CHAP peer authentication failed\n"));
00631 cstate->serverstate = CHAPSS_BADAUTH;
00632 auth_peer_fail(cstate->unit, PPP_CHAP);
00633 }
00634 }
00635
00636
00637
00638
00639 static void
00640 ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len)
00641 {
00642 LWIP_UNUSED_ARG(id);
00643 LWIP_UNUSED_ARG(inp);
00644
00645 CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: Rcvd id %d.\n", id));
00646
00647 if (cstate->clientstate == CHAPCS_OPEN) {
00648
00649 return;
00650 }
00651
00652 if (cstate->clientstate != CHAPCS_RESPONSE) {
00653
00654 CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: in state %d\n", cstate->clientstate));
00655 return;
00656 }
00657
00658 UNTIMEOUT(ChapResponseTimeout, cstate);
00659
00660
00661
00662
00663 if (len > 0) {
00664 PRINTMSG(inp, len);
00665 }
00666
00667 cstate->clientstate = CHAPCS_OPEN;
00668
00669 auth_withpeer_success(cstate->unit, PPP_CHAP);
00670 }
00671
00672
00673
00674
00675
00676 static void
00677 ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len)
00678 {
00679 LWIP_UNUSED_ARG(id);
00680 LWIP_UNUSED_ARG(inp);
00681
00682 CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: Rcvd id %d.\n", id));
00683
00684 if (cstate->clientstate != CHAPCS_RESPONSE) {
00685
00686 CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: in state %d\n", cstate->clientstate));
00687 return;
00688 }
00689
00690 UNTIMEOUT(ChapResponseTimeout, cstate);
00691
00692
00693
00694
00695 if (len > 0) {
00696 PRINTMSG(inp, len);
00697 }
00698
00699 CHAPDEBUG((LOG_ERR, "CHAP authentication failed\n"));
00700 auth_withpeer_fail(cstate->unit, PPP_CHAP);
00701 }
00702
00703
00704
00705
00706
00707 static void
00708 ChapSendChallenge(chap_state *cstate)
00709 {
00710 u_char *outp;
00711 int chal_len, name_len;
00712 int outlen;
00713
00714 chal_len = cstate->chal_len;
00715 name_len = strlen(cstate->chal_name);
00716 outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len;
00717 outp = outpacket_buf[cstate->unit];
00718
00719 MAKEHEADER(outp, PPP_CHAP);
00720
00721 PUTCHAR(CHAP_CHALLENGE, outp);
00722 PUTCHAR(cstate->chal_id, outp);
00723 PUTSHORT(outlen, outp);
00724
00725 PUTCHAR(chal_len, outp);
00726 BCOPY(cstate->challenge, outp, chal_len);
00727 INCPTR(chal_len, outp);
00728
00729 BCOPY(cstate->chal_name, outp, name_len);
00730
00731 pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
00732
00733 CHAPDEBUG((LOG_INFO, "ChapSendChallenge: Sent id %d.\n", cstate->chal_id));
00734
00735 TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime);
00736 ++cstate->chal_transmits;
00737 }
00738
00739
00740
00741
00742
00743 static void
00744 ChapSendStatus(chap_state *cstate, int code)
00745 {
00746 u_char *outp;
00747 int outlen, msglen;
00748 char msg[256];
00749
00750 if (code == CHAP_SUCCESS) {
00751 strcpy(msg, "Welcome!");
00752 } else {
00753 strcpy(msg, "I don't like you. Go 'way.");
00754 }
00755 msglen = strlen(msg);
00756
00757 outlen = CHAP_HEADERLEN + msglen;
00758 outp = outpacket_buf[cstate->unit];
00759
00760 MAKEHEADER(outp, PPP_CHAP);
00761
00762 PUTCHAR(code, outp);
00763 PUTCHAR(cstate->chal_id, outp);
00764 PUTSHORT(outlen, outp);
00765 BCOPY(msg, outp, msglen);
00766 pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
00767
00768 CHAPDEBUG((LOG_INFO, "ChapSendStatus: Sent code %d, id %d.\n", code, cstate->chal_id));
00769 }
00770
00771
00772
00773
00774
00775
00776
00777
00778 static void
00779 ChapGenChallenge(chap_state *cstate)
00780 {
00781 int chal_len;
00782 u_char *ptr = cstate->challenge;
00783 int i;
00784
00785
00786
00787 chal_len = (unsigned)
00788 ((((magic() >> 16) *
00789 (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) >> 16)
00790 + MIN_CHALLENGE_LENGTH);
00791 cstate->chal_len = chal_len;
00792 cstate->chal_id = ++cstate->id;
00793 cstate->chal_transmits = 0;
00794
00795
00796 for (i = 0; i < chal_len; i++ ) {
00797 *ptr++ = (char) (magic() & 0xff);
00798 }
00799 }
00800
00801
00802
00803
00804
00805
00806 static void
00807 ChapSendResponse(chap_state *cstate)
00808 {
00809 u_char *outp;
00810 int outlen, md_len, name_len;
00811
00812 md_len = cstate->resp_length;
00813 name_len = strlen(cstate->resp_name);
00814 outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len;
00815 outp = outpacket_buf[cstate->unit];
00816
00817 MAKEHEADER(outp, PPP_CHAP);
00818
00819 PUTCHAR(CHAP_RESPONSE, outp);
00820 PUTCHAR(cstate->resp_id, outp);
00821 PUTSHORT(outlen, outp);
00822
00823 PUTCHAR(md_len, outp);
00824 BCOPY(cstate->response, outp, md_len);
00825 INCPTR(md_len, outp);
00826
00827 BCOPY(cstate->resp_name, outp, name_len);
00828
00829
00830 pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
00831
00832 cstate->clientstate = CHAPCS_RESPONSE;
00833 TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime);
00834 ++cstate->resp_transmits;
00835 }
00836
00837 #if 0
00838 static char *ChapCodenames[] = {
00839 "Challenge", "Response", "Success", "Failure"
00840 };
00841
00842
00843
00844 static int
00845 ChapPrintPkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg)
00846 {
00847 int code, id, len;
00848 int clen, nlen;
00849 u_char x;
00850
00851 if (plen < CHAP_HEADERLEN) {
00852 return 0;
00853 }
00854 GETCHAR(code, p);
00855 GETCHAR(id, p);
00856 GETSHORT(len, p);
00857 if (len < CHAP_HEADERLEN || len > plen) {
00858 return 0;
00859 }
00860 if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *)) {
00861 printer(arg, " %s", ChapCodenames[code-1]);
00862 } else {
00863 printer(arg, " code=0x%x", code);
00864 }
00865 printer(arg, " id=0x%x", id);
00866 len -= CHAP_HEADERLEN;
00867 switch (code) {
00868 case CHAP_CHALLENGE:
00869 case CHAP_RESPONSE:
00870 if (len < 1) {
00871 break;
00872 }
00873 clen = p[0];
00874 if (len < clen + 1) {
00875 break;
00876 }
00877 ++p;
00878 nlen = len - clen - 1;
00879 printer(arg, " <");
00880 for (; clen > 0; --clen) {
00881 GETCHAR(x, p);
00882 printer(arg, "%.2x", x);
00883 }
00884 printer(arg, ">, name = %.*Z", nlen, p);
00885 break;
00886 case CHAP_FAILURE:
00887 case CHAP_SUCCESS:
00888 printer(arg, " %.*Z", len, p);
00889 break;
00890 default:
00891 for (clen = len; clen > 0; --clen) {
00892 GETCHAR(x, p);
00893 printer(arg, " %.2x", x);
00894 }
00895 }
00896
00897 return len + CHAP_HEADERLEN;
00898 }
00899 #endif
00900
00901 #endif
00902
00903 #endif