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