xref: /freebsd/usr.sbin/ppp/lcp.c (revision cfd6422a5217410fbd66f7a7a8a64d9d85e61229)
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 */
86 struct lqrreq {
87   struct fsm_opt_hdr hdr;
88   u_short proto;		/* Quality protocol */
89   u_int32_t period;		/* Reporting interval */
90 };
91 
92 static int LcpLayerUp(struct fsm *);
93 static void LcpLayerDown(struct fsm *);
94 static void LcpLayerStart(struct fsm *);
95 static void LcpLayerFinish(struct fsm *);
96 static void LcpInitRestartCounter(struct fsm *, int);
97 static void LcpSendConfigReq(struct fsm *);
98 static void LcpSentTerminateReq(struct fsm *);
99 static void LcpSendTerminateAck(struct fsm *, u_char);
100 static void LcpDecodeConfig(struct fsm *, u_char *, u_char *, int,
101                             struct fsm_decode *);
102 
103 static struct fsm_callbacks lcp_Callbacks = {
104   LcpLayerUp,
105   LcpLayerDown,
106   LcpLayerStart,
107   LcpLayerFinish,
108   LcpInitRestartCounter,
109   LcpSendConfigReq,
110   LcpSentTerminateReq,
111   LcpSendTerminateAck,
112   LcpDecodeConfig,
113   fsm_NullRecvResetReq,
114   fsm_NullRecvResetAck
115 };
116 
117 static const char * const lcp_TimerNames[] =
118   {"LCP restart", "LCP openmode", "LCP stopped"};
119 
120 static const char *
121 protoname(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 
157 int
158 lcp_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 
233 static u_int32_t
234 GenerateMagic(void)
235 {
236   /* Generate random number which will be used as magic number */
237   randinit();
238   return random();
239 }
240 
241 void
242 lcp_SetupCallbacks(struct lcp *lcp)
243 {
244   lcp->fsm.fn = &lcp_Callbacks;
245   lcp->fsm.FsmTimer.name = lcp_TimerNames[0];
246   lcp->fsm.OpenTimer.name = lcp_TimerNames[1];
247   lcp->fsm.StoppedTimer.name = lcp_TimerNames[2];
248 }
249 
250 void
251 lcp_Init(struct lcp *lcp, struct bundle *bundle, struct link *l,
252          const struct fsm_parent *parent)
253 {
254   /* Initialise ourselves */
255   int mincode = parent ? 1 : LCP_MINMPCODE;
256 
257   fsm_Init(&lcp->fsm, "LCP", PROTO_LCP, mincode, LCP_MAXCODE, LogLCP,
258            bundle, l, parent, &lcp_Callbacks, lcp_TimerNames);
259 
260   lcp->cfg.mru = 0;
261   lcp->cfg.max_mru = MAX_MRU;
262   lcp->cfg.mtu = 0;
263   lcp->cfg.max_mtu = MAX_MTU;
264   lcp->cfg.accmap = 0;
265   lcp->cfg.openmode = 1;
266   lcp->cfg.lqrperiod = DEF_LQRPERIOD;
267   lcp->cfg.fsm.timeout = DEF_FSMRETRY;
268   lcp->cfg.fsm.maxreq = DEF_FSMTRIES;
269   lcp->cfg.fsm.maxtrm = DEF_FSMTRIES;
270 
271   lcp->cfg.acfcomp = NEG_ENABLED|NEG_ACCEPTED;
272   lcp->cfg.chap05 = NEG_ACCEPTED;
273 #ifndef NODES
274   lcp->cfg.chap80nt = NEG_ACCEPTED;
275   lcp->cfg.chap80lm = 0;
276   lcp->cfg.chap81 = NEG_ACCEPTED;
277 #endif
278   lcp->cfg.lqr = NEG_ACCEPTED;
279   lcp->cfg.echo = 0;
280   lcp->cfg.pap = NEG_ACCEPTED;
281   lcp->cfg.protocomp = NEG_ENABLED|NEG_ACCEPTED;
282   *lcp->cfg.ident = '\0';
283 
284   lcp_Setup(lcp, lcp->cfg.openmode);
285 }
286 
287 void
288 lcp_Setup(struct lcp *lcp, int openmode)
289 {
290   struct physical *p = link2physical(lcp->fsm.link);
291 
292   lcp->fsm.open_mode = openmode;
293 
294   lcp->his_mru = DEF_MRU;
295   lcp->his_mrru = 0;
296   lcp->his_magic = 0;
297   lcp->his_lqrperiod = 0;
298   lcp->his_acfcomp = 0;
299   lcp->his_auth = 0;
300   lcp->his_authtype = 0;
301   lcp->his_callback.opmask = 0;
302   lcp->his_shortseq = 0;
303   lcp->mru_req = 0;
304 
305   if ((lcp->want_mru = lcp->cfg.mru) == 0)
306     lcp->want_mru = DEF_MRU;
307   lcp->want_mrru = lcp->fsm.bundle->ncp.mp.cfg.mrru;
308   lcp->want_shortseq = IsEnabled(lcp->fsm.bundle->ncp.mp.cfg.shortseq) ? 1 : 0;
309   lcp->want_acfcomp = IsEnabled(lcp->cfg.acfcomp) ? 1 : 0;
310 
311   if (lcp->fsm.parent) {
312     lcp->his_accmap = 0xffffffff;
313     lcp->want_accmap = lcp->cfg.accmap;
314     lcp->his_protocomp = 0;
315     lcp->want_protocomp = IsEnabled(lcp->cfg.protocomp) ? 1 : 0;
316     lcp->want_magic = GenerateMagic();
317 
318     if (IsEnabled(lcp->cfg.chap05)) {
319       lcp->want_auth = PROTO_CHAP;
320       lcp->want_authtype = 0x05;
321 #ifndef NODES
322     } else if (IsEnabled(lcp->cfg.chap80nt) ||
323                IsEnabled(lcp->cfg.chap80lm)) {
324       lcp->want_auth = PROTO_CHAP;
325       lcp->want_authtype = 0x80;
326     } else if (IsEnabled(lcp->cfg.chap81)) {
327       lcp->want_auth = PROTO_CHAP;
328       lcp->want_authtype = 0x81;
329 #endif
330     } else if (IsEnabled(lcp->cfg.pap)) {
331       lcp->want_auth = PROTO_PAP;
332       lcp->want_authtype = 0;
333     } else {
334       lcp->want_auth = 0;
335       lcp->want_authtype = 0;
336     }
337 
338     if (p->type != PHYS_DIRECT)
339       memcpy(&lcp->want_callback, &p->dl->cfg.callback,
340              sizeof(struct callback));
341     else
342       lcp->want_callback.opmask = 0;
343     lcp->want_lqrperiod = IsEnabled(lcp->cfg.lqr) ?
344                           lcp->cfg.lqrperiod * 100 : 0;
345   } else {
346     lcp->his_accmap = lcp->want_accmap = 0;
347     lcp->his_protocomp = lcp->want_protocomp = 1;
348     lcp->want_magic = 0;
349     lcp->want_auth = 0;
350     lcp->want_authtype = 0;
351     lcp->want_callback.opmask = 0;
352     lcp->want_lqrperiod = 0;
353   }
354 
355   lcp->his_reject = lcp->my_reject = 0;
356   lcp->auth_iwait = lcp->auth_ineed = 0;
357   lcp->LcpFailedMagic = 0;
358 }
359 
360 static void
361 LcpInitRestartCounter(struct fsm *fp, int what)
362 {
363   /* Set fsm timer load */
364   struct lcp *lcp = fsm2lcp(fp);
365 
366   fp->FsmTimer.load = lcp->cfg.fsm.timeout * SECTICKS;
367   switch (what) {
368     case FSM_REQ_TIMER:
369       fp->restart = lcp->cfg.fsm.maxreq;
370       break;
371     case FSM_TRM_TIMER:
372       fp->restart = lcp->cfg.fsm.maxtrm;
373       break;
374     default:
375       fp->restart = 1;
376       break;
377   }
378 }
379 
380 static void
381 LcpSendConfigReq(struct fsm *fp)
382 {
383   /* Send config REQ please */
384   struct physical *p = link2physical(fp->link);
385   struct lcp *lcp = fsm2lcp(fp);
386   u_char buff[200];
387   struct fsm_opt *o;
388   struct mp *mp;
389   u_int16_t proto;
390   u_short maxmru;
391 
392   if (!p) {
393     log_Printf(LogERROR, "%s: LcpSendConfigReq: Not a physical link !\n",
394               fp->link->name);
395     return;
396   }
397 
398   o = (struct fsm_opt *)buff;
399   if (!physical_IsSync(p)) {
400     if (lcp->want_acfcomp && !REJECTED(lcp, TY_ACFCOMP))
401       INC_FSM_OPT(TY_ACFCOMP, 2, o);
402 
403     if (lcp->want_protocomp && !REJECTED(lcp, TY_PROTOCOMP))
404       INC_FSM_OPT(TY_PROTOCOMP, 2, o);
405 
406     if (!REJECTED(lcp, TY_ACCMAP)) {
407       ua_htonl(&lcp->want_accmap, o->data);
408       INC_FSM_OPT(TY_ACCMAP, 6, o);
409     }
410   }
411 
412   maxmru = p ? physical_DeviceMTU(p) : 0;
413   if (lcp->cfg.max_mru && (!maxmru || maxmru > lcp->cfg.max_mru))
414     maxmru = lcp->cfg.max_mru;
415   if (maxmru && lcp->want_mru > maxmru) {
416     log_Printf(LogWARN, "%s: Reducing configured MRU from %u to %u\n",
417                fp->link->name, lcp->want_mru, maxmru);
418     lcp->want_mru = maxmru;
419   }
420   if (!REJECTED(lcp, TY_MRU)) {
421     ua_htons(&lcp->want_mru, o->data);
422     INC_FSM_OPT(TY_MRU, 4, o);
423   }
424 
425   if (lcp->want_magic && !REJECTED(lcp, TY_MAGICNUM)) {
426     ua_htonl(&lcp->want_magic, o->data);
427     INC_FSM_OPT(TY_MAGICNUM, 6, o);
428   }
429 
430   if (lcp->want_lqrperiod && !REJECTED(lcp, TY_QUALPROTO)) {
431     proto = PROTO_LQR;
432     ua_htons(&proto, o->data);
433     ua_htonl(&lcp->want_lqrperiod, o->data + 2);
434     INC_FSM_OPT(TY_QUALPROTO, 8, o);
435   }
436 
437   switch (lcp->want_auth) {
438   case PROTO_PAP:
439     proto = PROTO_PAP;
440     ua_htons(&proto, o->data);
441     INC_FSM_OPT(TY_AUTHPROTO, 4, o);
442     break;
443 
444   case PROTO_CHAP:
445     proto = PROTO_CHAP;
446     ua_htons(&proto, o->data);
447     o->data[2] = lcp->want_authtype;
448     INC_FSM_OPT(TY_AUTHPROTO, 5, o);
449     break;
450   }
451 
452   if (!REJECTED(lcp, TY_CALLBACK)) {
453     if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) {
454       *o->data = CALLBACK_AUTH;
455       INC_FSM_OPT(TY_CALLBACK, 3, o);
456     } else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) {
457       *o->data = CALLBACK_CBCP;
458       INC_FSM_OPT(TY_CALLBACK, 3, o);
459     } else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_E164)) {
460       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 
493 void
494 lcp_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 
501 int
502 lcp_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 
529 void
530 lcp_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 
536 static void
537 LcpSentTerminateReq(struct fsm *fp __unused)
538 {
539   /* Term REQ just sent by FSM */
540 }
541 
542 static void
543 LcpSendTerminateAck(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 
554 static void
555 LcpLayerStart(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 
566 static void
567 LcpLayerFinish(struct fsm *fp)
568 {
569   /* We're now down */
570   log_Printf(LogLCP, "%s: LayerFinish\n", fp->link->name);
571 }
572 
573 static int
574 LcpLayerUp(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 
591 static void
592 LcpLayerDown(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 
603 static int
604 E164ok(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 
622 static int
623 lcp_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 
660 static void
661 LcpDecodeConfig(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 
1300 extern struct mbuf *
1301 lcp_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