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