1 /*-
2 * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org>
3 * based on work by Toshiharu OHNO <tony-o@iij.ad.jp>
4 * Internet Initiative Japan, Inc (IIJ)
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 * $OpenBSD: lcp.c,v 1.41 2005/07/17 19:13:24 brad Exp $
29 */
30
31 #include <sys/param.h>
32 #include <netinet/in.h>
33 #include <netinet/in_systm.h>
34 #include <netinet/ip.h>
35 #include <sys/socket.h>
36 #include <sys/un.h>
37
38 #include <signal.h>
39 #include <stdarg.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <termios.h>
44 #include <unistd.h>
45
46 #include "layer.h"
47 #include "ua.h"
48 #include "defs.h"
49 #include "command.h"
50 #include "mbuf.h"
51 #include "log.h"
52 #include "timer.h"
53 #include "fsm.h"
54 #include "iplist.h"
55 #include "throughput.h"
56 #include "proto.h"
57 #include "descriptor.h"
58 #include "lqr.h"
59 #include "hdlc.h"
60 #include "lcp.h"
61 #include "ccp.h"
62 #include "async.h"
63 #include "link.h"
64 #include "physical.h"
65 #include "prompt.h"
66 #include "slcompress.h"
67 #include "ncpaddr.h"
68 #include "ipcp.h"
69 #include "filter.h"
70 #include "mp.h"
71 #include "chat.h"
72 #include "auth.h"
73 #include "chap.h"
74 #include "cbcp.h"
75 #include "datalink.h"
76 #ifndef NORADIUS
77 #include "radius.h"
78 #endif
79 #include "ipv6cp.h"
80 #include "ncp.h"
81 #include "bundle.h"
82
83 __RCSID("$MirOS: src/usr.sbin/ppp/ppp/lcp.c,v 1.2 2014/03/13 00:52:15 tg Exp $");
84
85 /* for received LQRs */
86 struct lqrreq {
87 struct fsm_opt_hdr hdr;
88 u_short proto; /* Quality protocol */
89 u_int32_t period; /* Reporting interval */
90 };
91
92 static int LcpLayerUp(struct fsm *);
93 static void LcpLayerDown(struct fsm *);
94 static void LcpLayerStart(struct fsm *);
95 static void LcpLayerFinish(struct fsm *);
96 static void LcpInitRestartCounter(struct fsm *, int);
97 static void LcpSendConfigReq(struct fsm *);
98 static void LcpSentTerminateReq(struct fsm *);
99 static void LcpSendTerminateAck(struct fsm *, u_char);
100 static void LcpDecodeConfig(struct fsm *, u_char *, u_char *, int,
101 struct fsm_decode *);
102
103 static struct fsm_callbacks lcp_Callbacks = {
104 LcpLayerUp,
105 LcpLayerDown,
106 LcpLayerStart,
107 LcpLayerFinish,
108 LcpInitRestartCounter,
109 LcpSendConfigReq,
110 LcpSentTerminateReq,
111 LcpSendTerminateAck,
112 LcpDecodeConfig,
113 fsm_NullRecvResetReq,
114 fsm_NullRecvResetAck
115 };
116
117 static const char * const lcp_TimerNames[] =
118 {"LCP restart", "LCP openmode", "LCP stopped"};
119
120 static const char *
protoname(int proto)121 protoname(int proto)
122 {
123 static const char * const cftypes[] = {
124 /* Check out the latest ``Assigned numbers'' rfc (1700) */
125 NULL,
126 "MRU", /* 1: Maximum-Receive-Unit */
127 "ACCMAP", /* 2: Async-Control-Character-Map */
128 "AUTHPROTO", /* 3: Authentication-Protocol */
129 "QUALPROTO", /* 4: Quality-Protocol */
130 "MAGICNUM", /* 5: Magic-Number */
131 "RESERVED", /* 6: RESERVED */
132 "PROTOCOMP", /* 7: Protocol-Field-Compression */
133 "ACFCOMP", /* 8: Address-and-Control-Field-Compression */
134 "FCSALT", /* 9: FCS-Alternatives */
135 "SDP", /* 10: Self-Describing-Pad */
136 "NUMMODE", /* 11: Numbered-Mode */
137 "MULTIPROC", /* 12: Multi-Link-Procedure */
138 "CALLBACK", /* 13: Callback */
139 "CONTIME", /* 14: Connect-Time */
140 "COMPFRAME", /* 15: Compound-Frames */
141 "NDE", /* 16: Nominal-Data-Encapsulation */
142 "MRRU", /* 17: Multilink-MRRU */
143 "SHORTSEQ", /* 18: Multilink-Short-Sequence-Number-Header */
144 "ENDDISC", /* 19: Multilink-Endpoint-Discriminator */
145 "PROPRIETRY", /* 20: Proprietary */
146 "DCEID", /* 21: DCE-Identifier */
147 "MULTIPP", /* 22: Multi-Link-Plus-Procedure */
148 "LDBACP", /* 23: Link Discriminator for BACP */
149 };
150
151 if (proto < 0 || proto > sizeof cftypes / sizeof *cftypes ||
152 cftypes[proto] == NULL)
153 return HexStr(proto, NULL, 0);
154
155 return cftypes[proto];
156 }
157
158 int
lcp_ReportStatus(struct cmdargs const * arg)159 lcp_ReportStatus(struct cmdargs const *arg)
160 {
161 struct link *l;
162 struct lcp *lcp;
163
164 l = command_ChooseLink(arg);
165 lcp = &l->lcp;
166
167 prompt_Printf(arg->prompt, "%s: %s [%s]\n", l->name, lcp->fsm.name,
168 State2Nam(lcp->fsm.state));
169 prompt_Printf(arg->prompt,
170 " his side: MRU %d, ACCMAP %08lx, PROTOCOMP %s, ACFCOMP %s,\n"
171 " MAGIC %08lx, MRRU %u, SHORTSEQ %s, REJECT %04x\n",
172 lcp->his_mru, (u_long)lcp->his_accmap,
173 lcp->his_protocomp ? "on" : "off",
174 lcp->his_acfcomp ? "on" : "off",
175 (u_long)lcp->his_magic, lcp->his_mrru,
176 lcp->his_shortseq ? "on" : "off", lcp->his_reject);
177 prompt_Printf(arg->prompt,
178 " my side: MRU %d, ACCMAP %08lx, PROTOCOMP %s, ACFCOMP %s,\n"
179 " MAGIC %08lx, MRRU %u, SHORTSEQ %s, REJECT %04x\n",
180 lcp->want_mru, (u_long)lcp->want_accmap,
181 lcp->want_protocomp ? "on" : "off",
182 lcp->want_acfcomp ? "on" : "off",
183 (u_long)lcp->want_magic, lcp->want_mrru,
184 lcp->want_shortseq ? "on" : "off", lcp->my_reject);
185
186 if (lcp->cfg.mru)
187 prompt_Printf(arg->prompt, "\n Defaults: MRU = %d (max %d), ",
188 lcp->cfg.mru, lcp->cfg.max_mru);
189 else
190 prompt_Printf(arg->prompt, "\n Defaults: MRU = any (max %d), ",
191 lcp->cfg.max_mru);
192 if (lcp->cfg.mtu)
193 prompt_Printf(arg->prompt, "MTU = %d (max %d), ",
194 lcp->cfg.mtu, lcp->cfg.max_mtu);
195 else
196 prompt_Printf(arg->prompt, "MTU = any (max %d), ", lcp->cfg.max_mtu);
197 prompt_Printf(arg->prompt, "ACCMAP = %08lx\n", (u_long)lcp->cfg.accmap);
198 prompt_Printf(arg->prompt, " LQR period = %us, ",
199 lcp->cfg.lqrperiod);
200 prompt_Printf(arg->prompt, "Open Mode = %s",
201 lcp->cfg.openmode == OPEN_PASSIVE ? "passive" : "active");
202 if (lcp->cfg.openmode > 0)
203 prompt_Printf(arg->prompt, " (delay %ds)", lcp->cfg.openmode);
204 prompt_Printf(arg->prompt, "\n FSM retry = %us, max %u Config"
205 " REQ%s, %u Term REQ%s\n", lcp->cfg.fsm.timeout,
206 lcp->cfg.fsm.maxreq, lcp->cfg.fsm.maxreq == 1 ? "" : "s",
207 lcp->cfg.fsm.maxtrm, lcp->cfg.fsm.maxtrm == 1 ? "" : "s");
208 prompt_Printf(arg->prompt, " Ident: %s\n", lcp->cfg.ident);
209 prompt_Printf(arg->prompt, "\n Negotiation:\n");
210 prompt_Printf(arg->prompt, " ACFCOMP = %s\n",
211 command_ShowNegval(lcp->cfg.acfcomp));
212 prompt_Printf(arg->prompt, " CHAP = %s\n",
213 command_ShowNegval(lcp->cfg.chap05));
214 #ifndef NODES
215 prompt_Printf(arg->prompt, " CHAP80 = %s\n",
216 command_ShowNegval(lcp->cfg.chap80nt));
217 prompt_Printf(arg->prompt, " LANMan = %s\n",
218 command_ShowNegval(lcp->cfg.chap80lm));
219 prompt_Printf(arg->prompt, " CHAP81 = %s\n",
220 command_ShowNegval(lcp->cfg.chap81));
221 #endif
222 prompt_Printf(arg->prompt, " LQR = %s\n",
223 command_ShowNegval(lcp->cfg.lqr));
224 prompt_Printf(arg->prompt, " LCP ECHO = %s\n",
225 lcp->cfg.echo ? "enabled" : "disabled");
226 prompt_Printf(arg->prompt, " PAP = %s\n",
227 command_ShowNegval(lcp->cfg.pap));
228 prompt_Printf(arg->prompt, " PROTOCOMP = %s\n",
229 command_ShowNegval(lcp->cfg.protocomp));
230
231 return 0;
232 }
233
234 static u_int32_t
GenerateMagic(void)235 GenerateMagic(void)
236 {
237 /* Generate random number which will be used as magic number */
238 return (arc4random());
239 }
240
241 void
lcp_SetupCallbacks(struct lcp * lcp)242 lcp_SetupCallbacks(struct lcp *lcp)
243 {
244 lcp->fsm.fn = &lcp_Callbacks;
245 lcp->fsm.FsmTimer.name = lcp_TimerNames[0];
246 lcp->fsm.OpenTimer.name = lcp_TimerNames[1];
247 lcp->fsm.StoppedTimer.name = lcp_TimerNames[2];
248 }
249
250 void
lcp_Init(struct lcp * lcp,struct bundle * bundle,struct link * l,const struct fsm_parent * parent)251 lcp_Init(struct lcp *lcp, struct bundle *bundle, struct link *l,
252 const struct fsm_parent *parent)
253 {
254 /* Initialise ourselves */
255 int mincode = parent ? 1 : LCP_MINMPCODE;
256
257 fsm_Init(&lcp->fsm, "LCP", PROTO_LCP, mincode, LCP_MAXCODE, LogLCP,
258 bundle, l, parent, &lcp_Callbacks, lcp_TimerNames);
259
260 lcp->cfg.mru = 0;
261 lcp->cfg.max_mru = MAX_MRU;
262 lcp->cfg.mtu = 0;
263 lcp->cfg.max_mtu = MAX_MTU;
264 lcp->cfg.accmap = 0;
265 lcp->cfg.openmode = 1;
266 lcp->cfg.lqrperiod = DEF_LQRPERIOD;
267 lcp->cfg.fsm.timeout = DEF_FSMRETRY;
268 lcp->cfg.fsm.maxreq = DEF_FSMTRIES;
269 lcp->cfg.fsm.maxtrm = DEF_FSMTRIES;
270
271 lcp->cfg.acfcomp = NEG_ENABLED|NEG_ACCEPTED;
272 lcp->cfg.chap05 = NEG_ACCEPTED;
273 #ifndef NODES
274 lcp->cfg.chap80nt = NEG_ACCEPTED;
275 lcp->cfg.chap80lm = 0;
276 lcp->cfg.chap81 = NEG_ACCEPTED;
277 #endif
278 lcp->cfg.lqr = NEG_ACCEPTED;
279 lcp->cfg.echo = 0;
280 lcp->cfg.pap = NEG_ACCEPTED;
281 lcp->cfg.protocomp = NEG_ENABLED|NEG_ACCEPTED;
282 *lcp->cfg.ident = '\0';
283
284 lcp_Setup(lcp, lcp->cfg.openmode);
285 }
286
287 void
lcp_Setup(struct lcp * lcp,int openmode)288 lcp_Setup(struct lcp *lcp, int openmode)
289 {
290 struct physical *p = link2physical(lcp->fsm.link);
291
292 lcp->fsm.open_mode = openmode;
293
294 lcp->his_mru = DEF_MRU;
295 lcp->his_mrru = 0;
296 lcp->his_magic = 0;
297 lcp->his_lqrperiod = 0;
298 lcp->his_acfcomp = 0;
299 lcp->his_auth = 0;
300 lcp->his_authtype = 0;
301 lcp->his_callback.opmask = 0;
302 lcp->his_shortseq = 0;
303 lcp->mru_req = 0;
304
305 if ((lcp->want_mru = lcp->cfg.mru) == 0)
306 lcp->want_mru = DEF_MRU;
307 lcp->want_mrru = lcp->fsm.bundle->ncp.mp.cfg.mrru;
308 lcp->want_shortseq = IsEnabled(lcp->fsm.bundle->ncp.mp.cfg.shortseq) ? 1 : 0;
309 lcp->want_acfcomp = IsEnabled(lcp->cfg.acfcomp) ? 1 : 0;
310
311 if (lcp->fsm.parent) {
312 lcp->his_accmap = 0xffffffff;
313 lcp->want_accmap = lcp->cfg.accmap;
314 lcp->his_protocomp = 0;
315 lcp->want_protocomp = IsEnabled(lcp->cfg.protocomp) ? 1 : 0;
316 lcp->want_magic = GenerateMagic();
317
318 if (IsEnabled(lcp->cfg.chap05)) {
319 lcp->want_auth = PROTO_CHAP;
320 lcp->want_authtype = 0x05;
321 #ifndef NODES
322 } else if (IsEnabled(lcp->cfg.chap80nt) ||
323 IsEnabled(lcp->cfg.chap80lm)) {
324 lcp->want_auth = PROTO_CHAP;
325 lcp->want_authtype = 0x80;
326 } else if (IsEnabled(lcp->cfg.chap81)) {
327 lcp->want_auth = PROTO_CHAP;
328 lcp->want_authtype = 0x81;
329 #endif
330 } else if (IsEnabled(lcp->cfg.pap)) {
331 lcp->want_auth = PROTO_PAP;
332 lcp->want_authtype = 0;
333 } else {
334 lcp->want_auth = 0;
335 lcp->want_authtype = 0;
336 }
337
338 if (p->type != PHYS_DIRECT)
339 memcpy(&lcp->want_callback, &p->dl->cfg.callback,
340 sizeof(struct callback));
341 else
342 lcp->want_callback.opmask = 0;
343 lcp->want_lqrperiod = IsEnabled(lcp->cfg.lqr) ?
344 lcp->cfg.lqrperiod * 100 : 0;
345 } else {
346 lcp->his_accmap = lcp->want_accmap = 0;
347 lcp->his_protocomp = lcp->want_protocomp = 1;
348 lcp->want_magic = 0;
349 lcp->want_auth = 0;
350 lcp->want_authtype = 0;
351 lcp->want_callback.opmask = 0;
352 lcp->want_lqrperiod = 0;
353 }
354
355 lcp->his_reject = lcp->my_reject = 0;
356 lcp->auth_iwait = lcp->auth_ineed = 0;
357 lcp->LcpFailedMagic = 0;
358 }
359
360 static void
LcpInitRestartCounter(struct fsm * fp,int what)361 LcpInitRestartCounter(struct fsm *fp, int what)
362 {
363 /* Set fsm timer load */
364 struct lcp *lcp = fsm2lcp(fp);
365
366 fp->FsmTimer.load = lcp->cfg.fsm.timeout * SECTICKS;
367 switch (what) {
368 case FSM_REQ_TIMER:
369 fp->restart = lcp->cfg.fsm.maxreq;
370 break;
371 case FSM_TRM_TIMER:
372 fp->restart = lcp->cfg.fsm.maxtrm;
373 break;
374 default:
375 fp->restart = 1;
376 break;
377 }
378 }
379
380 static void
LcpSendConfigReq(struct fsm * fp)381 LcpSendConfigReq(struct fsm *fp)
382 {
383 /* Send config REQ please */
384 struct physical *p = link2physical(fp->link);
385 struct lcp *lcp = fsm2lcp(fp);
386 u_char buff[200];
387 struct fsm_opt *o;
388 struct mp *mp;
389 u_int16_t proto;
390 u_short maxmru;
391
392 if (!p) {
393 log_Printf(LogERROR, "%s: LcpSendConfigReq: Not a physical link !\n",
394 fp->link->name);
395 return;
396 }
397
398 o = (struct fsm_opt *)buff;
399 if (!physical_IsSync(p)) {
400 if (lcp->want_acfcomp && !REJECTED(lcp, TY_ACFCOMP))
401 INC_FSM_OPT(TY_ACFCOMP, 2, o);
402
403 if (lcp->want_protocomp && !REJECTED(lcp, TY_PROTOCOMP))
404 INC_FSM_OPT(TY_PROTOCOMP, 2, o);
405
406 if (!REJECTED(lcp, TY_ACCMAP)) {
407 ua_htonl(&lcp->want_accmap, o->data);
408 INC_FSM_OPT(TY_ACCMAP, 6, o);
409 }
410 }
411
412 maxmru = p ? physical_DeviceMTU(p) : 0;
413 if (lcp->cfg.max_mru && (!maxmru || maxmru > lcp->cfg.max_mru))
414 maxmru = lcp->cfg.max_mru;
415 if (maxmru && lcp->want_mru > maxmru) {
416 log_Printf(LogWARN, "%s: Reducing configured MRU from %u to %u\n",
417 fp->link->name, lcp->want_mru, maxmru);
418 lcp->want_mru = maxmru;
419 }
420 if (!REJECTED(lcp, TY_MRU)) {
421 ua_htons(&lcp->want_mru, o->data);
422 INC_FSM_OPT(TY_MRU, 4, o);
423 }
424
425 if (lcp->want_magic && !REJECTED(lcp, TY_MAGICNUM)) {
426 ua_htonl(&lcp->want_magic, o->data);
427 INC_FSM_OPT(TY_MAGICNUM, 6, o);
428 }
429
430 if (lcp->want_lqrperiod && !REJECTED(lcp, TY_QUALPROTO)) {
431 proto = PROTO_LQR;
432 ua_htons(&proto, o->data);
433 ua_htonl(&lcp->want_lqrperiod, o->data + 2);
434 INC_FSM_OPT(TY_QUALPROTO, 8, o);
435 }
436
437 switch (lcp->want_auth) {
438 case PROTO_PAP:
439 proto = PROTO_PAP;
440 ua_htons(&proto, o->data);
441 INC_FSM_OPT(TY_AUTHPROTO, 4, o);
442 break;
443
444 case PROTO_CHAP:
445 proto = PROTO_CHAP;
446 ua_htons(&proto, o->data);
447 o->data[2] = lcp->want_authtype;
448 INC_FSM_OPT(TY_AUTHPROTO, 5, o);
449 break;
450 }
451
452 if (!REJECTED(lcp, TY_CALLBACK)) {
453 if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) {
454 *o->data = CALLBACK_AUTH;
455 INC_FSM_OPT(TY_CALLBACK, 3, o);
456 } else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) {
457 *o->data = CALLBACK_CBCP;
458 INC_FSM_OPT(TY_CALLBACK, 3, o);
459 } else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_E164)) {
460 int sz = strlen(lcp->want_callback.msg);
461
462 if (sz > sizeof o->data - 1) {
463 sz = sizeof o->data - 1;
464 log_Printf(LogWARN, "Truncating E164 data to %d octets (oops!)\n", sz);
465 }
466 *o->data = CALLBACK_E164;
467 memcpy(o->data + 1, lcp->want_callback.msg, sz);
468 INC_FSM_OPT(TY_CALLBACK, sz + 3, o);
469 }
470 }
471
472 if (lcp->want_mrru && !REJECTED(lcp, TY_MRRU)) {
473 ua_htons(&lcp->want_mrru, o->data);
474 INC_FSM_OPT(TY_MRRU, 4, o);
475
476 if (lcp->want_shortseq && !REJECTED(lcp, TY_SHORTSEQ))
477 INC_FSM_OPT(TY_SHORTSEQ, 2, o);
478 }
479
480 mp = &lcp->fsm.bundle->ncp.mp;
481 if (mp->cfg.enddisc.class != 0 && IsEnabled(mp->cfg.negenddisc) &&
482 !REJECTED(lcp, TY_ENDDISC)) {
483 *o->data = mp->cfg.enddisc.class;
484 memcpy(o->data+1, mp->cfg.enddisc.address, mp->cfg.enddisc.len);
485 INC_FSM_OPT(TY_ENDDISC, mp->cfg.enddisc.len + 3, o);
486 }
487
488 fsm_Output(fp, CODE_CONFIGREQ, fp->reqid, buff, (u_char *)o - buff,
489 MB_LCPOUT);
490 }
491
492 void
lcp_SendProtoRej(struct lcp * lcp,u_char * option,int count)493 lcp_SendProtoRej(struct lcp *lcp, u_char *option, int count)
494 {
495 /* Don't understand `option' */
496 fsm_Output(&lcp->fsm, CODE_PROTOREJ, lcp->fsm.reqid, option, count,
497 MB_LCPOUT);
498 }
499
500 int
lcp_SendIdentification(struct lcp * lcp)501 lcp_SendIdentification(struct lcp *lcp)
502 {
503 static u_char id; /* Use a private id */
504 u_char msg[DEF_MRU - 3];
505 const char *argv[2];
506 char *exp[2];
507
508 if (*lcp->cfg.ident == '\0')
509 return 0;
510
511 argv[0] = lcp->cfg.ident;
512 argv[1] = NULL;
513
514 command_Expand(exp, 1, argv, lcp->fsm.bundle, 1, getpid());
515
516 ua_htonl(&lcp->want_magic, msg);
517 strncpy(msg + 4, exp[0], sizeof msg - 5);
518 msg[sizeof msg - 1] = '\0';
519
520 fsm_Output(&lcp->fsm, CODE_IDENT, id++, msg, 4 + strlen(msg + 4), MB_LCPOUT);
521 log_Printf(LogLCP, " MAGICNUM %08x\n", lcp->want_magic);
522 log_Printf(LogLCP, " TEXT %s\n", msg + 4);
523
524 command_Free(1, exp);
525 return 1;
526 }
527
528 void
lcp_RecvIdentification(struct lcp * lcp,char * data)529 lcp_RecvIdentification(struct lcp *lcp, char *data)
530 {
531 log_Printf(LogLCP, " MAGICNUM %08x\n", lcp->his_magic);
532 log_Printf(LogLCP, " TEXT %s\n", data);
533 }
534
535 static void
LcpSentTerminateReq(struct fsm * fp)536 LcpSentTerminateReq(struct fsm *fp)
537 {
538 /* Term REQ just sent by FSM */
539 }
540
541 static void
LcpSendTerminateAck(struct fsm * fp,u_char id)542 LcpSendTerminateAck(struct fsm *fp, u_char id)
543 {
544 /* Send Term ACK please */
545 struct physical *p = link2physical(fp->link);
546
547 if (p && p->dl->state == DATALINK_CBCP)
548 cbcp_ReceiveTerminateReq(p);
549
550 fsm_Output(fp, CODE_TERMACK, id, NULL, 0, MB_LCPOUT);
551 }
552
553 static void
LcpLayerStart(struct fsm * fp)554 LcpLayerStart(struct fsm *fp)
555 {
556 /* We're about to start up ! */
557 struct lcp *lcp = fsm2lcp(fp);
558
559 log_Printf(LogLCP, "%s: LayerStart\n", fp->link->name);
560 lcp->LcpFailedMagic = 0;
561 fp->more.reqs = fp->more.naks = fp->more.rejs = lcp->cfg.fsm.maxreq * 3;
562 lcp->mru_req = 0;
563 }
564
565 static void
LcpLayerFinish(struct fsm * fp)566 LcpLayerFinish(struct fsm *fp)
567 {
568 /* We're now down */
569 log_Printf(LogLCP, "%s: LayerFinish\n", fp->link->name);
570 }
571
572 static int
LcpLayerUp(struct fsm * fp)573 LcpLayerUp(struct fsm *fp)
574 {
575 /* We're now up */
576 struct physical *p = link2physical(fp->link);
577 struct lcp *lcp = fsm2lcp(fp);
578
579 log_Printf(LogLCP, "%s: LayerUp\n", fp->link->name);
580 physical_SetAsyncParams(p, lcp->want_accmap, lcp->his_accmap);
581 lqr_Start(lcp);
582 hdlc_StartTimer(&p->hdlc);
583 fp->more.reqs = fp->more.naks = fp->more.rejs = lcp->cfg.fsm.maxreq * 3;
584
585 lcp_SendIdentification(lcp);
586
587 return 1;
588 }
589
590 static void
LcpLayerDown(struct fsm * fp)591 LcpLayerDown(struct fsm *fp)
592 {
593 /* About to come down */
594 struct physical *p = link2physical(fp->link);
595
596 log_Printf(LogLCP, "%s: LayerDown\n", fp->link->name);
597 hdlc_StopTimer(&p->hdlc);
598 lqr_StopTimer(p);
599 lcp_Setup(fsm2lcp(fp), 0);
600 }
601
602 static int
E164ok(struct callback * cb,char * req,int sz)603 E164ok(struct callback *cb, char *req, int sz)
604 {
605 char list[sizeof cb->msg], *next;
606 int len;
607
608 if (!strcmp(cb->msg, "*"))
609 return 1;
610
611 strncpy(list, cb->msg, sizeof list - 1);
612 list[sizeof list - 1] = '\0';
613 for (next = strtok(list, ","); next; next = strtok(NULL, ",")) {
614 len = strlen(next);
615 if (sz == len && !memcmp(list, req, sz))
616 return 1;
617 }
618 return 0;
619 }
620
621 static int
lcp_auth_nak(struct lcp * lcp,struct fsm_decode * dec)622 lcp_auth_nak(struct lcp *lcp, struct fsm_decode *dec)
623 {
624 struct fsm_opt nak;
625
626 nak.hdr.id = TY_AUTHPROTO;
627
628 if (IsAccepted(lcp->cfg.pap)) {
629 nak.hdr.len = 4;
630 nak.data[0] = (unsigned char)(PROTO_PAP >> 8);
631 nak.data[1] = (unsigned char)PROTO_PAP;
632 fsm_nak(dec, &nak);
633 return 1;
634 }
635
636 nak.hdr.len = 5;
637 nak.data[0] = (unsigned char)(PROTO_CHAP >> 8);
638 nak.data[1] = (unsigned char)PROTO_CHAP;
639
640 if (IsAccepted(lcp->cfg.chap05)) {
641 nak.data[2] = 0x05;
642 fsm_nak(dec, &nak);
643 #ifndef NODES
644 } else if (IsAccepted(lcp->cfg.chap80nt) ||
645 IsAccepted(lcp->cfg.chap80lm)) {
646 nak.data[2] = 0x80;
647 fsm_nak(dec, &nak);
648 } else if (IsAccepted(lcp->cfg.chap81)) {
649 nak.data[2] = 0x81;
650 fsm_nak(dec, &nak);
651 #endif
652 } else {
653 return 0;
654 }
655
656 return 1;
657 }
658
659 static void
LcpDecodeConfig(struct fsm * fp,u_char * cp,u_char * end,int mode_type,struct fsm_decode * dec)660 LcpDecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type,
661 struct fsm_decode *dec)
662 {
663 /* Deal with incoming PROTO_LCP */
664 struct lcp *lcp = fsm2lcp(fp);
665 int sz, pos, op, callback_req, chap_type;
666 u_int32_t magic, accmap;
667 u_short mru, phmtu, maxmtu, maxmru, wantmtu, wantmru, proto;
668 struct lqrreq *req, reqbuff;
669 char request[20], desc[22];
670 struct mp *mp;
671 struct physical *p = link2physical(fp->link);
672 struct fsm_opt *opt, nak;
673
674 sz = op = callback_req = 0;
675
676 while (end - cp >= sizeof(opt->hdr)) {
677 if ((opt = fsm_readopt(&cp)) == NULL)
678 break;
679
680 snprintf(request, sizeof request, " %s[%d]", protoname(opt->hdr.id),
681 opt->hdr.len);
682
683 switch (opt->hdr.id) {
684 case TY_MRRU:
685 mp = &lcp->fsm.bundle->ncp.mp;
686 ua_ntohs(opt->data, &mru);
687 log_Printf(LogLCP, "%s %u\n", request, mru);
688
689 switch (mode_type) {
690 case MODE_REQ:
691 if (mp->cfg.mrru) {
692 if (REJECTED(lcp, TY_MRRU))
693 /* Ignore his previous reject so that we REQ next time */
694 lcp->his_reject &= ~(1 << opt->hdr.id);
695
696 if (mru > MAX_MRU) {
697 /* Push him down to MAX_MRU */
698 lcp->his_mrru = MAX_MRU;
699 nak.hdr.id = TY_MRRU;
700 nak.hdr.len = 4;
701 ua_htons(&lcp->his_mrru, nak.data);
702 fsm_nak(dec, &nak);
703 } else if (mru < MIN_MRU) {
704 /* Push him up to MIN_MRU */
705 lcp->his_mrru = MIN_MRU;
706 nak.hdr.id = TY_MRRU;
707 nak.hdr.len = 4;
708 ua_htons(&lcp->his_mrru, nak.data);
709 fsm_nak(dec, &nak);
710 } else {
711 lcp->his_mrru = mru;
712 fsm_ack(dec, opt);
713 }
714 break;
715 } else {
716 fsm_rej(dec, opt);
717 lcp->my_reject |= (1 << opt->hdr.id);
718 }
719 break;
720 case MODE_NAK:
721 if (mp->cfg.mrru) {
722 if (REJECTED(lcp, TY_MRRU))
723 /* Must have changed his mind ! */
724 lcp->his_reject &= ~(1 << opt->hdr.id);
725
726 if (mru > MAX_MRU)
727 lcp->want_mrru = MAX_MRU;
728 else if (mru < MIN_MRU)
729 lcp->want_mrru = MIN_MRU;
730 else
731 lcp->want_mrru = mru;
732 }
733 /* else we honour our config and don't send the suggested REQ */
734 break;
735 case MODE_REJ:
736 lcp->his_reject |= (1 << opt->hdr.id);
737 lcp->want_mrru = 0; /* Ah well, no multilink :-( */
738 break;
739 }
740 break;
741
742 case TY_MRU:
743 lcp->mru_req = 1;
744 ua_ntohs(opt->data, &mru);
745 log_Printf(LogLCP, "%s %d\n", request, mru);
746
747 switch (mode_type) {
748 case MODE_REQ:
749 maxmtu = p ? physical_DeviceMTU(p) : 0;
750 if (lcp->cfg.max_mtu && (!maxmtu || maxmtu > lcp->cfg.max_mtu))
751 maxmtu = lcp->cfg.max_mtu;
752 wantmtu = lcp->cfg.mtu;
753 if (maxmtu && wantmtu > maxmtu) {
754 log_Printf(LogWARN, "%s: Reducing configured MTU from %u to %u\n",
755 fp->link->name, wantmtu, maxmtu);
756 wantmtu = maxmtu;
757 }
758
759 if (maxmtu && mru > maxmtu) {
760 lcp->his_mru = maxmtu;
761 nak.hdr.id = TY_MRU;
762 nak.hdr.len = 4;
763 ua_htons(&lcp->his_mru, nak.data);
764 fsm_nak(dec, &nak);
765 } else if (wantmtu && mru < wantmtu) {
766 /* Push him up to MTU or MIN_MRU */
767 lcp->his_mru = wantmtu;
768 nak.hdr.id = TY_MRU;
769 nak.hdr.len = 4;
770 ua_htons(&lcp->his_mru, nak.data);
771 fsm_nak(dec, &nak);
772 } else {
773 lcp->his_mru = mru;
774 fsm_ack(dec, opt);
775 }
776 break;
777 case MODE_NAK:
778 maxmru = p ? physical_DeviceMTU(p) : 0;
779 if (lcp->cfg.max_mru && (!maxmru || maxmru > lcp->cfg.max_mru))
780 maxmru = lcp->cfg.max_mru;
781 wantmru = lcp->cfg.mru > maxmru ? maxmru : lcp->cfg.mru;
782
783 if (wantmru && mru > wantmru)
784 lcp->want_mru = wantmru;
785 else if (mru > maxmru)
786 lcp->want_mru = maxmru;
787 else if (mru < MIN_MRU)
788 lcp->want_mru = MIN_MRU;
789 else
790 lcp->want_mru = mru;
791 break;
792 case MODE_REJ:
793 lcp->his_reject |= (1 << opt->hdr.id);
794 break;
795 }
796 break;
797
798 case TY_ACCMAP:
799 ua_ntohl(opt->data, &accmap);
800 log_Printf(LogLCP, "%s 0x%08lx\n", request, (u_long)accmap);
801
802 switch (mode_type) {
803 case MODE_REQ:
804 lcp->his_accmap = accmap;
805 fsm_ack(dec, opt);
806 break;
807 case MODE_NAK:
808 lcp->want_accmap = accmap;
809 break;
810 case MODE_REJ:
811 lcp->his_reject |= (1 << opt->hdr.id);
812 break;
813 }
814 break;
815
816 case TY_AUTHPROTO:
817 ua_ntohs(opt->data, &proto);
818 chap_type = opt->hdr.len == 5 ? opt->data[2] : 0;
819
820 log_Printf(LogLCP, "%s 0x%04x (%s)\n", request, proto,
821 Auth2Nam(proto, chap_type));
822
823 switch (mode_type) {
824 case MODE_REQ:
825 switch (proto) {
826 case PROTO_PAP:
827 if (opt->hdr.len == 4 && IsAccepted(lcp->cfg.pap)) {
828 lcp->his_auth = proto;
829 lcp->his_authtype = 0;
830 fsm_ack(dec, opt);
831 } else if (!lcp_auth_nak(lcp, dec)) {
832 lcp->my_reject |= (1 << opt->hdr.id);
833 fsm_rej(dec, opt);
834 }
835 break;
836
837 case PROTO_CHAP:
838 if ((chap_type == 0x05 && IsAccepted(lcp->cfg.chap05))
839 #ifndef NODES
840 || (chap_type == 0x80 && (IsAccepted(lcp->cfg.chap80nt) ||
841 (IsAccepted(lcp->cfg.chap80lm))))
842 || (chap_type == 0x81 && IsAccepted(lcp->cfg.chap81))
843 #endif
844 ) {
845 lcp->his_auth = proto;
846 lcp->his_authtype = chap_type;
847 fsm_ack(dec, opt);
848 } else {
849 #ifdef NODES
850 if (chap_type == 0x80) {
851 log_Printf(LogWARN, "CHAP 0x80 not available without DES\n");
852 } else if (chap_type == 0x81) {
853 log_Printf(LogWARN, "CHAP 0x81 not available without DES\n");
854 } else
855 #endif
856 if (chap_type != 0x05)
857 log_Printf(LogWARN, "%s not supported\n",
858 Auth2Nam(PROTO_CHAP, chap_type));
859
860 if (!lcp_auth_nak(lcp, dec)) {
861 lcp->my_reject |= (1 << opt->hdr.id);
862 fsm_rej(dec, opt);
863 }
864 }
865 break;
866
867 default:
868 log_Printf(LogLCP, "%s 0x%04x - not recognised\n",
869 request, proto);
870 if (!lcp_auth_nak(lcp, dec)) {
871 lcp->my_reject |= (1 << opt->hdr.id);
872 fsm_rej(dec, opt);
873 }
874 break;
875 }
876 break;
877
878 case MODE_NAK:
879 switch (proto) {
880 case PROTO_PAP:
881 if (IsEnabled(lcp->cfg.pap)) {
882 lcp->want_auth = PROTO_PAP;
883 lcp->want_authtype = 0;
884 } else {
885 log_Printf(LogLCP, "Peer will only send PAP (not enabled)\n");
886 lcp->his_reject |= (1 << opt->hdr.id);
887 }
888 break;
889 case PROTO_CHAP:
890 if (chap_type == 0x05 && IsEnabled(lcp->cfg.chap05)) {
891 lcp->want_auth = PROTO_CHAP;
892 lcp->want_authtype = 0x05;
893 #ifndef NODES
894 } else if (chap_type == 0x80 && (IsEnabled(lcp->cfg.chap80nt) ||
895 IsEnabled(lcp->cfg.chap80lm))) {
896 lcp->want_auth = PROTO_CHAP;
897 lcp->want_authtype = 0x80;
898 } else if (chap_type == 0x81 && IsEnabled(lcp->cfg.chap81)) {
899 lcp->want_auth = PROTO_CHAP;
900 lcp->want_authtype = 0x81;
901 #endif
902 } else {
903 #ifdef NODES
904 if (chap_type == 0x80) {
905 log_Printf(LogLCP, "Peer will only send MSCHAP (not available"
906 " without DES)\n");
907 } else if (chap_type == 0x81) {
908 log_Printf(LogLCP, "Peer will only send MSCHAPV2 (not available"
909 " without DES)\n");
910 } else
911 #endif
912 log_Printf(LogLCP, "Peer will only send %s (not %s)\n",
913 Auth2Nam(PROTO_CHAP, chap_type),
914 #ifndef NODES
915 (chap_type == 0x80 || chap_type == 0x81) ? "configured" :
916 #endif
917 "supported");
918 lcp->his_reject |= (1 << opt->hdr.id);
919 }
920 break;
921 default:
922 /* We've been NAK'd with something we don't understand :-( */
923 lcp->his_reject |= (1 << opt->hdr.id);
924 break;
925 }
926 break;
927
928 case MODE_REJ:
929 lcp->his_reject |= (1 << opt->hdr.id);
930 break;
931 }
932 break;
933
934 case TY_QUALPROTO:
935 req = &reqbuff;
936 memcpy(req, opt, sizeof(reqbuff));
937 log_Printf(LogLCP, "%s proto %x, interval %lums\n",
938 request, ntohs(req->proto), (u_long)ntohl(req->period) * 10);
939 switch (mode_type) {
940 case MODE_REQ:
941 if (ntohs(req->proto) != PROTO_LQR || !IsAccepted(lcp->cfg.lqr)) {
942 fsm_rej(dec, opt);
943 lcp->my_reject |= (1 << opt->hdr.id);
944 } else {
945 lcp->his_lqrperiod = ntohl(req->period);
946 if (lcp->his_lqrperiod < MIN_LQRPERIOD * 100)
947 lcp->his_lqrperiod = MIN_LQRPERIOD * 100;
948 req->period = htonl(lcp->his_lqrperiod);
949 fsm_ack(dec, opt);
950 }
951 break;
952 case MODE_NAK:
953 lcp->want_lqrperiod = ntohl(req->period);
954 break;
955 case MODE_REJ:
956 lcp->his_reject |= (1 << opt->hdr.id);
957 break;
958 }
959 break;
960
961 case TY_MAGICNUM:
962 ua_ntohl(opt->data, &magic);
963 log_Printf(LogLCP, "%s 0x%08lx\n", request, (u_long)magic);
964
965 switch (mode_type) {
966 case MODE_REQ:
967 if (lcp->want_magic) {
968 /* Validate magic number */
969 if (magic == lcp->want_magic) {
970 sigset_t emptyset;
971
972 log_Printf(LogLCP, "Magic is same (%08lx) - %d times\n",
973 (u_long)magic, ++lcp->LcpFailedMagic);
974 lcp->want_magic = GenerateMagic();
975 fsm_nak(dec, opt);
976 ualarm(TICKUNIT * (4 + 4 * lcp->LcpFailedMagic), 0);
977 sigemptyset(&emptyset);
978 sigsuspend(&emptyset);
979 } else {
980 lcp->his_magic = magic;
981 lcp->LcpFailedMagic = 0;
982 fsm_ack(dec, opt);
983 }
984 } else {
985 lcp->my_reject |= (1 << opt->hdr.id);
986 fsm_rej(dec, opt);
987 }
988 break;
989 case MODE_NAK:
990 log_Printf(LogLCP, " Magic 0x%08lx is NAKed!\n", (u_long)magic);
991 lcp->want_magic = GenerateMagic();
992 break;
993 case MODE_REJ:
994 log_Printf(LogLCP, " Magic 0x%08x is REJected!\n", magic);
995 lcp->want_magic = 0;
996 lcp->his_reject |= (1 << opt->hdr.id);
997 break;
998 }
999 break;
1000
1001 case TY_PROTOCOMP:
1002 log_Printf(LogLCP, "%s\n", request);
1003
1004 switch (mode_type) {
1005 case MODE_REQ:
1006 if (IsAccepted(lcp->cfg.protocomp)) {
1007 lcp->his_protocomp = 1;
1008 fsm_ack(dec, opt);
1009 } else {
1010 #ifdef OLDMST
1011 /* MorningStar before v1.3 needs NAK */
1012 fsm_nak(dec, opt);
1013 #else
1014 fsm_rej(dec, opt);
1015 lcp->my_reject |= (1 << opt->hdr.id);
1016 #endif
1017 }
1018 break;
1019 case MODE_NAK:
1020 case MODE_REJ:
1021 lcp->want_protocomp = 0;
1022 lcp->his_reject |= (1 << opt->hdr.id);
1023 break;
1024 }
1025 break;
1026
1027 case TY_ACFCOMP:
1028 log_Printf(LogLCP, "%s\n", request);
1029 switch (mode_type) {
1030 case MODE_REQ:
1031 if (IsAccepted(lcp->cfg.acfcomp)) {
1032 lcp->his_acfcomp = 1;
1033 fsm_ack(dec, opt);
1034 } else {
1035 #ifdef OLDMST
1036 /* MorningStar before v1.3 needs NAK */
1037 fsm_nak(dec, opt);
1038 #else
1039 fsm_rej(dec, opt);
1040 lcp->my_reject |= (1 << opt->hdr.id);
1041 #endif
1042 }
1043 break;
1044 case MODE_NAK:
1045 case MODE_REJ:
1046 lcp->want_acfcomp = 0;
1047 lcp->his_reject |= (1 << opt->hdr.id);
1048 break;
1049 }
1050 break;
1051
1052 case TY_SDP:
1053 log_Printf(LogLCP, "%s\n", request);
1054 switch (mode_type) {
1055 case MODE_REQ:
1056 case MODE_NAK:
1057 case MODE_REJ:
1058 break;
1059 }
1060 break;
1061
1062 case TY_CALLBACK:
1063 if (opt->hdr.len == 2)
1064 op = CALLBACK_NONE;
1065 else
1066 op = (int)opt->data[0];
1067 sz = opt->hdr.len - 3;
1068 switch (op) {
1069 case CALLBACK_AUTH:
1070 log_Printf(LogLCP, "%s Auth\n", request);
1071 break;
1072 case CALLBACK_DIALSTRING:
1073 log_Printf(LogLCP, "%s Dialstring %.*s\n", request, sz,
1074 opt->data + 1);
1075 break;
1076 case CALLBACK_LOCATION:
1077 log_Printf(LogLCP, "%s Location %.*s\n", request, sz, opt->data + 1);
1078 break;
1079 case CALLBACK_E164:
1080 log_Printf(LogLCP, "%s E.164 (%.*s)\n", request, sz, opt->data + 1);
1081 break;
1082 case CALLBACK_NAME:
1083 log_Printf(LogLCP, "%s Name %.*s\n", request, sz, opt->data + 1);
1084 break;
1085 case CALLBACK_CBCP:
1086 log_Printf(LogLCP, "%s CBCP\n", request);
1087 break;
1088 default:
1089 log_Printf(LogLCP, "%s ???\n", request);
1090 break;
1091 }
1092
1093 switch (mode_type) {
1094 case MODE_REQ:
1095 callback_req = 1;
1096 if (p->type != PHYS_DIRECT) {
1097 fsm_rej(dec, opt);
1098 lcp->my_reject |= (1 << opt->hdr.id);
1099 }
1100 nak.hdr.id = opt->hdr.id;
1101 nak.hdr.len = 3;
1102 if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(op)) &&
1103 (op != CALLBACK_AUTH || p->link.lcp.want_auth) &&
1104 (op != CALLBACK_E164 ||
1105 E164ok(&p->dl->cfg.callback, opt->data + 1, sz))) {
1106 lcp->his_callback.opmask = CALLBACK_BIT(op);
1107 if (sz > sizeof lcp->his_callback.msg - 1) {
1108 sz = sizeof lcp->his_callback.msg - 1;
1109 log_Printf(LogWARN, "Truncating option arg to %d octets\n", sz);
1110 }
1111 memcpy(lcp->his_callback.msg, opt->data + 1, sz);
1112 lcp->his_callback.msg[sz] = '\0';
1113 fsm_ack(dec, opt);
1114 } else if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) &&
1115 p->link.lcp.auth_ineed) {
1116 nak.data[0] = CALLBACK_AUTH;
1117 fsm_nak(dec, &nak);
1118 } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) {
1119 nak.data[0] = CALLBACK_CBCP;
1120 fsm_nak(dec, &nak);
1121 } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_E164)) {
1122 nak.data[0] = CALLBACK_E164;
1123 fsm_nak(dec, &nak);
1124 } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) {
1125 log_Printf(LogWARN, "Cannot insist on auth callback without"
1126 " PAP or CHAP enabled !\n");
1127 nak.data[0] = 2;
1128 fsm_nak(dec, &nak);
1129 } else {
1130 lcp->my_reject |= (1 << opt->hdr.id);
1131 fsm_rej(dec, opt);
1132 }
1133 break;
1134 case MODE_NAK:
1135 /* We don't do what he NAKs with, we do things in our preferred order */
1136 if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_AUTH))
1137 lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_AUTH);
1138 else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_CBCP))
1139 lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_CBCP);
1140 else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_E164))
1141 lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_E164);
1142 if (lcp->want_callback.opmask == CALLBACK_BIT(CALLBACK_NONE)) {
1143 log_Printf(LogPHASE, "Peer NAKd all callbacks, trying none\n");
1144 lcp->want_callback.opmask = 0;
1145 } else if (!lcp->want_callback.opmask) {
1146 log_Printf(LogPHASE, "Peer NAKd last configured callback\n");
1147 fsm_Close(&lcp->fsm);
1148 }
1149 break;
1150 case MODE_REJ:
1151 if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_NONE)) {
1152 lcp->his_reject |= (1 << opt->hdr.id);
1153 lcp->want_callback.opmask = 0;
1154 } else {
1155 log_Printf(LogPHASE, "Peer rejected *required* callback\n");
1156 fsm_Close(&lcp->fsm);
1157 }
1158 break;
1159 }
1160 break;
1161
1162 case TY_SHORTSEQ:
1163 mp = &lcp->fsm.bundle->ncp.mp;
1164 log_Printf(LogLCP, "%s\n", request);
1165
1166 switch (mode_type) {
1167 case MODE_REQ:
1168 if (lcp->want_mrru && IsAccepted(mp->cfg.shortseq)) {
1169 lcp->his_shortseq = 1;
1170 fsm_ack(dec, opt);
1171 } else {
1172 fsm_rej(dec, opt);
1173 lcp->my_reject |= (1 << opt->hdr.id);
1174 }
1175 break;
1176 case MODE_NAK:
1177 /*
1178 * He's trying to get us to ask for short sequence numbers.
1179 * We ignore the NAK and honour our configuration file instead.
1180 */
1181 break;
1182 case MODE_REJ:
1183 lcp->his_reject |= (1 << opt->hdr.id);
1184 lcp->want_shortseq = 0; /* For when we hit MP */
1185 break;
1186 }
1187 break;
1188
1189 case TY_ENDDISC:
1190 mp = &lcp->fsm.bundle->ncp.mp;
1191 log_Printf(LogLCP, "%s %s\n", request,
1192 mp_Enddisc(opt->data[0], opt->data + 1, opt->hdr.len - 3));
1193 switch (mode_type) {
1194 case MODE_REQ:
1195 if (!p) {
1196 log_Printf(LogLCP, " ENDDISC rejected - not a physical link\n");
1197 fsm_rej(dec, opt);
1198 lcp->my_reject |= (1 << opt->hdr.id);
1199 } else if (!IsAccepted(mp->cfg.negenddisc)) {
1200 lcp->my_reject |= (1 << opt->hdr.id);
1201 fsm_rej(dec, opt);
1202 } else if (opt->hdr.len - 3 < sizeof p->dl->peer.enddisc.address &&
1203 opt->data[0] <= MAX_ENDDISC_CLASS) {
1204 p->dl->peer.enddisc.class = opt->data[0];
1205 p->dl->peer.enddisc.len = opt->hdr.len - 3;
1206 memcpy(p->dl->peer.enddisc.address, opt->data + 1, opt->hdr.len - 3);
1207 p->dl->peer.enddisc.address[opt->hdr.len - 3] = '\0';
1208 /* XXX: If mp->active, compare and NAK with mp->peer ? */
1209 fsm_ack(dec, opt);
1210 } else {
1211 if (opt->data[0] > MAX_ENDDISC_CLASS)
1212 log_Printf(LogLCP, " ENDDISC rejected - unrecognised class %d\n",
1213 opt->data[0]);
1214 else
1215 log_Printf(LogLCP, " ENDDISC rejected - local max length is %ld\n",
1216 (long)(sizeof p->dl->peer.enddisc.address - 1));
1217 fsm_rej(dec, opt);
1218 lcp->my_reject |= (1 << opt->hdr.id);
1219 }
1220 break;
1221
1222 case MODE_NAK: /* Treat this as a REJ, we don't vary our disc (yet) */
1223 case MODE_REJ:
1224 lcp->his_reject |= (1 << opt->hdr.id);
1225 break;
1226 }
1227 break;
1228
1229 default:
1230 sz = (sizeof desc - 2) / 2;
1231 if (sz > opt->hdr.len - 2)
1232 sz = opt->hdr.len - 2;
1233 pos = 0;
1234 desc[0] = sz ? ' ' : '\0';
1235 for (pos = 0; sz--; pos++)
1236 snprintf(desc+(pos<<1)+1, sizeof desc - ((pos<<1)+1),
1237 "%02x", opt->data[pos]);
1238
1239 log_Printf(LogLCP, "%s%s\n", request, desc);
1240
1241 if (mode_type == MODE_REQ) {
1242 fsm_rej(dec, opt);
1243 lcp->my_reject |= (1 << opt->hdr.id);
1244 }
1245 break;
1246 }
1247 }
1248
1249 if (mode_type != MODE_NOP) {
1250 if (mode_type == MODE_REQ && p && p->type == PHYS_DIRECT &&
1251 p->dl->cfg.callback.opmask && !callback_req &&
1252 !(p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_NONE))) {
1253 /* We *REQUIRE* that the peer requests callback */
1254 nak.hdr.id = TY_CALLBACK;
1255 nak.hdr.len = 3;
1256 if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) &&
1257 p->link.lcp.want_auth)
1258 nak.data[0] = CALLBACK_AUTH;
1259 else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_CBCP))
1260 nak.data[0] = CALLBACK_CBCP;
1261 else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_E164))
1262 nak.data[0] = CALLBACK_E164;
1263 else {
1264 log_Printf(LogWARN, "Cannot insist on auth callback without"
1265 " PAP or CHAP enabled !\n");
1266 nak.hdr.len = 2; /* XXX: Silly ! */
1267 }
1268 fsm_nak(dec, &nak);
1269 }
1270 if (mode_type == MODE_REQ && !lcp->mru_req) {
1271 mru = DEF_MRU;
1272 phmtu = p ? physical_DeviceMTU(p) : 0;
1273 if (phmtu && mru > phmtu)
1274 mru = phmtu;
1275 if (mru > lcp->cfg.max_mtu)
1276 mru = lcp->cfg.max_mtu;
1277 if (mru < DEF_MRU) {
1278 /* Don't let the peer use the default MRU */
1279 lcp->his_mru = lcp->cfg.mtu && lcp->cfg.mtu < mru ? lcp->cfg.mtu : mru;
1280 nak.hdr.id = TY_MRU;
1281 nak.hdr.len = 4;
1282 ua_htons(&lcp->his_mru, nak.data);
1283 fsm_nak(dec, &nak);
1284 lcp->mru_req = 1; /* Don't keep NAK'ing this */
1285 }
1286 }
1287 fsm_opt_normalise(dec);
1288 }
1289 }
1290
1291 extern struct mbuf *
lcp_Input(struct bundle * bundle,struct link * l,struct mbuf * bp)1292 lcp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
1293 {
1294 /* Got PROTO_LCP from link */
1295 m_settype(bp, MB_LCPIN);
1296 fsm_Input(&l->lcp.fsm, bp);
1297 return NULL;
1298 }
1299