1 /* $OpenBSD: lcp.c,v 1.18 2019/02/27 04:52:19 denis Exp $ */
2
3 /*-
4 * Copyright (c) 2009 Internet Initiative Japan Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28 /* $Id: lcp.c,v 1.18 2019/02/27 04:52:19 denis Exp $ */
29 /**@file
30 * This file provides LCP related functions.
31 *<pre>
32 * RFC1661: The Point-to-Point Protocol (PPP)
33 * RFC1570: PPP LCP Extensions
34 *</pre>
35 */
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <sys/time.h>
39 #include <netinet/in.h>
40 #include <net/if_dl.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <syslog.h>
44 #include <string.h>
45 #include <event.h>
46 #include <ctype.h>
47
48 #include "npppd.h"
49 #include "ppp.h"
50 #include "psm-opt.h"
51
52 #define SPACE " \t\r\n"
53
54 #include "debugutil.h"
55
56 #ifdef LCP_DEBUG
57 #define LCP_DBG(x) fsm_log x
58 #define LCP_ASSERT(x) ASSERT(x)
59 #else
60 #define LCP_DBG(x)
61 #define LCP_ASSERT(x)
62 #endif
63
64 #define PROTREJ 0x08
65 #define ECHOREQ 0x09
66 #define ECHOREP 0x0a
67 #define IDENTIFICATION 0x0c
68
69 static void lcp_resetci(fsm *);
70 static void lcp_addci(fsm *, u_char *, int *);
71 static int lcp_reqci(fsm *, u_char *, int *, int);
72 static int lcp_ackci(fsm *, u_char *, int);
73 static int lcp_nakci(fsm *, u_char *, int);
74 static int lcp_rejci(fsm *, u_char *, int);
75 static int lcp_cilen(fsm *);
76 static void lcp_open(fsm *);
77 static void lcp_down(fsm *);
78 static void lcp_finished(fsm *);
79 static int lcp_ext(fsm *, int, int, u_char *, int);
80 static void lcp_timeout(void *);
81 static void lcp_reset_timeout(void *);
82 static int lcp_proxy_recv_ci(fsm *, u_char *, int);
83 static int lcp_proxy_sent_ci(fsm *, u_char *, int);
84 static void lcp_load_authconfig(fsm *f);
85
86 static struct fsm_callbacks lcp_callbacks = {
87 lcp_resetci, /* Reset our Configuration Information */
88 lcp_cilen, /* Length of our Configuration Information */
89 lcp_addci, /* Add our Configuration Information */
90 lcp_ackci, /* ACK our Configuration Information */
91 lcp_nakci, /* NAK our Configuration Information */
92 lcp_rejci, /* Reject our Configuration Information */
93 lcp_reqci, /* Request peer's Configuration Information */
94 lcp_open, /* Called when fsm reaches OPENED state */
95 lcp_down, /* Called when fsm leaves OPENED state */
96 NULL, /* Called when we want the lower layer up */
97 lcp_finished, /* Called when we want the lower layer down */
98 NULL, /* Called when Protocol-Reject received */
99 NULL, /* Retransmission is necessary */
100 lcp_ext, /* Called to handle LCP-specific codes */
101 "lcp" /* String name of protocol */
102 };
103 #define NO_AUTH_AGREEABLE(lcp) \
104 (!psm_opt_is_enabled(lcp, pap) || psm_opt_is_rejected(lcp, pap)) && \
105 (!psm_opt_is_enabled(lcp, chap) || psm_opt_is_rejected(lcp, chap)) && \
106 (!psm_opt_is_enabled(lcp, chapms) || psm_opt_is_rejected(lcp, chapms)) &&\
107 (!psm_opt_is_enabled(lcp, chapms_v2) || psm_opt_is_rejected(lcp, chapms_v2)) && \
108 (!psm_opt_is_enabled(lcp, eap) || psm_opt_is_rejected(lcp, eap))
109
110
111 /** initializing context for LCP. */
112 void
lcp_init(lcp * _this,npppd_ppp * ppp)113 lcp_init(lcp *_this, npppd_ppp *ppp)
114 {
115 struct tunnconf *conf;
116
117 fsm_init(&_this->fsm);
118
119 _this->fsm.ppp = ppp;
120 _this->fsm.callbacks = &lcp_callbacks;
121 _this->fsm.protocol = PPP_PROTO_LCP;
122 _this->fsm.flags |= OPT_SILENT;
123 _this->timerctx.ctx = _this;
124
125 _this->recv_ress = 0;
126 _this->recv_reqs = 0;
127 _this->magic_number = arc4random();
128
129 conf = ppp_get_tunnconf(ppp);
130 PPP_FSM_CONFIG(&_this->fsm, timeouttime, conf->lcp_timeout);
131 PPP_FSM_CONFIG(&_this->fsm, maxconfreqtransmits,
132 conf->lcp_max_configure);
133 PPP_FSM_CONFIG(&_this->fsm, maxtermtransmits,
134 conf->lcp_max_terminate);
135 PPP_FSM_CONFIG(&_this->fsm, maxnakloops,
136 conf->lcp_max_nak_loop);
137
138 _this->echo_failures = 0;
139 if (!conf->lcp_keepalive)
140 _this->echo_interval = 0;
141 else {
142 _this->echo_interval = conf->lcp_keepalive_interval;
143 _this->echo_retry_interval = conf->lcp_keepalive_retry_interval;
144 _this->echo_max_retries = conf->lcp_keepalive_max_retries;
145 }
146 _this->auth_order[0] = -1;
147 }
148
149
150 /**
151 * This function is called when HDLC as LCP's lower layer is up.
152 */
153 void
lcp_lowerup(lcp * _this)154 lcp_lowerup(lcp *_this)
155 {
156 fsm_lowerup(&_this->fsm);
157 fsm_open(&_this->fsm);
158
159 if (_this->dialin_proxy != 0 &&
160 _this->dialin_proxy_lcp_renegotiation == 0) {
161 _this->fsm.state = OPENED;
162 lcp_open(&_this->fsm);
163 }
164 }
165
166 /**
167 * sending Protocol-Reject.
168 */
169 void
lcp_send_protrej(lcp * _this,u_char * pktp,int lpktp)170 lcp_send_protrej(lcp *_this, u_char *pktp, int lpktp)
171 {
172 LCP_ASSERT(_this != NULL);
173 LCP_ASSERT(pktp != NULL);
174
175 fsm_sdata(&_this->fsm, PROTREJ, _this->fsm.id++, pktp, lpktp);
176 }
177
178 static const char *
lcp_auth_string(int auth)179 lcp_auth_string(int auth)
180 {
181 switch (auth) {
182 case PPP_AUTH_PAP: return "PAP";
183 case PPP_AUTH_CHAP_MD5: return "MD5-CHAP";
184 case PPP_AUTH_CHAP_MS: return "MS-CHAP";
185 case PPP_AUTH_CHAP_MS_V2: return "MS-CHAP-V2";
186 case PPP_AUTH_EAP: return "EAP";
187 case 0: return "none";
188 default: return "ERROR";
189 }
190 }
191
192 static void
lcp_open(fsm * f)193 lcp_open(fsm *f)
194 {
195 lcp *_this;
196 int peer_auth = 0;
197
198 LCP_ASSERT(f != NULL);
199 _this = &f->ppp->lcp;
200
201 if (psm_opt_is_accepted(_this, pap))
202 peer_auth = PPP_AUTH_PAP;
203 else if (psm_opt_is_accepted(_this, chap))
204 peer_auth = PPP_AUTH_CHAP_MD5;
205 else if (psm_opt_is_accepted(_this, chapms))
206 peer_auth = PPP_AUTH_CHAP_MS;
207 else if (psm_opt_is_accepted(_this, chapms_v2))
208 peer_auth = PPP_AUTH_CHAP_MS_V2;
209 else if (psm_opt_is_accepted(_this, eap))
210 peer_auth = PPP_AUTH_EAP;
211 else {
212 if (_this->auth_order[0] > 0) {
213 fsm_log(f, LOG_INFO,
214 "failed to negotiate a auth protocol.");
215 fsm_close(f, "Authentication is required");
216 ppp_set_disconnect_cause(f->ppp,
217 PPP_DISCON_AUTH_PROTOCOL_UNACCEPTABLE,
218 _this->auth_order[0] /* first one */,
219 1 /* peer refused */, NULL);
220 ppp_stop(f->ppp, "Authentication is required");
221 return;
222 }
223 }
224 f->ppp->peer_auth = peer_auth;
225
226 if (_this->xxxmru > 0 && f->ppp->peer_mru <= 0)
227 f->ppp->peer_mru = _this->xxxmru;
228 if (f->ppp->peer_mru <= 0)
229 f->ppp->peer_mru = f->ppp->mru;
230
231 /* checking the size of ppp->peer_mru. */
232 LCP_ASSERT(f->ppp->peer_mru > 500);
233
234 fsm_log(f, LOG_INFO, "logtype=Opened mru=%d/%d auth=%s magic=%08x/%08x"
235 , f->ppp->mru, f->ppp->peer_mru
236 , lcp_auth_string(peer_auth)
237 , f->ppp->lcp.magic_number, f->ppp->lcp.peer_magic_number
238 );
239 lcp_reset_timeout(_this);
240
241 ppp_lcp_up(f->ppp);
242 }
243
244 static void
lcp_down(fsm * f)245 lcp_down(fsm *f)
246 {
247 lcp *_this;
248
249 if (f->ppp->disconnect_code == PPP_DISCON_NO_INFORMATION) {
250 /*
251 * disconnect code is set when we are closing the lcp, so
252 * 'no info' means the lcp is going down by peer's termreq.
253 */
254 ppp_set_disconnect_cause(f->ppp, PPP_DISCON_NORMAL, 0,
255 1 /* peer */, NULL);
256 #ifdef USE_NPPPD_RADIUS
257 ppp_set_radius_terminate_cause(f->ppp,
258 RADIUS_TERMNATE_CAUSE_USER_REQUEST);
259 #endif
260 }
261
262 _this = &f->ppp->lcp;
263 UNTIMEOUT(lcp_timeout, _this);
264 }
265
266 static void
lcp_finished(fsm * f)267 lcp_finished(fsm *f)
268 {
269 ppp_lcp_finished(f->ppp);
270 }
271
272 /**
273 * resetting ConfReq.
274 */
275 static void
lcp_resetci(fsm * f)276 lcp_resetci(fsm *f)
277 {
278 LCP_ASSERT(f != NULL);
279
280 /* Unless doing dialin-proxy without re-negotiation */
281 if (!(f->ppp->lcp.dialin_proxy != 0 &&
282 f->ppp->lcp.dialin_proxy_lcp_renegotiation == 0)) {
283
284 /* Reset the LCP options' state */
285 memset(&f->ppp->lcp.opt, 0, sizeof(f->ppp->lcp.opt));
286 f->ppp->lcp.auth_order[0] = -1;
287 }
288 }
289
290 /**
291 * The length of ConfReq.
292 */
293 static int
lcp_cilen(fsm * f)294 lcp_cilen(fsm *f)
295 {
296 LCP_ASSERT(f != NULL);
297 return f->ppp->mru;
298 }
299
300 /**
301 * selecting authentication protocols which is not rejected yet in order
302 * of auth_order, and adding Authentication-Protocol options in ConfReq
303 * packet area.
304 */
305 static int
lcp_add_auth(fsm * f,u_char ** ucpp)306 lcp_add_auth(fsm *f, u_char **ucpp)
307 {
308 int i;
309 u_char *ucp;
310 lcp *_this;
311
312 ucp = *ucpp;
313 _this = &f->ppp->lcp;
314
315 for (i = 0; _this->auth_order[i] > 0 &&
316 i < countof(_this->auth_order); i++) {
317 switch (_this->auth_order[i]) {
318 case PPP_AUTH_PAP:
319 if (psm_opt_is_rejected(_this, pap))
320 break;
321 PUTCHAR(PPP_LCP_AUTH_PROTOCOL, ucp);
322 PUTCHAR(4, ucp);
323 PUTSHORT(PPP_AUTH_PAP, ucp);
324 psm_opt_set_requested(_this, pap, 1);
325 _this->lastauth = PPP_AUTH_PAP;
326 goto end_loop;
327 case PPP_AUTH_CHAP_MD5:
328 if (psm_opt_is_rejected(_this, chap))
329 break;
330 PUTCHAR(PPP_LCP_AUTH_PROTOCOL, ucp);
331 PUTCHAR(5, ucp);
332 PUTSHORT(PPP_AUTH_CHAP, ucp);
333 PUTCHAR(PPP_AUTH_CHAP_MD5, ucp);
334 psm_opt_set_requested(_this, chap, 1);
335 _this->lastauth = PPP_AUTH_CHAP_MD5;
336 goto end_loop;
337 case PPP_AUTH_CHAP_MS:
338 if (psm_opt_is_rejected(_this, chapms))
339 break;
340 PUTCHAR(PPP_LCP_AUTH_PROTOCOL, ucp);
341 PUTCHAR(5, ucp);
342 PUTSHORT(PPP_AUTH_CHAP, ucp);
343 PUTCHAR(PPP_AUTH_CHAP_MS, ucp);
344 psm_opt_set_requested(_this, chapms, 1);
345 _this->lastauth = PPP_AUTH_CHAP_MS;
346 goto end_loop;
347 case PPP_AUTH_CHAP_MS_V2:
348 if (psm_opt_is_rejected(_this, chapms_v2))
349 break;
350 PUTCHAR(PPP_LCP_AUTH_PROTOCOL, ucp);
351 PUTCHAR(5, ucp);
352 PUTSHORT(PPP_AUTH_CHAP, ucp);
353 PUTCHAR(PPP_AUTH_CHAP_MS_V2, ucp);
354 psm_opt_set_requested(_this, chapms_v2,1);
355 _this->lastauth = PPP_AUTH_CHAP_MS_V2;
356 goto end_loop;
357 case PPP_AUTH_EAP:
358 if (psm_opt_is_rejected(_this, eap))
359 break;
360 PUTCHAR(PPP_LCP_AUTH_PROTOCOL, ucp);
361 PUTCHAR(4, ucp);
362 PUTSHORT(PPP_AUTH_EAP, ucp);
363 psm_opt_set_requested(_this, eap, 1);
364 _this->lastauth = PPP_AUTH_EAP;
365 goto end_loop;
366 }
367 }
368 _this->lastauth = -1;
369 return -1;
370 end_loop:
371 *ucpp = ucp;
372
373 return 0;
374 }
375
376 /**
377 * making ConfReq.
378 */
379 static void
lcp_addci(fsm * f,u_char * ucp,int * lenp)380 lcp_addci(fsm *f, u_char *ucp, int *lenp)
381 {
382 lcp *_this;
383 u_char *start_ucp = ucp;
384
385 LCP_ASSERT(f != NULL);
386
387 _this = &f->ppp->lcp;
388 if (!psm_opt_is_rejected(_this, mru)) {
389 PUTCHAR(PPP_LCP_MRU, ucp);
390 PUTCHAR(4, ucp);
391
392 if (_this->xxxmru > 0) { /* this value is got by Nak. */
393 PUTSHORT(_this->xxxmru, ucp);
394 } else {
395 PUTSHORT(f->ppp->mru, ucp);
396 }
397 psm_opt_set_requested(_this, mru, 1);
398 }
399 if (f->ppp->has_acf == 1) {
400 if (!psm_opt_is_rejected(_this, pfc)) {
401 PUTCHAR(PPP_LCP_PFC, ucp);
402 PUTCHAR(2, ucp);
403 psm_opt_set_requested(_this, pfc, 1);
404 }
405 if (!psm_opt_is_rejected(_this, acfc)) {
406 PUTCHAR(PPP_LCP_ACFC, ucp);
407 PUTCHAR(2, ucp);
408 psm_opt_set_requested(_this, acfc, 1);
409 }
410 }
411 PUTCHAR(PPP_LCP_MAGICNUMBER, ucp);
412 PUTCHAR(6, ucp);
413 PUTLONG(_this->magic_number, ucp);
414
415 if (f->ppp->peer_auth != 0) {
416 _this->auth_order[0] = f->ppp->peer_auth;
417 _this->auth_order[1] = -1;
418 } else if (_this->auth_order[0] < 0) {
419 lcp_load_authconfig(f);
420 }
421
422 lcp_add_auth(f, &ucp);
423 *lenp = ucp - start_ucp;
424 }
425
426 static int
lcp_reqci(fsm * f,u_char * inp,int * lenp,int reject_if_disagree)427 lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree)
428 {
429 uint32_t magic;
430 int type, len, rcode, mru, lrej;
431 u_char *inp0, *rejbuf, *nakbuf, *nakbuf0;
432 lcp *_this;
433
434 _this = &f->ppp->lcp;
435 rejbuf = NULL;
436 rcode = -1;
437 inp0 = inp;
438 lrej = 0;
439
440 if ((rejbuf = malloc(*lenp)) == NULL)
441 return -1;
442 if ((nakbuf0 = malloc(*lenp)) == NULL) {
443 free(rejbuf);
444 return -1;
445 }
446 nakbuf = nakbuf0;
447
448 #define remlen() (*lenp - (inp - inp0))
449 #define LCP_OPT_PEER_ACCEPTED(opt) \
450 psm_peer_opt_set_accepted(&f->ppp->lcp, opt, 1);
451
452 f->ppp->lcp.recv_reqs++;
453
454 while (remlen() >= 2) {
455 GETCHAR(type, inp);
456 GETCHAR(len, inp);
457 if (len <= 0 || remlen() + 2 < len)
458 goto fail;
459
460 switch (type) {
461 case PPP_LCP_MRU:
462 if (len != 4)
463 goto fail;
464 GETSHORT(mru, inp);
465 f->ppp->peer_mru = mru;
466 if (mru < NPPPD_MIN_MRU) {
467 if (reject_if_disagree) {
468 inp -= 2;
469 goto reject;
470 }
471 if (lrej > 0) {
472 /* if there is a reject, will send Rej, not send Nak. */
473 } else {
474 inp -= 2;
475 memcpy(nakbuf, inp, len);
476 nakbuf += len;
477 inp += 2;
478 PUTSHORT(f->ppp->mru, nakbuf);
479
480 rcode = CONFNAK;
481 }
482 } else
483 LCP_OPT_PEER_ACCEPTED(mru);
484 break;
485 case PPP_LCP_MAGICNUMBER:
486 if (len != 6)
487 goto fail;
488 GETLONG(magic, inp);
489 if (magic == _this->magic_number) {
490 inp -= 4;
491 goto reject;
492 }
493 _this->peer_magic_number = magic;
494 break;
495 case PPP_LCP_PFC:
496 if (len != 2)
497 goto fail;
498 LCP_OPT_PEER_ACCEPTED(pfc);
499 break;
500 case PPP_LCP_ACFC:
501 if (len != 2)
502 goto fail;
503 LCP_OPT_PEER_ACCEPTED(acfc);
504 break;
505 case PPP_LCP_AUTH_PROTOCOL:
506 /* currently never authenticate. */
507 case PPP_LCP_QUALITY_PROTOCOL: /* not used */
508 default:
509 reject:
510 inp -= 2;
511 memcpy(rejbuf + lrej, inp, len);
512 lrej += len;
513 inp += len;
514 rcode = CONFREJ;
515 }
516 continue;
517 }
518 if (rcode == -1)
519 rcode = CONFACK;
520 fail:
521 switch (rcode) {
522 case CONFREJ:
523 memcpy(inp0, rejbuf, lrej);
524 *lenp = lrej;
525 break;
526 case CONFNAK:
527 memcpy(inp0, nakbuf0, nakbuf - nakbuf0);
528 *lenp = nakbuf - nakbuf0;
529 break;
530 }
531 if (rcode != CONFACK) {
532 psm_peer_opt_set_accepted(&f->ppp->lcp, mru, 0);
533 psm_peer_opt_set_accepted(&f->ppp->lcp, pfc, 0);
534 psm_peer_opt_set_accepted(&f->ppp->lcp, acfc, 0);
535 }
536 free(rejbuf);
537 free(nakbuf0);
538
539 return rcode;
540 #undef remlen
541 #undef LCP_OPT_PEER_ACCEPTED
542 }
543
544 /** receiving ConfAck. */
545 static int
lcp_ackci(fsm * f,u_char * inp,int inlen)546 lcp_ackci(fsm *f, u_char *inp, int inlen)
547 {
548 int chapalg, authproto, type, len, mru, magic;
549 u_char *inp0;
550
551 #define remlen() (inlen - (inp - inp0))
552 #define LCP_OPT_ACCEPTED(opt) \
553 if (!psm_opt_is_requested(&f->ppp->lcp, opt)) \
554 goto fail; \
555 psm_opt_set_accepted(&f->ppp->lcp, opt, 1);
556
557 f->ppp->lcp.recv_ress++;
558 inp0 = inp;
559 while (remlen() >= 2) {
560 GETCHAR(type, inp);
561 GETCHAR(len, inp);
562
563 if (len <= 0 || remlen() + 2 < len)
564 goto fail;
565
566 switch (type) {
567 case PPP_LCP_MAGICNUMBER:
568 if (len != 6)
569 goto fail;
570 GETLONG(magic, inp);
571 if (f->ppp->lcp.magic_number != magic)
572 goto fail;
573 break;
574 case PPP_LCP_MRU:
575 if (len != 4)
576 goto fail;
577 LCP_OPT_ACCEPTED(mru);
578 GETSHORT(mru, inp);
579 break;
580 case PPP_LCP_AUTH_PROTOCOL:
581 if (len < 4)
582 goto fail;
583 GETSHORT(authproto, inp);
584 switch (authproto) {
585 case PPP_AUTH_PAP:
586 if (len != 4)
587 goto fail;
588 LCP_OPT_ACCEPTED(pap);
589 break;
590 case PPP_AUTH_CHAP:
591 if (len != 5)
592 goto fail;
593 GETCHAR(chapalg, inp);
594 switch (chapalg) {
595 case PPP_AUTH_CHAP_MD5:
596 LCP_OPT_ACCEPTED(chap);
597 break;
598 case PPP_AUTH_CHAP_MS:
599 LCP_OPT_ACCEPTED(chapms);
600 break;
601 case PPP_AUTH_CHAP_MS_V2:
602 LCP_OPT_ACCEPTED(chapms_v2);
603 break;
604 }
605 break;
606 case PPP_AUTH_EAP:
607 if (len != 4)
608 goto fail;
609 LCP_OPT_ACCEPTED(eap);
610 break;
611 }
612 break;
613
614 /*
615 * As RFC1661, ConfRej must be used for boolean options, but
616 * at least RouterTester uses ConfNak for them.
617 */
618 case PPP_LCP_PFC:
619 if (len != 2)
620 goto fail;
621 LCP_OPT_ACCEPTED(pfc);
622 break;
623 case PPP_LCP_ACFC:
624 if (len != 2)
625 goto fail;
626 LCP_OPT_ACCEPTED(acfc);
627 break;
628
629 default:
630 goto fail;
631 }
632 }
633 return 1;
634 fail:
635 fsm_log(f, LOG_ERR, "Received unexpected ConfAck.");
636 if (debug_get_debugfp() != NULL)
637 show_hd(debug_get_debugfp(), inp, remlen());
638 return 0;
639 #undef LCP_OPT_ACCEPTED
640 }
641
642 /** receiving ConfNak. */
643 static int
lcp_nakci(fsm * f,u_char * inp,int inlen)644 lcp_nakci(fsm *f, u_char *inp, int inlen)
645 {
646 int chapalg, authproto, type, len, mru;
647 u_char *inp0;
648 lcp *_this;
649 const char *peer_auth = "unknown";
650
651 #define remlen() (inlen - (inp - inp0))
652 #define LCP_OPT_REJECTED(opt) \
653 if (!psm_opt_is_requested(&f->ppp->lcp, opt)) \
654 goto fail; \
655 psm_opt_set_rejected(&f->ppp->lcp, opt, 1);
656
657 f->ppp->lcp.recv_ress++;
658 inp0 = inp;
659 _this = &f->ppp->lcp;
660 while (remlen() >= 2) {
661 GETCHAR(type, inp);
662 GETCHAR(len, inp);
663
664 if (len <= 0 || remlen() + 2 < len)
665 goto fail;
666
667 switch (type) {
668 case PPP_LCP_MRU:
669 if (len < 4)
670 goto fail;
671 GETSHORT(mru, inp);
672 fsm_log(f, LOG_NOTICE,
673 "ignored ConfNak from the peer: mru=%d", mru);
674 _this->xxxmru = mru;
675 break;
676 case PPP_LCP_AUTH_PROTOCOL:
677 if (len < 4)
678 goto fail;
679 switch (_this->lastauth) {
680 case PPP_AUTH_PAP:
681 psm_opt_set_rejected(_this, pap, 1);
682 break;
683 case PPP_AUTH_CHAP_MD5:
684 psm_opt_set_rejected(_this, chap, 1);
685 break;
686 case PPP_AUTH_CHAP_MS:
687 psm_opt_set_rejected(_this, chapms, 1);
688 break;
689 case PPP_AUTH_CHAP_MS_V2:
690 psm_opt_set_rejected(_this, chapms_v2, 1);
691 break;
692 case PPP_AUTH_EAP:
693 psm_opt_set_rejected(_this, eap, 1);
694 break;
695 }
696 GETSHORT(authproto, inp);
697 switch (authproto) {
698 case PPP_AUTH_PAP:
699 if (psm_opt_is_requested(_this, pap))
700 psm_opt_set_accepted(_this, pap, 1);
701 peer_auth = "pap";
702 break;
703 case PPP_AUTH_CHAP:
704 chapalg = 0;
705 if (len == 5)
706 GETCHAR(chapalg, inp);
707 switch (chapalg) {
708 case PPP_AUTH_CHAP_MD5:
709 if (psm_opt_is_requested(_this, chap))
710 psm_opt_set_accepted(_this,
711 chap, 1);
712 peer_auth = "chap";
713 break;
714 case PPP_AUTH_CHAP_MS:
715 if (psm_opt_is_requested(_this, chapms))
716 psm_opt_set_accepted(_this,
717 chapms, 1);
718 peer_auth = "mschap";
719 break;
720 case PPP_AUTH_CHAP_MS_V2:
721 if (psm_opt_is_requested(_this,
722 chapms_v2))
723 psm_opt_set_accepted(_this,
724 chapms_v2, 1);
725 peer_auth = "mschap_v2";
726 break;
727 default:
728 fsm_log(f, LOG_INFO,
729 "Nacked chap algorithm is "
730 "unknown(%d).", chapalg);
731 peer_auth = "unknown";
732 break;
733 }
734 break;
735 case PPP_AUTH_EAP:
736 if (len != 4)
737 goto fail;
738 peer_auth = "eap";
739 if (psm_opt_is_requested(_this, eap))
740 psm_opt_set_accepted(_this, eap, 1);
741 break;
742 }
743 if (NO_AUTH_AGREEABLE(_this)) {
744 fsm_log(f, LOG_INFO, "No authentication "
745 "protocols are agreeable. peer's "
746 "auth proto=%s",
747 peer_auth);
748 ppp_set_disconnect_cause(f->ppp,
749 PPP_DISCON_AUTH_PROTOCOL_UNACCEPTABLE,
750 authproto, 2 /* couldn't accept peer's */,
751 NULL);
752 ppp_stop(f->ppp, "Authentication is required");
753 return 1;
754 }
755 break;
756 case PPP_LCP_PFC:
757 if (len != 2)
758 goto fail;
759 LCP_OPT_REJECTED(pfc);
760 break;
761 case PPP_LCP_ACFC:
762 if (len != 2)
763 goto fail;
764 LCP_OPT_REJECTED(acfc);
765 break;
766 default:
767 goto fail;
768 }
769 }
770 return 1;
771 fail:
772 log_printf(LOG_ERR, "Received unexpected ConfNak.");
773 if (debug_get_debugfp() != NULL)
774 show_hd(debug_get_debugfp(), inp, inlen);
775 return 0;
776 #undef remlen
777 #undef LCP_OPT_REJECTED
778 }
779
780 /**
781 * receiving ConfRej.
782 */
783 static int
lcp_rejci(fsm * f,u_char * inp,int inlen)784 lcp_rejci(fsm *f, u_char *inp, int inlen)
785 {
786 int chapalg, authproto, type, len, mru;
787 u_char *inp0;
788 lcp *_this;
789
790 #define remlen() (inlen - (inp - inp0))
791 #define LCP_OPT_REJECTED(opt) \
792 if (!psm_opt_is_requested(&f->ppp->lcp, opt)) \
793 goto fail; \
794 psm_opt_set_rejected(&f->ppp->lcp, opt, 1);
795
796 f->ppp->lcp.recv_ress++;
797 inp0 = inp;
798 _this = &f->ppp->lcp;
799 while (remlen() >= 2) {
800 GETCHAR(type, inp);
801 GETCHAR(len, inp);
802
803 if (len <= 0 || remlen() + 2 < len)
804 goto fail;
805
806 switch (type) {
807 case PPP_LCP_MAGICNUMBER:
808 if (f->ppp->lcp.echo_interval > 0)
809 goto fail;
810 inp += 4;
811 break;
812 case PPP_LCP_MRU:
813 LCP_OPT_REJECTED(mru);
814 GETSHORT(mru, inp);
815 break;
816 case PPP_LCP_AUTH_PROTOCOL:
817 if (len < 4)
818 goto fail;
819 GETSHORT(authproto, inp);
820 switch (authproto) {
821 case PPP_AUTH_PAP:
822 if (len != 4)
823 goto fail;
824 LCP_OPT_REJECTED(pap);
825 break;
826 case PPP_AUTH_CHAP:
827 chapalg = 0;
828 if (len == 5)
829 GETCHAR(chapalg, inp);
830 switch (chapalg) {
831 case PPP_AUTH_CHAP_MD5:
832 LCP_OPT_REJECTED(chap);
833 break;
834 case PPP_AUTH_CHAP_MS:
835 LCP_OPT_REJECTED(chapms);
836 break;
837 case PPP_AUTH_CHAP_MS_V2:
838 LCP_OPT_REJECTED(chapms_v2);
839 break;
840 default:
841 fsm_log(f, LOG_INFO,
842 "Rejected chap algorithm is "
843 "unknown(%d).", chapalg);
844 break;
845 }
846 break;
847 case PPP_AUTH_EAP:
848 if (len != 4)
849 goto fail;
850 LCP_OPT_REJECTED(eap);
851 break;
852 }
853 if (NO_AUTH_AGREEABLE(_this)) {
854 fsm_log(f, LOG_INFO, "No authentication "
855 "protocols are agreeable.");
856 ppp_set_disconnect_cause(f->ppp,
857 PPP_DISCON_AUTH_PROTOCOL_UNACCEPTABLE,
858 authproto, 1 /* rejected by peer */, NULL);
859 ppp_stop(f->ppp, "Authentication is required");
860 return 1;
861 }
862 break;
863 case PPP_LCP_PFC:
864 if (len != 2)
865 goto fail;
866 LCP_OPT_REJECTED(pfc);
867 break;
868 case PPP_LCP_ACFC:
869 if (len != 2)
870 goto fail;
871 LCP_OPT_REJECTED(acfc);
872 break;
873 default:
874 goto fail;
875 }
876 }
877 return 1;
878 fail:
879 log_printf(LOG_ERR, "Received unexpected ConfRej.");
880 if (debug_get_debugfp() != NULL)
881 show_hd(debug_get_debugfp(), inp, inlen);
882 return 0;
883 #undef remlen
884 }
885
886 static void
lcp_rcoderej(fsm * f,u_char * inp,int inlen)887 lcp_rcoderej(fsm *f, u_char *inp, int inlen)
888 {
889 uint16_t proto;
890 fsm *rejfsm;
891
892 if (inlen < 2) {
893 fsm_log(f, LOG_WARNING, "Received short ProtRej packet.");
894 return;
895 }
896 GETSHORT(proto, inp);
897
898 rejfsm = NULL;
899
900 switch (proto) {
901 case PPP_PROTO_LCP:
902 rejfsm = &f->ppp->lcp.fsm;
903 break;
904 case PPP_PROTO_PAP:
905 fsm_log(f, LOG_WARNING, "our PAP packet is rejected");
906 return;
907 case PPP_PROTO_CHAP:
908 fsm_log(f, LOG_WARNING, "our CHAP packet is rejected");
909 return;
910 case PPP_PROTO_EAP:
911 fsm_log(f, LOG_ERR, "our EAP packet is rejected");
912 ppp_stop(f->ppp, "Authentication Required");
913 break;
914 case PPP_PROTO_NCP | NCP_IPCP:
915 rejfsm = &f->ppp->ipcp.fsm;
916 break;
917 case PPP_PROTO_NCP | NCP_CCP:
918 rejfsm = &f->ppp->ccp.fsm;
919 break;
920 }
921 if (rejfsm == NULL) {
922 fsm_log(f, LOG_WARNING,
923 "Received ProtRej packet for unknown protocol=(%d/%04x)",
924 proto, proto);
925 return;
926 }
927 fsm_protreject(rejfsm);
928
929 return;
930 }
931
932 static void
lcp_reset_timeout(void * ctx)933 lcp_reset_timeout(void *ctx)
934 {
935 lcp *_this;
936
937 _this = ctx;
938
939 if (_this->echo_interval > 0) {
940 if (_this->echo_failures == 0) {
941 TIMEOUT(lcp_timeout, _this, _this->echo_interval);
942 } else {
943 TIMEOUT(lcp_timeout, _this, _this->echo_retry_interval);
944 }
945 } else {
946 UNTIMEOUT(lcp_timeout, _this);
947 }
948 }
949
950 static void
lcp_timeout(void * ctx)951 lcp_timeout(void *ctx)
952 {
953 lcp *_this;
954 u_char *cp, buf[32];
955
956 _this = ctx;
957 if (_this->echo_failures >= _this->echo_max_retries) {
958 fsm_log(&_this->fsm, LOG_NOTICE, "keepalive failure.");
959 if (_this->fsm.ppp != NULL) {
960 #ifdef USE_NPPPD_RADIUS
961 ppp_set_radius_terminate_cause(_this->fsm.ppp,
962 RADIUS_TERMNATE_CAUSE_IDLE_TIMEOUT);
963 #endif
964 ppp_stop(_this->fsm.ppp, NULL);
965 }
966 return;
967 }
968 cp = buf;
969 PUTLONG(_this->magic_number, cp);
970 fsm_sdata(&_this->fsm, ECHOREQ, _this->fsm.id++, buf, 4);
971 _this->echo_failures++;
972
973 lcp_reset_timeout(_this);
974 }
975
976 static int
lcp_rechoreq(fsm * f,int id,u_char * inp,int inlen)977 lcp_rechoreq(fsm *f, int id, u_char *inp, int inlen)
978 {
979 u_char *inp0;
980 lcp *_this;
981 int len;
982
983 if (inlen < 4)
984 return 0;
985
986 _this = &f->ppp->lcp;
987 inp0 = inp;
988 PUTLONG(_this->magic_number, inp)
989
990 len = MINIMUM(inlen, f->ppp->peer_mru - 8);
991 fsm_sdata(f, ECHOREP, id, inp0, len);
992
993 return 1;
994 }
995
996 static int
lcp_ext(fsm * f,int code,int id,u_char * inp,int inlen)997 lcp_ext(fsm *f, int code, int id, u_char *inp, int inlen)
998 {
999 lcp *_this;
1000 uint32_t magic;
1001 char buf[256];
1002 int i, len;
1003
1004 _this = &f->ppp->lcp;
1005
1006 switch (code) {
1007 case IDENTIFICATION:
1008 /* RFC 1570 */
1009 if (inlen > 4) {
1010 GETLONG(magic, inp);
1011 inlen -= 4;
1012 memset(buf, 0, sizeof(buf));
1013 len = MINIMUM(inlen, sizeof(buf) - 1);
1014 memcpy(buf, inp, len);
1015 buf[len] = '\0';
1016 for (i = 0; i < len; i++) {
1017 if (!isprint((unsigned char)buf[i]))
1018 buf[i] = '.';
1019 }
1020 fsm_log(f, LOG_INFO,
1021 "RecvId magic=%08x text=%s", magic, buf);
1022 }
1023 return 1;
1024 case PROTREJ:
1025 lcp_rcoderej(f, inp, inlen);
1026 return 1;
1027 case ECHOREP:
1028 if (f->state == OPENED) {
1029 if (inlen >= 4) {
1030 GETLONG(magic, inp);
1031 if (_this->peer_magic_number == magic) {
1032 _this->echo_failures = 0;
1033 lcp_reset_timeout(_this);
1034 }
1035 }
1036 }
1037 return 1;
1038 case ECHOREQ:
1039 if (f->state == OPENED)
1040 return lcp_rechoreq(f, id, inp, inlen);
1041 return 1;
1042 }
1043
1044 return 0;
1045 }
1046
1047
1048 /*
1049 * reading some authentication settings and storing ppp_order in
1050 * order of settings.
1051 */
1052 static void
lcp_load_authconfig(fsm * f)1053 lcp_load_authconfig(fsm *f)
1054 {
1055 int i;
1056 lcp *_this;
1057 struct tunnconf *conf;
1058
1059 i = 0;
1060 _this = &f->ppp->lcp;
1061 conf = ppp_get_tunnconf(f->ppp);
1062 if ((conf->auth_methods & NPPPD_AUTH_METHODS_MSCHAPV2) != 0) {
1063 _this->auth_order[i++] = PPP_AUTH_CHAP_MS_V2;
1064 psm_opt_set_enabled(_this,chapms_v2, 1);
1065 }
1066 if ((conf->auth_methods & NPPPD_AUTH_METHODS_CHAP) != 0) {
1067 _this->auth_order[i++] = PPP_AUTH_CHAP_MD5;
1068 psm_opt_set_enabled(_this, chap, 1);
1069 }
1070 if ((conf->auth_methods & NPPPD_AUTH_METHODS_PAP) != 0) {
1071 _this->auth_order[i++] = PPP_AUTH_PAP;
1072 psm_opt_set_enabled(_this, pap, 1);
1073 }
1074
1075 _this->auth_order[i] = -1;
1076 }
1077
1078 /***********************************************************************
1079 * related functions of Dialin Proxy
1080 **********************************************************************/
1081 /**
1082 * This function set LCP status following dialin proxy information.
1083 * This returns non-zero value when LCP status is unacceptable.
1084 *
1085 */
1086 int
lcp_dialin_proxy(lcp * _this,dialin_proxy_info * dpi,int renegotiation,int force_renegotiation)1087 lcp_dialin_proxy(lcp *_this, dialin_proxy_info *dpi, int renegotiation,
1088 int force_renegotiation)
1089 {
1090 int i, authok;
1091
1092 _this->dialin_proxy = 1;
1093 lcp_load_authconfig(&_this->fsm);
1094
1095 /* whether authentication type is permitted by configuration or not. */
1096 authok = 0;
1097 if (dpi->auth_type != 0) {
1098 for (i = 0; _this->auth_order[i] > 0; i++) {
1099 if (_this->auth_order[i] != dpi->auth_type)
1100 continue;
1101 authok = 1;
1102 break;
1103 }
1104 }
1105 if (!authok) {
1106 if (!renegotiation) {
1107 fsm_log(&_this->fsm, LOG_NOTICE,
1108 "dialin-proxy failed. auth-method=%s is "
1109 "not enabled. Try 'l2tp.dialin.lcp_renegotion'",
1110 lcp_auth_string(dpi->auth_type));
1111 return 1;
1112 }
1113 _this->dialin_proxy_lcp_renegotiation = 1;
1114 }
1115 if (force_renegotiation)
1116 _this->dialin_proxy_lcp_renegotiation = 1;
1117
1118 if (_this->dialin_proxy_lcp_renegotiation == 0) {
1119 _this->fsm.ppp->peer_auth = dpi->auth_type;
1120 /*
1121 * Set the rejected flag to all options here for the moment,
1122 * the agreeed options will be handled in lcp_proxy_sent_ci().
1123 */
1124 psm_opt_set_rejected(_this, mru, 1);
1125 psm_opt_set_rejected(_this, pfc, 1);
1126 psm_opt_set_rejected(_this, acfc, 1);
1127 psm_opt_set_rejected(_this, pap, 1);
1128 psm_opt_set_rejected(_this, chap, 1);
1129 psm_opt_set_rejected(_this, chapms, 1);
1130 psm_opt_set_rejected(_this, chapms_v2, 1);
1131 psm_opt_set_rejected(_this, eap, 1);
1132
1133 }
1134 switch (dpi->auth_type) {
1135 case PPP_AUTH_PAP:
1136 pap_proxy_authen_prepare(&_this->fsm.ppp->pap, dpi);
1137 break;
1138 case PPP_AUTH_CHAP_MD5:
1139 chap_proxy_authen_prepare(&_this->fsm.ppp->chap, dpi);
1140 break;
1141 }
1142 if (lcp_proxy_sent_ci(&_this->fsm, dpi->last_sent_lcp.data,
1143 dpi->last_sent_lcp.ldata) != 0) {
1144 fsm_log(&_this->fsm, LOG_NOTICE,
1145 "dialin-proxy failed. couldn't use proxied lcp.");
1146 return 1;
1147 }
1148 if (lcp_proxy_recv_ci(&_this->fsm, dpi->last_recv_lcp.data,
1149 dpi->last_recv_lcp.ldata) != 0) {
1150 fsm_log(&_this->fsm, LOG_NOTICE,
1151 "dialin-proxy failed. couldn't use proxied lcp.");
1152 return 1;
1153 }
1154
1155 fsm_log(&_this->fsm, LOG_INFO,
1156 "dialin-proxy user=%s auth-type=%s renegotiate=%s",
1157 dpi->username,
1158 (dpi->auth_type == 0)? "none" : lcp_auth_string(dpi->auth_type),
1159 (_this->dialin_proxy_lcp_renegotiation != 0)? "yes" : "no");
1160
1161
1162 if (_this->dialin_proxy_lcp_renegotiation == 0)
1163 _this->fsm.flags |= OPT_SILENT; /* It's ready to be "Opened" */
1164 else
1165 _this->fsm.flags &= ~OPT_SILENT;
1166
1167 return 0;
1168 }
1169
1170 /*
1171 * This function copies from lcp_reqci. It only differs as follows:
1172 * - changes LCP_OPT_ACCEPTED.
1173 * - Magic Number and MRU.
1174 */
1175 static int
lcp_proxy_recv_ci(fsm * f,u_char * inp,int inlen)1176 lcp_proxy_recv_ci(fsm *f, u_char *inp, int inlen)
1177 {
1178 int type, mru, len;
1179 uint32_t magic;
1180 u_char *inp0;
1181 lcp *_this;
1182
1183 #define remlen() (inlen - (inp - inp0))
1184 #define LCP_OPT_PEER_ACCEPTED(opt) \
1185 psm_peer_opt_set_rejected(&f->ppp->lcp, opt, 0); \
1186 psm_peer_opt_set_requested(&f->ppp->lcp, opt, 1); \
1187 psm_peer_opt_set_accepted(&f->ppp->lcp, opt, 1);
1188
1189 _this = &f->ppp->lcp;
1190 inp0 = inp;
1191
1192 while (remlen() >= 2) {
1193 GETCHAR(type, inp);
1194 GETCHAR(len, inp);
1195 if (len <= 0 || remlen() + 2 < len)
1196 goto fail;
1197
1198 switch (type) {
1199 case PPP_LCP_MRU:
1200 if (len != 4)
1201 goto fail;
1202 GETSHORT(mru, inp);
1203 f->ppp->peer_mru = mru;
1204 if (mru < NPPPD_MIN_MRU)
1205 goto fail;
1206 else
1207 LCP_OPT_PEER_ACCEPTED(mru);
1208 break;
1209 case PPP_LCP_MAGICNUMBER:
1210 if (len != 6)
1211 goto fail;
1212 GETLONG(magic, inp);
1213 if (magic == _this->magic_number)
1214 goto fail;
1215 _this->peer_magic_number = magic;
1216 break;
1217 case PPP_LCP_PFC:
1218 if (len != 2)
1219 goto fail;
1220 LCP_OPT_PEER_ACCEPTED(pfc);
1221 break;
1222 case PPP_LCP_ACFC:
1223 if (len != 2)
1224 goto fail;
1225 LCP_OPT_PEER_ACCEPTED(acfc);
1226 break;
1227 case PPP_LCP_ACCM:
1228 if (len != 6)
1229 goto fail;
1230 /* we don't use async framing. ignore this */
1231 inp += (len - 2);
1232 break;
1233 default:
1234 goto fail;
1235 }
1236 }
1237
1238 #undef remlen
1239 #undef LCP_OPT_PEER_ACCEPTED
1240 return 0;
1241 fail:
1242 return 1;
1243 }
1244
1245 /*
1246 * This function copies from lcp_ackci. It only differs as follows:
1247 * - Do not recv_reass++.
1248 * - changes LCP_OPT_ACCEPTED.
1249 * - Magic Number and MRU.
1250 */
1251 static int
lcp_proxy_sent_ci(fsm * f,u_char * inp,int inlen)1252 lcp_proxy_sent_ci(fsm *f, u_char *inp, int inlen)
1253 {
1254 int chapalg, authproto, type, len, mru, magic;
1255 u_char *inp0;
1256
1257 #define remlen() (inlen - (inp - inp0))
1258 #define LCP_OPT_ACCEPTED(opt) \
1259 if (f->ppp->lcp.dialin_proxy_lcp_renegotiation == 0) { \
1260 psm_opt_set_rejected(&f->ppp->lcp, opt, 0); \
1261 psm_opt_set_requested(&f->ppp->lcp, opt, 1); \
1262 psm_opt_set_accepted(&f->ppp->lcp, opt, 1); \
1263 }
1264
1265 inp0 = inp;
1266 while (remlen() >= 2) {
1267 GETCHAR(type, inp);
1268 GETCHAR(len, inp);
1269
1270 if (len <= 0 || remlen() + 2 < len)
1271 goto fail;
1272
1273 switch (type) {
1274 case PPP_LCP_MAGICNUMBER:
1275 if (len != 6)
1276 goto fail;
1277 GETLONG(magic, inp);
1278 f->ppp->lcp.magic_number = magic;
1279 break;
1280 case PPP_LCP_MRU:
1281 if (len != 4)
1282 goto fail;
1283 LCP_OPT_ACCEPTED(mru);
1284 GETSHORT(mru, inp);
1285 f->ppp->lcp.xxxmru = mru;
1286 break;
1287 case PPP_LCP_AUTH_PROTOCOL:
1288 if (len < 4)
1289 goto fail;
1290 GETSHORT(authproto, inp);
1291 switch (authproto) {
1292 case PPP_AUTH_PAP:
1293 if (len != 4)
1294 goto fail;
1295 LCP_OPT_ACCEPTED(pap);
1296 break;
1297 case PPP_AUTH_CHAP:
1298 if (len != 5)
1299 goto fail;
1300 GETCHAR(chapalg, inp);
1301 switch (chapalg) {
1302 case PPP_AUTH_CHAP_MD5:
1303 LCP_OPT_ACCEPTED(chap);
1304 break;
1305 case PPP_AUTH_CHAP_MS:
1306 LCP_OPT_ACCEPTED(chapms);
1307 break;
1308 case PPP_AUTH_CHAP_MS_V2:
1309 LCP_OPT_ACCEPTED(chapms_v2);
1310 break;
1311 }
1312 break;
1313 case PPP_AUTH_EAP:
1314 if (len != 4)
1315 goto fail;
1316 LCP_OPT_ACCEPTED(eap);
1317 break;
1318 }
1319 break;
1320 case PPP_LCP_PFC:
1321 if (len != 2)
1322 goto fail;
1323 LCP_OPT_ACCEPTED(pfc);
1324 break;
1325 case PPP_LCP_ACFC:
1326 if (len != 2)
1327 goto fail;
1328 LCP_OPT_ACCEPTED(acfc);
1329 break;
1330 case PPP_LCP_ACCM:
1331 if (len != 6)
1332 goto fail;
1333 /* we don't use async framing. ignore this */
1334 inp += (len - 2);
1335 break;
1336 default:
1337 goto fail;
1338 }
1339 }
1340 return 0;
1341 fail:
1342 return 1;
1343 #undef LCP_OPT_ACCEPTED
1344 }
1345