GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/npppd/npppd/lcp.c Lines: 0 558 0.0 %
Date: 2017-11-13 Branches: 0 464 0.0 %

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