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