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 * $FreeBSD: src/usr.sbin/ppp/lcp.c,v 1.110.14.1 2010/12/21 17:10:29 kensmith 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/* for received LQRs */
84struct lqrreq {
85  struct fsm_opt_hdr hdr;
86  u_short proto;		/* Quality protocol */
87  u_int32_t period;		/* Reporting interval */
88};
89
90static int LcpLayerUp(struct fsm *);
91static void LcpLayerDown(struct fsm *);
92static void LcpLayerStart(struct fsm *);
93static void LcpLayerFinish(struct fsm *);
94static void LcpInitRestartCounter(struct fsm *, int);
95static void LcpSendConfigReq(struct fsm *);
96static void LcpSentTerminateReq(struct fsm *);
97static void LcpSendTerminateAck(struct fsm *, u_char);
98static void LcpDecodeConfig(struct fsm *, u_char *, u_char *, int,
99                            struct fsm_decode *);
100
101static 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
115static const char * const lcp_TimerNames[] =
116  {"LCP restart", "LCP openmode", "LCP stopped"};
117
118static const char *
119protoname(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
155int
156lcp_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
231static u_int32_t
232GenerateMagic(void)
233{
234  /* Generate random number which will be used as magic number */
235  randinit();
236  return random();
237}
238
239void
240lcp_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
248void
249lcp_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
285void
286lcp_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
358static void
359LcpInitRestartCounter(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
378static void
379LcpSendConfigReq(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
491void
492lcp_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
499int
500lcp_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
527void
528lcp_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
534static void
535LcpSentTerminateReq(struct fsm *fp __unused)
536{
537  /* Term REQ just sent by FSM */
538}
539
540static void
541LcpSendTerminateAck(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
552static void
553LcpLayerStart(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
564static void
565LcpLayerFinish(struct fsm *fp)
566{
567  /* We're now down */
568  log_Printf(LogLCP, "%s: LayerFinish\n", fp->link->name);
569}
570
571static int
572LcpLayerUp(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
589static void
590LcpLayerDown(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
601static int
602E164ok(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
620static int
621lcp_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
658static void
659LcpDecodeConfig(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
1298extern struct mbuf *
1299lcp_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