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