Annotation of embedaddon/mpd/src/lcp.c, revision 1.1.1.3.2.1
1.1 misho 1:
2: /*
3: * lcp.c
4: *
5: * Written by Toshiharu OHNO <tony-o@iij.ad.jp>
6: * Copyright (c) 1993, Internet Initiative Japan, Inc. All rights reserved.
7: * See ``COPYRIGHT.iij''
8: *
9: * Rewritten by Archie Cobbs <archie@freebsd.org>
10: * Copyright (c) 1995-1999 Whistle Communications, Inc. All rights reserved.
11: * See ``COPYRIGHT.whistle''
12: */
13:
14: #include "ppp.h"
15: #include "lcp.h"
16: #include "fsm.h"
17: #include "mp.h"
18: #include "phys.h"
19: #include "link.h"
20: #include "msg.h"
21: #include "util.h"
22:
23: /*
24: * DEFINITIONS
25: */
26:
27: #define LCP_ECHO_INTERVAL 5 /* Enable keep alive by default */
28: #define LCP_ECHO_TIMEOUT 40
1.1.1.3.2.1! misho 29: #define LCP_MAX_RESETS 3
1.1 misho 30:
31: #define LCP_KNOWN_CODES ( (1 << CODE_CONFIGREQ) \
32: | (1 << CODE_CONFIGACK) \
33: | (1 << CODE_CONFIGNAK) \
34: | (1 << CODE_CONFIGREJ) \
35: | (1 << CODE_TERMREQ) \
36: | (1 << CODE_TERMACK) \
37: | (1 << CODE_CODEREJ) \
38: | (1 << CODE_PROTOREJ) \
39: | (1 << CODE_ECHOREQ) \
40: | (1 << CODE_ECHOREP) \
41: | (1 << CODE_DISCREQ) \
42: | (1 << CODE_IDENT) \
43: | (1 << CODE_TIMEREM) )
44:
45: #define LCP_PEER_REJECTED(p,x) ((p)->peer_reject & (1<<x))
46: #define LCP_PEER_REJ(p,x) do{(p)->peer_reject |= (1<<(x));}while(0)
47: #define LCP_PEER_UNREJ(p,x) do{(p)->peer_reject &= ~(1<<(x));}while(0)
48:
49: /*
50: * INTERNAL FUNCTIONS
51: */
52:
53: static void LcpConfigure(Fsm fp);
54: static void LcpNewState(Fsm fp, enum fsm_state old, enum fsm_state new);
55: static void LcpNewPhase(Link l, enum lcp_phase new);
56:
57: static u_char *LcpBuildConfigReq(Fsm fp, u_char *cp);
58: static void LcpDecodeConfig(Fsm fp, FsmOption list, int num, int mode);
59: static void LcpLayerDown(Fsm fp);
60: static void LcpLayerStart(Fsm fp);
61: static void LcpLayerFinish(Fsm fp);
62: static int LcpRecvProtoRej(Fsm fp, int proto, Mbuf bp);
63: static void LcpFailure(Fsm fp, enum fsmfail reason);
64: static const struct fsmoption *LcpAuthProtoNak(ushort proto, u_char alg);
65: static short LcpFindAuthProto(ushort proto, u_char alg);
66: static void LcpRecvIdent(Fsm fp, Mbuf bp);
67: static void LcpStopActivity(Link l);
68:
69: /*
70: * INTERNAL VARIABLES
71: */
72:
73: static const struct fsmoptinfo gLcpConfOpts[] = {
74: { "VENDOR", TY_VENDOR, 4, 255, TRUE },
75: { "MRU", TY_MRU, 2, 2, TRUE },
76: { "ACCMAP", TY_ACCMAP, 4, 4, TRUE },
77: { "AUTHPROTO", TY_AUTHPROTO, 2, 255, TRUE },
78: { "QUALPROTO", TY_QUALPROTO, 0, 0, FALSE },
79: { "MAGICNUM", TY_MAGICNUM, 4, 4, TRUE },
80: { "RESERVED", TY_RESERVED, 0, 0, FALSE }, /* DEPRECATED */
81: { "PROTOCOMP", TY_PROTOCOMP, 0, 0, TRUE },
82: { "ACFCOMP", TY_ACFCOMP, 0, 0, TRUE },
83: { "FCSALT", TY_FCSALT, 0, 0, FALSE },
84: { "SDP", TY_SDP, 0, 0, FALSE },
85: { "NUMMODE", TY_NUMMODE, 0, 0, FALSE },
86: { "MULTILINK", TY_MULTILINK, 0, 0, FALSE }, /* DEPRECATED */
87: { "CALLBACK", TY_CALLBACK, 1, 255, TRUE },
88: { "CONNECTTIME", TY_CONNECTTIME, 0, 0, FALSE }, /* DEPRECATED */
89: { "COMPFRAME", TY_COMPFRAME, 0, 0, FALSE }, /* DEPRECATED */
90: { "NDS", TY_NDS, 0, 0, FALSE }, /* DEPRECATED */
91: { "MP MRRU", TY_MRRU, 2, 2, TRUE },
92: { "MP SHORTSEQ", TY_SHORTSEQNUM, 0, 0, TRUE },
93: { "ENDPOINTDISC", TY_ENDPOINTDISC, 1, 255, TRUE },
94: { "PROPRIETARY", TY_PROPRIETARY, 0, 0, FALSE },
95: { "DCEIDENTIFIER", TY_DCEIDENTIFIER, 0, 0, FALSE },
96: { "MULTILINKPLUS", TY_MULTILINKPLUS, 0, 0, FALSE },
97: { "BACP", TY_BACP, 0, 0, FALSE },
98: { "LCPAUTHOPT", TY_LCPAUTHOPT, 0, 0, FALSE },
99: { "COBS", TY_COBS, 0, 0, FALSE },
100: { "PREFIXELISION", TY_PREFIXELISION, 0, 0, FALSE },
101: { "MULTILINKHEADERFMT", TY_MULTILINKHEADERFMT, 0, 0, FALSE },
102: { "INTERNAT", TY_INTERNAT, 0, 0, FALSE },
103: { "SDATALINKSONET", TY_SDATALINKSONET, 0, 0, FALSE },
1.1.1.3 misho 104: { NULL, 0, 0, 0, 0 }
1.1 misho 105: };
106:
107: static struct fsmtype gLcpFsmType = {
108: "LCP", /* Name of protocol */
109: PROTO_LCP, /* Protocol Number */
110: LCP_KNOWN_CODES,
111: TRUE,
112: LG_LCP, LG_LCP2,
113: LcpNewState,
114: NULL,
115: LcpLayerDown,
116: LcpLayerStart,
117: LcpLayerFinish,
118: LcpBuildConfigReq,
119: LcpDecodeConfig,
120: LcpConfigure,
121: NULL,
122: NULL,
123: NULL,
124: NULL,
125: LcpRecvProtoRej,
126: LcpFailure,
127: NULL,
128: NULL,
129: LcpRecvIdent,
1.1.1.3 misho 130: NULL, NULL, NULL
1.1 misho 131: };
132:
133: /* List of possible Authentication Protocols */
134: static struct lcpauthproto gLcpAuthProtos[] = {
135: {
136: PROTO_PAP,
137: 0,
138: LINK_CONF_PAP,
139: },
140: {
141: PROTO_CHAP,
142: CHAP_ALG_MD5,
143: LINK_CONF_CHAPMD5
144: },
145: {
146: PROTO_CHAP,
147: CHAP_ALG_MSOFT,
148: LINK_CONF_CHAPMSv1
149: },
150: {
151: PROTO_CHAP,
152: CHAP_ALG_MSOFTv2,
153: LINK_CONF_CHAPMSv2
154: },
155: {
156: PROTO_EAP,
157: 0,
158: LINK_CONF_EAP
159: }
160:
161: };
162:
163: static const char *PhaseNames[] = {
164: "DEAD",
165: "ESTABLISH",
166: "AUTHENTICATE",
167: "NETWORK",
168: "TERMINATE",
169: };
170:
171: /*
172: * LcpInit()
173: */
174:
175: void
176: LcpInit(Link l)
177: {
178: LcpState const lcp = &l->lcp;
179:
180: memset(lcp, 0, sizeof(*lcp));
181: FsmInit(&lcp->fsm, &gLcpFsmType, l);
182: lcp->fsm.conf.echo_int = LCP_ECHO_INTERVAL;
183: lcp->fsm.conf.echo_max = LCP_ECHO_TIMEOUT;
1.1.1.3.2.1! misho 184: lcp->resets = LCP_MAX_RESETS;
1.1 misho 185: lcp->phase = PHASE_DEAD;
186:
187: AuthInit(l);
188: }
189:
190: /*
191: * LcpInst()
192: */
193:
194: void
195: LcpInst(Link l, Link lt)
196: {
197: LcpState const lcp = &l->lcp;
198:
199: memcpy(lcp, <->lcp, sizeof(*lcp));
200: FsmInst(&lcp->fsm, <->lcp.fsm, l);
201: AuthInst(&lcp->auth, <->lcp.auth);
202: }
203:
204: /*
205: * LcpShutdown()
206: */
207:
208: void
209: LcpShutdown(Link l)
210: {
211: AuthShutdown(l);
212: }
213:
214: /*
215: * LcpConfigure()
216: */
217:
218: static void
219: LcpConfigure(Fsm fp)
220: {
221: Link l = (Link)fp->arg;
222: LcpState const lcp = &l->lcp;
223: short i;
224:
225: /* FSM stuff */
226: lcp->fsm.conf.passive = Enabled(&l->conf.options, LINK_CONF_PASSIVE);
227: lcp->fsm.conf.check_magic =
228: Enabled(&l->conf.options, LINK_CONF_CHECK_MAGIC);
229: lcp->peer_reject = 0;
1.1.1.3 misho 230: lcp->need_reset = 0;
1.1 misho 231:
232: /* Initialize normal LCP stuff */
1.1.1.2 misho 233: lcp->peer_mru = PhysGetMtu(l, 1);
234: lcp->want_mru = PhysGetMru(l, 1);
235: if (l->type && (lcp->want_mru > PhysGetMru(l, 0)))
236: lcp->want_mru = PhysGetMru(l, 0);
1.1 misho 237: lcp->peer_accmap = 0xffffffff;
238: lcp->want_accmap = l->conf.accmap;
239: lcp->peer_acfcomp = FALSE;
240: lcp->want_acfcomp = Enabled(&l->conf.options, LINK_CONF_ACFCOMP);
241: lcp->peer_protocomp = FALSE;
242: lcp->want_protocomp = Enabled(&l->conf.options, LINK_CONF_PROTOCOMP);
243: lcp->peer_magic = 0;
244: lcp->want_magic = Enabled(&l->conf.options,
245: LINK_CONF_MAGICNUM) ? GenerateMagic() : 0;
246: if (l->originate == LINK_ORIGINATE_LOCAL)
247: lcp->want_callback = Enabled(&l->conf.options, LINK_CONF_CALLBACK);
248: else
249: lcp->want_callback = FALSE;
250:
251: /* Authentication stuff */
252: lcp->peer_auth = 0;
253: lcp->want_auth = 0;
254: lcp->peer_alg = 0;
255: lcp->want_alg = 0;
256: lcp->peer_ident[0] = 0;
257:
258: memset(lcp->want_protos, 0, sizeof(lcp->want_protos));
259: /* fill my list of possible auth-protos, most to least secure */
260: /* prefer MS-CHAP to others to get encryption keys */
261: lcp->want_protos[0] = &gLcpAuthProtos[LINK_CONF_CHAPMSv2];
262: lcp->want_protos[1] = &gLcpAuthProtos[LINK_CONF_CHAPMSv1];
263: lcp->want_protos[2] = &gLcpAuthProtos[LINK_CONF_CHAPMD5];
264: lcp->want_protos[3] = &gLcpAuthProtos[LINK_CONF_PAP];
265: lcp->want_protos[4] = &gLcpAuthProtos[LINK_CONF_EAP];
266:
267: /* Use the same list for the MODE_REQ */
268: memcpy(lcp->peer_protos, lcp->want_protos, sizeof(lcp->peer_protos));
269:
270: for (i = 0; i < LCP_NUM_AUTH_PROTOS; i++) {
271: if (Enabled(&l->conf.options, lcp->want_protos[i]->conf) && lcp->want_auth == 0) {
272: lcp->want_auth = lcp->want_protos[i]->proto;
273: lcp->want_alg = lcp->want_protos[i]->alg;
274: /* avoid re-requesting this proto, if it was nak'd by the peer */
275: lcp->want_protos[i] = NULL;
276: } else if (!Enabled(&l->conf.options, lcp->want_protos[i]->conf)) {
277: /* don't request disabled Protos */
278: lcp->want_protos[i] = NULL;
279: }
280:
281: /* remove all denied protos */
282: if (!Acceptable(&l->conf.options, lcp->peer_protos[i]->conf))
283: lcp->peer_protos[i] = NULL;
284: }
285:
286: /* Multi-link stuff */
287: lcp->peer_mrru = 0;
288: lcp->peer_shortseq = FALSE;
289: if (Enabled(&l->conf.options, LINK_CONF_MULTILINK)) {
290: lcp->want_mrru = l->conf.mrru;
291: lcp->want_shortseq = Enabled(&l->conf.options, LINK_CONF_SHORTSEQ);
292: } else {
293: lcp->want_mrru = 0;
294: lcp->want_shortseq = FALSE;
295: }
296:
297: /* Peer discriminator */
298: lcp->peer_discrim.class = DISCRIM_CLASS_NULL;
299: lcp->peer_discrim.len = 0;
300: }
301:
302: /*
303: * LcpNewState()
304: *
305: * Keep track of phase shifts
306: */
307:
308: static void
309: LcpNewState(Fsm fp, enum fsm_state old, enum fsm_state new)
310: {
311: Link l = (Link)fp->arg;
312:
313: switch (old) {
314: case ST_INITIAL: /* DEAD */
315: case ST_STARTING:
316: switch (new) {
317: case ST_INITIAL:
318: /* fall through */
319: case ST_STARTING:
320: break;
321: default:
322: LcpNewPhase(l, PHASE_ESTABLISH);
323: break;
324: }
325: break;
326:
327: case ST_CLOSED: /* ESTABLISH */
328: case ST_STOPPED:
329: switch (new) {
330: case ST_INITIAL:
331: case ST_STARTING:
332: LcpNewPhase(l, PHASE_DEAD);
333: break;
334: default:
335: break;
336: }
337: break;
338:
339: case ST_CLOSING: /* TERMINATE */
340: case ST_STOPPING:
341: switch (new) {
342: case ST_INITIAL:
343: case ST_STARTING:
344: LcpNewPhase(l, PHASE_DEAD);
345: break;
346: case ST_CLOSED:
347: case ST_STOPPED:
348: LcpNewPhase(l, PHASE_ESTABLISH);
349: break;
350: default:
351: break;
352: }
353: break;
354:
355: case ST_REQSENT: /* ESTABLISH */
356: case ST_ACKRCVD:
357: case ST_ACKSENT:
358: switch (new) {
359: case ST_INITIAL:
360: case ST_STARTING:
361: LcpNewPhase(l, PHASE_DEAD);
362: break;
363: case ST_CLOSING:
364: case ST_STOPPING:
365: LcpNewPhase(l, PHASE_TERMINATE);
366: break;
367: case ST_OPENED:
368: LcpNewPhase(l, PHASE_AUTHENTICATE);
369: break;
370: default:
371: break;
372: }
373: break;
374:
375: case ST_OPENED: /* AUTHENTICATE, NETWORK */
376: switch (new) {
377: case ST_STARTING:
378: LcpNewPhase(l, PHASE_DEAD);
379: break;
380: case ST_REQSENT:
381: case ST_ACKSENT:
382: LcpNewPhase(l, PHASE_ESTABLISH);
383: break;
384: case ST_CLOSING:
385: case ST_STOPPING:
386: LcpNewPhase(l, PHASE_TERMINATE);
387: break;
388: default:
389: assert(0);
390: }
391: break;
392:
393: default:
394: assert(0);
395: }
396:
397: LinkShutdownCheck(l, new);
398: }
399:
400: /*
401: * LcpNewPhase()
402: */
403:
404: static void
405: LcpNewPhase(Link l, enum lcp_phase new)
406: {
407: LcpState const lcp = &l->lcp;
408: enum lcp_phase old = lcp->phase;
409:
410: /* Logit */
411: Log(LG_LCP2, ("[%s] %s: phase shift %s --> %s",
412: Pref(&lcp->fsm), Fsm(&lcp->fsm), PhaseNames[old], PhaseNames[new]));
413:
414: /* Sanity check transition (The picture on RFC 1661 p. 6 is incomplete) */
415: switch (old) {
416: case PHASE_DEAD:
417: assert(new == PHASE_ESTABLISH);
418: break;
419: case PHASE_ESTABLISH:
420: assert(new == PHASE_DEAD
421: || new == PHASE_TERMINATE
422: || new == PHASE_AUTHENTICATE);
423: break;
424: case PHASE_AUTHENTICATE:
425: assert(new == PHASE_TERMINATE
426: || new == PHASE_ESTABLISH
427: || new == PHASE_NETWORK
428: || new == PHASE_DEAD);
429: break;
430: case PHASE_NETWORK:
431: assert(new == PHASE_TERMINATE
432: || new == PHASE_ESTABLISH
433: || new == PHASE_DEAD);
434: break;
435: case PHASE_TERMINATE:
436: assert(new == PHASE_ESTABLISH
437: || new == PHASE_DEAD);
438: break;
439: default:
440: assert(0);
441: }
442:
443: /* Change phase now */
444: lcp->phase = new;
445:
446: /* Do whatever for leaving old phase */
447: switch (old) {
448: case PHASE_AUTHENTICATE:
449: if (new != PHASE_NETWORK)
450: AuthCleanup(l);
451: break;
452:
453: case PHASE_NETWORK:
454: if (l->joined_bund)
455: BundLeave(l);
456: AuthCleanup(l);
457: break;
458:
459: default:
460: break;
461: }
462:
463: /* Do whatever for entering new phase */
464: switch (new) {
465: case PHASE_ESTABLISH:
466: break;
467:
468: case PHASE_AUTHENTICATE:
469: if (!PhysIsSync(l))
470: PhysSetAccm(l, lcp->peer_accmap, lcp->want_accmap);
471: AuthStart(l);
472: break;
473:
474: case PHASE_NETWORK:
475: /* Send ident string, if configured */
476: if (l->conf.ident != NULL)
477: FsmSendIdent(&lcp->fsm, l->conf.ident);
478:
479: /* Send Time-Remaining if known */
480: if (Enabled(&l->conf.options, LINK_CONF_TIMEREMAIN) &&
481: lcp->auth.params.session_timeout != 0)
482: FsmSendTimeRemaining(&lcp->fsm, lcp->auth.params.session_timeout);
483:
484: /* Join my bundle */
485: if (!BundJoin(l)) {
486: Log(LG_LINK|LG_BUND,
487: ("[%s] link did not validate in bundle",
488: l->name));
489: RecordLinkUpDownReason(NULL, l,
490: 0, STR_PROTO_ERR, "%s", STR_MULTI_FAIL);
491: FsmFailure(&l->lcp.fsm, FAIL_NEGOT_FAILURE);
492: } else {
493: /* If link connection complete, reset redial counter */
494: l->num_redial = 0;
495: }
496: break;
497:
498: case PHASE_TERMINATE:
499: break;
500:
501: case PHASE_DEAD:
502: break;
503:
504: default:
505: assert(0);
506: }
507: }
508:
509: /*
510: * LcpAuthResult()
511: */
512:
513: void
514: LcpAuthResult(Link l, int success)
515: {
516: Log(LG_AUTH|LG_LCP, ("[%s] %s: authorization %s",
517: Pref(&l->lcp.fsm), Fsm(&l->lcp.fsm), success ? "successful" : "failed"));
518: if (success) {
519: if (l->lcp.phase != PHASE_NETWORK)
520: LcpNewPhase(l, PHASE_NETWORK);
521: } else {
522: RecordLinkUpDownReason(NULL, l, 0, STR_LOGIN_FAIL,
523: "%s", STR_PPP_AUTH_FAILURE);
524: FsmFailure(&l->lcp.fsm, FAIL_NEGOT_FAILURE);
525: }
526: }
527:
528: /*
529: * LcpStat()
530: */
531:
532: int
1.1.1.3 misho 533: LcpStat(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 534: {
535: Link const l = ctx->lnk;
536: LcpState const lcp = &l->lcp;
537: char buf[64];
538:
1.1.1.3 misho 539: (void)ac;
540: (void)av;
541: (void)arg;
542:
1.1 misho 543: Printf("%s [%s]\r\n", lcp->fsm.type->name, FsmStateName(lcp->fsm.state));
544:
545: Printf("Self:\r\n");
546: Printf( "\tMRU : %d bytes\r\n"
547: "\tMAGIC : 0x%08x\r\n"
548: "\tACCMAP : 0x%08x\r\n"
549: "\tACFCOMP : %s\r\n"
550: "\tPROTOCOMP: %s\r\n"
551: "\tAUTHTYPE : %s\r\n",
552: (int) lcp->want_mru,
553: (int) lcp->want_magic,
554: (int) lcp->want_accmap,
555: lcp->want_acfcomp ? "Yes" : "No",
556: lcp->want_protocomp ? "Yes" : "No",
557: (lcp->want_auth)?ProtoName(lcp->want_auth):"none");
558:
559: if (lcp->want_mrru) {
560: Printf( "\tMRRU : %d bytes\r\n", (int) lcp->want_mrru);
561: Printf( "\tSHORTSEQ : %s\r\n", lcp->want_shortseq ? "Yes" : "No");
562: Printf( "\tENDPOINTDISC: %s\r\n", MpDiscrimText(&self_discrim, buf, sizeof(buf)));
563: }
564: if (l->conf.ident)
565: Printf( "\tIDENT : %s\r\n", l->conf.ident);
566:
567: Printf("Peer:\r\n");
568: Printf( "\tMRU : %d bytes\r\n"
569: "\tMAGIC : 0x%08x\r\n"
570: "\tACCMAP : 0x%08x\r\n"
571: "\tACFCOMP : %s\r\n"
572: "\tPROTOCOMP: %s\r\n"
573: "\tAUTHTYPE : %s\r\n",
574: (int) lcp->peer_mru,
575: (int) lcp->peer_magic,
576: (int) lcp->peer_accmap,
577: lcp->peer_acfcomp ? "Yes" : "No",
578: lcp->peer_protocomp ? "Yes" : "No",
579: (lcp->peer_auth)?ProtoName(lcp->peer_auth):"none");
580:
581: if (lcp->peer_mrru) {
582: Printf( "\tMRRU : %d bytes\r\n", (int) lcp->peer_mrru);
583: Printf( "\tSHORTSEQ : %s\r\n", lcp->peer_shortseq ? "Yes" : "No");
584: Printf( "\tENDPOINTDISC: %s\r\n", MpDiscrimText(&lcp->peer_discrim, buf, sizeof(buf)));
585: }
586: if (lcp->peer_ident[0])
587: Printf( "\tIDENT : %s\r\n", lcp->peer_ident);
588:
589: return(0);
590: }
591:
592: /*
593: * LcpBuildConfigReq()
594: */
595:
596: static u_char *
597: LcpBuildConfigReq(Fsm fp, u_char *cp)
598: {
599: Link l = (Link)fp->arg;
600: LcpState const lcp = &l->lcp;
601:
602: /* Standard stuff */
603: if (lcp->want_acfcomp && !LCP_PEER_REJECTED(lcp, TY_ACFCOMP))
604: cp = FsmConfValue(cp, TY_ACFCOMP, 0, NULL);
605: if (lcp->want_protocomp && !LCP_PEER_REJECTED(lcp, TY_PROTOCOMP))
606: cp = FsmConfValue(cp, TY_PROTOCOMP, 0, NULL);
607: if ((!PhysIsSync(l)) && (!LCP_PEER_REJECTED(lcp, TY_ACCMAP)))
608: cp = FsmConfValue(cp, TY_ACCMAP, -4, &lcp->want_accmap);
609: if (!LCP_PEER_REJECTED(lcp, TY_MRU))
610: cp = FsmConfValue(cp, TY_MRU, -2, &lcp->want_mru);
611: if (lcp->want_magic && !LCP_PEER_REJECTED(lcp, TY_MAGICNUM))
612: cp = FsmConfValue(cp, TY_MAGICNUM, -4, &lcp->want_magic);
613: if (lcp->want_callback && !LCP_PEER_REJECTED(lcp, TY_CALLBACK)) {
614: struct {
615: u_char op;
616: u_char data[0];
617: } s_callback;
618:
619: s_callback.op = 0;
620: cp = FsmConfValue(cp, TY_CALLBACK, 1, &s_callback);
621: }
622:
623: /* Authorization stuff */
624: switch (lcp->want_auth) {
625: case PROTO_PAP:
626: case PROTO_EAP:
627: cp = FsmConfValue(cp, TY_AUTHPROTO, -2, &lcp->want_auth);
628: break;
629: case PROTO_CHAP: {
630: struct {
631: u_short want_auth;
632: u_char alg;
633: } s_mdx;
634:
635: s_mdx.want_auth = htons(PROTO_CHAP);
636: s_mdx.alg = lcp->want_alg;
637: cp = FsmConfValue(cp, TY_AUTHPROTO, 3, &s_mdx);
638: }
639: break;
640: }
641:
642: /* Multi-link stuff */
643: if (Enabled(&l->conf.options, LINK_CONF_MULTILINK)
644: && !LCP_PEER_REJECTED(lcp, TY_MRRU)) {
645: cp = FsmConfValue(cp, TY_MRRU, -2, &lcp->want_mrru);
646: if (lcp->want_shortseq && !LCP_PEER_REJECTED(lcp, TY_SHORTSEQNUM))
647: cp = FsmConfValue(cp, TY_SHORTSEQNUM, 0, NULL);
648: if (!LCP_PEER_REJECTED(lcp, TY_ENDPOINTDISC))
649: cp = FsmConfValue(cp, TY_ENDPOINTDISC, 1 + self_discrim.len, &self_discrim.class);
650: }
651:
652: /* Done */
653: return(cp);
654: }
655:
656: static void
657: LcpLayerStart(Fsm fp)
658: {
659: Link l = (Link)fp->arg;
660:
661: LinkNgInit(l);
662: if (!TimerStarted(&l->openTimer))
663: PhysOpen(l);
664: }
665:
666: static void
667: LcpStopActivity(Link l)
668: {
669: AuthStop(l);
670: }
671:
672: static void
673: LcpLayerFinish(Fsm fp)
674: {
675: Link l = (Link)fp->arg;
676:
677: LcpStopActivity(l);
678: if (!l->rep) {
679: PhysClose(l);
680: LinkNgShutdown(l);
681: }
682: }
683:
684: /*
685: * LcpLayerDown()
686: */
687:
688: static void
689: LcpLayerDown(Fsm fp)
690: {
691: Link l = (Link)fp->arg;
1.1.1.3 misho 692: LcpState const lcp = &l->lcp;
693:
1.1 misho 694: LcpStopActivity(l);
1.1.1.3.2.1! misho 695: if (lcp->phase == PHASE_AUTHENTICATE || lcp->phase == PHASE_NETWORK) {
1.1.1.3 misho 696: lcp->need_reset = 1;
1.1.1.3.2.1! misho 697: if (lcp->resets > 0) {
! 698: Log(LG_LCP2, ("[%s] LCP: Reset (%u left)", l->name, (int)lcp->resets));
! 699: lcp->resets--;
! 700: } else {
! 701: Log(LG_LCP2, ("[%s] LCP: Too many resets", l->name));
! 702: FsmFailure(&lcp->fsm, FAIL_NEGOT_FAILURE);
! 703: lcp->resets = LCP_MAX_RESETS;
! 704: }
! 705: }
1.1 misho 706: }
707:
708: void LcpOpen(Link l)
709: {
710: FsmOpen(&l->lcp.fsm);
711: }
712:
713: void LcpClose(Link l)
714: {
715: FsmClose(&l->lcp.fsm);
716: }
717:
718: void LcpUp(Link l)
719: {
720: FsmUp(&l->lcp.fsm);
721: }
722:
723: void LcpDown(Link l)
724: {
725: FsmDown(&l->lcp.fsm);
726: }
727:
728: /*
729: * LcpRecvProtoRej()
730: */
731:
732: static int
733: LcpRecvProtoRej(Fsm fp, int proto, Mbuf bp)
734: {
1.1.1.3 misho 735: Link l = (Link)fp->arg;
1.1 misho 736: int fatal = FALSE;
737: Fsm rej = NULL;
738:
1.1.1.3 misho 739: (void)bp;
740:
1.1 misho 741: /* Which protocol? */
742: switch (proto) {
743: case PROTO_CCP:
744: case PROTO_COMPD:
745: rej = l->bund ? &l->bund->ccp.fsm : NULL;
746: break;
747: case PROTO_ECP:
748: case PROTO_CRYPT:
749: rej = l->bund ? &l->bund->ecp.fsm : NULL;
750: break;
751: case PROTO_IPCP:
752: rej = l->bund ? &l->bund->ipcp.fsm : NULL;
753: break;
754: case PROTO_IPV6CP:
755: rej = l->bund ? &l->bund->ipv6cp.fsm : NULL;
756: break;
757: default:
758: break;
759: }
760:
761: /* Turn off whatever protocol got rejected */
762: if (rej)
763: FsmFailure(rej, FAIL_WAS_PROTREJ);
764: return(fatal);
765: }
766:
767: /*
768: * LcpRecvIdent()
769: */
770:
771: static void
772: LcpRecvIdent(Fsm fp, Mbuf bp)
773: {
774: Link l = (Link)fp->arg;
1.1.1.3 misho 775: unsigned len, clen;
1.1 misho 776:
777: if (bp == NULL)
778: return;
779:
780: if (l->lcp.peer_ident[0] != 0)
781: strlcat(l->lcp.peer_ident, " ", sizeof(l->lcp.peer_ident));
782:
783: len = strlen(l->lcp.peer_ident);
784: clen = sizeof(l->lcp.peer_ident) - len - 1;
785: if (clen > MBLEN(bp))
786: clen = MBLEN(bp);
787: memcpy(l->lcp.peer_ident + len, (char *) MBDATAU(bp), clen);
788: l->lcp.peer_ident[len + clen] = 0;
789: }
790:
791: /*
792: * LcpFailure()
793: */
794:
795: static void
796: LcpFailure(Fsm fp, enum fsmfail reason)
797: {
798: Link l = (Link)fp->arg;
799: char buf[100];
800:
801: snprintf(buf, sizeof(buf), STR_LCP_FAILED, FsmFailureStr(reason));
802: RecordLinkUpDownReason(NULL, l, 0, reason == FAIL_ECHO_TIMEOUT ?
803: STR_ECHO_TIMEOUT : STR_PROTO_ERR, "%s", buf);
804: }
805:
806: /*
807: * LcpDecodeConfig()
808: */
809:
810: static void
811: LcpDecodeConfig(Fsm fp, FsmOption list, int num, int mode)
812: {
813: Link l = (Link)fp->arg;
814: LcpState const lcp = &l->lcp;
815: int k;
816:
817: /* If we have got request, forget the previous values */
818: if (mode == MODE_REQ) {
1.1.1.3 misho 819: if (lcp->need_reset) /* perform complete reset when going back */
820: LcpConfigure(fp); /* from PHASE_AUTHENTICATE or PHASE_NETWORK */
821: else {
1.1.1.2 misho 822: lcp->peer_mru = PhysGetMtu(l, 1);
1.1 misho 823: lcp->peer_accmap = 0xffffffff;
824: lcp->peer_acfcomp = FALSE;
825: lcp->peer_protocomp = FALSE;
826: lcp->peer_magic = 0;
827: lcp->peer_auth = 0;
828: lcp->peer_alg = 0;
829: lcp->peer_mrru = 0;
830: lcp->peer_shortseq = FALSE;
1.1.1.3 misho 831: }
1.1 misho 832: }
833:
834: /* Decode each config option */
835: for (k = 0; k < num; k++) {
836: FsmOption const opt = &list[k];
837: FsmOptInfo const oi = FsmFindOptInfo(gLcpConfOpts, opt->type);
838:
839: /* Check option */
840: if (!oi) {
841: Log(LG_LCP, ("[%s] UNKNOWN[%d] len=%d", l->name, opt->type, opt->len));
842: if (mode == MODE_REQ)
843: FsmRej(fp, opt);
844: continue;
845: }
846: if (!oi->supported) {
847: Log(LG_LCP, ("[%s] %s", l->name, oi->name));
848: if (mode == MODE_REQ) {
849: Log(LG_LCP, ("[%s] Not supported", l->name));
850: FsmRej(fp, opt);
851: }
852: continue;
853: }
854: if (opt->len < oi->minLen + 2 || opt->len > oi->maxLen + 2) {
855: Log(LG_LCP, ("[%s] %s", l->name, oi->name));
856: if (mode == MODE_REQ) {
857: Log(LG_LCP, ("[%s] Bogus length=%d", l->name, opt->len));
858: FsmRej(fp, opt);
859: }
860: continue;
861: }
862:
863: /* Do whatever */
864: switch (opt->type) {
865: case TY_MRU: /* link MRU */
866: {
867: u_int16_t mru;
868:
869: memcpy(&mru, opt->data, 2);
870: mru = ntohs(mru);
871: Log(LG_LCP, ("[%s] %s %d", l->name, oi->name, mru));
872: switch (mode) {
873: case MODE_REQ:
874: if (mru < LCP_MIN_MRU) {
875: mru = htons(LCP_MIN_MRU);
876: memcpy(opt->data, &mru, 2);
877: FsmNak(fp, opt);
878: break;
879: }
880: if (mru < lcp->peer_mru)
881: lcp->peer_mru = mru;
882: FsmAck(fp, opt);
883: break;
884: case MODE_NAK:
885: /* Windows 2000 PPPoE bug workaround */
886: if (mru == lcp->want_mru) {
887: LCP_PEER_REJ(lcp, opt->type);
888: break;
889: }
890: if (mru >= LCP_MIN_MRU
891: && (mru <= l->type->mru || mru < lcp->want_mru))
892: lcp->want_mru = mru;
893: break;
894: case MODE_REJ:
895: LCP_PEER_REJ(lcp, opt->type);
896: break;
897: }
898: }
899: break;
900:
901: case TY_ACCMAP: /* async control character escape map */
902: {
903: u_int32_t accm;
904:
905: memcpy(&accm, opt->data, 4);
906: accm = ntohl(accm);
907: Log(LG_LCP, ("[%s] %s 0x%08x", l->name, oi->name, accm));
908: switch (mode) {
909: case MODE_REQ:
910: lcp->peer_accmap = accm;
911: FsmAck(fp, opt);
912: break;
913: case MODE_NAK:
914: lcp->want_accmap = accm;
915: break;
916: case MODE_REJ:
917: LCP_PEER_REJ(lcp, opt->type);
918: break;
919: }
920: }
921: break;
922:
923: case TY_AUTHPROTO: /* authentication protocol */
924: {
925: u_int16_t proto;
926: int bogus = 0, i, protoPos = -1;
927: LcpAuthProto authProto = NULL;
928:
929: memcpy(&proto, opt->data, 2);
930: proto = ntohs(proto);
931:
932: /* Display it */
933: switch (proto) {
934: case PROTO_CHAP:
935: if (opt->len >= 5) {
936: char buf[20];
937: const char *ts;
938:
939: switch (opt->data[2]) {
940: case CHAP_ALG_MD5:
941: ts = "MD5";
942: break;
943: case CHAP_ALG_MSOFT:
944: ts = "MSOFT";
945: break;
946: case CHAP_ALG_MSOFTv2:
947: ts = "MSOFTv2";
948: break;
949: default:
950: snprintf(buf, sizeof(buf), "0x%02x", opt->data[2]);
951: ts = buf;
952: break;
953: }
954: Log(LG_LCP, ("[%s] %s %s %s", l->name, oi->name, ProtoName(proto), ts));
955: break;
956: }
957: break;
958: default:
959: Log(LG_LCP, ("[%s] %s %s", l->name, oi->name, ProtoName(proto)));
960: break;
961: }
962:
963: /* Sanity check */
964: switch (proto) {
965: case PROTO_PAP:
966: if (opt->len != 4) {
967: Log(LG_LCP, ("[%s] Bad len=%d", l->name, opt->len));
968: bogus = 1;
969: }
970: break;
971: case PROTO_CHAP:
972: if (opt->len != 5) {
973: Log(LG_LCP, ("[%s] Bad len=%d", l->name, opt->len));
974: bogus = 1;
975: }
976: break;
977: }
978: if (!bogus) {
979: protoPos = LcpFindAuthProto(proto, proto == PROTO_CHAP ? opt->data[2] : 0);
980: authProto = (protoPos == -1) ? NULL : &gLcpAuthProtos[protoPos];
981: }
982:
983: /* Deal with it */
984: switch (mode) {
985: case MODE_REQ:
986:
987: /* let us check, whether the requested auth-proto is acceptable */
988: if ((authProto != NULL) && Acceptable(&l->conf.options, authProto->conf)) {
989: lcp->peer_auth = proto;
990: if (proto == PROTO_CHAP)
991: lcp->peer_alg = opt->data[2];
992: FsmAck(fp, opt);
993: break;
994: }
995:
996: /* search an acceptable proto */
997: for(i = 0; i < LCP_NUM_AUTH_PROTOS; i++) {
998: if (lcp->peer_protos[i] != NULL) {
999: FsmNak(fp, LcpAuthProtoNak(lcp->peer_protos[i]->proto, lcp->peer_protos[i]->alg));
1000: break;
1001: }
1002: }
1003:
1004: /* no other acceptable auth-proto found */
1005: if (i == LCP_NUM_AUTH_PROTOS)
1006: FsmRej(fp, opt);
1007: break;
1008:
1009: case MODE_NAK:
1010: /* this should never happen */
1011: if (authProto == NULL)
1012: break;
1013:
1014: /* let us check, whether the requested auth-proto is enabled */
1015: if (Enabled(&l->conf.options, authProto->conf)) {
1016: lcp->want_auth = proto;
1017: if (proto == PROTO_CHAP)
1018: lcp->want_alg = opt->data[2];
1019: break;
1020: }
1021:
1022: /* Remove the disabled proto from my list */
1023: lcp->want_protos[protoPos] = NULL;
1024:
1025: /* Search the next enabled proto */
1026: for(i = 0; i < LCP_NUM_AUTH_PROTOS; i++) {
1027: if (lcp->want_protos[i] != NULL) {
1028: lcp->want_auth = lcp->want_protos[i]->proto;
1029: lcp->want_alg = lcp->want_protos[i]->alg;
1030: break;
1031: }
1032: }
1033: break;
1034:
1035: case MODE_REJ:
1036: LCP_PEER_REJ(lcp, opt->type);
1037: if (l->originate == LINK_ORIGINATE_LOCAL
1038: && Enabled(&l->conf.options, LINK_CONF_NO_ORIG_AUTH)) {
1039: lcp->want_auth = 0;
1040: }
1041: break;
1042: }
1043: }
1044: break;
1045:
1046: case TY_MRRU: /* multi-link MRRU */
1047: {
1048: u_int16_t mrru;
1049:
1050: memcpy(&mrru, opt->data, 2);
1051: mrru = ntohs(mrru);
1052: Log(LG_LCP, ("[%s] %s %d", l->name, oi->name, mrru));
1053: switch (mode) {
1054: case MODE_REQ:
1055: if (!Enabled(&l->conf.options, LINK_CONF_MULTILINK)) {
1056: FsmRej(fp, opt);
1057: break;
1058: }
1059: if (mrru < MP_MIN_MRRU) {
1060: mrru = htons(MP_MIN_MRRU);
1061: memcpy(opt->data, &mrru, 2);
1062: FsmNak(fp, opt);
1063: break;
1064: }
1065: lcp->peer_mrru = mrru;
1066: FsmAck(fp, opt);
1067: break;
1068: case MODE_NAK:
1069: {
1070: /* Let the peer to change it's mind. */
1071: if (LCP_PEER_REJECTED(lcp, opt->type)) {
1072: LCP_PEER_UNREJ(lcp, opt->type);
1073: if (Enabled(&l->conf.options, LINK_CONF_MULTILINK))
1074: lcp->want_mrru = l->conf.mrru;
1075: }
1076: /* Make sure we don't violate any rules by changing MRRU now */
1077: if (mrru > lcp->want_mrru) /* too big */
1078: break;
1079: if (mrru < MP_MIN_MRRU) /* too small; clip */
1080: mrru = MP_MIN_MRRU;
1081:
1082: /* Update our links */
1083: lcp->want_mrru = mrru;
1084: }
1085: break;
1086: case MODE_REJ:
1087: lcp->want_mrru = 0;
1088: LCP_PEER_REJ(lcp, opt->type);
1089: break;
1090: }
1091: }
1092: break;
1093:
1094: case TY_SHORTSEQNUM: /* multi-link short sequence numbers */
1095: Log(LG_LCP, ("[%s] %s", l->name, oi->name));
1096: switch (mode) {
1097: case MODE_REQ:
1098: if (!Enabled(&l->conf.options, LINK_CONF_MULTILINK) ||
1099: !Acceptable(&l->conf.options, LINK_CONF_SHORTSEQ)) {
1100: FsmRej(fp, opt);
1101: break;
1102: }
1103: lcp->peer_shortseq = TRUE;
1104: FsmAck(fp, opt);
1105: break;
1106: case MODE_NAK:
1107: /* Let the peer to change it's mind. */
1108: if (LCP_PEER_REJECTED(lcp, opt->type)) {
1109: LCP_PEER_UNREJ(lcp, opt->type);
1110: if (Enabled(&l->conf.options, LINK_CONF_MULTILINK))
1111: lcp->want_shortseq = Enabled(&l->conf.options, LINK_CONF_SHORTSEQ);
1112: }
1113: break;
1114: case MODE_REJ:
1115: lcp->want_shortseq = FALSE;
1116: LCP_PEER_REJ(lcp, opt->type);
1117: break;
1118: }
1119: break;
1120:
1121: case TY_ENDPOINTDISC: /* multi-link endpoint discriminator */
1122: {
1123: struct discrim dis;
1124: char buf[64];
1125:
1126: if (opt->len < 3 || opt->len > sizeof(dis.bytes)) {
1127: Log(LG_LCP, ("[%s] %s bad len=%d", l->name, oi->name, opt->len));
1128: if (mode == MODE_REQ)
1129: FsmRej(fp, opt);
1130: break;
1131: }
1132: memcpy(&dis.class, opt->data, opt->len - 2);
1133: dis.len = opt->len - 3;
1134: Log(LG_LCP, ("[%s] %s %s", l->name, oi->name, MpDiscrimText(&dis, buf, sizeof(buf))));
1135: switch (mode) {
1136: case MODE_REQ:
1137: lcp->peer_discrim = dis;
1138: FsmAck(fp, opt);
1139: break;
1140: case MODE_NAK:
1141: /* Let the peer to change it's mind. */
1142: LCP_PEER_UNREJ(lcp, opt->type);
1143: break;
1144: case MODE_REJ:
1145: LCP_PEER_REJ(lcp, opt->type);
1146: break;
1147: }
1148: }
1149: break;
1150:
1151: case TY_MAGICNUM: /* magic number */
1152: {
1153: u_int32_t magic;
1154:
1155: memcpy(&magic, opt->data, 4);
1156: magic = ntohl(magic);
1.1.1.2 misho 1157: Log(LG_LCP, ("[%s] %s 0x%08x", l->name, oi->name, magic));
1.1 misho 1158: switch (mode) {
1159: case MODE_REQ:
1160: if (lcp->want_magic) {
1161: if (magic == lcp->want_magic) {
1162: Log(LG_LCP, ("[%s] Same magic! Detected loopback condition", l->name));
1163: magic = htonl(~magic);
1164: memcpy(opt->data, &magic, 4);
1165: FsmNak(fp, opt);
1166: break;
1167: }
1168: lcp->peer_magic = magic;
1169: FsmAck(fp, opt);
1170: break;
1171: }
1172: FsmRej(fp, opt);
1173: break;
1174: case MODE_NAK:
1175: lcp->want_magic = GenerateMagic();
1176: break;
1177: case MODE_REJ:
1178: lcp->want_magic = 0;
1179: LCP_PEER_REJ(lcp, opt->type);
1180: break;
1181: }
1182: }
1183: break;
1184:
1185: case TY_PROTOCOMP: /* Protocol field compression */
1186: Log(LG_LCP, ("[%s] %s", l->name, oi->name));
1187: switch (mode) {
1188: case MODE_REQ:
1189: if (Acceptable(&l->conf.options, LINK_CONF_PROTOCOMP)) {
1190: lcp->peer_protocomp = TRUE;
1191: FsmAck(fp, opt);
1192: break;
1193: }
1194: FsmRej(fp, opt);
1195: break;
1196: case MODE_NAK: /* a NAK here doesn't make sense */
1197: case MODE_REJ:
1198: lcp->want_protocomp = FALSE;
1199: LCP_PEER_REJ(lcp, opt->type);
1200: break;
1201: }
1202: break;
1203:
1204: case TY_ACFCOMP: /* Address field compression */
1205: Log(LG_LCP, ("[%s] %s", l->name, oi->name));
1206: switch (mode) {
1207: case MODE_REQ:
1208: if (Acceptable(&l->conf.options, LINK_CONF_ACFCOMP)) {
1209: lcp->peer_acfcomp = TRUE;
1210: FsmAck(fp, opt);
1211: break;
1212: }
1213: FsmRej(fp, opt);
1214: break;
1215: case MODE_NAK: /* a NAK here doesn't make sense */
1216: case MODE_REJ:
1217: lcp->want_acfcomp = FALSE;
1218: LCP_PEER_REJ(lcp, opt->type);
1219: break;
1220: }
1221: break;
1222:
1223: case TY_CALLBACK: /* Callback */
1224: Log(LG_LCP, ("[%s] %s %d", l->name, oi->name, opt->data[0]));
1225: switch (mode) {
1226: case MODE_REQ: /* we only support peer calling us back */
1227: FsmRej(fp, opt);
1228: break;
1229: case MODE_NAK: /* we only know one way to do it */
1230: /* fall through */
1231: case MODE_REJ:
1232: lcp->want_callback = FALSE;
1233: LCP_PEER_REJ(lcp, opt->type);
1234: break;
1235: }
1236: break;
1237:
1238: case TY_VENDOR:
1239: {
1240: Log(LG_LCP, ("[%s] %s %02x%02x%02x:%d", l->name, oi->name,
1241: opt->data[0], opt->data[1], opt->data[2], opt->data[3]));
1242: switch (mode) {
1243: case MODE_REQ:
1244: FsmRej(fp, opt);
1245: break;
1246: case MODE_NAK:
1247: /* fall through */
1248: case MODE_REJ:
1249: LCP_PEER_REJ(lcp, opt->type);
1250: break;
1251: }
1252: break;
1253: }
1254: break;
1255:
1256: default:
1257: assert(0);
1258: }
1259: }
1260: }
1261:
1262: /*
1263: * LcpInput()
1264: */
1265:
1266: void
1267: LcpInput(Link l, Mbuf bp)
1268: {
1269: FsmInput(&l->lcp.fsm, bp);
1270: }
1271:
1272: static const struct fsmoption *
1273: LcpAuthProtoNak(ushort proto, u_char alg)
1274: {
1.1.1.3 misho 1275: static u_char chapmd5cf[] =
1.1 misho 1276: { PROTO_CHAP >> 8, PROTO_CHAP & 0xff, CHAP_ALG_MD5 };
1277: static const struct fsmoption chapmd5Nak =
1278: { TY_AUTHPROTO, 2 + sizeof(chapmd5cf), (u_char *) chapmd5cf };
1279:
1.1.1.3 misho 1280: static u_char chapmsv1cf[] =
1.1 misho 1281: { PROTO_CHAP >> 8, PROTO_CHAP & 0xff, CHAP_ALG_MSOFT };
1282: static const struct fsmoption chapmsv1Nak =
1283: { TY_AUTHPROTO, 2 + sizeof(chapmsv1cf), (u_char *) chapmsv1cf };
1284:
1.1.1.3 misho 1285: static u_char chapmsv2cf[] =
1.1 misho 1286: { PROTO_CHAP >> 8, PROTO_CHAP & 0xff, CHAP_ALG_MSOFTv2 };
1.1.1.3 misho 1287: static struct fsmoption chapmsv2Nak =
1.1 misho 1288: { TY_AUTHPROTO, 2 + sizeof(chapmsv2cf), (u_char *) chapmsv2cf };
1289:
1.1.1.3 misho 1290: static u_char papcf[] =
1.1 misho 1291: { PROTO_PAP >> 8, PROTO_PAP & 0xff };
1.1.1.3 misho 1292: static struct fsmoption papNak =
1.1 misho 1293: { TY_AUTHPROTO, 2 + sizeof(papcf), (u_char *) papcf };
1294:
1.1.1.3 misho 1295: static u_char eapcf[] =
1.1 misho 1296: { PROTO_EAP >> 8, PROTO_EAP & 0xff };
1.1.1.3 misho 1297: static struct fsmoption eapNak =
1.1 misho 1298: { TY_AUTHPROTO, 2 + sizeof(eapcf), (u_char *) eapcf };
1299:
1300: if (proto == PROTO_PAP) {
1301: return &papNak;
1302: } else if (proto == PROTO_EAP) {
1303: return &eapNak;
1304: } else {
1305: switch (alg) {
1306: case CHAP_ALG_MSOFTv2:
1307: return &chapmsv2Nak;
1308:
1309: case CHAP_ALG_MSOFT:
1310: return &chapmsv1Nak;
1311:
1312: case CHAP_ALG_MD5:
1313: return &chapmd5Nak;
1314:
1315: default:
1316: return NULL;
1317: }
1318: }
1319:
1320: }
1321:
1322: /*
1323: * LcpFindAuthProto()
1324: *
1325: */
1326: static short
1327: LcpFindAuthProto(ushort proto, u_char alg)
1328: {
1329: int i;
1330:
1331: for(i = 0; i < LCP_NUM_AUTH_PROTOS; i++) {
1332: if (gLcpAuthProtos[i].proto == proto && gLcpAuthProtos[i].alg == alg) {
1333: return i;
1334: }
1335: }
1336:
1337: return -1;
1338:
1339: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>