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