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