1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
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 * $FreeBSD$
31 */
32
33#include <sys/param.h>
34#include <netinet/in.h>
35#include <netinet/in_systm.h>
36#include <netinet/ip.h>
37#include <sys/socket.h>
38#include <sys/un.h>
39
40#include <signal.h>
41#include <stdarg.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <string.h>
45#include <termios.h>
46#include <unistd.h>
47
48#include "layer.h"
49#include "ua.h"
50#include "defs.h"
51#include "command.h"
52#include "mbuf.h"
53#include "log.h"
54#include "timer.h"
55#include "fsm.h"
56#include "iplist.h"
57#include "throughput.h"
58#include "proto.h"
59#include "descriptor.h"
60#include "lqr.h"
61#include "hdlc.h"
62#include "lcp.h"
63#include "ccp.h"
64#include "async.h"
65#include "link.h"
66#include "physical.h"
67#include "prompt.h"
68#include "slcompress.h"
69#include "ncpaddr.h"
70#include "ipcp.h"
71#include "filter.h"
72#include "mp.h"
73#include "chat.h"
74#include "auth.h"
75#include "chap.h"
76#include "cbcp.h"
77#include "datalink.h"
78#ifndef NORADIUS
79#include "radius.h"
80#endif
81#include "ipv6cp.h"
82#include "ncp.h"
83#include "bundle.h"
84
85/* for received LQRs */
86struct lqrreq {
87  struct fsm_opt_hdr hdr;
88  u_short proto;		/* Quality protocol */
89  u_int32_t period;		/* Reporting interval */
90};
91
92static int LcpLayerUp(struct fsm *);
93static void LcpLayerDown(struct fsm *);
94static void LcpLayerStart(struct fsm *);
95static void LcpLayerFinish(struct fsm *);
96static void LcpInitRestartCounter(struct fsm *, int);
97static void LcpSendConfigReq(struct fsm *);
98static void LcpSentTerminateReq(struct fsm *);
99static void LcpSendTerminateAck(struct fsm *, u_char);
100static void LcpDecodeConfig(struct fsm *, u_char *, u_char *, int,
101                            struct fsm_decode *);
102
103static 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
117static const char * const lcp_TimerNames[] =
118  {"LCP restart", "LCP openmode", "LCP stopped"};
119
120static const char *
121protoname(unsigned 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 > sizeof cftypes / sizeof *cftypes || cftypes[proto] == NULL)
152    return HexStr(proto, NULL, 0);
153
154  return cftypes[proto];
155}
156
157int
158lcp_ReportStatus(struct cmdargs const *arg)
159{
160  struct link *l;
161  struct lcp *lcp;
162
163  l = command_ChooseLink(arg);
164  lcp = &l->lcp;
165
166  prompt_Printf(arg->prompt, "%s: %s [%s]\n", l->name, lcp->fsm.name,
167                State2Nam(lcp->fsm.state));
168  prompt_Printf(arg->prompt,
169                " his side: MRU %d, ACCMAP %08lx, PROTOCOMP %s, ACFCOMP %s,\n"
170                "           MAGIC %08lx, MRRU %u, SHORTSEQ %s, REJECT %04x\n",
171                lcp->his_mru, (u_long)lcp->his_accmap,
172                lcp->his_protocomp ? "on" : "off",
173                lcp->his_acfcomp ? "on" : "off",
174                (u_long)lcp->his_magic, lcp->his_mrru,
175                lcp->his_shortseq ? "on" : "off", lcp->his_reject);
176  prompt_Printf(arg->prompt,
177                " my  side: MRU %d, ACCMAP %08lx, PROTOCOMP %s, ACFCOMP %s,\n"
178                "           MAGIC %08lx, MRRU %u, SHORTSEQ %s, REJECT %04x\n",
179                lcp->want_mru, (u_long)lcp->want_accmap,
180                lcp->want_protocomp ? "on" : "off",
181                lcp->want_acfcomp ? "on" : "off",
182                (u_long)lcp->want_magic, lcp->want_mrru,
183                lcp->want_shortseq ? "on" : "off", lcp->my_reject);
184
185  if (lcp->cfg.mru)
186    prompt_Printf(arg->prompt, "\n Defaults: MRU = %d (max %d), ",
187                  lcp->cfg.mru, lcp->cfg.max_mru);
188  else
189    prompt_Printf(arg->prompt, "\n Defaults: MRU = any (max %d), ",
190                  lcp->cfg.max_mru);
191  if (lcp->cfg.mtu)
192    prompt_Printf(arg->prompt, "MTU = %d (max %d), ",
193                  lcp->cfg.mtu, lcp->cfg.max_mtu);
194  else
195    prompt_Printf(arg->prompt, "MTU = any (max %d), ", lcp->cfg.max_mtu);
196  prompt_Printf(arg->prompt, "ACCMAP = %08lx\n", (u_long)lcp->cfg.accmap);
197  prompt_Printf(arg->prompt, "           LQR period = %us, ",
198                lcp->cfg.lqrperiod);
199  prompt_Printf(arg->prompt, "Open Mode = %s",
200                lcp->cfg.openmode == OPEN_PASSIVE ? "passive" : "active");
201  if (lcp->cfg.openmode > 0)
202    prompt_Printf(arg->prompt, " (delay %ds)", lcp->cfg.openmode);
203  prompt_Printf(arg->prompt, "\n           FSM retry = %us, max %u Config"
204                " REQ%s, %u Term REQ%s\n", lcp->cfg.fsm.timeout,
205                lcp->cfg.fsm.maxreq, lcp->cfg.fsm.maxreq == 1 ? "" : "s",
206                lcp->cfg.fsm.maxtrm, lcp->cfg.fsm.maxtrm == 1 ? "" : "s");
207  prompt_Printf(arg->prompt, "    Ident: %s\n", lcp->cfg.ident);
208  prompt_Printf(arg->prompt, "\n Negotiation:\n");
209  prompt_Printf(arg->prompt, "           ACFCOMP =   %s\n",
210                command_ShowNegval(lcp->cfg.acfcomp));
211  prompt_Printf(arg->prompt, "           CHAP =      %s\n",
212                command_ShowNegval(lcp->cfg.chap05));
213#ifndef NODES
214  prompt_Printf(arg->prompt, "           CHAP80 =    %s\n",
215                command_ShowNegval(lcp->cfg.chap80nt));
216  prompt_Printf(arg->prompt, "           LANMan =    %s\n",
217                command_ShowNegval(lcp->cfg.chap80lm));
218  prompt_Printf(arg->prompt, "           CHAP81 =    %s\n",
219                command_ShowNegval(lcp->cfg.chap81));
220#endif
221  prompt_Printf(arg->prompt, "           LQR =       %s\n",
222                command_ShowNegval(lcp->cfg.lqr));
223  prompt_Printf(arg->prompt, "           LCP ECHO =  %s\n",
224                lcp->cfg.echo ? "enabled" : "disabled");
225  prompt_Printf(arg->prompt, "           PAP =       %s\n",
226                command_ShowNegval(lcp->cfg.pap));
227  prompt_Printf(arg->prompt, "           PROTOCOMP = %s\n",
228                command_ShowNegval(lcp->cfg.protocomp));
229
230  return 0;
231}
232
233static u_int32_t
234GenerateMagic(void)
235{
236  /* Generate random number which will be used as magic number */
237  randinit();
238  return random();
239}
240
241void
242lcp_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
250void
251lcp_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
287void
288lcp_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
360static void
361LcpInitRestartCounter(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
380static void
381LcpSendConfigReq(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      size_t 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 %zu octets (oops!)\n",
465	    sz);
466      }
467      *o->data = CALLBACK_E164;
468      memcpy(o->data + 1, lcp->want_callback.msg, sz);
469      INC_FSM_OPT(TY_CALLBACK, sz + 3, o);
470    }
471  }
472
473  if (lcp->want_mrru && !REJECTED(lcp, TY_MRRU)) {
474    ua_htons(&lcp->want_mrru, o->data);
475    INC_FSM_OPT(TY_MRRU, 4, o);
476
477    if (lcp->want_shortseq && !REJECTED(lcp, TY_SHORTSEQ))
478      INC_FSM_OPT(TY_SHORTSEQ, 2, o);
479  }
480
481  mp = &lcp->fsm.bundle->ncp.mp;
482  if (mp->cfg.enddisc.class != 0 && IsEnabled(mp->cfg.negenddisc) &&
483      !REJECTED(lcp, TY_ENDDISC)) {
484    *o->data = mp->cfg.enddisc.class;
485    memcpy(o->data+1, mp->cfg.enddisc.address, mp->cfg.enddisc.len);
486    INC_FSM_OPT(TY_ENDDISC, mp->cfg.enddisc.len + 3, o);
487  }
488
489  fsm_Output(fp, CODE_CONFIGREQ, fp->reqid, buff, (u_char *)o - buff,
490             MB_LCPOUT);
491}
492
493void
494lcp_SendProtoRej(struct lcp *lcp, u_char *option, int count)
495{
496  /* Don't understand `option' */
497  fsm_Output(&lcp->fsm, CODE_PROTOREJ, lcp->fsm.reqid, option, count,
498             MB_LCPOUT);
499}
500
501int
502lcp_SendIdentification(struct lcp *lcp)
503{
504  static u_char id;		/* Use a private id */
505  u_char msg[DEF_MRU - 3];
506  const char *argv[2];
507  char *exp[2];
508
509  if (*lcp->cfg.ident == '\0')
510    return 0;
511
512  argv[0] = lcp->cfg.ident;
513  argv[1] = NULL;
514
515  command_Expand(exp, 1, argv, lcp->fsm.bundle, 1, getpid());
516
517  ua_htonl(&lcp->want_magic, msg);
518  strncpy(msg + 4, exp[0], sizeof msg - 5);
519  msg[sizeof msg - 1] = '\0';
520
521  fsm_Output(&lcp->fsm, CODE_IDENT, id++, msg, 4 + strlen(msg + 4), MB_LCPOUT);
522  log_Printf(LogLCP, " MAGICNUM %08x\n", lcp->want_magic);
523  log_Printf(LogLCP, " TEXT %s\n", msg + 4);
524
525  command_Free(1, exp);
526  return 1;
527}
528
529void
530lcp_RecvIdentification(struct lcp *lcp, char *data)
531{
532  log_Printf(LogLCP, " MAGICNUM %08x\n", lcp->his_magic);
533  log_Printf(LogLCP, " TEXT %s\n", data);
534}
535
536static void
537LcpSentTerminateReq(struct fsm *fp __unused)
538{
539  /* Term REQ just sent by FSM */
540}
541
542static void
543LcpSendTerminateAck(struct fsm *fp, u_char id)
544{
545  /* Send Term ACK please */
546  struct physical *p = link2physical(fp->link);
547
548  if (p && p->dl->state == DATALINK_CBCP)
549    cbcp_ReceiveTerminateReq(p);
550
551  fsm_Output(fp, CODE_TERMACK, id, NULL, 0, MB_LCPOUT);
552}
553
554static void
555LcpLayerStart(struct fsm *fp)
556{
557  /* We're about to start up ! */
558  struct lcp *lcp = fsm2lcp(fp);
559
560  log_Printf(LogLCP, "%s: LayerStart\n", fp->link->name);
561  lcp->LcpFailedMagic = 0;
562  fp->more.reqs = fp->more.naks = fp->more.rejs = lcp->cfg.fsm.maxreq * 3;
563  lcp->mru_req = 0;
564}
565
566static void
567LcpLayerFinish(struct fsm *fp)
568{
569  /* We're now down */
570  log_Printf(LogLCP, "%s: LayerFinish\n", fp->link->name);
571}
572
573static int
574LcpLayerUp(struct fsm *fp)
575{
576  /* We're now up */
577  struct physical *p = link2physical(fp->link);
578  struct lcp *lcp = fsm2lcp(fp);
579
580  log_Printf(LogLCP, "%s: LayerUp\n", fp->link->name);
581  physical_SetAsyncParams(p, lcp->want_accmap, lcp->his_accmap);
582  lqr_Start(lcp);
583  hdlc_StartTimer(&p->hdlc);
584  fp->more.reqs = fp->more.naks = fp->more.rejs = lcp->cfg.fsm.maxreq * 3;
585
586  lcp_SendIdentification(lcp);
587
588  return 1;
589}
590
591static void
592LcpLayerDown(struct fsm *fp)
593{
594  /* About to come down */
595  struct physical *p = link2physical(fp->link);
596
597  log_Printf(LogLCP, "%s: LayerDown\n", fp->link->name);
598  hdlc_StopTimer(&p->hdlc);
599  lqr_StopTimer(p);
600  lcp_Setup(fsm2lcp(fp), 0);
601}
602
603static int
604E164ok(struct callback *cb, char *req, int sz)
605{
606  char list[sizeof cb->msg], *next;
607  int len;
608
609  if (!strcmp(cb->msg, "*"))
610    return 1;
611
612  strncpy(list, cb->msg, sizeof list - 1);
613  list[sizeof list - 1] = '\0';
614  for (next = strtok(list, ","); next; next = strtok(NULL, ",")) {
615    len = strlen(next);
616    if (sz == len && !memcmp(list, req, sz))
617      return 1;
618  }
619  return 0;
620}
621
622static int
623lcp_auth_nak(struct lcp *lcp, struct fsm_decode *dec)
624{
625  struct fsm_opt nak;
626
627  nak.hdr.id = TY_AUTHPROTO;
628
629  if (IsAccepted(lcp->cfg.pap)) {
630    nak.hdr.len = 4;
631    nak.data[0] = (unsigned char)(PROTO_PAP >> 8);
632    nak.data[1] = (unsigned char)PROTO_PAP;
633    fsm_nak(dec, &nak);
634    return 1;
635  }
636
637  nak.hdr.len = 5;
638  nak.data[0] = (unsigned char)(PROTO_CHAP >> 8);
639  nak.data[1] = (unsigned char)PROTO_CHAP;
640
641  if (IsAccepted(lcp->cfg.chap05)) {
642    nak.data[2] = 0x05;
643    fsm_nak(dec, &nak);
644#ifndef NODES
645  } else if (IsAccepted(lcp->cfg.chap80nt) ||
646             IsAccepted(lcp->cfg.chap80lm)) {
647    nak.data[2] = 0x80;
648    fsm_nak(dec, &nak);
649  } else if (IsAccepted(lcp->cfg.chap81)) {
650    nak.data[2] = 0x81;
651    fsm_nak(dec, &nak);
652#endif
653  } else {
654    return 0;
655  }
656
657  return 1;
658}
659
660static void
661LcpDecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type,
662                struct fsm_decode *dec)
663{
664  /* Deal with incoming PROTO_LCP */
665  struct lcp *lcp = fsm2lcp(fp);
666  int pos, op, callback_req, chap_type;
667  size_t sz;
668  u_int32_t magic, accmap;
669  u_short mru, phmtu, maxmtu, maxmru, wantmtu, wantmru, proto;
670  struct lqrreq req;
671  char request[20], desc[22];
672  struct mp *mp;
673  struct physical *p = link2physical(fp->link);
674  struct fsm_opt *opt, nak;
675
676  sz = 0;
677  op = callback_req = 0;
678
679  while (end - cp >= (int)sizeof(opt->hdr)) {
680    if ((opt = fsm_readopt(&cp)) == NULL)
681      break;
682
683    snprintf(request, sizeof request, " %s[%d]", protoname(opt->hdr.id),
684             opt->hdr.len);
685
686    switch (opt->hdr.id) {
687    case TY_MRRU:
688      mp = &lcp->fsm.bundle->ncp.mp;
689      ua_ntohs(opt->data, &mru);
690      log_Printf(LogLCP, "%s %u\n", request, mru);
691
692      switch (mode_type) {
693      case MODE_REQ:
694        if (mp->cfg.mrru) {
695          if (REJECTED(lcp, TY_MRRU))
696            /* Ignore his previous reject so that we REQ next time */
697            lcp->his_reject &= ~(1 << opt->hdr.id);
698
699          if (mru > MAX_MRU) {
700            /* Push him down to MAX_MRU */
701            lcp->his_mrru = MAX_MRU;
702            nak.hdr.id = TY_MRRU;
703            nak.hdr.len = 4;
704            ua_htons(&lcp->his_mrru, nak.data);
705            fsm_nak(dec, &nak);
706          } else if (mru < MIN_MRU) {
707            /* Push him up to MIN_MRU */
708            lcp->his_mrru = MIN_MRU;
709            nak.hdr.id = TY_MRRU;
710            nak.hdr.len = 4;
711            ua_htons(&lcp->his_mrru, nak.data);
712            fsm_nak(dec, &nak);
713          } else {
714            lcp->his_mrru = mru;
715            fsm_ack(dec, opt);
716          }
717          break;
718        } else {
719          fsm_rej(dec, opt);
720          lcp->my_reject |= (1 << opt->hdr.id);
721        }
722        break;
723      case MODE_NAK:
724        if (mp->cfg.mrru) {
725          if (REJECTED(lcp, TY_MRRU))
726            /* Must have changed his mind ! */
727            lcp->his_reject &= ~(1 << opt->hdr.id);
728
729          if (mru > MAX_MRU)
730            lcp->want_mrru = MAX_MRU;
731          else if (mru < MIN_MRU)
732            lcp->want_mrru = MIN_MRU;
733          else
734            lcp->want_mrru = mru;
735        }
736        /* else we honour our config and don't send the suggested REQ */
737        break;
738      case MODE_REJ:
739        lcp->his_reject |= (1 << opt->hdr.id);
740        lcp->want_mrru = 0;		/* Ah well, no multilink :-( */
741        break;
742      }
743      break;
744
745    case TY_MRU:
746      lcp->mru_req = 1;
747      ua_ntohs(opt->data, &mru);
748      log_Printf(LogLCP, "%s %d\n", request, mru);
749
750      switch (mode_type) {
751      case MODE_REQ:
752        maxmtu = p ? physical_DeviceMTU(p) : 0;
753        if (lcp->cfg.max_mtu && (!maxmtu || maxmtu > lcp->cfg.max_mtu))
754          maxmtu = lcp->cfg.max_mtu;
755        wantmtu = lcp->cfg.mtu;
756        if (maxmtu && wantmtu > maxmtu) {
757          log_Printf(LogWARN, "%s: Reducing configured MTU from %u to %u\n",
758                     fp->link->name, wantmtu, maxmtu);
759          wantmtu = maxmtu;
760        }
761
762        if (maxmtu && mru > maxmtu) {
763          lcp->his_mru = maxmtu;
764          nak.hdr.id = TY_MRU;
765          nak.hdr.len = 4;
766          ua_htons(&lcp->his_mru, nak.data);
767          fsm_nak(dec, &nak);
768        } else if (wantmtu && mru < wantmtu) {
769          /* Push him up to MTU or MIN_MRU */
770          lcp->his_mru = wantmtu;
771          nak.hdr.id = TY_MRU;
772          nak.hdr.len = 4;
773          ua_htons(&lcp->his_mru, nak.data);
774          fsm_nak(dec, &nak);
775        } else {
776          lcp->his_mru = mru;
777          fsm_ack(dec, opt);
778        }
779        break;
780      case MODE_NAK:
781        maxmru = p ? physical_DeviceMTU(p) : 0;
782        if (lcp->cfg.max_mru && (!maxmru || maxmru > lcp->cfg.max_mru))
783          maxmru = lcp->cfg.max_mru;
784        wantmru = lcp->cfg.mru > maxmru ? maxmru : lcp->cfg.mru;
785
786        if (wantmru && mru > wantmru)
787          lcp->want_mru = wantmru;
788        else if (mru > maxmru)
789          lcp->want_mru = maxmru;
790        else if (mru < MIN_MRU)
791          lcp->want_mru = MIN_MRU;
792        else
793          lcp->want_mru = mru;
794        break;
795      case MODE_REJ:
796        lcp->his_reject |= (1 << opt->hdr.id);
797        /* Set the MTU to what we want anyway - the peer won't care! */
798        if (lcp->his_mru > lcp->want_mru)
799          lcp->his_mru = lcp->want_mru;
800        break;
801      }
802      break;
803
804    case TY_ACCMAP:
805      ua_ntohl(opt->data, &accmap);
806      log_Printf(LogLCP, "%s 0x%08lx\n", request, (u_long)accmap);
807
808      switch (mode_type) {
809      case MODE_REQ:
810        lcp->his_accmap = accmap;
811        fsm_ack(dec, opt);
812        break;
813      case MODE_NAK:
814        lcp->want_accmap = accmap;
815        break;
816      case MODE_REJ:
817        lcp->his_reject |= (1 << opt->hdr.id);
818        break;
819      }
820      break;
821
822    case TY_AUTHPROTO:
823      ua_ntohs(opt->data, &proto);
824      chap_type = opt->hdr.len == 5 ? opt->data[2] : 0;
825
826      log_Printf(LogLCP, "%s 0x%04x (%s)\n", request, proto,
827                 Auth2Nam(proto, chap_type));
828
829      switch (mode_type) {
830      case MODE_REQ:
831        switch (proto) {
832        case PROTO_PAP:
833          if (opt->hdr.len == 4 && IsAccepted(lcp->cfg.pap)) {
834            lcp->his_auth = proto;
835            lcp->his_authtype = 0;
836            fsm_ack(dec, opt);
837          } else if (!lcp_auth_nak(lcp, dec)) {
838            lcp->my_reject |= (1 << opt->hdr.id);
839            fsm_rej(dec, opt);
840          }
841          break;
842
843        case PROTO_CHAP:
844          if ((chap_type == 0x05 && IsAccepted(lcp->cfg.chap05))
845#ifndef NODES
846              || (chap_type == 0x80 && (IsAccepted(lcp->cfg.chap80nt) ||
847                                   (IsAccepted(lcp->cfg.chap80lm))))
848              || (chap_type == 0x81 && IsAccepted(lcp->cfg.chap81))
849#endif
850             ) {
851            lcp->his_auth = proto;
852            lcp->his_authtype = chap_type;
853            fsm_ack(dec, opt);
854          } else {
855#ifdef NODES
856            if (chap_type == 0x80) {
857              log_Printf(LogWARN, "CHAP 0x80 not available without DES\n");
858            } else if (chap_type == 0x81) {
859              log_Printf(LogWARN, "CHAP 0x81 not available without DES\n");
860            } else
861#endif
862            if (chap_type != 0x05)
863              log_Printf(LogWARN, "%s not supported\n",
864                         Auth2Nam(PROTO_CHAP, chap_type));
865
866            if (!lcp_auth_nak(lcp, dec)) {
867              lcp->my_reject |= (1 << opt->hdr.id);
868              fsm_rej(dec, opt);
869            }
870          }
871          break;
872
873        default:
874          log_Printf(LogLCP, "%s 0x%04x - not recognised\n",
875                    request, proto);
876          if (!lcp_auth_nak(lcp, dec)) {
877            lcp->my_reject |= (1 << opt->hdr.id);
878            fsm_rej(dec, opt);
879          }
880          break;
881        }
882        break;
883
884      case MODE_NAK:
885        switch (proto) {
886        case PROTO_PAP:
887          if (IsEnabled(lcp->cfg.pap)) {
888            lcp->want_auth = PROTO_PAP;
889            lcp->want_authtype = 0;
890          } else {
891            log_Printf(LogLCP, "Peer will only send PAP (not enabled)\n");
892            lcp->his_reject |= (1 << opt->hdr.id);
893          }
894          break;
895        case PROTO_CHAP:
896          if (chap_type == 0x05 && IsEnabled(lcp->cfg.chap05)) {
897            lcp->want_auth = PROTO_CHAP;
898            lcp->want_authtype = 0x05;
899#ifndef NODES
900          } else if (chap_type == 0x80 && (IsEnabled(lcp->cfg.chap80nt) ||
901                                           IsEnabled(lcp->cfg.chap80lm))) {
902            lcp->want_auth = PROTO_CHAP;
903            lcp->want_authtype = 0x80;
904          } else if (chap_type == 0x81 && IsEnabled(lcp->cfg.chap81)) {
905            lcp->want_auth = PROTO_CHAP;
906            lcp->want_authtype = 0x81;
907#endif
908          } else {
909#ifdef NODES
910            if (chap_type == 0x80) {
911              log_Printf(LogLCP, "Peer will only send MSCHAP (not available"
912                         " without DES)\n");
913            } else if (chap_type == 0x81) {
914              log_Printf(LogLCP, "Peer will only send MSCHAPV2 (not available"
915                         " without DES)\n");
916            } else
917#endif
918            log_Printf(LogLCP, "Peer will only send %s (not %s)\n",
919                       Auth2Nam(PROTO_CHAP, chap_type),
920#ifndef NODES
921                       (chap_type == 0x80 || chap_type == 0x81) ? "configured" :
922#endif
923                       "supported");
924            lcp->his_reject |= (1 << opt->hdr.id);
925          }
926          break;
927        default:
928          /* We've been NAK'd with something we don't understand :-( */
929          lcp->his_reject |= (1 << opt->hdr.id);
930          break;
931        }
932        break;
933
934      case MODE_REJ:
935        lcp->his_reject |= (1 << opt->hdr.id);
936        break;
937      }
938      break;
939
940    case TY_QUALPROTO:
941      memcpy(&req, opt, sizeof req);
942      log_Printf(LogLCP, "%s proto %x, interval %lums\n",
943                request, ntohs(req.proto), (u_long)ntohl(req.period) * 10);
944      switch (mode_type) {
945      case MODE_REQ:
946        if (ntohs(req.proto) != PROTO_LQR || !IsAccepted(lcp->cfg.lqr)) {
947          fsm_rej(dec, opt);
948          lcp->my_reject |= (1 << opt->hdr.id);
949        } else {
950          lcp->his_lqrperiod = ntohl(req.period);
951          if (lcp->his_lqrperiod < MIN_LQRPERIOD * 100)
952            lcp->his_lqrperiod = MIN_LQRPERIOD * 100;
953          req.period = htonl(lcp->his_lqrperiod);
954          fsm_ack(dec, opt);
955        }
956        break;
957      case MODE_NAK:
958        lcp->want_lqrperiod = ntohl(req.period);
959        break;
960      case MODE_REJ:
961        lcp->his_reject |= (1 << opt->hdr.id);
962        break;
963      }
964      break;
965
966    case TY_MAGICNUM:
967      ua_ntohl(opt->data, &magic);
968      log_Printf(LogLCP, "%s 0x%08lx\n", request, (u_long)magic);
969
970      switch (mode_type) {
971      case MODE_REQ:
972        if (lcp->want_magic) {
973          /* Validate magic number */
974          if (magic == lcp->want_magic) {
975            sigset_t emptyset;
976
977            log_Printf(LogLCP, "Magic is same (%08lx) - %d times\n",
978                      (u_long)magic, ++lcp->LcpFailedMagic);
979            lcp->want_magic = GenerateMagic();
980            fsm_nak(dec, opt);
981            ualarm(TICKUNIT * (4 + 4 * lcp->LcpFailedMagic), 0);
982            sigemptyset(&emptyset);
983            sigsuspend(&emptyset);
984          } else {
985            lcp->his_magic = magic;
986            lcp->LcpFailedMagic = 0;
987            fsm_ack(dec, opt);
988          }
989        } else {
990          lcp->my_reject |= (1 << opt->hdr.id);
991          fsm_rej(dec, opt);
992        }
993        break;
994      case MODE_NAK:
995        log_Printf(LogLCP, " Magic 0x%08lx is NAKed!\n", (u_long)magic);
996        lcp->want_magic = GenerateMagic();
997        break;
998      case MODE_REJ:
999        log_Printf(LogLCP, " Magic 0x%08x is REJected!\n", magic);
1000        lcp->want_magic = 0;
1001        lcp->his_reject |= (1 << opt->hdr.id);
1002        break;
1003      }
1004      break;
1005
1006    case TY_PROTOCOMP:
1007      log_Printf(LogLCP, "%s\n", request);
1008
1009      switch (mode_type) {
1010      case MODE_REQ:
1011        if (IsAccepted(lcp->cfg.protocomp)) {
1012          lcp->his_protocomp = 1;
1013          fsm_ack(dec, opt);
1014        } else {
1015#ifdef OLDMST
1016          /* MorningStar before v1.3 needs NAK */
1017          fsm_nak(dec, opt);
1018#else
1019          fsm_rej(dec, opt);
1020          lcp->my_reject |= (1 << opt->hdr.id);
1021#endif
1022        }
1023        break;
1024      case MODE_NAK:
1025      case MODE_REJ:
1026        lcp->want_protocomp = 0;
1027        lcp->his_reject |= (1 << opt->hdr.id);
1028        break;
1029      }
1030      break;
1031
1032    case TY_ACFCOMP:
1033      log_Printf(LogLCP, "%s\n", request);
1034      switch (mode_type) {
1035      case MODE_REQ:
1036        if (IsAccepted(lcp->cfg.acfcomp)) {
1037          lcp->his_acfcomp = 1;
1038          fsm_ack(dec, opt);
1039        } else {
1040#ifdef OLDMST
1041          /* MorningStar before v1.3 needs NAK */
1042          fsm_nak(dec, opt);
1043#else
1044          fsm_rej(dec, opt);
1045          lcp->my_reject |= (1 << opt->hdr.id);
1046#endif
1047        }
1048        break;
1049      case MODE_NAK:
1050      case MODE_REJ:
1051        lcp->want_acfcomp = 0;
1052        lcp->his_reject |= (1 << opt->hdr.id);
1053        break;
1054      }
1055      break;
1056
1057    case TY_SDP:
1058      log_Printf(LogLCP, "%s\n", request);
1059      switch (mode_type) {
1060      case MODE_REQ:
1061      case MODE_NAK:
1062      case MODE_REJ:
1063        break;
1064      }
1065      break;
1066
1067    case TY_CALLBACK:
1068      if (opt->hdr.len == 2) {
1069        op = CALLBACK_NONE;
1070        sz = 0;
1071      } else {
1072        op = (int)opt->data[0];
1073        sz = opt->hdr.len - 3;
1074      }
1075      switch (op) {
1076        case CALLBACK_AUTH:
1077          log_Printf(LogLCP, "%s Auth\n", request);
1078          break;
1079        case CALLBACK_DIALSTRING:
1080		log_Printf(LogLCP, "%s Dialstring %.*s\n", request, (int)sz,
1081                     opt->data + 1);
1082          break;
1083        case CALLBACK_LOCATION:
1084		log_Printf(LogLCP, "%s Location %.*s\n", request, (int)sz,
1085		    opt->data + 1);
1086          break;
1087        case CALLBACK_E164:
1088		log_Printf(LogLCP, "%s E.164 (%.*s)\n", request, (int)sz,
1089		    opt->data + 1);
1090          break;
1091        case CALLBACK_NAME:
1092		log_Printf(LogLCP, "%s Name %.*s\n", request, (int)sz,
1093		    opt->data + 1);
1094          break;
1095        case CALLBACK_CBCP:
1096          log_Printf(LogLCP, "%s CBCP\n", request);
1097          break;
1098        default:
1099          log_Printf(LogLCP, "%s ???\n", request);
1100          break;
1101      }
1102
1103      switch (mode_type) {
1104      case MODE_REQ:
1105        callback_req = 1;
1106        if (p->type != PHYS_DIRECT) {
1107          fsm_rej(dec, opt);
1108          lcp->my_reject |= (1 << opt->hdr.id);
1109        }
1110        nak.hdr.id = opt->hdr.id;
1111        nak.hdr.len = 3;
1112        if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(op)) &&
1113            (op != CALLBACK_AUTH || p->link.lcp.want_auth) &&
1114            (op != CALLBACK_E164 ||
1115             E164ok(&p->dl->cfg.callback, opt->data + 1, sz))) {
1116          lcp->his_callback.opmask = CALLBACK_BIT(op);
1117          if (sz > sizeof lcp->his_callback.msg - 1) {
1118            sz = sizeof lcp->his_callback.msg - 1;
1119            log_Printf(LogWARN, "Truncating option arg to %zu octets\n", sz);
1120          }
1121          memcpy(lcp->his_callback.msg, opt->data + 1, sz);
1122          lcp->his_callback.msg[sz] = '\0';
1123          fsm_ack(dec, opt);
1124        } else if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) &&
1125                    p->link.lcp.auth_ineed) {
1126          nak.data[0] = CALLBACK_AUTH;
1127          fsm_nak(dec, &nak);
1128        } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) {
1129          nak.data[0] = CALLBACK_CBCP;
1130          fsm_nak(dec, &nak);
1131        } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_E164)) {
1132          nak.data[0] = CALLBACK_E164;
1133          fsm_nak(dec, &nak);
1134        } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) {
1135          log_Printf(LogWARN, "Cannot insist on auth callback without"
1136                     " PAP or CHAP enabled !\n");
1137          nak.data[0] = 2;
1138          fsm_nak(dec, &nak);
1139        } else {
1140          lcp->my_reject |= (1 << opt->hdr.id);
1141          fsm_rej(dec, opt);
1142        }
1143        break;
1144      case MODE_NAK:
1145        /* We don't do what he NAKs with, we do things in our preferred order */
1146        if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_AUTH))
1147          lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_AUTH);
1148        else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_CBCP))
1149          lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_CBCP);
1150        else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_E164))
1151          lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_E164);
1152        if (lcp->want_callback.opmask == CALLBACK_BIT(CALLBACK_NONE)) {
1153          log_Printf(LogPHASE, "Peer NAKd all callbacks, trying none\n");
1154          lcp->want_callback.opmask = 0;
1155        } else if (!lcp->want_callback.opmask) {
1156          log_Printf(LogPHASE, "Peer NAKd last configured callback\n");
1157          fsm_Close(&lcp->fsm);
1158        }
1159        break;
1160      case MODE_REJ:
1161        if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_NONE)) {
1162          lcp->his_reject |= (1 << opt->hdr.id);
1163          lcp->want_callback.opmask = 0;
1164        } else {
1165          log_Printf(LogPHASE, "Peer rejected *required* callback\n");
1166          fsm_Close(&lcp->fsm);
1167        }
1168        break;
1169      }
1170      break;
1171
1172    case TY_SHORTSEQ:
1173      mp = &lcp->fsm.bundle->ncp.mp;
1174      log_Printf(LogLCP, "%s\n", request);
1175
1176      switch (mode_type) {
1177      case MODE_REQ:
1178        if (lcp->want_mrru && IsAccepted(mp->cfg.shortseq)) {
1179          lcp->his_shortseq = 1;
1180          fsm_ack(dec, opt);
1181        } else {
1182          fsm_rej(dec, opt);
1183          lcp->my_reject |= (1 << opt->hdr.id);
1184        }
1185        break;
1186      case MODE_NAK:
1187        /*
1188         * He's trying to get us to ask for short sequence numbers.
1189         * We ignore the NAK and honour our configuration file instead.
1190         */
1191        break;
1192      case MODE_REJ:
1193        lcp->his_reject |= (1 << opt->hdr.id);
1194        lcp->want_shortseq = 0;		/* For when we hit MP */
1195        break;
1196      }
1197      break;
1198
1199    case TY_ENDDISC:
1200      mp = &lcp->fsm.bundle->ncp.mp;
1201      log_Printf(LogLCP, "%s %s\n", request,
1202                 mp_Enddisc(opt->data[0], opt->data + 1, opt->hdr.len - 3));
1203      switch (mode_type) {
1204      case MODE_REQ:
1205        if (!p) {
1206          log_Printf(LogLCP, " ENDDISC rejected - not a physical link\n");
1207          fsm_rej(dec, opt);
1208          lcp->my_reject |= (1 << opt->hdr.id);
1209        } else if (!IsAccepted(mp->cfg.negenddisc)) {
1210          lcp->my_reject |= (1 << opt->hdr.id);
1211          fsm_rej(dec, opt);
1212        } else if (opt->hdr.len < sizeof p->dl->peer.enddisc.address + 3 &&
1213                   opt->data[0] <= MAX_ENDDISC_CLASS) {
1214          p->dl->peer.enddisc.class = opt->data[0];
1215          p->dl->peer.enddisc.len = opt->hdr.len - 3;
1216          memcpy(p->dl->peer.enddisc.address, opt->data + 1, opt->hdr.len - 3);
1217          p->dl->peer.enddisc.address[opt->hdr.len - 3] = '\0';
1218          /* XXX: If mp->active, compare and NAK with mp->peer ? */
1219          fsm_ack(dec, opt);
1220        } else {
1221          if (opt->data[0] > MAX_ENDDISC_CLASS)
1222            log_Printf(LogLCP, " ENDDISC rejected - unrecognised class %d\n",
1223                      opt->data[0]);
1224          else
1225            log_Printf(LogLCP, " ENDDISC rejected - local max length is %ld\n",
1226                      (long)(sizeof p->dl->peer.enddisc.address - 1));
1227          fsm_rej(dec, opt);
1228          lcp->my_reject |= (1 << opt->hdr.id);
1229        }
1230        break;
1231
1232      case MODE_NAK:	/* Treat this as a REJ, we don't vary our disc (yet) */
1233      case MODE_REJ:
1234        lcp->his_reject |= (1 << opt->hdr.id);
1235        break;
1236      }
1237      break;
1238
1239    default:
1240      sz = (sizeof desc - 2) / 2;
1241      if (sz + 2 > opt->hdr.len)
1242        sz = opt->hdr.len - 2;
1243      pos = 0;
1244      desc[0] = sz ? ' ' : '\0';
1245      for (pos = 0; sz--; pos++)
1246        sprintf(desc+(pos<<1)+1, "%02x", opt->data[pos]);
1247
1248      log_Printf(LogLCP, "%s%s\n", request, desc);
1249
1250      if (mode_type == MODE_REQ) {
1251        fsm_rej(dec, opt);
1252        lcp->my_reject |= (1 << opt->hdr.id);
1253      }
1254      break;
1255    }
1256  }
1257
1258  if (mode_type != MODE_NOP) {
1259    if (mode_type == MODE_REQ && p && p->type == PHYS_DIRECT &&
1260        p->dl->cfg.callback.opmask && !callback_req &&
1261        !(p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_NONE))) {
1262      /* We *REQUIRE* that the peer requests callback */
1263      nak.hdr.id = TY_CALLBACK;
1264      nak.hdr.len = 3;
1265      if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) &&
1266          p->link.lcp.want_auth)
1267        nak.data[0] = CALLBACK_AUTH;
1268      else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_CBCP))
1269        nak.data[0] = CALLBACK_CBCP;
1270      else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_E164))
1271        nak.data[0] = CALLBACK_E164;
1272      else {
1273        log_Printf(LogWARN, "Cannot insist on auth callback without"
1274                   " PAP or CHAP enabled !\n");
1275        nak.hdr.len = 2;	/* XXX: Silly ! */
1276      }
1277      fsm_nak(dec, &nak);
1278    }
1279    if (mode_type == MODE_REQ && !lcp->mru_req) {
1280      mru = DEF_MRU;
1281      phmtu = p ? physical_DeviceMTU(p) : 0;
1282      if (phmtu && mru > phmtu)
1283        mru = phmtu;
1284      if (mru > lcp->cfg.max_mtu)
1285        mru = lcp->cfg.max_mtu;
1286      if (mru < DEF_MRU) {
1287        /* Don't let the peer use the default MRU */
1288        lcp->his_mru = lcp->cfg.mtu && lcp->cfg.mtu < mru ? lcp->cfg.mtu : mru;
1289        nak.hdr.id = TY_MRU;
1290        nak.hdr.len = 4;
1291        ua_htons(&lcp->his_mru, nak.data);
1292        fsm_nak(dec, &nak);
1293        lcp->mru_req = 1;	/* Don't keep NAK'ing this */
1294      }
1295    }
1296    fsm_opt_normalise(dec);
1297  }
1298}
1299
1300extern struct mbuf *
1301lcp_Input(struct bundle *bundle __unused, struct link *l, struct mbuf *bp)
1302{
1303  /* Got PROTO_LCP from link */
1304  m_settype(bp, MB_LCPIN);
1305  fsm_Input(&l->lcp.fsm, bp);
1306  return NULL;
1307}
1308