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