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

Line Branch Exec Source
1
/*	$OpenBSD: lcp.c,v 1.13 2015/12/14 03:25:59 mmcc Exp $	*/
2
3
/*
4
 * lcp.c - PPP Link Control Protocol.
5
 *
6
 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 *
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 *
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in
17
 *    the documentation and/or other materials provided with the
18
 *    distribution.
19
 *
20
 * 3. The name "Carnegie Mellon University" must not be used to
21
 *    endorse or promote products derived from this software without
22
 *    prior written permission. For permission or any legal
23
 *    details, please contact
24
 *      Office of Technology Transfer
25
 *      Carnegie Mellon University
26
 *      5000 Forbes Avenue
27
 *      Pittsburgh, PA  15213-3890
28
 *      (412) 268-4387, fax: (412) 268-7395
29
 *      tech-transfer@andrew.cmu.edu
30
 *
31
 * 4. Redistributions of any form whatsoever must retain the following
32
 *    acknowledgment:
33
 *    "This product includes software developed by Computing Services
34
 *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
35
 *
36
 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
37
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
38
 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
39
 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
40
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
41
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
42
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
43
 */
44
45
/*
46
 * TODO:
47
 */
48
49
#include <stdio.h>
50
#include <string.h>
51
#include <syslog.h>
52
#include <assert.h>
53
#include <sys/ioctl.h>
54
#include <sys/types.h>
55
#include <sys/socket.h>
56
#include <sys/time.h>
57
#include <netinet/in.h>
58
59
#include "pppd.h"
60
#include "fsm.h"
61
#include "lcp.h"
62
#include "chap.h"
63
#include "magic.h"
64
65
/* global vars */
66
fsm lcp_fsm[NUM_PPP];			/* LCP fsm structure (global)*/
67
lcp_options lcp_wantoptions[NUM_PPP];	/* Options that we want to request */
68
lcp_options lcp_gotoptions[NUM_PPP];	/* Options that peer ack'd */
69
lcp_options lcp_allowoptions[NUM_PPP];	/* Options we allow peer to request */
70
lcp_options lcp_hisoptions[NUM_PPP];	/* Options that we ack'd */
71
u_int32_t xmit_accm[NUM_PPP][8];		/* extended transmit ACCM */
72
73
static u_int32_t lcp_echos_pending = 0;	/* Number of outstanding echo msgs */
74
static u_int32_t lcp_echo_number   = 0;	/* ID number of next echo frame */
75
static u_int32_t lcp_echo_timer_running = 0;  /* TRUE if a timer is running */
76
77
static u_char nak_buffer[PPP_MRU];	/* where we construct a nak packet */
78
79
/*
80
 * Callbacks for fsm code.  (CI = Configuration Information)
81
 */
82
static void lcp_resetci(fsm *);		/* Reset our CI */
83
static int  lcp_cilen(fsm *);		/* Return length of our CI */
84
static void lcp_addci(fsm *, u_char *, int *); /* Add our CI to pkt */
85
static int  lcp_ackci(fsm *, u_char *, int); /* Peer ack'd our CI */
86
static int  lcp_nakci(fsm *, u_char *, int); /* Peer nak'd our CI */
87
static int  lcp_rejci(fsm *, u_char *, int); /* Peer rej'd our CI */
88
static int  lcp_reqci(fsm *, u_char *, int *, int); /* Rcv peer CI */
89
static void lcp_up(fsm *);		/* We're UP */
90
static void lcp_down(fsm *);		/* We're DOWN */
91
static void lcp_starting(fsm *);	/* We need lower layer up */
92
static void lcp_finished(fsm *);	/* We need lower layer down */
93
static int  lcp_extcode(fsm *, int, int, u_char *, int);
94
static void lcp_rprotrej(fsm *, u_char *, int);
95
96
/*
97
 * routines to send LCP echos to peer
98
 */
99
100
static void lcp_echo_lowerup(int);
101
static void lcp_echo_lowerdown(int);
102
static void LcpEchoTimeout(void *);
103
static void lcp_received_echo_reply(fsm *, int, u_char *, int);
104
static void LcpSendEchoRequest(fsm *);
105
static void LcpLinkFailure(fsm *);
106
static void LcpEchoCheck(fsm *);
107
108
static fsm_callbacks lcp_callbacks = {	/* LCP callback routines */
109
    lcp_resetci,		/* Reset our Configuration Information */
110
    lcp_cilen,			/* Length of our Configuration Information */
111
    lcp_addci,			/* Add our Configuration Information */
112
    lcp_ackci,			/* ACK our Configuration Information */
113
    lcp_nakci,			/* NAK our Configuration Information */
114
    lcp_rejci,			/* Reject our Configuration Information */
115
    lcp_reqci,			/* Request peer's Configuration Information */
116
    lcp_up,			/* Called when fsm reaches OPENED state */
117
    lcp_down,			/* Called when fsm leaves OPENED state */
118
    lcp_starting,		/* Called when we want the lower layer up */
119
    lcp_finished,		/* Called when we want the lower layer down */
120
    NULL,			/* Called when Protocol-Reject received */
121
    NULL,			/* Retransmission is necessary */
122
    lcp_extcode,		/* Called to handle LCP-specific codes */
123
    "LCP"			/* String name of protocol */
124
};
125
126
/*
127
 * Protocol entry points.
128
 * Some of these are called directly.
129
 */
130
131
static void lcp_init(int);
132
static void lcp_input(int, u_char *, int);
133
static void lcp_protrej(int);
134
static int  lcp_printpkt(u_char *, int, void (*)(void *, char *, ...), void *);
135
136
struct protent lcp_protent = {
137
    PPP_LCP,
138
    lcp_init,
139
    lcp_input,
140
    lcp_protrej,
141
    lcp_lowerup,
142
    lcp_lowerdown,
143
    lcp_open,
144
    lcp_close,
145
    lcp_printpkt,
146
    NULL,
147
    1,
148
    "LCP",
149
    NULL,
150
    NULL,
151
    NULL
152
};
153
154
int lcp_loopbackfail = DEFLOOPBACKFAIL;
155
156
/*
157
 * Length of each type of configuration option (in octets)
158
 */
159
#define CILEN_VOID	2
160
#define CILEN_CHAR	3
161
#define CILEN_SHORT	4	/* CILEN_VOID + sizeof(short) */
162
#define CILEN_CHAP	5	/* CILEN_VOID + sizeof(short) + 1 */
163
#define CILEN_LONG	6	/* CILEN_VOID + sizeof(long) */
164
#define CILEN_LQR	8	/* CILEN_VOID + sizeof(short) + sizeof(long) */
165
#define CILEN_CBCP	3
166
167
#define CODENAME(x)	((x) == CONFACK ? "ACK" : \
168
			 (x) == CONFNAK ? "NAK" : "REJ")
169
170
171
/*
172
 * lcp_init - Initialize LCP.
173
 */
174
static void
175
lcp_init(unit)
176
    int unit;
177
{
178
    fsm *f = &lcp_fsm[unit];
179
    lcp_options *wo = &lcp_wantoptions[unit];
180
    lcp_options *ao = &lcp_allowoptions[unit];
181
182
    f->unit = unit;
183
    f->protocol = PPP_LCP;
184
    f->callbacks = &lcp_callbacks;
185
186
    fsm_init(f);
187
188
    wo->passive = 0;
189
    wo->silent = 0;
190
    wo->restart = 0;			/* Set to 1 in kernels or multi-line
191
					   implementations */
192
    wo->neg_mru = 1;
193
    wo->mru = DEFMRU;
194
    wo->neg_asyncmap = 0;
195
    wo->asyncmap = 0;
196
    wo->neg_chap = 0;			/* Set to 1 on server */
197
    wo->neg_upap = 0;			/* Set to 1 on server */
198
    wo->chap_mdtype = CHAP_DIGEST_MD5;
199
    wo->neg_magicnumber = 1;
200
    wo->neg_pcompression = 1;
201
    wo->neg_accompression = 1;
202
    wo->neg_lqr = 0;			/* no LQR implementation yet */
203
    wo->neg_cbcp = 0;
204
205
    ao->neg_mru = 1;
206
    ao->mru = MAXMRU;
207
    ao->neg_asyncmap = 1;
208
    ao->asyncmap = 0;
209
    ao->neg_chap = 1;
210
    ao->chap_mdtype = CHAP_DIGEST_MD5;
211
    ao->neg_upap = 1;
212
    ao->neg_magicnumber = 1;
213
    ao->neg_pcompression = 1;
214
    ao->neg_accompression = 1;
215
    ao->neg_lqr = 0;			/* no LQR implementation yet */
216
#ifdef CBCP_SUPPORT
217
    ao->neg_cbcp = 1;
218
#else
219
    ao->neg_cbcp = 0;
220
#endif
221
222
    memset(xmit_accm[unit], 0, sizeof(xmit_accm[0]));
223
    xmit_accm[unit][3] = 0x60000000;
224
}
225
226
227
/*
228
 * lcp_open - LCP is allowed to come up.
229
 */
230
void
231
lcp_open(unit)
232
    int unit;
233
{
234
    fsm *f = &lcp_fsm[unit];
235
    lcp_options *wo = &lcp_wantoptions[unit];
236
237
    f->flags = 0;
238
    if (wo->passive)
239
	f->flags |= OPT_PASSIVE;
240
    if (wo->silent)
241
	f->flags |= OPT_SILENT;
242
    fsm_open(f);
243
}
244
245
246
/*
247
 * lcp_close - Take LCP down.
248
 */
249
void
250
lcp_close(unit, reason)
251
    int unit;
252
    char *reason;
253
{
254
    fsm *f = &lcp_fsm[unit];
255
256
    if (phase != PHASE_DEAD)
257
	phase = PHASE_TERMINATE;
258
    if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {
259
	/*
260
	 * This action is not strictly according to the FSM in RFC1548,
261
	 * but it does mean that the program terminates if you do a
262
	 * lcp_close() in passive/silent mode when a connection hasn't
263
	 * been established.
264
	 */
265
	f->state = CLOSED;
266
	lcp_finished(f);
267
268
    } else
269
	fsm_close(&lcp_fsm[unit], reason);
270
}
271
272
273
/*
274
 * lcp_lowerup - The lower layer is up.
275
 */
276
void
277
lcp_lowerup(unit)
278
    int unit;
279
{
280
    lcp_options *wo = &lcp_wantoptions[unit];
281
282
    /*
283
     * Don't use A/C or protocol compression on transmission,
284
     * but accept A/C and protocol compressed packets
285
     * if we are going to ask for A/C and protocol compression.
286
     */
287
    ppp_set_xaccm(unit, xmit_accm[unit]);
288
    ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0);
289
    ppp_recv_config(unit, PPP_MRU, 0xffffffff,
290
		    wo->neg_pcompression, wo->neg_accompression);
291
    peer_mru[unit] = PPP_MRU;
292
    lcp_allowoptions[unit].asyncmap = xmit_accm[unit][0];
293
294
    fsm_lowerup(&lcp_fsm[unit]);
295
}
296
297
298
/*
299
 * lcp_lowerdown - The lower layer is down.
300
 */
301
void
302
lcp_lowerdown(unit)
303
    int unit;
304
{
305
    fsm_lowerdown(&lcp_fsm[unit]);
306
}
307
308
309
/*
310
 * lcp_input - Input LCP packet.
311
 */
312
static void
313
lcp_input(unit, p, len)
314
    int unit;
315
    u_char *p;
316
    int len;
317
{
318
    fsm *f = &lcp_fsm[unit];
319
320
    fsm_input(f, p, len);
321
}
322
323
324
/*
325
 * lcp_extcode - Handle a LCP-specific code.
326
 */
327
static int
328
lcp_extcode(f, code, id, inp, len)
329
    fsm *f;
330
    int code, id;
331
    u_char *inp;
332
    int len;
333
{
334
    u_char *magp;
335
336
    switch( code ){
337
    case PROTREJ:
338
	lcp_rprotrej(f, inp, len);
339
	break;
340
341
    case ECHOREQ:
342
	if (f->state != OPENED)
343
	    break;
344
	LCPDEBUG((LOG_INFO, "lcp: Echo-Request, Rcvd id %d", id));
345
	magp = inp;
346
	PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
347
	fsm_sdata(f, ECHOREP, id, inp, len);
348
	break;
349
350
    case ECHOREP:
351
	lcp_received_echo_reply(f, id, inp, len);
352
	break;
353
354
    case DISCREQ:
355
	break;
356
357
    default:
358
	return 0;
359
    }
360
    return 1;
361
}
362
363
364
/*
365
 * lcp_rprotrej - Receive an Protocol-Reject.
366
 *
367
 * Figure out which protocol is rejected and inform it.
368
 */
369
static void
370
lcp_rprotrej(f, inp, len)
371
    fsm *f;
372
    u_char *inp;
373
    int len;
374
{
375
    int i;
376
    struct protent *protp;
377
    u_short prot;
378
379
    LCPDEBUG((LOG_INFO, "lcp_rprotrej."));
380
381
    if (len < sizeof (u_short)) {
382
	LCPDEBUG((LOG_INFO,
383
		  "lcp_rprotrej: Rcvd short Protocol-Reject packet!"));
384
	return;
385
    }
386
387
    GETSHORT(prot, inp);
388
389
    LCPDEBUG((LOG_INFO,
390
	      "lcp_rprotrej: Rcvd Protocol-Reject packet for %x!",
391
	      prot));
392
393
    /*
394
     * Protocol-Reject packets received in any state other than the LCP
395
     * OPENED state SHOULD be silently discarded.
396
     */
397
    if( f->state != OPENED ){
398
	LCPDEBUG((LOG_INFO, "Protocol-Reject discarded: LCP in state %d",
399
		  f->state));
400
	return;
401
    }
402
403
    /*
404
     * Upcall the proper Protocol-Reject routine.
405
     */
406
    for (i = 0; (protp = protocols[i]) != NULL; ++i)
407
	if (protp->protocol == prot && protp->enabled_flag) {
408
	    (*protp->protrej)(f->unit);
409
	    return;
410
	}
411
412
    syslog(LOG_WARNING, "Protocol-Reject for unsupported protocol 0x%x",
413
	   prot);
414
}
415
416
417
/*
418
 * lcp_protrej - A Protocol-Reject was received.
419
 */
420
/*ARGSUSED*/
421
static void
422
lcp_protrej(unit)
423
    int unit;
424
{
425
    /*
426
     * Can't reject LCP!
427
     */
428
    LCPDEBUG((LOG_WARNING,
429
	      "lcp_protrej: Received Protocol-Reject for LCP!"));
430
    fsm_protreject(&lcp_fsm[unit]);
431
}
432
433
434
/*
435
 * lcp_sprotrej - Send a Protocol-Reject for some protocol.
436
 */
437
void
438
lcp_sprotrej(unit, p, len)
439
    int unit;
440
    u_char *p;
441
    int len;
442
{
443
    /*
444
     * Send back the protocol and the information field of the
445
     * rejected packet.  We only get here if LCP is in the OPENED state.
446
     */
447
    p += 2;
448
    len -= 2;
449
450
    fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id,
451
	      p, len);
452
}
453
454
455
/*
456
 * lcp_resetci - Reset our CI.
457
 */
458
static void
459
lcp_resetci(f)
460
    fsm *f;
461
{
462
    lcp_wantoptions[f->unit].magicnumber = magic();
463
    lcp_wantoptions[f->unit].numloops = 0;
464
    lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit];
465
    peer_mru[f->unit] = PPP_MRU;
466
    auth_reset(f->unit);
467
}
468
469
470
/*
471
 * lcp_cilen - Return length of our CI.
472
 */
473
static int
474
lcp_cilen(f)
475
    fsm *f;
476
{
477
    lcp_options *go = &lcp_gotoptions[f->unit];
478
479
#define LENCIVOID(neg)	((neg) ? CILEN_VOID : 0)
480
#define LENCICHAP(neg)	((neg) ? CILEN_CHAP : 0)
481
#define LENCISHORT(neg)	((neg) ? CILEN_SHORT : 0)
482
#define LENCILONG(neg)	((neg) ? CILEN_LONG : 0)
483
#define LENCILQR(neg)	((neg) ? CILEN_LQR: 0)
484
#define LENCICBCP(neg)	((neg) ? CILEN_CBCP: 0)
485
    /*
486
     * NB: we only ask for one of CHAP and UPAP, even if we will
487
     * accept either.
488
     */
489
    return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) +
490
	    LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) +
491
	    LENCICHAP(go->neg_chap) +
492
	    LENCISHORT(!go->neg_chap && go->neg_upap) +
493
	    LENCILQR(go->neg_lqr) +
494
	    LENCICBCP(go->neg_cbcp) +
495
	    LENCILONG(go->neg_magicnumber) +
496
	    LENCIVOID(go->neg_pcompression) +
497
	    LENCIVOID(go->neg_accompression));
498
}
499
500
501
/*
502
 * lcp_addci - Add our desired CIs to a packet.
503
 */
504
static void
505
lcp_addci(f, ucp, lenp)
506
    fsm *f;
507
    u_char *ucp;
508
    int *lenp;
509
{
510
    lcp_options *go = &lcp_gotoptions[f->unit];
511
    u_char *start_ucp = ucp;
512
513
#define ADDCIVOID(opt, neg) \
514
    if (neg) { \
515
	PUTCHAR(opt, ucp); \
516
	PUTCHAR(CILEN_VOID, ucp); \
517
    }
518
#define ADDCISHORT(opt, neg, val) \
519
    if (neg) { \
520
	PUTCHAR(opt, ucp); \
521
	PUTCHAR(CILEN_SHORT, ucp); \
522
	PUTSHORT(val, ucp); \
523
    }
524
#define ADDCICHAP(opt, neg, val, digest) \
525
    if (neg) { \
526
	PUTCHAR(opt, ucp); \
527
	PUTCHAR(CILEN_CHAP, ucp); \
528
	PUTSHORT(val, ucp); \
529
	PUTCHAR(digest, ucp); \
530
    }
531
#define ADDCILONG(opt, neg, val) \
532
    if (neg) { \
533
	PUTCHAR(opt, ucp); \
534
	PUTCHAR(CILEN_LONG, ucp); \
535
	PUTLONG(val, ucp); \
536
    }
537
#define ADDCILQR(opt, neg, val) \
538
    if (neg) { \
539
	PUTCHAR(opt, ucp); \
540
	PUTCHAR(CILEN_LQR, ucp); \
541
	PUTSHORT(PPP_LQR, ucp); \
542
	PUTLONG(val, ucp); \
543
    }
544
#define ADDCICHAR(opt, neg, val) \
545
    if (neg) { \
546
	PUTCHAR(opt, ucp); \
547
	PUTCHAR(CILEN_CHAR, ucp); \
548
	PUTCHAR(val, ucp); \
549
    }
550
551
    ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
552
    ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
553
	      go->asyncmap);
554
    ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
555
    ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
556
    ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
557
    ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
558
    ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
559
    ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
560
    ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
561
562
    if (ucp - start_ucp != *lenp) {
563
	/* this should never happen, because peer_mtu should be 1500 */
564
	syslog(LOG_ERR, "Bug in lcp_addci: wrong length");
565
    }
566
}
567
568
569
/*
570
 * lcp_ackci - Ack our CIs.
571
 * This should not modify any state if the Ack is bad.
572
 *
573
 * Returns:
574
 *	0 - Ack was bad.
575
 *	1 - Ack was good.
576
 */
577
static int
578
lcp_ackci(f, p, len)
579
    fsm *f;
580
    u_char *p;
581
    int len;
582
{
583
    lcp_options *go = &lcp_gotoptions[f->unit];
584
    u_char cilen, citype, cichar;
585
    u_short cishort;
586
    u_int32_t cilong;
587
588
    /*
589
     * CIs must be in exactly the same order that we sent.
590
     * Check packet length and CI length at each step.
591
     * If we find any deviations, then this packet is bad.
592
     */
593
#define ACKCIVOID(opt, neg) \
594
    if (neg) { \
595
	if ((len -= CILEN_VOID) < 0) \
596
	    goto bad; \
597
	GETCHAR(citype, p); \
598
	GETCHAR(cilen, p); \
599
	if (cilen != CILEN_VOID || \
600
	    citype != opt) \
601
	    goto bad; \
602
    }
603
#define ACKCISHORT(opt, neg, val) \
604
    if (neg) { \
605
	if ((len -= CILEN_SHORT) < 0) \
606
	    goto bad; \
607
	GETCHAR(citype, p); \
608
	GETCHAR(cilen, p); \
609
	if (cilen != CILEN_SHORT || \
610
	    citype != opt) \
611
	    goto bad; \
612
	GETSHORT(cishort, p); \
613
	if (cishort != val) \
614
	    goto bad; \
615
    }
616
#define ACKCICHAR(opt, neg, val) \
617
    if (neg) { \
618
	if ((len -= CILEN_CHAR) < 0) \
619
	    goto bad; \
620
	GETCHAR(citype, p); \
621
	GETCHAR(cilen, p); \
622
	if (cilen != CILEN_CHAR || \
623
	    citype != opt) \
624
	    goto bad; \
625
	GETCHAR(cichar, p); \
626
	if (cichar != val) \
627
	    goto bad; \
628
    }
629
#define ACKCICHAP(opt, neg, val, digest) \
630
    if (neg) { \
631
	if ((len -= CILEN_CHAP) < 0) \
632
	    goto bad; \
633
	GETCHAR(citype, p); \
634
	GETCHAR(cilen, p); \
635
	if (cilen != CILEN_CHAP || \
636
	    citype != opt) \
637
	    goto bad; \
638
	GETSHORT(cishort, p); \
639
	if (cishort != val) \
640
	    goto bad; \
641
	GETCHAR(cichar, p); \
642
	if (cichar != digest) \
643
	  goto bad; \
644
    }
645
#define ACKCILONG(opt, neg, val) \
646
    if (neg) { \
647
	if ((len -= CILEN_LONG) < 0) \
648
	    goto bad; \
649
	GETCHAR(citype, p); \
650
	GETCHAR(cilen, p); \
651
	if (cilen != CILEN_LONG || \
652
	    citype != opt) \
653
	    goto bad; \
654
	GETLONG(cilong, p); \
655
	if (cilong != val) \
656
	    goto bad; \
657
    }
658
#define ACKCILQR(opt, neg, val) \
659
    if (neg) { \
660
	if ((len -= CILEN_LQR) < 0) \
661
	    goto bad; \
662
	GETCHAR(citype, p); \
663
	GETCHAR(cilen, p); \
664
	if (cilen != CILEN_LQR || \
665
	    citype != opt) \
666
	    goto bad; \
667
	GETSHORT(cishort, p); \
668
	if (cishort != PPP_LQR) \
669
	    goto bad; \
670
	GETLONG(cilong, p); \
671
	if (cilong != val) \
672
	  goto bad; \
673
    }
674
675
    ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
676
    ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
677
	      go->asyncmap);
678
    ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
679
    ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
680
    ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
681
    ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
682
    ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
683
    ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
684
    ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
685
686
    /*
687
     * If there are any remaining CIs, then this packet is bad.
688
     */
689
    if (len != 0)
690
	goto bad;
691
    return (1);
692
bad:
693
    LCPDEBUG((LOG_WARNING, "lcp_acki: received bad Ack!"));
694
    return (0);
695
}
696
697
698
/*
699
 * lcp_nakci - Peer has sent a NAK for some of our CIs.
700
 * This should not modify any state if the Nak is bad
701
 * or if LCP is in the OPENED state.
702
 *
703
 * Returns:
704
 *	0 - Nak was bad.
705
 *	1 - Nak was good.
706
 */
707
static int
708
lcp_nakci(f, p, len)
709
    fsm *f;
710
    u_char *p;
711
    int len;
712
{
713
    lcp_options *go = &lcp_gotoptions[f->unit];
714
    lcp_options *wo = &lcp_wantoptions[f->unit];
715
    u_char citype, cichar, *next;
716
    u_short cishort;
717
    u_int32_t cilong;
718
    lcp_options no;		/* options we've seen Naks for */
719
    lcp_options try;		/* options to request next time */
720
    int looped_back = 0;
721
    int cilen;
722
723
    BZERO(&no, sizeof(no));
724
    try = *go;
725
726
    /*
727
     * Any Nak'd CIs must be in exactly the same order that we sent.
728
     * Check packet length and CI length at each step.
729
     * If we find any deviations, then this packet is bad.
730
     */
731
#define NAKCIVOID(opt, neg, code) \
732
    if (go->neg && \
733
	len >= CILEN_VOID && \
734
	p[1] == CILEN_VOID && \
735
	p[0] == opt) { \
736
	len -= CILEN_VOID; \
737
	INCPTR(CILEN_VOID, p); \
738
	no.neg = 1; \
739
	code \
740
    }
741
#define NAKCICHAP(opt, neg, code) \
742
    if (go->neg && \
743
	len >= CILEN_CHAP && \
744
	p[1] == CILEN_CHAP && \
745
	p[0] == opt) { \
746
	len -= CILEN_CHAP; \
747
	INCPTR(2, p); \
748
	GETSHORT(cishort, p); \
749
	GETCHAR(cichar, p); \
750
	no.neg = 1; \
751
	code \
752
    }
753
#define NAKCICHAR(opt, neg, code) \
754
    if (go->neg && \
755
	len >= CILEN_CHAR && \
756
	p[1] == CILEN_CHAR && \
757
	p[0] == opt) { \
758
	len -= CILEN_CHAR; \
759
	INCPTR(2, p); \
760
	GETCHAR(cichar, p); \
761
	no.neg = 1; \
762
	code \
763
    }
764
#define NAKCISHORT(opt, neg, code) \
765
    if (go->neg && \
766
	len >= CILEN_SHORT && \
767
	p[1] == CILEN_SHORT && \
768
	p[0] == opt) { \
769
	len -= CILEN_SHORT; \
770
	INCPTR(2, p); \
771
	GETSHORT(cishort, p); \
772
	no.neg = 1; \
773
	code \
774
    }
775
#define NAKCILONG(opt, neg, code) \
776
    if (go->neg && \
777
	len >= CILEN_LONG && \
778
	p[1] == CILEN_LONG && \
779
	p[0] == opt) { \
780
	len -= CILEN_LONG; \
781
	INCPTR(2, p); \
782
	GETLONG(cilong, p); \
783
	no.neg = 1; \
784
	code \
785
    }
786
#define NAKCILQR(opt, neg, code) \
787
    if (go->neg && \
788
	len >= CILEN_LQR && \
789
	p[1] == CILEN_LQR && \
790
	p[0] == opt) { \
791
	len -= CILEN_LQR; \
792
	INCPTR(2, p); \
793
	GETSHORT(cishort, p); \
794
	GETLONG(cilong, p); \
795
	no.neg = 1; \
796
	code \
797
    }
798
799
    /*
800
     * We don't care if they want to send us smaller packets than
801
     * we want.  Therefore, accept any MRU less than what we asked for,
802
     * but then ignore the new value when setting the MRU in the kernel.
803
     * If they send us a bigger MRU than what we asked, accept it, up to
804
     * the limit of the default MRU we'd get if we didn't negotiate.
805
     */
806
    if (go->neg_mru && go->mru != DEFMRU) {
807
	NAKCISHORT(CI_MRU, neg_mru,
808
		   if (cishort <= wo->mru || cishort <= DEFMRU)
809
		       try.mru = cishort;
810
		   );
811
    }
812
813
    /*
814
     * Add any characters they want to our (receive-side) asyncmap.
815
     */
816
    if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) {
817
	NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
818
		  try.asyncmap = go->asyncmap | cilong;
819
		  );
820
    }
821
822
    /*
823
     * If they've nak'd our authentication-protocol, check whether
824
     * they are proposing a different protocol, or a different
825
     * hash algorithm for CHAP.
826
     */
827
    if ((go->neg_chap || go->neg_upap)
828
	&& len >= CILEN_SHORT
829
	&& p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {
830
	cilen = p[1];
831
	len -= cilen;
832
	no.neg_chap = go->neg_chap;
833
	no.neg_upap = go->neg_upap;
834
	INCPTR(2, p);
835
        GETSHORT(cishort, p);
836
	if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
837
	    /*
838
	     * If we were asking for CHAP, they obviously don't want to do it.
839
	     * If we weren't asking for CHAP, then we were asking for PAP,
840
	     * in which case this Nak is bad.
841
	     */
842
	    if (!go->neg_chap)
843
		goto bad;
844
	    try.neg_chap = 0;
845
846
	} else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
847
	    GETCHAR(cichar, p);
848
	    if (go->neg_chap) {
849
		/*
850
		 * We were asking for CHAP/MD5; they must want a different
851
		 * algorithm.  If they can't do MD5, we'll have to stop
852
		 * asking for CHAP.
853
		 */
854
		if (cichar != go->chap_mdtype)
855
		    try.neg_chap = 0;
856
	    } else {
857
		/*
858
		 * Stop asking for PAP if we were asking for it.
859
		 */
860
		try.neg_upap = 0;
861
	    }
862
863
	} else {
864
	    /*
865
	     * We don't recognize what they're suggesting.
866
	     * Stop asking for what we were asking for.
867
	     */
868
	    if (go->neg_chap)
869
		try.neg_chap = 0;
870
	    else
871
		try.neg_upap = 0;
872
	    p += cilen - CILEN_SHORT;
873
	}
874
    }
875
876
    /*
877
     * If they can't cope with our link quality protocol, we'll have
878
     * to stop asking for LQR.  We haven't got any other protocol.
879
     * If they Nak the reporting period, take their value XXX ?
880
     */
881
    NAKCILQR(CI_QUALITY, neg_lqr,
882
	     if (cishort != PPP_LQR)
883
		 try.neg_lqr = 0;
884
	     else
885
		 try.lqr_period = cilong;
886
	     );
887
888
    /*
889
     * Only implementing CBCP...not the rest of the callback options
890
     */
891
    NAKCICHAR(CI_CALLBACK, neg_cbcp,
892
              try.neg_cbcp = 0;
893
              );
894
895
    /*
896
     * Check for a looped-back line.
897
     */
898
    NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
899
	      try.magicnumber = magic();
900
	      looped_back = 1;
901
	      );
902
903
    /*
904
     * Peer shouldn't send Nak for protocol compression or
905
     * address/control compression requests; they should send
906
     * a Reject instead.  If they send a Nak, treat it as a Reject.
907
     */
908
    NAKCIVOID(CI_PCOMPRESSION, neg_pcompression,
909
	      try.neg_pcompression = 0;
910
	      );
911
    NAKCIVOID(CI_ACCOMPRESSION, neg_accompression,
912
	      try.neg_accompression = 0;
913
	      );
914
915
    /*
916
     * There may be remaining CIs, if the peer is requesting negotiation
917
     * on an option that we didn't include in our request packet.
918
     * If we see an option that we requested, or one we've already seen
919
     * in this packet, then this packet is bad.
920
     * If we wanted to respond by starting to negotiate on the requested
921
     * option(s), we could, but we don't, because except for the
922
     * authentication type and quality protocol, if we are not negotiating
923
     * an option, it is because we were told not to.
924
     * For the authentication type, the Nak from the peer means
925
     * `let me authenticate myself with you' which is a bit pointless.
926
     * For the quality protocol, the Nak means `ask me to send you quality
927
     * reports', but if we didn't ask for them, we don't want them.
928
     * An option we don't recognize represents the peer asking to
929
     * negotiate some option we don't support, so ignore it.
930
     */
931
    while (len > CILEN_VOID) {
932
	GETCHAR(citype, p);
933
	GETCHAR(cilen, p);
934
	if (cilen < CILEN_VOID || (len -= cilen) < 0)
935
	    goto bad;
936
	next = p + cilen - 2;
937
938
	switch (citype) {
939
	case CI_MRU:
940
	    if ((go->neg_mru && go->mru != DEFMRU)
941
		|| no.neg_mru || cilen != CILEN_SHORT)
942
		goto bad;
943
	    GETSHORT(cishort, p);
944
	    if (cishort < DEFMRU)
945
		try.mru = cishort;
946
	    break;
947
	case CI_ASYNCMAP:
948
	    if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF)
949
		|| no.neg_asyncmap || cilen != CILEN_LONG)
950
		goto bad;
951
	    break;
952
	case CI_AUTHTYPE:
953
	    if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap)
954
		goto bad;
955
	    break;
956
	case CI_MAGICNUMBER:
957
	    if (go->neg_magicnumber || no.neg_magicnumber ||
958
		cilen != CILEN_LONG)
959
		goto bad;
960
	    break;
961
	case CI_PCOMPRESSION:
962
	    if (go->neg_pcompression || no.neg_pcompression
963
		|| cilen != CILEN_VOID)
964
		goto bad;
965
	    break;
966
	case CI_ACCOMPRESSION:
967
	    if (go->neg_accompression || no.neg_accompression
968
		|| cilen != CILEN_VOID)
969
		goto bad;
970
	    break;
971
	case CI_QUALITY:
972
	    if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR)
973
		goto bad;
974
	    break;
975
	}
976
	p = next;
977
    }
978
979
    /* If there is still anything left, this packet is bad. */
980
    if (len != 0)
981
	goto bad;
982
983
    /*
984
     * OK, the Nak is good.  Now we can update state.
985
     */
986
    if (f->state != OPENED) {
987
	if (looped_back) {
988
	    if (++try.numloops >= lcp_loopbackfail) {
989
		syslog(LOG_NOTICE, "Serial line is looped back.");
990
		lcp_close(f->unit, "Loopback detected");
991
	    }
992
	} else
993
	    try.numloops = 0;
994
	*go = try;
995
    }
996
997
    return 1;
998
999
bad:
1000
    LCPDEBUG((LOG_WARNING, "lcp_nakci: received bad Nak!"));
1001
    return 0;
1002
}
1003
1004
1005
/*
1006
 * lcp_rejci - Peer has Rejected some of our CIs.
1007
 * This should not modify any state if the Reject is bad
1008
 * or if LCP is in the OPENED state.
1009
 *
1010
 * Returns:
1011
 *	0 - Reject was bad.
1012
 *	1 - Reject was good.
1013
 */
1014
static int
1015
lcp_rejci(f, p, len)
1016
    fsm *f;
1017
    u_char *p;
1018
    int len;
1019
{
1020
    lcp_options *go = &lcp_gotoptions[f->unit];
1021
    u_char cichar;
1022
    u_short cishort;
1023
    u_int32_t cilong;
1024
    lcp_options try;		/* options to request next time */
1025
1026
    try = *go;
1027
1028
    /*
1029
     * Any Rejected CIs must be in exactly the same order that we sent.
1030
     * Check packet length and CI length at each step.
1031
     * If we find any deviations, then this packet is bad.
1032
     */
1033
#define REJCIVOID(opt, neg) \
1034
    if (go->neg && \
1035
	len >= CILEN_VOID && \
1036
	p[1] == CILEN_VOID && \
1037
	p[0] == opt) { \
1038
	len -= CILEN_VOID; \
1039
	INCPTR(CILEN_VOID, p); \
1040
	try.neg = 0; \
1041
	LCPDEBUG((LOG_INFO, "lcp_rejci rejected void opt %d", opt)); \
1042
    }
1043
#define REJCISHORT(opt, neg, val) \
1044
    if (go->neg && \
1045
	len >= CILEN_SHORT && \
1046
	p[1] == CILEN_SHORT && \
1047
	p[0] == opt) { \
1048
	len -= CILEN_SHORT; \
1049
	INCPTR(2, p); \
1050
	GETSHORT(cishort, p); \
1051
	/* Check rejected value. */ \
1052
	if (cishort != val) \
1053
	    goto bad; \
1054
	try.neg = 0; \
1055
	LCPDEBUG((LOG_INFO,"lcp_rejci rejected short opt %d", opt)); \
1056
    }
1057
#define REJCICHAP(opt, neg, val, digest) \
1058
    if (go->neg && \
1059
	len >= CILEN_CHAP && \
1060
	p[1] == CILEN_CHAP && \
1061
	p[0] == opt) { \
1062
	len -= CILEN_CHAP; \
1063
	INCPTR(2, p); \
1064
	GETSHORT(cishort, p); \
1065
	GETCHAR(cichar, p); \
1066
	/* Check rejected value. */ \
1067
	if (cishort != val || cichar != digest) \
1068
	    goto bad; \
1069
	try.neg = 0; \
1070
	try.neg_upap = 0; \
1071
	LCPDEBUG((LOG_INFO,"lcp_rejci rejected chap opt %d", opt)); \
1072
    }
1073
#define REJCILONG(opt, neg, val) \
1074
    if (go->neg && \
1075
	len >= CILEN_LONG && \
1076
	p[1] == CILEN_LONG && \
1077
	p[0] == opt) { \
1078
	len -= CILEN_LONG; \
1079
	INCPTR(2, p); \
1080
	GETLONG(cilong, p); \
1081
	/* Check rejected value. */ \
1082
	if (cilong != val) \
1083
	    goto bad; \
1084
	try.neg = 0; \
1085
	LCPDEBUG((LOG_INFO,"lcp_rejci rejected long opt %d", opt)); \
1086
    }
1087
#define REJCILQR(opt, neg, val) \
1088
    if (go->neg && \
1089
	len >= CILEN_LQR && \
1090
	p[1] == CILEN_LQR && \
1091
	p[0] == opt) { \
1092
	len -= CILEN_LQR; \
1093
	INCPTR(2, p); \
1094
	GETSHORT(cishort, p); \
1095
	GETLONG(cilong, p); \
1096
	/* Check rejected value. */ \
1097
	if (cishort != PPP_LQR || cilong != val) \
1098
	    goto bad; \
1099
	try.neg = 0; \
1100
	LCPDEBUG((LOG_INFO,"lcp_rejci rejected LQR opt %d", opt)); \
1101
    }
1102
#define REJCICBCP(opt, neg, val) \
1103
    if (go->neg && \
1104
	len >= CILEN_CBCP && \
1105
	p[1] == CILEN_CBCP && \
1106
	p[0] == opt) { \
1107
	len -= CILEN_CBCP; \
1108
	INCPTR(2, p); \
1109
	GETCHAR(cichar, p); \
1110
	/* Check rejected value. */ \
1111
	if (cichar != val) \
1112
	    goto bad; \
1113
	try.neg = 0; \
1114
	LCPDEBUG((LOG_INFO,"lcp_rejci rejected Callback opt %d", opt)); \
1115
    }
1116
1117
    REJCISHORT(CI_MRU, neg_mru, go->mru);
1118
    REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
1119
    REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype);
1120
    if (!go->neg_chap) {
1121
	REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
1122
    }
1123
    REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
1124
    REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);
1125
    REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
1126
    REJCIVOID(CI_PCOMPRESSION, neg_pcompression);
1127
    REJCIVOID(CI_ACCOMPRESSION, neg_accompression);
1128
1129
    /*
1130
     * If there are any remaining CIs, then this packet is bad.
1131
     */
1132
    if (len != 0)
1133
	goto bad;
1134
    /*
1135
     * Now we can update state.
1136
     */
1137
    if (f->state != OPENED)
1138
	*go = try;
1139
    return 1;
1140
1141
bad:
1142
    LCPDEBUG((LOG_WARNING, "lcp_rejci: received bad Reject!"));
1143
    return 0;
1144
}
1145
1146
1147
/*
1148
 * lcp_reqci - Check the peer's requested CIs and send appropriate response.
1149
 *
1150
 * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
1151
 * appropriately.  If reject_if_disagree is non-zero, doesn't return
1152
 * CONFNAK; returns CONFREJ if it can't return CONFACK.
1153
 */
1154
static int
1155
lcp_reqci(f, inp, lenp, reject_if_disagree)
1156
    fsm *f;
1157
    u_char *inp;		/* Requested CIs */
1158
    int *lenp;			/* Length of requested CIs */
1159
    int reject_if_disagree;
1160
{
1161
    lcp_options *go = &lcp_gotoptions[f->unit];
1162
    lcp_options *ho = &lcp_hisoptions[f->unit];
1163
    lcp_options *ao = &lcp_allowoptions[f->unit];
1164
    u_char *cip, *next;		/* Pointer to current and next CIs */
1165
    int cilen, citype, cichar;	/* Parsed len, type, char value */
1166
    u_short cishort;		/* Parsed short value */
1167
    u_int32_t cilong;		/* Parse long value */
1168
    int rc = CONFACK;		/* Final packet return code */
1169
    int orc;			/* Individual option return code */
1170
    u_char *p;			/* Pointer to next char to parse */
1171
    u_char *rejp;		/* Pointer to next char in reject frame */
1172
    u_char *nakp;		/* Pointer to next char in Nak frame */
1173
    int l = *lenp;		/* Length left */
1174
1175
    /*
1176
     * Reset all his options.
1177
     */
1178
    BZERO(ho, sizeof(*ho));
1179
1180
    /*
1181
     * Process all his options.
1182
     */
1183
    next = inp;
1184
    nakp = nak_buffer;
1185
    rejp = inp;
1186
    while (l) {
1187
	orc = CONFACK;			/* Assume success */
1188
	cip = p = next;			/* Remember beginning of CI */
1189
	if (l < 2 ||			/* Not enough data for CI header or */
1190
	    p[1] < 2 ||			/*  CI length too small or */
1191
	    p[1] > l) {			/*  CI length too big? */
1192
	    LCPDEBUG((LOG_WARNING, "lcp_reqci: bad CI length!"));
1193
	    orc = CONFREJ;		/* Reject bad CI */
1194
	    cilen = l;			/* Reject till end of packet */
1195
	    l = 0;			/* Don't loop again */
1196
	    citype = 0;
1197
	    goto endswitch;
1198
	}
1199
	GETCHAR(citype, p);		/* Parse CI type */
1200
	GETCHAR(cilen, p);		/* Parse CI length */
1201
	l -= cilen;			/* Adjust remaining length */
1202
	next += cilen;			/* Step to next CI */
1203
1204
	switch (citype) {		/* Check CI type */
1205
	case CI_MRU:
1206
	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd MRU"));
1207
	    if (!ao->neg_mru ||		/* Allow option? */
1208
		cilen != CILEN_SHORT) {	/* Check CI length */
1209
		orc = CONFREJ;		/* Reject CI */
1210
		break;
1211
	    }
1212
	    GETSHORT(cishort, p);	/* Parse MRU */
1213
	    LCPDEBUG((LOG_INFO, "(%d)", cishort));
1214
1215
	    /*
1216
	     * He must be able to receive at least our minimum.
1217
	     * No need to check a maximum.  If he sends a large number,
1218
	     * we'll just ignore it.
1219
	     */
1220
	    if (cishort < MINMRU) {
1221
		orc = CONFNAK;		/* Nak CI */
1222
		PUTCHAR(CI_MRU, nakp);
1223
		PUTCHAR(CILEN_SHORT, nakp);
1224
		PUTSHORT(MINMRU, nakp);	/* Give him a hint */
1225
		break;
1226
	    }
1227
	    ho->neg_mru = 1;		/* Remember he sent MRU */
1228
	    ho->mru = cishort;		/* And remember value */
1229
	    break;
1230
1231
	case CI_ASYNCMAP:
1232
	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd ASYNCMAP"));
1233
	    if (!ao->neg_asyncmap ||
1234
		cilen != CILEN_LONG) {
1235
		orc = CONFREJ;
1236
		break;
1237
	    }
1238
	    GETLONG(cilong, p);
1239
	    LCPDEBUG((LOG_INFO, "(%x)", (unsigned int) cilong));
1240
1241
	    /*
1242
	     * Asyncmap must have set at least the bits
1243
	     * which are set in lcp_allowoptions[unit].asyncmap.
1244
	     */
1245
	    if ((ao->asyncmap & ~cilong) != 0) {
1246
		orc = CONFNAK;
1247
		PUTCHAR(CI_ASYNCMAP, nakp);
1248
		PUTCHAR(CILEN_LONG, nakp);
1249
		PUTLONG(ao->asyncmap | cilong, nakp);
1250
		break;
1251
	    }
1252
	    ho->neg_asyncmap = 1;
1253
	    ho->asyncmap = cilong;
1254
	    break;
1255
1256
	case CI_AUTHTYPE:
1257
	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd AUTHTYPE"));
1258
	    if (cilen < CILEN_SHORT ||
1259
		!(ao->neg_upap || ao->neg_chap)) {
1260
		/*
1261
		 * Reject the option if we're not willing to authenticate.
1262
		 */
1263
		orc = CONFREJ;
1264
		break;
1265
	    }
1266
	    GETSHORT(cishort, p);
1267
	    LCPDEBUG((LOG_INFO, "(%x)", cishort));
1268
1269
	    /*
1270
	     * Authtype must be UPAP or CHAP.
1271
	     *
1272
	     * Note: if both ao->neg_upap and ao->neg_chap are set,
1273
	     * and the peer sends a Configure-Request with two
1274
	     * authenticate-protocol requests, one for CHAP and one
1275
	     * for UPAP, then we will reject the second request.
1276
	     * Whether we end up doing CHAP or UPAP depends then on
1277
	     * the ordering of the CIs in the peer's Configure-Request.
1278
	     */
1279
1280
	    if (cishort == PPP_PAP) {
1281
		if (ho->neg_chap ||	/* we've already accepted CHAP */
1282
		    cilen != CILEN_SHORT) {
1283
		    LCPDEBUG((LOG_WARNING,
1284
			      "lcp_reqci: rcvd AUTHTYPE PAP, rejecting..."));
1285
		    orc = CONFREJ;
1286
		    break;
1287
		}
1288
		if (!ao->neg_upap) {	/* we don't want to do PAP */
1289
		    orc = CONFNAK;	/* NAK it and suggest CHAP */
1290
		    PUTCHAR(CI_AUTHTYPE, nakp);
1291
		    PUTCHAR(CILEN_CHAP, nakp);
1292
		    PUTSHORT(PPP_CHAP, nakp);
1293
		    PUTCHAR(ao->chap_mdtype, nakp);
1294
		    break;
1295
		}
1296
		ho->neg_upap = 1;
1297
		break;
1298
	    }
1299
	    if (cishort == PPP_CHAP) {
1300
		if (ho->neg_upap ||	/* we've already accepted PAP */
1301
		    cilen != CILEN_CHAP) {
1302
		    LCPDEBUG((LOG_INFO,
1303
			      "lcp_reqci: rcvd AUTHTYPE CHAP, rejecting..."));
1304
		    orc = CONFREJ;
1305
		    break;
1306
		}
1307
		if (!ao->neg_chap) {	/* we don't want to do CHAP */
1308
		    orc = CONFNAK;	/* NAK it and suggest PAP */
1309
		    PUTCHAR(CI_AUTHTYPE, nakp);
1310
		    PUTCHAR(CILEN_SHORT, nakp);
1311
		    PUTSHORT(PPP_PAP, nakp);
1312
		    break;
1313
		}
1314
		GETCHAR(cichar, p);	/* get digest type*/
1315
		if (cichar != CHAP_DIGEST_MD5) {
1316
		    orc = CONFNAK;
1317
		    PUTCHAR(CI_AUTHTYPE, nakp);
1318
		    PUTCHAR(CILEN_CHAP, nakp);
1319
		    PUTSHORT(PPP_CHAP, nakp);
1320
		    PUTCHAR(ao->chap_mdtype, nakp);
1321
		    break;
1322
		}
1323
		ho->chap_mdtype = cichar; /* save md type */
1324
		ho->neg_chap = 1;
1325
		break;
1326
	    }
1327
1328
	    /*
1329
	     * We don't recognize the protocol they're asking for.
1330
	     * Nak it with something we're willing to do.
1331
	     * (At this point we know ao->neg_upap || ao->neg_chap.)
1332
	     */
1333
	    orc = CONFNAK;
1334
	    PUTCHAR(CI_AUTHTYPE, nakp);
1335
	    if (ao->neg_chap) {
1336
		PUTCHAR(CILEN_CHAP, nakp);
1337
		PUTSHORT(PPP_CHAP, nakp);
1338
		PUTCHAR(ao->chap_mdtype, nakp);
1339
	    } else {
1340
		PUTCHAR(CILEN_SHORT, nakp);
1341
		PUTSHORT(PPP_PAP, nakp);
1342
	    }
1343
	    break;
1344
1345
	case CI_QUALITY:
1346
	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd QUALITY"));
1347
	    if (!ao->neg_lqr ||
1348
		cilen != CILEN_LQR) {
1349
		orc = CONFREJ;
1350
		break;
1351
	    }
1352
1353
	    GETSHORT(cishort, p);
1354
	    GETLONG(cilong, p);
1355
	    LCPDEBUG((LOG_INFO, "(%x %x)", cishort, (unsigned int) cilong));
1356
1357
	    /*
1358
	     * Check the protocol and the reporting period.
1359
	     * XXX When should we Nak this, and what with?
1360
	     */
1361
	    if (cishort != PPP_LQR) {
1362
		orc = CONFNAK;
1363
		PUTCHAR(CI_QUALITY, nakp);
1364
		PUTCHAR(CILEN_LQR, nakp);
1365
		PUTSHORT(PPP_LQR, nakp);
1366
		PUTLONG(ao->lqr_period, nakp);
1367
		break;
1368
	    }
1369
	    break;
1370
1371
	case CI_MAGICNUMBER:
1372
	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd MAGICNUMBER"));
1373
	    if (!(ao->neg_magicnumber || go->neg_magicnumber) ||
1374
		cilen != CILEN_LONG) {
1375
		orc = CONFREJ;
1376
		break;
1377
	    }
1378
	    GETLONG(cilong, p);
1379
	    LCPDEBUG((LOG_INFO, "(%x)", (unsigned int) cilong));
1380
1381
	    /*
1382
	     * He must have a different magic number.
1383
	     */
1384
	    if (go->neg_magicnumber &&
1385
		cilong == go->magicnumber) {
1386
		cilong = magic();	/* Don't put magic() inside macro! */
1387
		orc = CONFNAK;
1388
		PUTCHAR(CI_MAGICNUMBER, nakp);
1389
		PUTCHAR(CILEN_LONG, nakp);
1390
		PUTLONG(cilong, nakp);
1391
		break;
1392
	    }
1393
	    ho->neg_magicnumber = 1;
1394
	    ho->magicnumber = cilong;
1395
	    break;
1396
1397
1398
	case CI_PCOMPRESSION:
1399
	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd PCOMPRESSION"));
1400
	    if (!ao->neg_pcompression ||
1401
		cilen != CILEN_VOID) {
1402
		orc = CONFREJ;
1403
		break;
1404
	    }
1405
	    ho->neg_pcompression = 1;
1406
	    break;
1407
1408
	case CI_ACCOMPRESSION:
1409
	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd ACCOMPRESSION"));
1410
	    if (!ao->neg_accompression ||
1411
		cilen != CILEN_VOID) {
1412
		orc = CONFREJ;
1413
		break;
1414
	    }
1415
	    ho->neg_accompression = 1;
1416
	    break;
1417
1418
	default:
1419
	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd unknown option %d",
1420
		      citype));
1421
	    orc = CONFREJ;
1422
	    break;
1423
	}
1424
1425
endswitch:
1426
	LCPDEBUG((LOG_INFO, " (%s)", CODENAME(orc)));
1427
	if (orc == CONFACK &&		/* Good CI */
1428
	    rc != CONFACK)		/*  but prior CI wasnt? */
1429
	    continue;			/* Don't send this one */
1430
1431
	if (orc == CONFNAK) {		/* Nak this CI? */
1432
	    if (reject_if_disagree	/* Getting fed up with sending NAKs? */
1433
		&& citype != CI_MAGICNUMBER) {
1434
		orc = CONFREJ;		/* Get tough if so */
1435
	    } else {
1436
		if (rc == CONFREJ)	/* Rejecting prior CI? */
1437
		    continue;		/* Don't send this one */
1438
		rc = CONFNAK;
1439
	    }
1440
	}
1441
	if (orc == CONFREJ) {		/* Reject this CI */
1442
	    rc = CONFREJ;
1443
	    if (cip != rejp)		/* Need to move rejected CI? */
1444
		BMOVE(cip, rejp, cilen); /* Move it (NB: overlapped regions) */
1445
	    INCPTR(cilen, rejp);	/* Update output pointer */
1446
	}
1447
    }
1448
1449
    /*
1450
     * If we wanted to send additional NAKs (for unsent CIs), the
1451
     * code would go here.  The extra NAKs would go at *nakp.
1452
     * At present there are no cases where we want to ask the
1453
     * peer to negotiate an option.
1454
     */
1455
1456
    switch (rc) {
1457
    case CONFACK:
1458
	*lenp = next - inp;
1459
	break;
1460
    case CONFNAK:
1461
	/*
1462
	 * Copy the Nak'd options from the nak_buffer to the caller's buffer.
1463
	 */
1464
	*lenp = nakp - nak_buffer;
1465
	BCOPY(nak_buffer, inp, *lenp);
1466
	break;
1467
    case CONFREJ:
1468
	*lenp = rejp - inp;
1469
	break;
1470
    }
1471
1472
    LCPDEBUG((LOG_INFO, "lcp_reqci: returning CONF%s.", CODENAME(rc)));
1473
    return (rc);			/* Return final code */
1474
}
1475
1476
1477
/*
1478
 * lcp_up - LCP has come UP.
1479
 */
1480
static void
1481
lcp_up(f)
1482
    fsm *f;
1483
{
1484
    lcp_options *wo = &lcp_wantoptions[f->unit];
1485
    lcp_options *ho = &lcp_hisoptions[f->unit];
1486
    lcp_options *go = &lcp_gotoptions[f->unit];
1487
    lcp_options *ao = &lcp_allowoptions[f->unit];
1488
1489
    if (!go->neg_magicnumber)
1490
	go->magicnumber = 0;
1491
    if (!ho->neg_magicnumber)
1492
	ho->magicnumber = 0;
1493
1494
    /*
1495
     * Set our MTU to the smaller of the MTU we wanted and
1496
     * the MRU our peer wanted.  If we negotiated an MRU,
1497
     * set our MRU to the larger of value we wanted and
1498
     * the value we got in the negotiation.
1499
     */
1500
    ppp_send_config(f->unit, MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)),
1501
		    (ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
1502
		    ho->neg_pcompression, ho->neg_accompression);
1503
    ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU),
1504
		    (go->neg_asyncmap? go->asyncmap: 0xffffffff),
1505
		    go->neg_pcompression, go->neg_accompression);
1506
1507
    if (ho->neg_mru)
1508
	peer_mru[f->unit] = ho->mru;
1509
1510
    lcp_echo_lowerup(f->unit);  /* Enable echo messages */
1511
1512
    link_established(f->unit);
1513
}
1514
1515
1516
/*
1517
 * lcp_down - LCP has gone DOWN.
1518
 *
1519
 * Alert other protocols.
1520
 */
1521
static void
1522
lcp_down(f)
1523
    fsm *f;
1524
{
1525
    lcp_options *go = &lcp_gotoptions[f->unit];
1526
1527
    lcp_echo_lowerdown(f->unit);
1528
1529
    link_down(f->unit);
1530
1531
    ppp_send_config(f->unit, PPP_MRU, 0xffffffff, 0, 0);
1532
    ppp_recv_config(f->unit, PPP_MRU,
1533
		    (go->neg_asyncmap? go->asyncmap: 0xffffffff),
1534
		    go->neg_pcompression, go->neg_accompression);
1535
    peer_mru[f->unit] = PPP_MRU;
1536
}
1537
1538
1539
/*
1540
 * lcp_starting - LCP needs the lower layer up.
1541
 */
1542
static void
1543
lcp_starting(f)
1544
    fsm *f;
1545
{
1546
    link_required(f->unit);
1547
}
1548
1549
1550
/*
1551
 * lcp_finished - LCP has finished with the lower layer.
1552
 */
1553
static void
1554
lcp_finished(f)
1555
    fsm *f;
1556
{
1557
    link_terminated(f->unit);
1558
}
1559
1560
1561
/*
1562
 * lcp_printpkt - print the contents of an LCP packet.
1563
 */
1564
static char *lcp_codenames[] = {
1565
    "ConfReq", "ConfAck", "ConfNak", "ConfRej",
1566
    "TermReq", "TermAck", "CodeRej", "ProtRej",
1567
    "EchoReq", "EchoRep", "DiscReq"
1568
};
1569
1570
static int
1571
lcp_printpkt(p, plen, printer, arg)
1572
    u_char *p;
1573
    int plen;
1574
    void (*printer)(void *, char *, ...);
1575
    void *arg;
1576
{
1577
    int code, id, len, olen;
1578
    u_char *pstart, *optend;
1579
    u_short cishort;
1580
    u_int32_t cilong;
1581
1582
    if (plen < HEADERLEN)
1583
	return 0;
1584
    pstart = p;
1585
    GETCHAR(code, p);
1586
    GETCHAR(id, p);
1587
    GETSHORT(len, p);
1588
    if (len < HEADERLEN || len > plen)
1589
	return 0;
1590
1591
    if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *))
1592
	printer(arg, " %s", lcp_codenames[code-1]);
1593
    else
1594
	printer(arg, " code=0x%x", code);
1595
    printer(arg, " id=0x%x", id);
1596
    len -= HEADERLEN;
1597
    switch (code) {
1598
    case CONFREQ:
1599
    case CONFACK:
1600
    case CONFNAK:
1601
    case CONFREJ:
1602
	/* print option list */
1603
	while (len >= 2) {
1604
	    GETCHAR(code, p);
1605
	    GETCHAR(olen, p);
1606
	    p -= 2;
1607
	    if (olen < 2 || olen > len) {
1608
		break;
1609
	    }
1610
	    printer(arg, " <");
1611
	    len -= olen;
1612
	    optend = p + olen;
1613
	    switch (code) {
1614
	    case CI_MRU:
1615
		if (olen == CILEN_SHORT) {
1616
		    p += 2;
1617
		    GETSHORT(cishort, p);
1618
		    printer(arg, "mru %d", cishort);
1619
		}
1620
		break;
1621
	    case CI_ASYNCMAP:
1622
		if (olen == CILEN_LONG) {
1623
		    p += 2;
1624
		    GETLONG(cilong, p);
1625
		    printer(arg, "asyncmap 0x%x", cilong);
1626
		}
1627
		break;
1628
	    case CI_AUTHTYPE:
1629
		if (olen >= CILEN_SHORT) {
1630
		    p += 2;
1631
		    printer(arg, "auth ");
1632
		    GETSHORT(cishort, p);
1633
		    switch (cishort) {
1634
		    case PPP_PAP:
1635
			printer(arg, "pap");
1636
			break;
1637
		    case PPP_CHAP:
1638
			printer(arg, "chap");
1639
			break;
1640
		    default:
1641
			printer(arg, "0x%x", cishort);
1642
		    }
1643
		}
1644
		break;
1645
	    case CI_QUALITY:
1646
		if (olen >= CILEN_SHORT) {
1647
		    p += 2;
1648
		    printer(arg, "quality ");
1649
		    GETSHORT(cishort, p);
1650
		    switch (cishort) {
1651
		    case PPP_LQR:
1652
			printer(arg, "lqr");
1653
			break;
1654
		    default:
1655
			printer(arg, "0x%x", cishort);
1656
		    }
1657
		}
1658
		break;
1659
	    case CI_CALLBACK:
1660
		if (olen >= CILEN_CHAR) {
1661
		    p += 2;
1662
		    printer(arg, "callback ");
1663
		    GETSHORT(cishort, p);
1664
		    switch (cishort) {
1665
		    case CBCP_OPT:
1666
			printer(arg, "CBCP");
1667
			break;
1668
		    default:
1669
			printer(arg, "0x%x", cishort);
1670
		    }
1671
		}
1672
		break;
1673
	    case CI_MAGICNUMBER:
1674
		if (olen == CILEN_LONG) {
1675
		    p += 2;
1676
		    GETLONG(cilong, p);
1677
		    printer(arg, "magic 0x%x", cilong);
1678
		}
1679
		break;
1680
	    case CI_PCOMPRESSION:
1681
		if (olen == CILEN_VOID) {
1682
		    p += 2;
1683
		    printer(arg, "pcomp");
1684
		}
1685
		break;
1686
	    case CI_ACCOMPRESSION:
1687
		if (olen == CILEN_VOID) {
1688
		    p += 2;
1689
		    printer(arg, "accomp");
1690
		}
1691
		break;
1692
	    }
1693
	    while (p < optend) {
1694
		GETCHAR(code, p);
1695
		printer(arg, " %.2x", code);
1696
	    }
1697
	    printer(arg, ">");
1698
	}
1699
	break;
1700
1701
    case TERMACK:
1702
    case TERMREQ:
1703
	if (len > 0 && *p >= ' ' && *p < 0x7f) {
1704
	    printer(arg, " ");
1705
	    print_string(p, len, printer, arg);
1706
	    p += len;
1707
	    len = 0;
1708
	}
1709
	break;
1710
1711
    case ECHOREQ:
1712
    case ECHOREP:
1713
    case DISCREQ:
1714
	if (len >= 4) {
1715
	    GETLONG(cilong, p);
1716
	    printer(arg, " magic=0x%x", cilong);
1717
	    p += 4;
1718
	    len -= 4;
1719
	}
1720
	break;
1721
    }
1722
1723
    /* print the rest of the bytes in the packet */
1724
    for (; len > 0; --len) {
1725
	GETCHAR(code, p);
1726
	printer(arg, " %.2x", code);
1727
    }
1728
1729
    return p - pstart;
1730
}
1731
1732
/*
1733
 * Time to shut down the link because there is nothing out there.
1734
 */
1735
1736
static
1737
void LcpLinkFailure (f)
1738
    fsm *f;
1739
{
1740
    if (f->state == OPENED) {
1741
	syslog(LOG_INFO, "No response to %d echo-requests", lcp_echos_pending);
1742
        syslog(LOG_NOTICE, "Serial link appears to be disconnected.");
1743
        lcp_close(f->unit, "Peer not responding");
1744
    }
1745
}
1746
1747
/*
1748
 * Timer expired for the LCP echo requests from this process.
1749
 */
1750
1751
static void
1752
LcpEchoCheck (f)
1753
    fsm *f;
1754
{
1755
    LcpSendEchoRequest (f);
1756
1757
    /*
1758
     * Start the timer for the next interval.
1759
     */
1760
    assert (lcp_echo_timer_running==0);
1761
    TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval);
1762
    lcp_echo_timer_running = 1;
1763
}
1764
1765
/*
1766
 * LcpEchoTimeout - Timer expired on the LCP echo
1767
 */
1768
1769
static void
1770
LcpEchoTimeout (arg)
1771
    void *arg;
1772
{
1773
    if (lcp_echo_timer_running != 0) {
1774
        lcp_echo_timer_running = 0;
1775
        LcpEchoCheck ((fsm *) arg);
1776
    }
1777
}
1778
1779
/*
1780
 * LcpEchoReply - LCP has received a reply to the echo
1781
 */
1782
1783
static void
1784
lcp_received_echo_reply (f, id, inp, len)
1785
    fsm *f;
1786
    int id; u_char *inp; int len;
1787
{
1788
    u_int32_t magic;
1789
1790
    /* Check the magic number - don't count replies from ourselves. */
1791
    if (len < 4) {
1792
	syslog(LOG_DEBUG, "lcp: received short Echo-Reply, length %d", len);
1793
	return;
1794
    }
1795
    GETLONG(magic, inp);
1796
    if (lcp_gotoptions[f->unit].neg_magicnumber
1797
	&& magic == lcp_gotoptions[f->unit].magicnumber) {
1798
	syslog(LOG_WARNING, "appear to have received our own echo-reply!");
1799
	return;
1800
    }
1801
1802
    /* Reset the number of outstanding echo frames */
1803
    lcp_echos_pending = 0;
1804
}
1805
1806
/*
1807
 * LcpSendEchoRequest - Send an echo request frame to the peer
1808
 */
1809
1810
static void
1811
LcpSendEchoRequest (f)
1812
    fsm *f;
1813
{
1814
    u_int32_t lcp_magic;
1815
    u_char pkt[4], *pktp;
1816
1817
    /*
1818
     * Detect the failure of the peer at this point.
1819
     */
1820
    if (lcp_echo_fails != 0) {
1821
        if (lcp_echos_pending >= lcp_echo_fails) {
1822
            LcpLinkFailure(f);
1823
	    lcp_echos_pending = 0;
1824
	}
1825
    }
1826
1827
    /*
1828
     * Make and send the echo request frame.
1829
     */
1830
    if (f->state == OPENED) {
1831
        lcp_magic = lcp_gotoptions[f->unit].magicnumber;
1832
	pktp = pkt;
1833
	PUTLONG(lcp_magic, pktp);
1834
        fsm_sdata(f, ECHOREQ, lcp_echo_number++ & 0xFF, pkt, pktp - pkt);
1835
	++lcp_echos_pending;
1836
    }
1837
}
1838
1839
/*
1840
 * lcp_echo_lowerup - Start the timer for the LCP frame
1841
 */
1842
1843
static void
1844
lcp_echo_lowerup (unit)
1845
    int unit;
1846
{
1847
    fsm *f = &lcp_fsm[unit];
1848
1849
    /* Clear the parameters for generating echo frames */
1850
    lcp_echos_pending      = 0;
1851
    lcp_echo_number        = 0;
1852
    lcp_echo_timer_running = 0;
1853
1854
    /* If a timeout interval is specified then start the timer */
1855
    if (lcp_echo_interval != 0)
1856
        LcpEchoCheck (f);
1857
}
1858
1859
/*
1860
 * lcp_echo_lowerdown - Stop the timer for the LCP frame
1861
 */
1862
1863
static void
1864
lcp_echo_lowerdown (unit)
1865
    int unit;
1866
{
1867
    fsm *f = &lcp_fsm[unit];
1868
1869
    if (lcp_echo_timer_running != 0) {
1870
        UNTIMEOUT (LcpEchoTimeout, f);
1871
        lcp_echo_timer_running = 0;
1872
    }
1873
}