2f5a5aa83df74497659935d3e5f93a2892c8f035
[dragonfly.git] / usr.sbin / ppp / lcp.c
1 /*-
2  * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org>
3  *          based on work by Toshiharu OHNO <tony-o@iij.ad.jp>
4  *                           Internet Initiative Japan, Inc (IIJ)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD: src/usr.sbin/ppp/lcp.c,v 1.81.2.13 2002/09/01 02:12:28 brian Exp $
29  * $DragonFly: src/usr.sbin/ppp/lcp.c,v 1.2 2003/06/17 04:30:00 dillon Exp $
30  */
31
32 #include <sys/param.h>
33 #include <netinet/in.h>
34 #include <netinet/in_systm.h>
35 #include <netinet/ip.h>
36 #include <sys/socket.h>
37 #include <sys/un.h>
38
39 #include <signal.h>
40 #include <stdarg.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <termios.h>
45 #include <unistd.h>
46
47 #include "layer.h"
48 #include "ua.h"
49 #include "defs.h"
50 #include "command.h"
51 #include "mbuf.h"
52 #include "log.h"
53 #include "timer.h"
54 #include "fsm.h"
55 #include "iplist.h"
56 #include "throughput.h"
57 #include "proto.h"
58 #include "descriptor.h"
59 #include "lqr.h"
60 #include "hdlc.h"
61 #include "lcp.h"
62 #include "ccp.h"
63 #include "async.h"
64 #include "link.h"
65 #include "physical.h"
66 #include "prompt.h"
67 #include "slcompress.h"
68 #include "ncpaddr.h"
69 #include "ipcp.h"
70 #include "filter.h"
71 #include "mp.h"
72 #include "chat.h"
73 #include "auth.h"
74 #include "chap.h"
75 #include "cbcp.h"
76 #include "datalink.h"
77 #ifndef NORADIUS
78 #include "radius.h"
79 #endif
80 #include "ipv6cp.h"
81 #include "ncp.h"
82 #include "bundle.h"
83
84 /* for received LQRs */
85 struct lqrreq {
86   struct fsm_opt_hdr hdr;
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 *, u_char *, 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(unsigned 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 > sizeof cftypes / sizeof *cftypes || cftypes[proto] == NULL)
151     return HexStr(proto, NULL, 0);
152
153   return cftypes[proto];
154 }
155
156 int
157 lcp_ReportStatus(struct cmdargs const *arg)
158 {
159   struct link *l;
160   struct lcp *lcp;
161
162   l = command_ChooseLink(arg);
163   lcp = &l->lcp;
164
165   prompt_Printf(arg->prompt, "%s: %s [%s]\n", l->name, lcp->fsm.name,
166                 State2Nam(lcp->fsm.state));
167   prompt_Printf(arg->prompt,
168                 " his side: MRU %d, ACCMAP %08lx, PROTOCOMP %s, ACFCOMP %s,\n"
169                 "           MAGIC %08lx, MRRU %u, SHORTSEQ %s, REJECT %04x\n",
170                 lcp->his_mru, (u_long)lcp->his_accmap,
171                 lcp->his_protocomp ? "on" : "off",
172                 lcp->his_acfcomp ? "on" : "off",
173                 (u_long)lcp->his_magic, lcp->his_mrru,
174                 lcp->his_shortseq ? "on" : "off", lcp->his_reject);
175   prompt_Printf(arg->prompt,
176                 " my  side: MRU %d, ACCMAP %08lx, PROTOCOMP %s, ACFCOMP %s,\n"
177                 "           MAGIC %08lx, MRRU %u, SHORTSEQ %s, REJECT %04x\n",
178                 lcp->want_mru, (u_long)lcp->want_accmap,
179                 lcp->want_protocomp ? "on" : "off",
180                 lcp->want_acfcomp ? "on" : "off",
181                 (u_long)lcp->want_magic, lcp->want_mrru,
182                 lcp->want_shortseq ? "on" : "off", lcp->my_reject);
183
184   if (lcp->cfg.mru)
185     prompt_Printf(arg->prompt, "\n Defaults: MRU = %d (max %d), ",
186                   lcp->cfg.mru, lcp->cfg.max_mru);
187   else
188     prompt_Printf(arg->prompt, "\n Defaults: MRU = any (max %d), ",
189                   lcp->cfg.max_mru);
190   if (lcp->cfg.mtu)
191     prompt_Printf(arg->prompt, "MTU = %d (max %d), ",
192                   lcp->cfg.mtu, lcp->cfg.max_mtu);
193   else
194     prompt_Printf(arg->prompt, "MTU = any (max %d), ", lcp->cfg.max_mtu);
195   prompt_Printf(arg->prompt, "ACCMAP = %08lx\n", (u_long)lcp->cfg.accmap);
196   prompt_Printf(arg->prompt, "           LQR period = %us, ",
197                 lcp->cfg.lqrperiod);
198   prompt_Printf(arg->prompt, "Open Mode = %s",
199                 lcp->cfg.openmode == OPEN_PASSIVE ? "passive" : "active");
200   if (lcp->cfg.openmode > 0)
201     prompt_Printf(arg->prompt, " (delay %ds)", lcp->cfg.openmode);
202   prompt_Printf(arg->prompt, "\n           FSM retry = %us, max %u Config"
203                 " REQ%s, %u Term REQ%s\n", lcp->cfg.fsm.timeout,
204                 lcp->cfg.fsm.maxreq, lcp->cfg.fsm.maxreq == 1 ? "" : "s",
205                 lcp->cfg.fsm.maxtrm, lcp->cfg.fsm.maxtrm == 1 ? "" : "s");
206   prompt_Printf(arg->prompt, "    Ident: %s\n", lcp->cfg.ident);
207   prompt_Printf(arg->prompt, "\n Negotiation:\n");
208   prompt_Printf(arg->prompt, "           ACFCOMP =   %s\n",
209                 command_ShowNegval(lcp->cfg.acfcomp));
210   prompt_Printf(arg->prompt, "           CHAP =      %s\n",
211                 command_ShowNegval(lcp->cfg.chap05));
212 #ifndef NODES
213   prompt_Printf(arg->prompt, "           CHAP80 =    %s\n",
214                 command_ShowNegval(lcp->cfg.chap80nt));
215   prompt_Printf(arg->prompt, "           LANMan =    %s\n",
216                 command_ShowNegval(lcp->cfg.chap80lm));
217   prompt_Printf(arg->prompt, "           CHAP81 =    %s\n",
218                 command_ShowNegval(lcp->cfg.chap81));
219 #endif
220   prompt_Printf(arg->prompt, "           LQR =       %s\n",
221                 command_ShowNegval(lcp->cfg.lqr));
222   prompt_Printf(arg->prompt, "           PAP =       %s\n",
223                 command_ShowNegval(lcp->cfg.pap));
224   prompt_Printf(arg->prompt, "           PROTOCOMP = %s\n",
225                 command_ShowNegval(lcp->cfg.protocomp));
226
227   return 0;
228 }
229
230 static u_int32_t
231 GenerateMagic(void)
232 {
233   /* Generate random number which will be used as magic number */
234   randinit();
235   return random();
236 }
237
238 void
239 lcp_SetupCallbacks(struct lcp *lcp)
240 {
241   lcp->fsm.fn = &lcp_Callbacks;
242   lcp->fsm.FsmTimer.name = lcp_TimerNames[0];
243   lcp->fsm.OpenTimer.name = lcp_TimerNames[1];
244   lcp->fsm.StoppedTimer.name = lcp_TimerNames[2];
245 }
246
247 void
248 lcp_Init(struct lcp *lcp, struct bundle *bundle, struct link *l,
249          const struct fsm_parent *parent)
250 {
251   /* Initialise ourselves */
252   int mincode = parent ? 1 : LCP_MINMPCODE;
253
254   fsm_Init(&lcp->fsm, "LCP", PROTO_LCP, mincode, LCP_MAXCODE, LogLCP,
255            bundle, l, parent, &lcp_Callbacks, lcp_TimerNames);
256
257   lcp->cfg.mru = 0;
258   lcp->cfg.max_mru = MAX_MRU;
259   lcp->cfg.mtu = 0;
260   lcp->cfg.max_mtu = MAX_MTU;
261   lcp->cfg.accmap = 0;
262   lcp->cfg.openmode = 1;
263   lcp->cfg.lqrperiod = DEF_LQRPERIOD;
264   lcp->cfg.fsm.timeout = DEF_FSMRETRY;
265   lcp->cfg.fsm.maxreq = DEF_FSMTRIES;
266   lcp->cfg.fsm.maxtrm = DEF_FSMTRIES;
267
268   lcp->cfg.acfcomp = NEG_ENABLED|NEG_ACCEPTED;
269   lcp->cfg.chap05 = NEG_ACCEPTED;
270 #ifndef NODES
271   lcp->cfg.chap80nt = NEG_ACCEPTED;
272   lcp->cfg.chap80lm = 0;
273   lcp->cfg.chap81 = NEG_ACCEPTED;
274 #endif
275   lcp->cfg.lqr = NEG_ACCEPTED;
276   lcp->cfg.pap = NEG_ACCEPTED;
277   lcp->cfg.protocomp = NEG_ENABLED|NEG_ACCEPTED;
278   *lcp->cfg.ident = '\0';
279
280   lcp_Setup(lcp, lcp->cfg.openmode);
281 }
282
283 void
284 lcp_Setup(struct lcp *lcp, int openmode)
285 {
286   struct physical *p = link2physical(lcp->fsm.link);
287
288   lcp->fsm.open_mode = openmode;
289
290   lcp->his_mru = DEF_MRU;
291   lcp->his_mrru = 0;
292   lcp->his_magic = 0;
293   lcp->his_lqrperiod = 0;
294   lcp->his_acfcomp = 0;
295   lcp->his_auth = 0;
296   lcp->his_authtype = 0;
297   lcp->his_callback.opmask = 0;
298   lcp->his_shortseq = 0;
299   lcp->mru_req = 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 #ifndef NODES
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 fsm_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 fsm_opt *)buff;
395   if (!physical_IsSync(p)) {
396     if (lcp->want_acfcomp && !REJECTED(lcp, TY_ACFCOMP))
397       INC_FSM_OPT(TY_ACFCOMP, 2, o);
398
399     if (lcp->want_protocomp && !REJECTED(lcp, TY_PROTOCOMP))
400       INC_FSM_OPT(TY_PROTOCOMP, 2, o);
401
402     if (!REJECTED(lcp, TY_ACCMAP)) {
403       ua_htonl(&lcp->want_accmap, o->data);
404       INC_FSM_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_FSM_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_FSM_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_FSM_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_FSM_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_FSM_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_FSM_OPT(TY_CALLBACK, 3, o);
452     } else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) {
453       *o->data = CALLBACK_CBCP;
454       INC_FSM_OPT(TY_CALLBACK, 3, o);
455     } else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_E164)) {
456       size_t 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 %zu octets (oops!)\n", sz);
461       }
462       *o->data = CALLBACK_E164;
463       memcpy(o->data + 1, lcp->want_callback.msg, sz);
464       INC_FSM_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_FSM_OPT(TY_MRRU, 4, o);
471
472     if (lcp->want_shortseq && !REJECTED(lcp, TY_SHORTSEQ))
473       INC_FSM_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_FSM_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   fsm_Output(&lcp->fsm, CODE_IDENT, id++, msg, 4 + strlen(msg + 4), MB_LCPOUT);
517   log_Printf(LogLCP, " MAGICNUM %08x\n", lcp->want_magic);
518   log_Printf(LogLCP, " TEXT %s\n", msg + 4);
519
520   command_Free(1, exp);
521   return 1;
522 }
523
524 void
525 lcp_RecvIdentification(struct lcp *lcp, char *data)
526 {
527   log_Printf(LogLCP, " MAGICNUM %08x\n", lcp->his_magic);
528   log_Printf(LogLCP, " TEXT %s\n", data);
529 }
530
531 static void
532 LcpSentTerminateReq(struct fsm *fp __unused)
533 {
534   /* Term REQ just sent by FSM */
535 }
536
537 static void
538 LcpSendTerminateAck(struct fsm *fp, u_char id)
539 {
540   /* Send Term ACK please */
541   struct physical *p = link2physical(fp->link);
542
543   if (p && p->dl->state == DATALINK_CBCP)
544     cbcp_ReceiveTerminateReq(p);
545
546   fsm_Output(fp, CODE_TERMACK, id, NULL, 0, MB_LCPOUT);
547 }
548
549 static void
550 LcpLayerStart(struct fsm *fp)
551 {
552   /* We're about to start up ! */
553   struct lcp *lcp = fsm2lcp(fp);
554
555   log_Printf(LogLCP, "%s: LayerStart\n", fp->link->name);
556   lcp->LcpFailedMagic = 0;
557   fp->more.reqs = fp->more.naks = fp->more.rejs = lcp->cfg.fsm.maxreq * 3;
558   lcp->mru_req = 0;
559 }
560
561 static void
562 LcpLayerFinish(struct fsm *fp)
563 {
564   /* We're now down */
565   log_Printf(LogLCP, "%s: LayerFinish\n", fp->link->name);
566 }
567
568 static int
569 LcpLayerUp(struct fsm *fp)
570 {
571   /* We're now up */
572   struct physical *p = link2physical(fp->link);
573   struct lcp *lcp = fsm2lcp(fp);
574
575   log_Printf(LogLCP, "%s: LayerUp\n", fp->link->name);
576   physical_SetAsyncParams(p, lcp->want_accmap, lcp->his_accmap);
577   lqr_Start(lcp);
578   hdlc_StartTimer(&p->hdlc);
579   fp->more.reqs = fp->more.naks = fp->more.rejs = lcp->cfg.fsm.maxreq * 3;
580
581   lcp_SendIdentification(lcp);
582
583   return 1;
584 }
585
586 static void
587 LcpLayerDown(struct fsm *fp)
588 {
589   /* About to come down */
590   struct physical *p = link2physical(fp->link);
591
592   log_Printf(LogLCP, "%s: LayerDown\n", fp->link->name);
593   hdlc_StopTimer(&p->hdlc);
594   lqr_StopTimer(p);
595   lcp_Setup(fsm2lcp(fp), 0);
596 }
597
598 static int
599 E164ok(struct callback *cb, char *req, int sz)
600 {
601   char list[sizeof cb->msg], *next;
602   int len;
603
604   if (!strcmp(cb->msg, "*"))
605     return 1;
606
607   strncpy(list, cb->msg, sizeof list - 1);
608   list[sizeof list - 1] = '\0';
609   for (next = strtok(list, ","); next; next = strtok(NULL, ",")) {
610     len = strlen(next);
611     if (sz == len && !memcmp(list, req, sz))
612       return 1;
613   }
614   return 0;
615 }
616
617 static int
618 lcp_auth_nak(struct lcp *lcp, struct fsm_decode *dec)
619 {
620   struct fsm_opt nak;
621
622   nak.hdr.id = TY_AUTHPROTO;
623
624   if (IsAccepted(lcp->cfg.pap)) {
625     nak.hdr.len = 4;
626     nak.data[0] = (unsigned char)(PROTO_PAP >> 8);
627     nak.data[1] = (unsigned char)PROTO_PAP;
628     fsm_nak(dec, &nak);
629     return 1;
630   }
631
632   nak.hdr.len = 5;
633   nak.data[0] = (unsigned char)(PROTO_CHAP >> 8);
634   nak.data[1] = (unsigned char)PROTO_CHAP;
635
636   if (IsAccepted(lcp->cfg.chap05)) {
637     nak.data[2] = 0x05;
638     fsm_nak(dec, &nak);
639 #ifndef NODES
640   } else if (IsAccepted(lcp->cfg.chap80nt) ||
641              IsAccepted(lcp->cfg.chap80lm)) {
642     nak.data[2] = 0x80;
643     fsm_nak(dec, &nak);
644   } else if (IsAccepted(lcp->cfg.chap81)) {
645     nak.data[2] = 0x81;
646     fsm_nak(dec, &nak);
647 #endif
648   } else {
649     return 0;
650   }
651
652   return 1;
653 }
654
655 static void
656 LcpDecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type,
657                 struct fsm_decode *dec)
658 {
659   /* Deal with incoming PROTO_LCP */
660   struct lcp *lcp = fsm2lcp(fp);
661   int pos, op, callback_req, chap_type;
662   size_t sz;
663   u_int32_t magic, accmap;
664   u_short mru, phmtu, maxmtu, maxmru, wantmtu, wantmru, proto;
665   struct lqrreq *req;
666   char request[20], desc[22];
667   struct mp *mp;
668   struct physical *p = link2physical(fp->link);
669   struct fsm_opt *opt, nak;
670
671   sz = 0;
672   op = callback_req = 0;
673
674   while (end - cp >= (int)sizeof(opt->hdr)) {
675     if ((opt = fsm_readopt(&cp)) == NULL)
676       break;
677
678     snprintf(request, sizeof request, " %s[%d]", protoname(opt->hdr.id),
679              opt->hdr.len);
680
681     switch (opt->hdr.id) {
682     case TY_MRRU:
683       mp = &lcp->fsm.bundle->ncp.mp;
684       ua_ntohs(opt->data, &mru);
685       log_Printf(LogLCP, "%s %u\n", request, mru);
686
687       switch (mode_type) {
688       case MODE_REQ:
689         if (mp->cfg.mrru) {
690           if (REJECTED(lcp, TY_MRRU))
691             /* Ignore his previous reject so that we REQ next time */
692             lcp->his_reject &= ~(1 << opt->hdr.id);
693
694           if (mru > MAX_MRU) {
695             /* Push him down to MAX_MRU */
696             lcp->his_mrru = MAX_MRU;
697             nak.hdr.id = TY_MRRU;
698             nak.hdr.len = 4;
699             ua_htons(&lcp->his_mrru, nak.data);
700             fsm_nak(dec, &nak);
701           } else if (mru < MIN_MRU) {
702             /* Push him up to MIN_MRU */
703             lcp->his_mrru = MIN_MRU;
704             nak.hdr.id = TY_MRRU;
705             nak.hdr.len = 4;
706             ua_htons(&lcp->his_mrru, nak.data);
707             fsm_nak(dec, &nak);
708           } else {
709             lcp->his_mrru = mru;
710             fsm_ack(dec, opt);
711           }
712           break;
713         } else {
714           fsm_rej(dec, opt);
715           lcp->my_reject |= (1 << opt->hdr.id);
716         }
717         break;
718       case MODE_NAK:
719         if (mp->cfg.mrru) {
720           if (REJECTED(lcp, TY_MRRU))
721             /* Must have changed his mind ! */
722             lcp->his_reject &= ~(1 << opt->hdr.id);
723
724           if (mru > MAX_MRU)
725             lcp->want_mrru = MAX_MRU;
726           else if (mru < MIN_MRU)
727             lcp->want_mrru = MIN_MRU;
728           else
729             lcp->want_mrru = mru;
730         }
731         /* else we honour our config and don't send the suggested REQ */
732         break;
733       case MODE_REJ:
734         lcp->his_reject |= (1 << opt->hdr.id);
735         lcp->want_mrru = 0;             /* Ah well, no multilink :-( */
736         break;
737       }
738       break;
739
740     case TY_MRU:
741       lcp->mru_req = 1;
742       ua_ntohs(opt->data, &mru);
743       log_Printf(LogLCP, "%s %d\n", request, mru);
744
745       switch (mode_type) {
746       case MODE_REQ:
747         maxmtu = p ? physical_DeviceMTU(p) : 0;
748         if (lcp->cfg.max_mtu && (!maxmtu || maxmtu > lcp->cfg.max_mtu))
749           maxmtu = lcp->cfg.max_mtu;
750         wantmtu = lcp->cfg.mtu;
751         if (maxmtu && wantmtu > maxmtu) {
752           log_Printf(LogWARN, "%s: Reducing configured MTU from %u to %u\n",
753                      fp->link->name, wantmtu, maxmtu);
754           wantmtu = maxmtu;
755         }
756
757         if (maxmtu && mru > maxmtu) {
758           lcp->his_mru = maxmtu;
759           nak.hdr.id = TY_MRU;
760           nak.hdr.len = 4;
761           ua_htons(&lcp->his_mru, nak.data);
762           fsm_nak(dec, &nak);
763         } else if (wantmtu && mru < wantmtu) {
764           /* Push him up to MTU or MIN_MRU */
765           lcp->his_mru = wantmtu;
766           nak.hdr.id = TY_MRU;
767           nak.hdr.len = 4;
768           ua_htons(&lcp->his_mru, nak.data);
769           fsm_nak(dec, &nak);
770         } else {
771           lcp->his_mru = mru;
772           fsm_ack(dec, opt);
773         }
774         break;
775       case MODE_NAK:
776         maxmru = p ? physical_DeviceMTU(p) : 0;
777         if (lcp->cfg.max_mru && (!maxmru || maxmru > lcp->cfg.max_mru))
778           maxmru = lcp->cfg.max_mru;
779         wantmru = lcp->cfg.mru > maxmru ? maxmru : lcp->cfg.mru;
780
781         if (wantmru && mru > wantmru)
782           lcp->want_mru = wantmru;
783         else if (mru > maxmru)
784           lcp->want_mru = maxmru;
785         else if (mru < MIN_MRU)
786           lcp->want_mru = MIN_MRU;
787         else
788           lcp->want_mru = mru;
789         break;
790       case MODE_REJ:
791         lcp->his_reject |= (1 << opt->hdr.id);
792         break;
793       }
794       break;
795
796     case TY_ACCMAP:
797       ua_ntohl(opt->data, &accmap);
798       log_Printf(LogLCP, "%s 0x%08lx\n", request, (u_long)accmap);
799
800       switch (mode_type) {
801       case MODE_REQ:
802         lcp->his_accmap = accmap;
803         fsm_ack(dec, opt);
804         break;
805       case MODE_NAK:
806         lcp->want_accmap = accmap;
807         break;
808       case MODE_REJ:
809         lcp->his_reject |= (1 << opt->hdr.id);
810         break;
811       }
812       break;
813
814     case TY_AUTHPROTO:
815       ua_ntohs(opt->data, &proto);
816       chap_type = opt->hdr.len == 5 ? opt->data[2] : 0;
817
818       log_Printf(LogLCP, "%s 0x%04x (%s)\n", request, proto,
819                  Auth2Nam(proto, chap_type));
820
821       switch (mode_type) {
822       case MODE_REQ:
823         switch (proto) {
824         case PROTO_PAP:
825           if (opt->hdr.len == 4 && IsAccepted(lcp->cfg.pap)) {
826             lcp->his_auth = proto;
827             lcp->his_authtype = 0;
828             fsm_ack(dec, opt);
829           } else if (!lcp_auth_nak(lcp, dec)) {
830             lcp->my_reject |= (1 << opt->hdr.id);
831             fsm_rej(dec, opt);
832           }
833           break;
834
835         case PROTO_CHAP:
836           if ((chap_type == 0x05 && IsAccepted(lcp->cfg.chap05))
837 #ifndef NODES
838               || (chap_type == 0x80 && (IsAccepted(lcp->cfg.chap80nt) ||
839                                    (IsAccepted(lcp->cfg.chap80lm))))
840               || (chap_type == 0x81 && IsAccepted(lcp->cfg.chap81))
841 #endif
842              ) {
843             lcp->his_auth = proto;
844             lcp->his_authtype = chap_type;
845             fsm_ack(dec, opt);
846           } else {
847 #ifdef NODES
848             if (chap_type == 0x80) {
849               log_Printf(LogWARN, "CHAP 0x80 not available without DES\n");
850             } else if (chap_type == 0x81) {
851               log_Printf(LogWARN, "CHAP 0x81 not available without DES\n");
852             } else
853 #endif
854             if (chap_type != 0x05)
855               log_Printf(LogWARN, "%s not supported\n",
856                          Auth2Nam(PROTO_CHAP, chap_type));
857
858             if (!lcp_auth_nak(lcp, dec)) {
859               lcp->my_reject |= (1 << opt->hdr.id);
860               fsm_rej(dec, opt);
861             }
862           }
863           break;
864
865         default:
866           log_Printf(LogLCP, "%s 0x%04x - not recognised\n",
867                     request, proto);
868           if (!lcp_auth_nak(lcp, dec)) {
869             lcp->my_reject |= (1 << opt->hdr.id);
870             fsm_rej(dec, opt);
871           }
872           break;
873         }
874         break;
875
876       case MODE_NAK:
877         switch (proto) {
878         case PROTO_PAP:
879           if (IsEnabled(lcp->cfg.pap)) {
880             lcp->want_auth = PROTO_PAP;
881             lcp->want_authtype = 0;
882           } else {
883             log_Printf(LogLCP, "Peer will only send PAP (not enabled)\n");
884             lcp->his_reject |= (1 << opt->hdr.id);
885           }
886           break;
887         case PROTO_CHAP:
888           if (chap_type == 0x05 && IsEnabled(lcp->cfg.chap05)) {
889             lcp->want_auth = PROTO_CHAP;
890             lcp->want_authtype = 0x05;
891 #ifndef NODES
892           } else if (chap_type == 0x80 && (IsEnabled(lcp->cfg.chap80nt) ||
893                                            IsEnabled(lcp->cfg.chap80lm))) {
894             lcp->want_auth = PROTO_CHAP;
895             lcp->want_authtype = 0x80;
896           } else if (chap_type == 0x81 && IsEnabled(lcp->cfg.chap81)) {
897             lcp->want_auth = PROTO_CHAP;
898             lcp->want_authtype = 0x81;
899 #endif
900           } else {
901 #ifdef NODES
902             if (chap_type == 0x80) {
903               log_Printf(LogLCP, "Peer will only send MSCHAP (not available"
904                          " without DES)\n");
905             } else if (chap_type == 0x81) {
906               log_Printf(LogLCP, "Peer will only send MSCHAPV2 (not available"
907                          " without DES)\n");
908             } else
909 #endif
910             log_Printf(LogLCP, "Peer will only send %s (not %s)\n",
911                        Auth2Nam(PROTO_CHAP, chap_type),
912 #ifndef NODES
913                        (chap_type == 0x80 || chap_type == 0x81) ? "configured" :
914 #endif
915                        "supported");
916             lcp->his_reject |= (1 << opt->hdr.id);
917           }
918           break;
919         default:
920           /* We've been NAK'd with something we don't understand :-( */
921           lcp->his_reject |= (1 << opt->hdr.id);
922           break;
923         }
924         break;
925
926       case MODE_REJ:
927         lcp->his_reject |= (1 << opt->hdr.id);
928         break;
929       }
930       break;
931
932     case TY_QUALPROTO:
933       req = (struct lqrreq *)opt;
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           fsm_rej(dec, opt);
940           lcp->my_reject |= (1 << opt->hdr.id);
941         } else {
942           lcp->his_lqrperiod = ntohl(req->period);
943           if (lcp->his_lqrperiod < MIN_LQRPERIOD * 100)
944             lcp->his_lqrperiod = MIN_LQRPERIOD * 100;
945           req->period = htonl(lcp->his_lqrperiod);
946           fsm_ack(dec, opt);
947         }
948         break;
949       case MODE_NAK:
950         lcp->want_lqrperiod = ntohl(req->period);
951         break;
952       case MODE_REJ:
953         lcp->his_reject |= (1 << opt->hdr.id);
954         break;
955       }
956       break;
957
958     case TY_MAGICNUM:
959       ua_ntohl(opt->data, &magic);
960       log_Printf(LogLCP, "%s 0x%08lx\n", request, (u_long)magic);
961
962       switch (mode_type) {
963       case MODE_REQ:
964         if (lcp->want_magic) {
965           /* Validate magic number */
966           if (magic == lcp->want_magic) {
967             sigset_t emptyset;
968
969             log_Printf(LogLCP, "Magic is same (%08lx) - %d times\n",
970                       (u_long)magic, ++lcp->LcpFailedMagic);
971             lcp->want_magic = GenerateMagic();
972             fsm_nak(dec, opt);
973             ualarm(TICKUNIT * (4 + 4 * lcp->LcpFailedMagic), 0);
974             sigemptyset(&emptyset);
975             sigsuspend(&emptyset);
976           } else {
977             lcp->his_magic = magic;
978             lcp->LcpFailedMagic = 0;
979             fsm_ack(dec, opt);
980           }
981         } else {
982           lcp->my_reject |= (1 << opt->hdr.id);
983           fsm_rej(dec, opt);
984         }
985         break;
986       case MODE_NAK:
987         log_Printf(LogLCP, " Magic 0x%08lx is NAKed!\n", (u_long)magic);
988         lcp->want_magic = GenerateMagic();
989         break;
990       case MODE_REJ:
991         log_Printf(LogLCP, " Magic 0x%08x is REJected!\n", magic);
992         lcp->want_magic = 0;
993         lcp->his_reject |= (1 << opt->hdr.id);
994         break;
995       }
996       break;
997
998     case TY_PROTOCOMP:
999       log_Printf(LogLCP, "%s\n", request);
1000
1001       switch (mode_type) {
1002       case MODE_REQ:
1003         if (IsAccepted(lcp->cfg.protocomp)) {
1004           lcp->his_protocomp = 1;
1005           fsm_ack(dec, opt);
1006         } else {
1007 #ifdef OLDMST
1008           /* MorningStar before v1.3 needs NAK */
1009           fsm_nak(dec, opt);
1010 #else
1011           fsm_rej(dec, opt);
1012           lcp->my_reject |= (1 << opt->hdr.id);
1013 #endif
1014         }
1015         break;
1016       case MODE_NAK:
1017       case MODE_REJ:
1018         lcp->want_protocomp = 0;
1019         lcp->his_reject |= (1 << opt->hdr.id);
1020         break;
1021       }
1022       break;
1023
1024     case TY_ACFCOMP:
1025       log_Printf(LogLCP, "%s\n", request);
1026       switch (mode_type) {
1027       case MODE_REQ:
1028         if (IsAccepted(lcp->cfg.acfcomp)) {
1029           lcp->his_acfcomp = 1;
1030           fsm_ack(dec, opt);
1031         } else {
1032 #ifdef OLDMST
1033           /* MorningStar before v1.3 needs NAK */
1034           fsm_nak(dec, opt);
1035 #else
1036           fsm_rej(dec, opt);
1037           lcp->my_reject |= (1 << opt->hdr.id);
1038 #endif
1039         }
1040         break;
1041       case MODE_NAK:
1042       case MODE_REJ:
1043         lcp->want_acfcomp = 0;
1044         lcp->his_reject |= (1 << opt->hdr.id);
1045         break;
1046       }
1047       break;
1048
1049     case TY_SDP:
1050       log_Printf(LogLCP, "%s\n", request);
1051       switch (mode_type) {
1052       case MODE_REQ:
1053       case MODE_NAK:
1054       case MODE_REJ:
1055         break;
1056       }
1057       break;
1058
1059     case TY_CALLBACK:
1060       if (opt->hdr.len == 2) {
1061         op = CALLBACK_NONE;
1062         sz = 0;
1063       } else {
1064         op = (int)opt->data[0];
1065         sz = opt->hdr.len - 3;
1066       }
1067       switch (op) {
1068         case CALLBACK_AUTH:
1069           log_Printf(LogLCP, "%s Auth\n", request);
1070           break;
1071         case CALLBACK_DIALSTRING:
1072           log_Printf(LogLCP, "%s Dialstring %.*s\n", request, (int)sz,
1073                      opt->data + 1);
1074           break;
1075         case CALLBACK_LOCATION:
1076           log_Printf(LogLCP, "%s Location %.*s\n", request, (int)sz, opt->data + 1);
1077           break;
1078         case CALLBACK_E164:
1079           log_Printf(LogLCP, "%s E.164 (%.*s)\n", request, (int)sz, opt->data + 1);
1080           break;
1081         case CALLBACK_NAME:
1082           log_Printf(LogLCP, "%s Name %.*s\n", request, (int)sz, opt->data + 1);
1083           break;
1084         case CALLBACK_CBCP:
1085           log_Printf(LogLCP, "%s CBCP\n", request);
1086           break;
1087         default:
1088           log_Printf(LogLCP, "%s ???\n", request);
1089           break;
1090       }
1091
1092       switch (mode_type) {
1093       case MODE_REQ:
1094         callback_req = 1;
1095         if (p->type != PHYS_DIRECT) {
1096           fsm_rej(dec, opt);
1097           lcp->my_reject |= (1 << opt->hdr.id);
1098         }
1099         nak.hdr.id = opt->hdr.id;
1100         nak.hdr.len = 3;
1101         if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(op)) &&
1102             (op != CALLBACK_AUTH || p->link.lcp.want_auth) &&
1103             (op != CALLBACK_E164 ||
1104              E164ok(&p->dl->cfg.callback, opt->data + 1, sz))) {
1105           lcp->his_callback.opmask = CALLBACK_BIT(op);
1106           if (sz > sizeof lcp->his_callback.msg - 1) {
1107             sz = sizeof lcp->his_callback.msg - 1;
1108             log_Printf(LogWARN, "Truncating option arg to %zu octets\n", sz);
1109           }
1110           memcpy(lcp->his_callback.msg, opt->data + 1, sz);
1111           lcp->his_callback.msg[sz] = '\0';
1112           fsm_ack(dec, opt);
1113         } else if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) &&
1114                     p->link.lcp.auth_ineed) {
1115           nak.data[0] = CALLBACK_AUTH;
1116           fsm_nak(dec, &nak);
1117         } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_CBCP)) {
1118           nak.data[0] = CALLBACK_CBCP;
1119           fsm_nak(dec, &nak);
1120         } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_E164)) {
1121           nak.data[0] = CALLBACK_E164;
1122           fsm_nak(dec, &nak);
1123         } else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) {
1124           log_Printf(LogWARN, "Cannot insist on auth callback without"
1125                      " PAP or CHAP enabled !\n");
1126           nak.data[0] = 2;
1127           fsm_nak(dec, &nak);
1128         } else {
1129           lcp->my_reject |= (1 << opt->hdr.id);
1130           fsm_rej(dec, opt);
1131         }
1132         break;
1133       case MODE_NAK:
1134         /* We don't do what he NAKs with, we do things in our preferred order */
1135         if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_AUTH))
1136           lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_AUTH);
1137         else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_CBCP))
1138           lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_CBCP);
1139         else if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_E164))
1140           lcp->want_callback.opmask &= ~CALLBACK_BIT(CALLBACK_E164);
1141         if (lcp->want_callback.opmask == CALLBACK_BIT(CALLBACK_NONE)) {
1142           log_Printf(LogPHASE, "Peer NAKd all callbacks, trying none\n");
1143           lcp->want_callback.opmask = 0;
1144         } else if (!lcp->want_callback.opmask) {
1145           log_Printf(LogPHASE, "Peer NAKd last configured callback\n");
1146           fsm_Close(&lcp->fsm);
1147         }
1148         break;
1149       case MODE_REJ:
1150         if (lcp->want_callback.opmask & CALLBACK_BIT(CALLBACK_NONE)) {
1151           lcp->his_reject |= (1 << opt->hdr.id);
1152           lcp->want_callback.opmask = 0;
1153         } else {
1154           log_Printf(LogPHASE, "Peer rejected *required* callback\n");
1155           fsm_Close(&lcp->fsm);
1156         }
1157         break;
1158       }
1159       break;
1160
1161     case TY_SHORTSEQ:
1162       mp = &lcp->fsm.bundle->ncp.mp;
1163       log_Printf(LogLCP, "%s\n", request);
1164
1165       switch (mode_type) {
1166       case MODE_REQ:
1167         if (lcp->want_mrru && IsAccepted(mp->cfg.shortseq)) {
1168           lcp->his_shortseq = 1;
1169           fsm_ack(dec, opt);
1170         } else {
1171           fsm_rej(dec, opt);
1172           lcp->my_reject |= (1 << opt->hdr.id);
1173         }
1174         break;
1175       case MODE_NAK:
1176         /*
1177          * He's trying to get us to ask for short sequence numbers.
1178          * We ignore the NAK and honour our configuration file instead.
1179          */
1180         break;
1181       case MODE_REJ:
1182         lcp->his_reject |= (1 << opt->hdr.id);
1183         lcp->want_shortseq = 0;         /* For when we hit MP */
1184         break;
1185       }
1186       break;
1187
1188     case TY_ENDDISC:
1189       mp = &lcp->fsm.bundle->ncp.mp;
1190       log_Printf(LogLCP, "%s %s\n", request,
1191                  mp_Enddisc(opt->data[0], opt->data + 1, opt->hdr.len - 3));
1192       switch (mode_type) {
1193       case MODE_REQ:
1194         if (!p) {
1195           log_Printf(LogLCP, " ENDDISC rejected - not a physical link\n");
1196           fsm_rej(dec, opt);
1197           lcp->my_reject |= (1 << opt->hdr.id);
1198         } else if (!IsAccepted(mp->cfg.negenddisc)) {
1199           lcp->my_reject |= (1 << opt->hdr.id);
1200           fsm_rej(dec, opt);
1201         } else if (opt->hdr.len < sizeof p->dl->peer.enddisc.address + 3 &&
1202                    opt->data[0] <= MAX_ENDDISC_CLASS) {
1203           p->dl->peer.enddisc.class = opt->data[0];
1204           p->dl->peer.enddisc.len = opt->hdr.len - 3;
1205           memcpy(p->dl->peer.enddisc.address, opt->data + 1, opt->hdr.len - 3);
1206           p->dl->peer.enddisc.address[opt->hdr.len - 3] = '\0';
1207           /* XXX: If mp->active, compare and NAK with mp->peer ? */
1208           fsm_ack(dec, opt);
1209         } else {
1210           if (opt->data[0] > MAX_ENDDISC_CLASS)
1211             log_Printf(LogLCP, " ENDDISC rejected - unrecognised class %d\n",
1212                       opt->data[0]);
1213           else
1214             log_Printf(LogLCP, " ENDDISC rejected - local max length is %ld\n",
1215                       (long)(sizeof p->dl->peer.enddisc.address - 1));
1216           fsm_rej(dec, opt);
1217           lcp->my_reject |= (1 << opt->hdr.id);
1218         }
1219         break;
1220
1221       case MODE_NAK:    /* Treat this as a REJ, we don't vary our disc (yet) */
1222       case MODE_REJ:
1223         lcp->his_reject |= (1 << opt->hdr.id);
1224         break;
1225       }
1226       break;
1227
1228     default:
1229       sz = (sizeof desc - 2) / 2;
1230       if (sz + 2 > opt->hdr.len)
1231         sz = opt->hdr.len - 2;
1232       pos = 0;
1233       desc[0] = sz ? ' ' : '\0';
1234       for (pos = 0; sz--; pos++)
1235         sprintf(desc+(pos<<1)+1, "%02x", opt->data[pos]);
1236
1237       log_Printf(LogLCP, "%s%s\n", request, desc);
1238
1239       if (mode_type == MODE_REQ) {
1240         fsm_rej(dec, opt);
1241         lcp->my_reject |= (1 << opt->hdr.id);
1242       }
1243       break;
1244     }
1245   }
1246
1247   if (mode_type != MODE_NOP) {
1248     if (mode_type == MODE_REQ && p && p->type == PHYS_DIRECT &&
1249         p->dl->cfg.callback.opmask && !callback_req &&
1250         !(p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_NONE))) {
1251       /* We *REQUIRE* that the peer requests callback */
1252       nak.hdr.id = TY_CALLBACK;
1253       nak.hdr.len = 3;
1254       if ((p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_AUTH)) &&
1255           p->link.lcp.want_auth)
1256         nak.data[0] = CALLBACK_AUTH;
1257       else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_CBCP))
1258         nak.data[0] = CALLBACK_CBCP;
1259       else if (p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_E164))
1260         nak.data[0] = CALLBACK_E164;
1261       else {
1262         log_Printf(LogWARN, "Cannot insist on auth callback without"
1263                    " PAP or CHAP enabled !\n");
1264         nak.hdr.len = 2;        /* XXX: Silly ! */
1265       }
1266       fsm_nak(dec, &nak);
1267     }
1268     if (mode_type == MODE_REQ && !lcp->mru_req) {
1269       mru = DEF_MRU;
1270       phmtu = p ? physical_DeviceMTU(p) : 0;
1271       if (phmtu && mru > phmtu)
1272         mru = phmtu;
1273       if (mru > lcp->cfg.max_mtu)
1274         mru = lcp->cfg.max_mtu;
1275       if (mru < DEF_MRU) {
1276         /* Don't let the peer use the default MRU */
1277         lcp->his_mru = lcp->cfg.mtu && lcp->cfg.mtu < mru ? lcp->cfg.mtu : mru;
1278         nak.hdr.id = TY_MRU;
1279         nak.hdr.len = 4;
1280         ua_htons(&lcp->his_mru, nak.data);
1281         fsm_nak(dec, &nak);
1282         lcp->mru_req = 1;       /* Don't keep NAK'ing this */
1283       }
1284     }
1285     fsm_opt_normalise(dec);
1286   }
1287 }
1288
1289 extern struct mbuf *
1290 lcp_Input(struct bundle *bundle __unused, struct link *l, struct mbuf *bp)
1291 {
1292   /* Got PROTO_LCP from link */
1293   m_settype(bp, MB_LCPIN);
1294   fsm_Input(&l->lcp.fsm, bp);
1295   return NULL;
1296 }