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